From b720c6d360b09faa81392e9a7fe8a7c386ebeb28 Mon Sep 17 00:00:00 2001 From: lixulun Date: Thu, 18 Jun 2026 02:39:51 +0800 Subject: [PATCH] add env command --- .gitignore | 1 + env.go | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 5 +++- 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 env.go diff --git a/.gitignore b/.gitignore index 057f232..ca685b0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ , commago *~ +.env* diff --git a/env.go b/env.go new file mode 100644 index 0000000..ca6b133 --- /dev/null +++ b/env.go @@ -0,0 +1,74 @@ +package main + +import ( + "flag" + "fmt" + "log" + "os" + "os/exec" + "strings" +) + +var commandEnvDescription = "load environment variable from .env file" + +func commandEnv(args []string) { + var flagSet = flag.NewFlagSet("env", flag.ContinueOnError) + envFilePath := flagSet.String("file", ".env", "the file contains environment variables to parse") + printToScreen := flagSet.Bool("print", false, "wethear or not print to screen") + _ = printToScreen + printWithExport := flagSet.Bool("export", false, "wethear or not add `export` prefix to each variable when printing") + flagSet.Parse(args[1:]) + _, err := parseEnvFileAndSetEnv(*envFilePath, *printToScreen, *printWithExport) + if err != nil { + fmt.Printf("%v", err) + os.Exit(2) + } + if len(flagSet.Args()) > 0 { + cmd := exec.Command(flagSet.Args()[0], flagSet.Args()[1:]...) + var out strings.Builder + cmd.Stdout = &out + err = cmd.Run() + if err != nil { + log.Fatal(err) + } + fmt.Printf(out.String()) + } + +} + +func parseEnvFileAndSetEnv(filePath string, printToScreen, printWithExport bool) (string, error) { + raw, err := os.ReadFile(filePath) + if err != nil { + return "", fmt.Errorf("read from %v has error: %w", filePath, err) + } + rawLines := strings.Split(string(raw), "\n") + for i, line := range rawLines { + trimedLine := strings.TrimSpace(line) + if strings.HasPrefix(trimedLine, "#") { + continue + } + if trimedLine == "" { + continue + } + parts := strings.Split(trimedLine, "=") + if len(parts) != 2 { + return "", fmt.Errorf("line %v is malformed: `%v`", i+1, trimedLine) + } + if strings.TrimSpace(parts[0]) != parts[0] { + return "", fmt.Errorf("line %v is malformed: between variable name and `=` can't has any space", i+1) + } + if strings.TrimSpace(parts[1]) != parts[1] { + return "", fmt.Errorf("line %v is malformed: between `=` and value can't has any space", i+1) + } + os.Setenv(parts[0], parts[1]) + if printToScreen { + s := fmt.Sprintf("%v=%v\n", parts[0], parts[1]) + if printWithExport { + s = fmt.Sprintf("export %v", s) + } + fmt.Print(s) + } + + } + return "", nil +} diff --git a/main.go b/main.go index 7df6147..876b805 100644 --- a/main.go +++ b/main.go @@ -8,15 +8,18 @@ import ( func commandsUsage() string { return fmt.Sprintf( `commands: + env %v path %v time %v week %v -`, commandPathDescription, commandTimeDescription, commandWeekDescription) +`, commandEnvDescription, commandPathDescription, commandTimeDescription, commandWeekDescription) } func main() { if len(os.Args) >= 2 { switch os.Args[1] { + case "env": + commandEnv(os.Args[1:]) case "path": commandPath(os.Args[1:]) case "time":