Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file removed hw08_envdir_tool/.sync
Empty file.
83 changes: 81 additions & 2 deletions hw08_envdir_tool/env_reader.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
package main

import (
"bufio"
"fmt"
"io/fs"
"io/ioutil"
"os"
"strings"
)

const INVALID_FILE_NAME_CHARACTER = "="

type Environment map[string]EnvValue

// EnvValue helps to distinguish between empty files and files with the first empty line.
Expand All @@ -11,6 +22,74 @@ type EnvValue struct {
// ReadDir reads a specified directory and returns map of env variables.
// Variables represented as files where filename is name of variable, file first line is a value.
func ReadDir(dir string) (Environment, error) {
// Place your code here
return nil, nil
var valName string
var valValue string
var needRemove bool
var ok bool

result := make(Environment)

files, err := ioutil.ReadDir(dir)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

С Go 1.16 функции пакета ioutil помечены как deprecated, рекомендуется использовать функции пакета io и os: https://go.dev/doc/go1.16#ioutil

if err != nil {
return result, fmt.Errorf("read dir: %w", err)
}

for _, f := range files {

valName, ok = getFileName(f)
if ok == false {
continue
}

valValue, needRemove, err = getValue(dir, f)
if err != nil {
return result, fmt.Errorf("get value error: %w", err)
}

result[valName] = EnvValue{valValue, needRemove}
}

return result, nil
}

func getFileName(file fs.FileInfo) (string, bool) {
if file.IsDir() {
return "", false
}

if strings.Contains(file.Name(), INVALID_FILE_NAME_CHARACTER) {
return "", false
}

return file.Name(), true
}

func getValue(dir string, fileInfo fs.FileInfo) (string, bool, error) {
if fileInfo.Size() == 0 {
return "", true, nil
}

file, err := os.Open(dir + "/" + fileInfo.Name())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Для получения пути к файлу рекомендую использовать https://pkg.go.dev/path/filepath#Join


if err != nil {
return "", false, err
}

defer file.Close()

scanner := bufio.NewScanner(file)

scanner.Scan()
value := scanner.Text()

err = scanner.Err()
if err != nil {
return "", false, err
}

result := strings.TrimRight(value, " \t")

result = strings.Replace(result, "\x00", "\n", -1)

return result, false, nil
}
69 changes: 67 additions & 2 deletions hw08_envdir_tool/env_reader_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,72 @@
package main

import "testing"
import (
"fmt"
"github.com/stretchr/testify/require"
"os"
"testing"
)

func TestReadDir(t *testing.T) {
// Place your code here
_, err := ReadDir("not_exist_dir")
require.Error(t, err)

result, err := ReadDir("testdata/env")
require.NoError(t, err)
require.Equal(t, getExpectedResult(), result)

// check if ignores files
testDirName := "testdata/env/2"
createTestDir(testDirName)
result, err = ReadDir("testdata/env")
require.NoError(t, err)
require.Equal(t, getExpectedResult(), result)
removeTestDir(testDirName)

// check if ignores files with the - in the name
testFileName := "testdata/env/2=2.txt"
createTestFile(testFileName, []byte("hello\ngo\n"))
result, err = ReadDir("testdata/env")
require.NoError(t, err)
require.Equal(t, getExpectedResult(), result)
removeTestFile(testFileName)
}

func createTestDir(dir string) {
err := os.MkdirAll(dir, os.ModePerm)
if err != nil {
panic(fmt.Errorf("Error creating test directory: %w", err))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Желательно не паниковать, даже в тестах. Предложил бы использовать функции пакета testify/require

}
}

func removeTestDir(dir string) {
err := os.RemoveAll(dir)
if err != nil {
panic(fmt.Errorf("Error removing test directory: %w", err))
}
}

func createTestFile(file string, data []byte) {
err := os.WriteFile(file, data, os.ModePerm)
if err != nil {
panic(fmt.Errorf("Error creating test file: %w", err))
}
}

func removeTestFile(file string) {
err := os.Remove(file)
if err != nil {
panic(fmt.Errorf("Error removing test directory: %w", err))
}
}

func getExpectedResult() Environment {
result := make(Environment)
result["BAR"] = EnvValue{"bar", false}
result["EMPTY"] = EnvValue{"", false}
result["FOO"] = EnvValue{" foo\nwith new line", false}
result["HELLO"] = EnvValue{"\"hello\"", false}
result["UNSET"] = EnvValue{"", true}

return result
}
37 changes: 35 additions & 2 deletions hw08_envdir_tool/executor.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,40 @@
package main

import (
"os"
"os/exec"
)

// RunCmd runs a command + arguments (cmd) with environment variables from env.
func RunCmd(cmd []string, env Environment) (returnCode int) {
// Place your code here.
return
command := exec.Command(cmd[0], cmd[1:]...)
setEnvironmentVariables(env)

command.Stdout = os.Stdout
command.Stdin = os.Stdin

err := command.Start()
if err != nil {
panic(err)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В программе особенно не рекомендуется паниковать. Обработанная ошибка для пользователя будет выглядеть гораздо понятнее

}

err = command.Wait()
if err != nil {
panic(err)
}

return command.ProcessState.ExitCode()
}

func setEnvironmentVariables(env Environment) bool {
for name, envValue := range env {
if envValue.NeedRemove == true {
os.Unsetenv(name)
continue
}

os.Setenv(name, envValue.Value)
}

return true
}
81 changes: 79 additions & 2 deletions hw08_envdir_tool/executor_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,84 @@
package main

import "testing"
import (
"github.com/stretchr/testify/require"
"testing"
//"fmt"
"os"
)

func TestCanSetEnvironmentVariables(t *testing.T) {
// backup env variables before the test if any was set
backup := backupEnvironment()

os.Unsetenv("HELLO")

env := make(Environment)
env["HELLO"] = EnvValue{"hello", false}

setEnvironmentVariables(env)

value, present := os.LookupEnv("HELLO")
require.Equal(t, true, present)
require.Equal(t, "hello", value)

// restore backup variables
restoreEnvironmentFromTheBackup(backup)
}

func TestCanRemoveEnvironmentVariables(t *testing.T) {
// backup env variables before the test if any was set
backup := backupEnvironment()

os.Setenv("HELLO", "hello")

env := make(Environment)
env["HELLO"] = EnvValue{"hello", true}

setEnvironmentVariables(env)
_, present := os.LookupEnv("HELLO")
require.Equal(t, false, present)

// restore backup variables
restoreEnvironmentFromTheBackup(backup)
}

func TestRunCmd(t *testing.T) {
// Place your code here
cmd := make([]string, 2)
cmd[0] = "testdata/echo.sh"
cmd[1] = "arg1"
code := RunCmd(cmd, getAllValues())
require.Equal(t, 0, code)
}

func backupEnvironment() map[string]string {
var testEnvNames = []string{"HELLO", "BAR", "FOO", "UNSET", "ADDED", "EMPTY"}
result := make(map[string]string)

for _, name := range testEnvNames {
value, present := os.LookupEnv(name)
if present == true {
result[name] = value
}
}

return result
}

func restoreEnvironmentFromTheBackup(env map[string]string) {
for name, value := range env {
os.Setenv(name, value)
}
}

func getAllValues() Environment {
result := make(Environment)
result["HELLO"] = EnvValue{"hello", false}
result["BAR"] = EnvValue{"bar", false}
result["FOO"] = EnvValue{"foo", false}
result["UNSET"] = EnvValue{"unset", false}
result["ADDED"] = EnvValue{"added", false}
result["EMPTY"] = EnvValue{"empty", false}

return result
}
4 changes: 3 additions & 1 deletion hw08_envdir_tool/go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module github.com/fixme_my_friend/hw08_envdir_tool
module github.com/sofiiakulish/hw08_envdir_tool
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
module github.com/sofiiakulish/hw08_envdir_tool
module github.com/sofiiakulish/hw/hw08_envdir_tool


go 1.16

require github.com/stretchr/testify v1.8.0
15 changes: 15 additions & 0 deletions hw08_envdir_tool/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Binary file added hw08_envdir_tool/hw08_envdir_tool
Binary file not shown.
13 changes: 12 additions & 1 deletion hw08_envdir_tool/main.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
package main

import (
"os"
)

func main() {
// Place your code here.
// go-envdir /path/to/env/dir command arg1 arg2
args := os.Args
env, err := ReadDir(args[1])
if err != nil {
panic(err)
}

RunCmd(args[2:], env)
}