From 3641ab5f82a08f12f107c91a96748089870637cd Mon Sep 17 00:00:00 2001 From: Horiodino Date: Sat, 8 Jun 2024 08:14:03 +0530 Subject: [PATCH 1/5] direnv intigration Signed-off-by: Horiodino --- cmd/init/init.go | 2 +- cmd/init/model.go | 2 +- cmd/precheck/precheck.go | 51 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/cmd/init/init.go b/cmd/init/init.go index c66b7966..17abff9a 100644 --- a/cmd/init/init.go +++ b/cmd/init/init.go @@ -72,7 +72,7 @@ func GetBSFInitializers() (bsfv1.SearchServiceClient, *hcl2nix.FileHandlers, err } // CleanUp removes the bsf config if any error occurs in init process (ctrl+c or any init process stage) -func cleanUp(){ +func cleanUp() { configs := []string{"bsf", "bsf.hcl", "bsf.lock"} for _, f := range configs { diff --git a/cmd/init/model.go b/cmd/init/model.go index ddc1c7dd..940f4d34 100644 --- a/cmd/init/model.go +++ b/cmd/init/model.go @@ -73,7 +73,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } err = m.processStages(m.stage) if err != nil { - cleanUp() + cleanUp() return m, tea.Quit } m.stage++ diff --git a/cmd/precheck/precheck.go b/cmd/precheck/precheck.go index 3b8d2ac8..c2144afd 100644 --- a/cmd/precheck/precheck.go +++ b/cmd/precheck/precheck.go @@ -71,6 +71,55 @@ func IsFlakesEnabled() { } } +// generates .envrc for Direnv intigration +func generateEnvrc() error { + + if _, err := os.Stat(".envrc"); err == nil { + + read, err := os.ReadFile(".envrc") + if err != nil { + fmt.Println(styles.ErrorStyle.Render("", err.Error())) + os.Exit(1) + } + + if !strings.Contains(string(read), "use flake bsf/.") { + + file, err := os.OpenFile(".envrc", os.O_APPEND|os.O_WRONLY, 0644) + if err != nil { + fmt.Println(styles.ErrorStyle.Render("", err.Error())) + os.Exit(1) + } + + _, err = file.WriteString("\nuse flake bsf/.") + if err != nil { + fmt.Println(styles.ErrorStyle.Render("", err.Error())) + os.Exit(1) + } + return nil + } + fmt.Println(styles.HelpStyle.Render(" ✅ .envrc already exists")) + + } else { + file, err := os.Create(".envrc") + if err != nil { + fmt.Println(styles.ErrorStyle.Render("", err.Error())) + os.Exit(1) + } + + defer file.Close() + + _, err = file.WriteString("use flake bsf/.") + if err != nil { + fmt.Println(styles.ErrorStyle.Render("", err.Error())) + os.Exit(1) + } + } + + fmt.Println(styles.HelpStyle.Render(" ✅ .envrc generated")) + + return nil +} + // AllPrechecks runs all the prechecks func AllPrechecks() { fmt.Println(styles.TextStyle.Render("Running prechecks...")) @@ -86,8 +135,8 @@ func AllPrechecks() { }() go func() { + generateEnvrc() wg.Done() - }() wg.Wait() From 0fa592f9e349cff4cf15018617a81d4901dd4924 Mon Sep 17 00:00:00 2001 From: Horiodino Date: Tue, 11 Jun 2024 09:45:11 +0530 Subject: [PATCH 2/5] direnv intigration Signed-off-by: Horiodino --- .envrc | 2 +- cmd/cmd.go | 2 + cmd/direnv/direnv.go | 163 +++++++++++++++++++++++++++++++++++++++ cmd/precheck/precheck.go | 56 +------------- 4 files changed, 167 insertions(+), 56 deletions(-) create mode 100644 cmd/direnv/direnv.go diff --git a/.envrc b/.envrc index 8392d159..60768d10 100644 --- a/.envrc +++ b/.envrc @@ -1 +1 @@ -use flake \ No newline at end of file +use flake bsf/. \ No newline at end of file diff --git a/cmd/cmd.go b/cmd/cmd.go index b91d9f9c..bcc776f8 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -17,6 +17,7 @@ import ( "github.com/buildsafedev/bsf/cmd/build" "github.com/buildsafedev/bsf/cmd/configure" "github.com/buildsafedev/bsf/cmd/develop" + "github.com/buildsafedev/bsf/cmd/direnv" "github.com/buildsafedev/bsf/cmd/dockerfile" initCmd "github.com/buildsafedev/bsf/cmd/init" "github.com/buildsafedev/bsf/cmd/nixgenerate" @@ -63,6 +64,7 @@ func Execute() { rootCmd.AddCommand(scan.ScanCmd) rootCmd.AddCommand(update.UpdateCmd) rootCmd.AddCommand(attestation.AttCmd) + rootCmd.AddCommand(direnv.Direnv) if os.Getenv("BSF_DEBUG_MODE") == "true" { rootCmd.AddCommand(configure.ConfigureCmd) diff --git a/cmd/direnv/direnv.go b/cmd/direnv/direnv.go new file mode 100644 index 00000000..585f0d1d --- /dev/null +++ b/cmd/direnv/direnv.go @@ -0,0 +1,163 @@ +package direnv + +import ( + "fmt" + "os" + "os/exec" + "strings" + + "github.com/buildsafedev/bsf/cmd/styles" + "github.com/spf13/cobra" +) + +var Direnv = &cobra.Command{ + Use: "direnv", + Short: "direnv initializes the direnv environment for the project", + Run: func(cmd *cobra.Command, args []string) { + err := generateEnvrc() + if err != nil { + fmt.Println(styles.ErrorStyle.Render("error: ", err.Error())) + os.Exit(1) + } + err = fetchGitignore() + if err != nil { + fmt.Println(styles.ErrorStyle.Render("error: ", err.Error())) + os.Exit(1) + } + + if envVar != "" { + err = setDIrenv(envVar) + if err != nil { + fmt.Println(styles.ErrorStyle.Render("error: ", err.Error())) + os.Exit(1) + } + } + }, +} + +var ( + envVar string +) + +func init() { + Direnv.Flags().StringVarP(&envVar, "env", "e", "", "set environment variable [key=value]") +} + +func generateEnvrc() error { + + if _, err := os.Stat(".envrc"); err == nil { + + read, err := os.ReadFile(".envrc") + if err != nil { + return err + } + + if !strings.Contains(string(read), "use flake bsf/.") { + + file, err := os.OpenFile(".envrc", os.O_APPEND|os.O_WRONLY, 0644) + if err != nil { + return err + } + + _, err = file.WriteString("\nuse flake bsf/.") + if err != nil { + fmt.Println(styles.ErrorStyle.Render("", err.Error())) + return err + } + return nil + } + fmt.Println(styles.HelpStyle.Render(" ✅ .envrc already exists")) + + } else { + file, err := os.Create(".envrc") + if err != nil { + return err + } + + defer file.Close() + + _, err = file.WriteString("use flake bsf/.") + if err != nil { + return err + } + + fmt.Println(styles.HelpStyle.Render(" ✅ .envrc generated")) + + cmd := exec.Command("direnv", "allow") + err = cmd.Run() + if err != nil { + return err + } + } + + return nil +} + +func fetchGitignore() error { + + if _, err := os.Stat(".gitignore"); err == nil { + + read, err := os.ReadFile(".gitignore") + if err != nil { + return err + } + + if !strings.Contains(string(read), ".envrc") { + + file, err := os.OpenFile(".gitignore", os.O_APPEND|os.O_WRONLY, 0644) + _, err = file.WriteString("\n.envrc") + if err != nil { + fmt.Println(styles.ErrorStyle.Render("", err.Error())) + return err + } + } + fmt.Println(styles.HelpStyle.Render(" ✅ .gitignore already exists")) + + return nil + } else { + _, err := os.Create(".gitignore") + if err != nil { + return err + } + + file, err := os.OpenFile(".gitignore", os.O_APPEND|os.O_WRONLY, 0644) + if err != nil { + return err + } + + _, err = file.WriteString("\n.envrc") + if err != nil { + return err + } + + fmt.Println(styles.HelpStyle.Render(" ✅ .gitignore generated")) + } + + return nil + +} + +func setDIrenv(args string) error { + + if !strings.Contains(args, "=") { + return fmt.Errorf("Hint: use --env key=value") + } else { + file, err := os.OpenFile(".envrc", os.O_APPEND|os.O_WRONLY, 0644) + if err != nil { + return err + } + + _, err = file.WriteString("\nexport " + args) + if err != nil { + fmt.Println(styles.ErrorStyle.Render("", err.Error())) + return err + } + + cmd := exec.Command("direnv", "allow") + err = cmd.Run() + if err != nil { + return err + } + } + return nil +} diff --git a/cmd/precheck/precheck.go b/cmd/precheck/precheck.go index c2144afd..d47b282a 100644 --- a/cmd/precheck/precheck.go +++ b/cmd/precheck/precheck.go @@ -71,60 +71,11 @@ func IsFlakesEnabled() { } } -// generates .envrc for Direnv intigration -func generateEnvrc() error { - - if _, err := os.Stat(".envrc"); err == nil { - - read, err := os.ReadFile(".envrc") - if err != nil { - fmt.Println(styles.ErrorStyle.Render("", err.Error())) - os.Exit(1) - } - - if !strings.Contains(string(read), "use flake bsf/.") { - - file, err := os.OpenFile(".envrc", os.O_APPEND|os.O_WRONLY, 0644) - if err != nil { - fmt.Println(styles.ErrorStyle.Render("", err.Error())) - os.Exit(1) - } - - _, err = file.WriteString("\nuse flake bsf/.") - if err != nil { - fmt.Println(styles.ErrorStyle.Render("", err.Error())) - os.Exit(1) - } - return nil - } - fmt.Println(styles.HelpStyle.Render(" ✅ .envrc already exists")) - - } else { - file, err := os.Create(".envrc") - if err != nil { - fmt.Println(styles.ErrorStyle.Render("", err.Error())) - os.Exit(1) - } - - defer file.Close() - - _, err = file.WriteString("use flake bsf/.") - if err != nil { - fmt.Println(styles.ErrorStyle.Render("", err.Error())) - os.Exit(1) - } - } - - fmt.Println(styles.HelpStyle.Render(" ✅ .envrc generated")) - - return nil -} - // AllPrechecks runs all the prechecks func AllPrechecks() { fmt.Println(styles.TextStyle.Render("Running prechecks...")) var wg sync.WaitGroup - wg.Add(3) + wg.Add(2) go func() { ValidateNixVersion() wg.Done() @@ -134,11 +85,6 @@ func AllPrechecks() { wg.Done() }() - go func() { - generateEnvrc() - wg.Done() - }() - wg.Wait() fmt.Println(styles.SucessStyle.Render(" Prechecks ran successfully")) From be8b642c5a3df6807423504b397ab44bb324bf62 Mon Sep 17 00:00:00 2001 From: Horiodino Date: Tue, 11 Jun 2024 09:07:31 +0100 Subject: [PATCH 3/5] fix after review Signed-off-by: Horiodino --- cmd/direnv/direnv.go | 79 +++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 23 deletions(-) diff --git a/cmd/direnv/direnv.go b/cmd/direnv/direnv.go index 585f0d1d..61f909d3 100644 --- a/cmd/direnv/direnv.go +++ b/cmd/direnv/direnv.go @@ -1,9 +1,11 @@ package direnv import ( + "errors" "fmt" "os" "os/exec" + "regexp" "strings" "github.com/buildsafedev/bsf/cmd/styles" @@ -32,6 +34,12 @@ var Direnv = &cobra.Command{ os.Exit(1) } } + + cmD := exec.Command("direnv", "allow") + err = cmD.Run() + if err != nil { + os.Exit(1) + } }, } @@ -66,7 +74,6 @@ func generateEnvrc() error { } return nil } - fmt.Println(styles.HelpStyle.Render(" ✅ .envrc already exists")) } else { file, err := os.Create(".envrc") @@ -81,13 +88,6 @@ func generateEnvrc() error { return err } - fmt.Println(styles.HelpStyle.Render(" ✅ .envrc generated")) - - cmd := exec.Command("direnv", "allow") - err = cmd.Run() - if err != nil { - return err - } } return nil @@ -111,7 +111,6 @@ func fetchGitignore() error { return err } } - fmt.Println(styles.HelpStyle.Render(" ✅ .gitignore already exists")) return nil } else { @@ -129,8 +128,6 @@ func fetchGitignore() error { if err != nil { return err } - - fmt.Println(styles.HelpStyle.Render(" ✅ .gitignore generated")) } return nil @@ -139,25 +136,61 @@ func fetchGitignore() error { func setDIrenv(args string) error { - if !strings.Contains(args, "=") { - return fmt.Errorf("Hint: use --env key=value") - } else { - file, err := os.OpenFile(".envrc", os.O_APPEND|os.O_WRONLY, 0644) - if err != nil { - return err + err := validateEnvVars(args) + if err != nil { + return err + } + file, err := os.OpenFile(".envrc", os.O_APPEND|os.O_WRONLY, 0644) + if err != nil { + return err + } + + _, err = file.WriteString("\nexport " + args) + if err != nil { + fmt.Println(styles.ErrorStyle.Render("", err.Error())) + return err + } + + cmd := exec.Command("direnv", "allow") + err = cmd.Run() + if err != nil { + return err + } + + return nil +} + +func validateEnvVars(args string) error { + validKeyValRegex := regexp.MustCompile(`^[\w]+=[^\s]+$`) + + envVars := strings.Split(args, ",") + + for _, envVar := range envVars { + if !validKeyValRegex.MatchString(envVar) { + return errors.New("Invalid key-value pair format") } - _, err = file.WriteString("\nexport " + args) - if err != nil { - fmt.Println(styles.ErrorStyle.Render("", err.Error())) - return err + resp := strings.SplitN(envVar, "=", 2) + key := resp[0] + value := resp[1] + + if strings.ContainsAny(key, "= \t\n") { + return errors.New("Invalid characters in key") + } + + if strings.ContainsAny(value, "\x00") { + return errors.New("Invalid characters in value") } - cmd := exec.Command("direnv", "allow") - err = cmd.Run() + read, err := os.ReadFile(".envrc") if err != nil { return err } + + if strings.Contains(string(read), key) { + return errors.New("Key already exists") + } } + return nil } From 962f855e7cc9cda8ebae1778a996acc3f585376c Mon Sep 17 00:00:00 2001 From: Horiodino Date: Tue, 11 Jun 2024 15:43:45 +0100 Subject: [PATCH 4/5] fix after review Signed-off-by: Horiodino --- cmd/direnv/direnv.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/cmd/direnv/direnv.go b/cmd/direnv/direnv.go index 61f909d3..aebe5c03 100644 --- a/cmd/direnv/direnv.go +++ b/cmd/direnv/direnv.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "os" - "os/exec" "regexp" "strings" @@ -34,12 +33,6 @@ var Direnv = &cobra.Command{ os.Exit(1) } } - - cmD := exec.Command("direnv", "allow") - err = cmD.Run() - if err != nil { - os.Exit(1) - } }, } @@ -69,7 +62,6 @@ func generateEnvrc() error { _, err = file.WriteString("\nuse flake bsf/.") if err != nil { - fmt.Println(styles.ErrorStyle.Render("", err.Error())) return err } return nil @@ -107,7 +99,6 @@ func fetchGitignore() error { file, err := os.OpenFile(".gitignore", os.O_APPEND|os.O_WRONLY, 0644) _, err = file.WriteString("\n.envrc") if err != nil { - fmt.Println(styles.ErrorStyle.Render("", err.Error())) return err } } @@ -151,12 +142,6 @@ func setDIrenv(args string) error { return err } - cmd := exec.Command("direnv", "allow") - err = cmd.Run() - if err != nil { - return err - } - return nil } From 2b789873e788cc20384d6f8a0399d633de1f2d93 Mon Sep 17 00:00:00 2001 From: Horiodino Date: Fri, 14 Jun 2024 02:09:20 +0530 Subject: [PATCH 5/5] fix after review Signed-off-by: Horiodino --- cmd/direnv/direnv.go | 35 +++--------------------- cmd/direnv/direnv_test.go | 56 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 31 deletions(-) create mode 100644 cmd/direnv/direnv_test.go diff --git a/cmd/direnv/direnv.go b/cmd/direnv/direnv.go index aebe5c03..064934a7 100644 --- a/cmd/direnv/direnv.go +++ b/cmd/direnv/direnv.go @@ -27,7 +27,7 @@ var Direnv = &cobra.Command{ } if envVar != "" { - err = setDIrenv(envVar) + err = setDirenv(envVar) if err != nil { fmt.Println(styles.ErrorStyle.Render("error: ", err.Error())) os.Exit(1) @@ -68,20 +68,12 @@ func generateEnvrc() error { } } else { - file, err := os.Create(".envrc") - if err != nil { - return err - } - - defer file.Close() - - _, err = file.WriteString("use flake bsf/.") + err = os.WriteFile(".envrc", []byte("use flake bsf/."), 0644) if err != nil { return err } } - return nil } @@ -105,17 +97,7 @@ func fetchGitignore() error { return nil } else { - _, err := os.Create(".gitignore") - if err != nil { - return err - } - - file, err := os.OpenFile(".gitignore", os.O_APPEND|os.O_WRONLY, 0644) - if err != nil { - return err - } - - _, err = file.WriteString("\n.envrc") + err = os.WriteFile(".gitignore", []byte(".envrc"), 0644) if err != nil { return err } @@ -125,7 +107,7 @@ func fetchGitignore() error { } -func setDIrenv(args string) error { +func setDirenv(args string) error { err := validateEnvVars(args) if err != nil { @@ -166,15 +148,6 @@ func validateEnvVars(args string) error { if strings.ContainsAny(value, "\x00") { return errors.New("Invalid characters in value") } - - read, err := os.ReadFile(".envrc") - if err != nil { - return err - } - - if strings.Contains(string(read), key) { - return errors.New("Key already exists") - } } return nil diff --git a/cmd/direnv/direnv_test.go b/cmd/direnv/direnv_test.go new file mode 100644 index 00000000..1eb8d359 --- /dev/null +++ b/cmd/direnv/direnv_test.go @@ -0,0 +1,56 @@ +package direnv + +import ( + "testing" +) + +func TestValidateEnvVars(t *testing.T) { + tests := []struct { + name string + args string + wantErr bool + }{ + { + name: "Valid env vars", + args: "KEY1=value1,KEY2=value2", + wantErr: false, + }, + { + name: "Invalid format (no value)", + args: "KEY1=value1,KEY2", + wantErr: true, + }, + { + name: "Invalid format (no key)", + args: "=value1,KEY2=value2", + wantErr: true, + }, + { + name: "Invalid format (empty)", + args: "", + wantErr: true, + }, + { + name: "Invalid format (no equals sign)", + args: "KEY1value1,KEY2=value2", + wantErr: true, + }, + { + name: "Invalid characters in key", + args: "KEY1 =value1,KEY2=value2", + wantErr: true, + }, + { + name: "Invalid characters in value", + args: "KEY1=value1,KEY2=value\x00", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := validateEnvVars(tt.args); (err != nil) != tt.wantErr { + t.Errorf("validateEnvVars() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +}