Skip to content

Commit 6cd8ea3

Browse files
S.KulishS.Kulish
authored andcommitted
hw08_envdir_tool
1 parent 27351a3 commit 6cd8ea3

9 files changed

Lines changed: 295 additions & 10 deletions

File tree

hw08_envdir_tool/.sync

Whitespace-only changes.

hw08_envdir_tool/env_reader.go

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
package main
22

3+
import (
4+
"bufio"
5+
"fmt"
6+
"io/fs"
7+
"io/ioutil"
8+
"os"
9+
"strings"
10+
)
11+
12+
const INVALID_FILE_NAME_CHARACTER = "="
13+
314
type Environment map[string]EnvValue
415

516
// EnvValue helps to distinguish between empty files and files with the first empty line.
@@ -11,6 +22,77 @@ type EnvValue struct {
1122
// ReadDir reads a specified directory and returns map of env variables.
1223
// Variables represented as files where filename is name of variable, file first line is a value.
1324
func ReadDir(dir string) (Environment, error) {
14-
// Place your code here
15-
return nil, nil
25+
var valName string
26+
var valValue string
27+
var needRemove bool
28+
var ok bool
29+
30+
result := make(Environment)
31+
32+
files, err := ioutil.ReadDir(dir)
33+
if err != nil {
34+
return result, fmt.Errorf("read dir: %w", err)
35+
}
36+
37+
for _, f := range files {
38+
39+
valName, ok = getFileName(f)
40+
if ok == false {
41+
continue
42+
}
43+
44+
valValue, needRemove, err = getValue(dir, f)
45+
if err != nil {
46+
return result, fmt.Errorf("get value error: %w", err)
47+
}
48+
49+
result[valName] = EnvValue{valValue, needRemove}
50+
}
51+
52+
return result, nil
53+
}
54+
55+
func getFileName(file fs.FileInfo) (string, bool) {
56+
if file.IsDir() {
57+
return "", false
58+
}
59+
60+
if strings.Contains(file.Name(), INVALID_FILE_NAME_CHARACTER) {
61+
return "", false
62+
}
63+
64+
return file.Name(), true
65+
}
66+
67+
func getValue(dir string, fileInfo fs.FileInfo) (string, bool, error) {
68+
if fileInfo.Size() == 0 {
69+
return "", true, nil
70+
}
71+
72+
file, err := os.Open(dir + "/" + fileInfo.Name())
73+
74+
if err != nil {
75+
return "", false, err
76+
}
77+
78+
defer file.Close()
79+
80+
scanner := bufio.NewScanner(file)
81+
82+
scanner.Scan()
83+
value := scanner.Text()
84+
85+
err = scanner.Err()
86+
if err != nil {
87+
return "", false, err
88+
}
89+
90+
result := strings.TrimRight(value, " \t")
91+
92+
index := strings.Index(result, "\x00")
93+
if index > -1 {
94+
result = result[0:index]
95+
}
96+
97+
return result, false, nil
1698
}
Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,72 @@
11
package main
22

3-
import "testing"
3+
import (
4+
"fmt"
5+
"github.com/stretchr/testify/require"
6+
"os"
7+
"testing"
8+
)
49

510
func TestReadDir(t *testing.T) {
6-
// Place your code here
11+
_, err := ReadDir("not_exist_dir")
12+
require.Error(t, err)
13+
14+
result, err := ReadDir("testdata/env")
15+
require.NoError(t, err)
16+
require.Equal(t, getExpectedResult(), result)
17+
18+
// check if ignores files
19+
testDirName := "testdata/env/2"
20+
createTestDir(testDirName)
21+
result, err = ReadDir("testdata/env")
22+
require.NoError(t, err)
23+
require.Equal(t, getExpectedResult(), result)
24+
removeTestDir(testDirName)
25+
26+
// check if ignores files with the - in the name
27+
testFileName := "testdata/env/2=2.txt"
28+
createTestFile(testFileName, []byte("hello\ngo\n"))
29+
result, err = ReadDir("testdata/env")
30+
require.NoError(t, err)
31+
require.Equal(t, getExpectedResult(), result)
32+
removeTestFile(testFileName)
33+
}
34+
35+
func createTestDir(dir string) {
36+
err := os.MkdirAll(dir, os.ModePerm)
37+
if err != nil {
38+
panic(fmt.Errorf("Error creating test directory: %w", err))
39+
}
40+
}
41+
42+
func removeTestDir(dir string) {
43+
err := os.RemoveAll(dir)
44+
if err != nil {
45+
panic(fmt.Errorf("Error removing test directory: %w", err))
46+
}
47+
}
48+
49+
func createTestFile(file string, data []byte) {
50+
err := os.WriteFile(file, data, os.ModePerm)
51+
if err != nil {
52+
panic(fmt.Errorf("Error creating test file: %w", err))
53+
}
54+
}
55+
56+
func removeTestFile(file string) {
57+
err := os.Remove(file)
58+
if err != nil {
59+
panic(fmt.Errorf("Error removing test directory: %w", err))
60+
}
61+
}
62+
63+
func getExpectedResult() Environment {
64+
result := make(Environment)
65+
result["BAR"] = EnvValue{"bar", false}
66+
result["EMPTY"] = EnvValue{"", false}
67+
result["FOO"] = EnvValue{" foo", false}
68+
result["HELLO"] = EnvValue{"\"hello\"", false}
69+
result["UNSET"] = EnvValue{"", true}
70+
71+
return result
772
}

hw08_envdir_tool/executor.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,40 @@
11
package main
22

3+
import (
4+
"os"
5+
"os/exec"
6+
)
7+
38
// RunCmd runs a command + arguments (cmd) with environment variables from env.
49
func RunCmd(cmd []string, env Environment) (returnCode int) {
5-
// Place your code here.
6-
return
10+
command := exec.Command(cmd[0], cmd[1:]...)
11+
setEnvironmentVariables(env)
12+
13+
command.Stdout = os.Stdout
14+
command.Stdin = os.Stdin
15+
16+
err := command.Start()
17+
if err != nil {
18+
panic(err)
19+
}
20+
21+
err = command.Wait()
22+
if err != nil {
23+
panic(err)
24+
}
25+
26+
return command.ProcessState.ExitCode()
27+
}
28+
29+
func setEnvironmentVariables(env Environment) bool {
30+
for name, envValue := range env {
31+
if envValue.NeedRemove == true {
32+
os.Unsetenv(name)
33+
continue
34+
}
35+
36+
os.Setenv(name, envValue.Value)
37+
}
38+
39+
return true
740
}

hw08_envdir_tool/executor_test.go

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,84 @@
11
package main
22

3-
import "testing"
3+
import (
4+
"github.com/stretchr/testify/require"
5+
"testing"
6+
//"fmt"
7+
"os"
8+
)
9+
10+
func TestCanSetEnvironmentVariables(t *testing.T) {
11+
// backup env variables before the test if any was set
12+
backup := backupEnvironment()
13+
14+
os.Unsetenv("HELLO")
15+
16+
env := make(Environment)
17+
env["HELLO"] = EnvValue{"hello", false}
18+
19+
setEnvironmentVariables(env)
20+
21+
value, present := os.LookupEnv("HELLO")
22+
require.Equal(t, true, present)
23+
require.Equal(t, "hello", value)
24+
25+
// restore backup variables
26+
restoreEnvironmentFromTheBackup(backup)
27+
}
28+
29+
func TestCanRemoveEnvironmentVariables(t *testing.T) {
30+
// backup env variables before the test if any was set
31+
backup := backupEnvironment()
32+
33+
os.Setenv("HELLO", "hello")
34+
35+
env := make(Environment)
36+
env["HELLO"] = EnvValue{"hello", true}
37+
38+
setEnvironmentVariables(env)
39+
_, present := os.LookupEnv("HELLO")
40+
require.Equal(t, false, present)
41+
42+
// restore backup variables
43+
restoreEnvironmentFromTheBackup(backup)
44+
}
445

546
func TestRunCmd(t *testing.T) {
6-
// Place your code here
47+
cmd := make([]string, 2)
48+
cmd[0] = "testdata/echo.sh"
49+
cmd[1] = "arg1"
50+
code := RunCmd(cmd, getAllValues())
51+
require.Equal(t, 0, code)
52+
}
53+
54+
func backupEnvironment() map[string]string {
55+
var testEnvNames = []string{"HELLO", "BAR", "FOO", "UNSET", "ADDED", "EMPTY"}
56+
result := make(map[string]string)
57+
58+
for _, name := range testEnvNames {
59+
value, present := os.LookupEnv(name)
60+
if present == true {
61+
result[name] = value
62+
}
63+
}
64+
65+
return result
66+
}
67+
68+
func restoreEnvironmentFromTheBackup(env map[string]string) {
69+
for name, value := range env {
70+
os.Setenv(name, value)
71+
}
72+
}
73+
74+
func getAllValues() Environment {
75+
result := make(Environment)
76+
result["HELLO"] = EnvValue{"hello", false}
77+
result["BAR"] = EnvValue{"bar", false}
78+
result["FOO"] = EnvValue{"foo", false}
79+
result["UNSET"] = EnvValue{"unset", false}
80+
result["ADDED"] = EnvValue{"added", false}
81+
result["EMPTY"] = EnvValue{"empty", false}
82+
83+
return result
784
}

hw08_envdir_tool/go.mod

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
module github.com/fixme_my_friend/hw08_envdir_tool
1+
module github.com/sofiiakulish/hw08_envdir_tool
22

33
go 1.16
4+
5+
require github.com/stretchr/testify v1.8.0

hw08_envdir_tool/go.sum

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
3+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
5+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
6+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
7+
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
8+
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
9+
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
10+
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
11+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
12+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
13+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
14+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
15+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

hw08_envdir_tool/hw08_envdir_tool

2.04 MB
Binary file not shown.

hw08_envdir_tool/main.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
package main
22

3+
import (
4+
"os"
5+
)
6+
37
func main() {
4-
// Place your code here.
8+
// go-envdir /path/to/env/dir command arg1 arg2
9+
args := os.Args
10+
env, err := ReadDir(args[1])
11+
if err != nil {
12+
panic(err)
13+
}
14+
15+
RunCmd(args[2:], env)
516
}

0 commit comments

Comments
 (0)