From bae88f058fcefd982cd823ce5ef7b09ff1653cbf Mon Sep 17 00:00:00 2001 From: Edoardo Tenani Date: Thu, 8 Jun 2023 23:01:46 +0200 Subject: [PATCH 1/2] (ci): update linter settings --- .golangci.yaml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 88143f1..6021eb6 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -42,7 +42,7 @@ linters: # - rowserrcheck # style - asciicheck - - depguard + # depguard - dogsled - dupl # - exhaustivestruct @@ -62,7 +62,6 @@ linters: - gomodguard - goprintffuncname - gosimple - - ifshort - importas # - interfacer - lll @@ -82,13 +81,10 @@ linters: - whitespace - wrapcheck - wsl - # unused - - deadcode + - unused - ineffassign - - structcheck - unparam - unused - - varcheck fast: false linters-settings: From 875de20f076ce80579bcb631a6ef2a72da39eb50 Mon Sep 17 00:00:00 2001 From: Edoardo Tenani Date: Thu, 8 Jun 2023 23:02:25 +0200 Subject: [PATCH 2/2] fix all linter issues --- cmd/backup.go | 2 +- cmd/cmd.go | 5 +- cmd/rehash.go | 190 +++++++++++++-------------- cmd/root.go | 2 - cmd/shell.go | 1 + cmd/whoami.go | 1 + internal/persona/new.go | 22 ---- internal/plugin/manager/shellfile.go | 3 +- internal/settings/settings.go | 2 +- internal/utils/editor.go | 2 +- plugins/bin/renderable.go | 2 +- plugins/envs/renderable.go | 2 +- plugins/gcp/plugin.go | 4 +- plugins/gcp/renderable.go | 2 +- plugins/identity/renderable.go | 2 +- plugins/tmux/generator.go | 2 +- plugins/tmux/renderable.go | 2 +- 17 files changed, 113 insertions(+), 133 deletions(-) diff --git a/cmd/backup.go b/cmd/backup.go index e45a816..c67359d 100644 --- a/cmd/backup.go +++ b/cmd/backup.go @@ -68,8 +68,8 @@ value takes precedence over the --persona flag. ui.Infof("Encryption passphrase is: %s", passphrase) }, } + backupCmd.Flags().String("persona", "", "The persona to backup") return backupCmd - } diff --git a/cmd/cmd.go b/cmd/cmd.go index 5615199..ad5d714 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -1,11 +1,12 @@ package cmd import ( - "github.com/endorama/devid/cmd/ui" "github.com/spf13/cobra" + + "github.com/endorama/devid/cmd/ui" ) -var cli *cobra.Command +var cli *cobra.Command //nolint:gochecknoglobals // one cli to rule them all // Init initialises a cobra CLI with all commands from this package. func Init() { diff --git a/cmd/rehash.go b/cmd/rehash.go index 6b566bf..86d102c 100644 --- a/cmd/rehash.go +++ b/cmd/rehash.go @@ -26,6 +26,7 @@ import ( "github.com/endorama/devid/cmd/ui" cmdutils "github.com/endorama/devid/cmd/utils" + "github.com/endorama/devid/internal/persona" "github.com/endorama/devid/internal/plugin/manager" "github.com/endorama/devid/internal/utils" ) @@ -50,103 +51,102 @@ goes bad you can still load a persona's shell environment by running rehash command is directly inspired by rbenv, a ruby version manager. `, - Run: func(cmd *cobra.Command, args []string) { - if viper.GetString("active_persona") != "" { - // NOTE: rehashing when a profile is active is dangerous, as the environment - // has been changed with customizations and there is no guarantee about - // what those changes have affected. - // This may be especially problematic for executable path detection in - // plugin. - // As such we prevent rehashing while there is an active profile. - ui.Fatal(errRehashWithActiveProfile, genericExitCode) - } - - var errs []error - var err error - - p, err := cmdutils.LoadPersona(cmd) - if err != nil { - ui.Fatal(fmt.Errorf("cannot instantiate persona: %w", err), noPersonaLoadedExitCode) - } - // errs, err := manager.LoadPlugins(p.Config) - // if err != nil { - // ui.Error(err.Error()) - // - // for _, e := range errs { - // ui.Error(e.Error()) - // } - // - // os.Exit(pluginManagerLoadingErrorExitCode) - // } - - errs, err = manager.LoadCorePlugins(p.Config) - if err != nil { - ui.Error(err) - - for _, e := range errs { - ui.Error(e) - } - - os.Exit(pluginManagerCoreLoadingErrorExitCode) - } - - errs, err = manager.LoadOptionalPlugins(p.Config) - if err != nil { - ui.Error(err) - - for _, e := range errs { - ui.Error(e) - } - - os.Exit(pluginManagerOptionalLoadingErrorExitCode) - } - - log.Printf("persona: %+v\n", p) - - errs, err = manager.SetupPlugins(p) - if err != nil { - ui.Error(err) - - for _, e := range errs { - ui.Error(e) - } - - os.Exit(pluginGenerationExitCode) - } - - errs, err = manager.Generate(p) - if err != nil { - ui.Error(err) - - for _, e := range errs { - ui.Error(e) - } - - os.Exit(pluginGenerationExitCode) - } - - content, err := manager.ShellLoader(p) - if err != nil { - ui.Error(err) - os.Exit(1) - } - - log.Printf("%+v\n", content) - - shellLoaderFilePath := path.Join(p.Location(), viper.GetString("shell_loader_filename")) - err = utils.PersistFile(shellLoaderFilePath, content) - if err != nil { - ui.Fatal(fmt.Errorf("cannot save shell loader: %w", err), genericExitCode) - } - - if err := os.Chmod(shellLoaderFilePath, permUserRWX); err != nil { - ui.Fatal( - fmt.Errorf("cannot change permissions to %s on %s: %v", permUserRWX, shellLoaderFilePath, err), - genericExitCode) - } - }, + Run: runRehash, } rehashCmd.Flags().String("persona", "", "The persona for which to rebuild the shell configuration") + return rehashCmd } + +func runRehash(cmd *cobra.Command, _ []string) { + if viper.GetString("active_persona") != "" { + // NOTE: rehashing when a profile is active is dangerous, as the environment + // has been changed with customizations and there is no guarantee about + // what those changes have affected. + // This may be especially problematic for executable path detection in + // plugin. + // As such we prevent rehashing while there is an active profile. + ui.Fatal(errRehashWithActiveProfile, genericExitCode) + } + + var ( + errs []error + err error + ) + + p, err := cmdutils.LoadPersona(cmd) + if err != nil { + ui.Fatal(fmt.Errorf("cannot instantiate persona: %w", err), noPersonaLoadedExitCode) + } + // errs, err := manager.LoadPlugins(p.Config) + // if err != nil { + // ui.Error(err.Error()) + // + // for _, e := range errs { + // ui.Error(e.Error()) + // } + // + // os.Exit(pluginManagerLoadingErrorExitCode) + // } + + errs, err = manager.LoadCorePlugins(p.Config) + if err != nil { + handleAllErrors(errs, err, pluginManagerCoreLoadingErrorExitCode) + } + + errs, err = manager.LoadOptionalPlugins(p.Config) + if err != nil { + handleAllErrors(errs, err, pluginManagerOptionalLoadingErrorExitCode) + } + + log.Printf("persona: %+v\n", p) + + errs, err = manager.SetupPlugins(p) + if err != nil { + handleAllErrors(errs, err, pluginGenerationExitCode) + } + + errs, err = manager.Generate(p) + if err != nil { + handleAllErrors(errs, err, pluginGenerationExitCode) + } + + fn := viper.GetString("shell_loader_filename") + if err := writeShellLoader(p, fn); err != nil { + ui.Fatal(err, genericExitCode) + } +} + +func handleAllErrors(errs []error, err error, exitCode int) { + ui.Error(err) + + for _, e := range errs { + ui.Error(e) + } + + os.Exit(exitCode) +} + +func writeShellLoader(p persona.Persona, filename string) error { + content, err := manager.ShellLoader(p) + if err != nil { + ui.Error(err) + os.Exit(1) + } + + log.Printf("%+v\n", content) + + shellLoaderFilePath := path.Join(p.Location(), filename) + + err = utils.PersistFile(shellLoaderFilePath, content) + if err != nil { + return fmt.Errorf("cannot save shell loader: %w", err) + } + + if err := os.Chmod(shellLoaderFilePath, permUserRWX); err != nil { + return fmt.Errorf("cannot change permissions to %s on %s: %w", permUserRWX, shellLoaderFilePath, err) + } + + return nil +} diff --git a/cmd/root.go b/cmd/root.go index c7f1a2c..77378a5 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -32,7 +32,6 @@ var cfgFile string //nolint:gochecknoglobals // required for init var verbose bool //nolint:gochecknoglobals // require for init func RootCmd() *cobra.Command { - // rootCmd represents the base command when called without any subcommands. var rootCmd = &cobra.Command{ //nolint:gochecknoglobals // required by cobra Use: "devid", Short: "Secure manager for your developer personas", @@ -68,7 +67,6 @@ for persona's folders. func init() { //nolint:gochecknoinits // required by cobra cobra.OnInitialize(initConfig) - } // initConfig reads in config file and ENV variables if set. diff --git a/cmd/shell.go b/cmd/shell.go index c62094d..14d34d2 100644 --- a/cmd/shell.go +++ b/cmd/shell.go @@ -41,5 +41,6 @@ value takes precedence over the --persona flag.`, } shellCmd.Flags().String("persona", "", "The persona's shell to load") + return shellCmd } diff --git a/cmd/whoami.go b/cmd/whoami.go index 06c9191..8448674 100644 --- a/cmd/whoami.go +++ b/cmd/whoami.go @@ -81,5 +81,6 @@ value takes precedence over the --persona flag. } whoamiCmd.Flags().BoolP("extended", "e", false, "Print extended identity information") + return whoamiCmd } diff --git a/internal/persona/new.go b/internal/persona/new.go index 71aaf69..e0d8aca 100644 --- a/internal/persona/new.go +++ b/internal/persona/new.go @@ -1,8 +1,6 @@ package persona import ( - "errors" - "fmt" "path" "github.com/spf13/viper" @@ -35,23 +33,3 @@ func NewWithCustomLocation(name, location string) (Persona, error) { Config: v, }, nil } - -var errPersonaDoesNotExists = errors.New("does not exists") - -func Load(name string) (Persona, error) { - p, err := New(name) - if err != nil { - return p, fmt.Errorf("init failed: %w", err) - } - - if !p.Exists() { - return p, fmt.Errorf("%w in %s", errPersonaDoesNotExists, p.Location()) - } - - err = p.Load() - if err != nil { - return p, fmt.Errorf("cannot load persona configuration: %w", err) - } - - return p, nil -} diff --git a/internal/plugin/manager/shellfile.go b/internal/plugin/manager/shellfile.go index 6aa4bda..b7a1b13 100644 --- a/internal/plugin/manager/shellfile.go +++ b/internal/plugin/manager/shellfile.go @@ -15,8 +15,9 @@ import ( "github.com/endorama/devid/internal/plugin" ) +// +//nolint:gochecknoglobals // required by embed //go:embed load.sh.txt -// nolint:gochecknoglobals // required by embed var shellLoader string // ShellLoader generate profile shell loader file. diff --git a/internal/settings/settings.go b/internal/settings/settings.go index 8e2e2fe..7138cef 100644 --- a/internal/settings/settings.go +++ b/internal/settings/settings.go @@ -32,7 +32,7 @@ func setDefaults() { viper.SetDefault("shell", os.Getenv("SHELL")) } -// nolint:deadcode,unused // will use it +//nolint:deadcode,unused // will use it func readConfigFile() { viper.SetConfigName("config") viper.SetConfigType("yaml") diff --git a/internal/utils/editor.go b/internal/utils/editor.go index 7c8e67a..7727765 100644 --- a/internal/utils/editor.go +++ b/internal/utils/editor.go @@ -36,7 +36,7 @@ func OpenWithEditor(path string) error { // AllowedEditors is a list of allowed values for the EDITOR environment variable. // FIXME: prevent unknown command execution when some of these editor is not available. // FIXME: make this a function so is not directly modifiable. -var AllowedEditors = []string{ // nolint:gochecknoglobals // implementation detail +var AllowedEditors = []string{ //nolint:gochecknoglobals // implementation detail "/bin/ed", "/bin/nano", "/usr/bin/vim", diff --git a/plugins/bin/renderable.go b/plugins/bin/renderable.go index be461ba..140ad76 100644 --- a/plugins/bin/renderable.go +++ b/plugins/bin/renderable.go @@ -2,7 +2,7 @@ package bin import "strings" -func (p Plugin) Render(profileName, profileLocation string) string { +func (p Plugin) Render(_, profileLocation string) string { sb := strings.Builder{} sb.WriteString("export PATH=\"" + profileLocation + "/bin:$PATH\"\n") diff --git a/plugins/envs/renderable.go b/plugins/envs/renderable.go index 225fc4c..3205bb0 100644 --- a/plugins/envs/renderable.go +++ b/plugins/envs/renderable.go @@ -5,7 +5,7 @@ import ( "strings" ) -func (p Plugin) Render(profileName, profileLocation string) string { +func (p Plugin) Render(_, _ string) string { sb := strings.Builder{} for name, value := range p.config { diff --git a/plugins/gcp/plugin.go b/plugins/gcp/plugin.go index 1e9b911..cd31e7a 100644 --- a/plugins/gcp/plugin.go +++ b/plugins/gcp/plugin.go @@ -1,7 +1,7 @@ package gcp -// TODO: add gcp.NewPlugin() to internal/plugin/manager/available.go under Optional -// TODO: add enabled check in internal/plugin/manager/manager.go LoadOptionalPlugins switch case +// TODO: add gcp.NewPlugin() to internal/plugin/manager/available.go under Optional. +// TODO: add enabled check in internal/plugin/manager/manager.go LoadOptionalPlugins switch case. const pluginName = "gcp" type Plugin struct { diff --git a/plugins/gcp/renderable.go b/plugins/gcp/renderable.go index 3912f15..9c64116 100644 --- a/plugins/gcp/renderable.go +++ b/plugins/gcp/renderable.go @@ -4,7 +4,7 @@ import "strings" // Render returns content rendered by the plugin. // Implements `plugin.Renderable` interface. -func (p Plugin) Render(personaName, personaDirectory string) string { +func (p Plugin) Render(_, _ string) string { // TODO: implement rendering logic sb := strings.Builder{} // sb.WriteString("plugin rendered content") diff --git a/plugins/identity/renderable.go b/plugins/identity/renderable.go index eadd05d..d8d4833 100644 --- a/plugins/identity/renderable.go +++ b/plugins/identity/renderable.go @@ -4,7 +4,7 @@ import ( "strings" ) -func (p Plugin) Render(profileName, profileLocation string) string { +func (p Plugin) Render(_, _ string) string { sb := strings.Builder{} sb.WriteString("export IDENTITY_EMAIL=\"" + p.config.Email + "\"\n") diff --git a/plugins/tmux/generator.go b/plugins/tmux/generator.go index 8b34386..0984e68 100644 --- a/plugins/tmux/generator.go +++ b/plugins/tmux/generator.go @@ -8,7 +8,7 @@ import ( "github.com/endorama/devid/internal/plugin" ) -func (p *Plugin) Generate(personaDirectory string) (plugin.Generated, error) { +func (p *Plugin) Generate(_ string) (plugin.Generated, error) { tmux := strings.Builder{} tmux.WriteString("#!/usr/bin/env bash\n") tmux.WriteString("exec ") diff --git a/plugins/tmux/renderable.go b/plugins/tmux/renderable.go index 3c0a29c..3dbbee1 100644 --- a/plugins/tmux/renderable.go +++ b/plugins/tmux/renderable.go @@ -4,6 +4,6 @@ import "fmt" // Render returns content rendered by the plugin. // Implements `plugin.Renderable` interface. -func (p Plugin) Render(personaName, personaDirectory string) string { +func (p Plugin) Render(personaName, _ string) string { return fmt.Sprintf("export TMUX_SOCKET_NAME=\"%s.%s\"\n", pluginName, personaName) }