-
Notifications
You must be signed in to change notification settings - Fork 0
HW08 is completed #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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. | ||
|
|
@@ -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) | ||
| 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()) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
| } | ||
| 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)) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Желательно не паниковать, даже в тестах. Предложил бы использовать функции пакета |
||
| } | ||
| } | ||
|
|
||
| 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 | ||
| } | ||
| 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) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
| } | ||
| 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 | ||
| } |
| 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 | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| go 1.16 | ||||||
|
|
||||||
| require github.com/stretchr/testify v1.8.0 | ||||||
| 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= |
| 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) | ||
| } |
There was a problem hiding this comment.
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