diff --git a/cmd/config/root.go b/cmd/config/root.go index 21fc568..28bae8d 100644 --- a/cmd/config/root.go +++ b/cmd/config/root.go @@ -4,7 +4,8 @@ import ( "github.com/spf13/cobra" ) -// RootCmd is the config command that will be added to the root HkUp command. +// RootCmd is the root config subcommand that will be added to the root HkUp +// command. var RootCmd = &cobra.Command{ Use: "config", Short: "HkUp configuration settings", diff --git a/cmd/root.go b/cmd/root.go index 5320292..4a1fa2b 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -8,11 +8,8 @@ import ( ) var ( - // version holds the centralized version of HkUp. - // It is updated to the latest release version at build time of the binaries. - // - // INFO: look at the .github/workflows/release-please.yml to view how version - // is updated. + // NOTE: Updated to the latest release version at build time of the binaries + // via .github/workflows/release-please.yml version = "dev" rootCmd = &cobra.Command{ @@ -35,8 +32,8 @@ func init() { rootCmd.AddCommand(listCmd) } -// Execute serves as a wrapper for the Cobra API's Execute function, -// allowing it to be called from the [github.com/iton0/hkup-cli] package. +// Execute serves as a wrapper for the Cobra API's Execute function, allowing it +// to be called from the [github.com/iton0/hkup-cli] package. func Execute() { rootCmd.Execute() } diff --git a/cmd/template/root.go b/cmd/template/root.go index eb08131..2cded6b 100644 --- a/cmd/template/root.go +++ b/cmd/template/root.go @@ -4,7 +4,8 @@ import ( "github.com/spf13/cobra" ) -// RootCmd is the template command that will be added to the root HkUp command. +// RootCmd is the root template subcommand that will be added to the root HkUp +// command. var RootCmd = &cobra.Command{ Use: "template", Short: "Reusable Git hook", diff --git a/internal/logic/add.go b/internal/logic/add.go index f320199..6d76265 100644 --- a/internal/logic/add.go +++ b/internal/logic/add.go @@ -13,17 +13,14 @@ import ( var LangFlg string // Add creates a new Git hook with the specified git hook name and optional -// programming language in the designated .hkup directory. -// -// Returns error if any of the steps fail above. +// programming language in the designated .hkup directory. Returns error if any +// of the steps fail above. func Add(cmd *cobra.Command, args []string) error { isBare, err := isBareRepo(".") if err != nil { // Current working directory is not a git repository at all return err } - // Tries to create .hkup directory if it does not exist and current working - // directory is not a bare git repository if !util.DoesDirectoryExist(util.HkupDirName) && !isBare { if err := util.CreateDirectory(util.HkupDirName); err != nil { return err @@ -35,16 +32,13 @@ func Add(cmd *cobra.Command, args []string) error { hook := args[0] filePath := util.GetHookFilePath(hook) - // Does not add if hook already exists in .hkup directory if util.DoesFileExist(filePath) { return fmt.Errorf("%s hook already exists", hook) } var sheBangLine string - // Uses the specified language from lang flag; else default to sh if LangFlg != "" { - // Makes sure lang is supported if isValid := git.CheckLangSupported(LangFlg); !isValid { return fmt.Errorf("language not supported: %s", LangFlg) } @@ -53,19 +47,16 @@ func Add(cmd *cobra.Command, args []string) error { sheBangLine = "#!/bin/sh" } - // Creates the git hook file file, err := util.CreateFile(filePath) if err != nil { return err } defer file.Close() - // Writes the language shebang line to the created file from above _, err = file.WriteString(sheBangLine) if err != nil { return err } - // Either changes the create file's permissions successful or returns error return util.MakeExecutable(filePath) } diff --git a/internal/logic/config/get.go b/internal/logic/config/get.go index 3f0e071..4247286 100644 --- a/internal/logic/config/get.go +++ b/internal/logic/config/get.go @@ -5,15 +5,14 @@ import ( "github.com/spf13/cobra" ) -// Get prints out the value of a specified configuration setting. -// -// Returns error if issue with getting the value. +// Get prints out the value of a specified configuration setting. Returns error +// if issue with getting the value. func Get(cmd *cobra.Command, args []string) error { out, err := util.GetINIValue(args[0]) if err != nil { return err } - cmd.Println(out) // This may be empty if the value is not set but key is valid + cmd.Println(out) return nil } diff --git a/internal/logic/config/set.go b/internal/logic/config/set.go index 46a579b..7806293 100644 --- a/internal/logic/config/set.go +++ b/internal/logic/config/set.go @@ -5,11 +5,8 @@ import ( "github.com/spf13/cobra" ) -// Set updates a configuration setting with a new value. -// -// Returns error if issue with settings the configuration setting. +// Set updates a configuration setting with a new value. Returns error if issue +// with settings the configuration setting. func Set(cmd *cobra.Command, args []string) error { - // Either setting configuration setting is successful and returns nil or - // returns error return util.SetINIValue(args[0], args[1]) } diff --git a/internal/logic/doc.go b/internal/logic/doc.go index a162721..be29186 100644 --- a/internal/logic/doc.go +++ b/internal/logic/doc.go @@ -14,9 +14,10 @@ import ( // It constructs the URL for the documentation based on the hook name and attempts // to open it using the appropriate command for the operating system. // -// Returns: -// - error if the hook key is invalid, if the platform is unsupported, or if -// there is an issue starting the command. +// Returns error if: +// - hook key is invalid +// - platform is unsupported +// - issue starting the command func Doc(cmd *cobra.Command, args []string) error { // Full url path for the specified git hook url := "https://git-scm.com/docs/githooks#" + git.GetHookUrl(args[0]) @@ -38,6 +39,5 @@ func Doc(cmd *cobra.Command, args []string) error { return err } - // Must be called after successfully starting terminal command above - return termCmd.Wait() // Returns error if command fails + return termCmd.Wait() } diff --git a/internal/logic/init.go b/internal/logic/init.go index ed286f6..53a52a9 100644 --- a/internal/logic/init.go +++ b/internal/logic/init.go @@ -35,8 +35,6 @@ func Init(cmd *cobra.Command, args []string) error { gitCmd := []string{} // Holds everything after the root git command var hkupDirPath string // Holds the path the .hkup directory - // If both flags are set, configure core.hooksPath with their values. - // Otherwise, use the default hooks directory (util.HkupDirName). if GitDirFlg != "" && WorkTreeFlg != "" { hkupDirPath = filepath.Join(WorkTreeFlg, util.HkupDirName) gitCmd = []string{"--git-dir=" + GitDirFlg, "--work-tree=" + WorkTreeFlg, "config", "--local", "core.hooksPath", hkupDirPath} @@ -45,8 +43,6 @@ func Init(cmd *cobra.Command, args []string) error { gitCmd = []string{"config", "--local", "core.hooksPath", hkupDirPath} } - // Does not override the hooksPath variable if already set and force flag is - // not used if !ForceFlg { out, _ := exec.Command("git", gitCmd[:len(gitCmd)-1]...).CombinedOutput() if len(out) != 0 { diff --git a/internal/logic/list.go b/internal/logic/list.go index 80850e0..c68ffdc 100644 --- a/internal/logic/list.go +++ b/internal/logic/list.go @@ -19,7 +19,7 @@ import ( func List(cmd *cobra.Command, args []string) error { out := []string{} - if len(args) > 0 { // Gets appropriate output based on argument provided + if len(args) > 0 { switch args[0] { case "template": out = getHookTemplates() @@ -31,7 +31,7 @@ func List(cmd *cobra.Command, args []string) error { case "lang": out = util.ConvertMapKeysToSlice(git.SupportedLangs()) } - } else { // No args; gets hooks in current working directory + } else { out = getCwdHooks() if out == nil { return fmt.Errorf("could not read .hkup directory") @@ -53,8 +53,8 @@ func formatOutput(out []string) string { return fout } -// getHookTemplates returns all user-defined templates. -// If no templates are found, returns a empty string slice. +// getHookTemplates returns a slice of all user-defined template file names. +// If no templates are found, returns a empty slice. func getHookTemplates() []string { out := []string{} diff --git a/internal/logic/remove.go b/internal/logic/remove.go index ca3f997..7601267 100644 --- a/internal/logic/remove.go +++ b/internal/logic/remove.go @@ -9,8 +9,7 @@ import ( // Remove deletes a specified Git hook from the .hkup directory. // It takes a single argument, which is the name of the hook to be removed. -// -// Returns error if issue deleting the file +// Returns error if issue deleting the file. func Remove(cmd *cobra.Command, args []string) error { return os.Remove(util.GetHookFilePath(args[0])) } diff --git a/internal/logic/root.go b/internal/logic/root.go index 127ac15..bd107d5 100644 --- a/internal/logic/root.go +++ b/internal/logic/root.go @@ -10,10 +10,8 @@ import ( ) // Root wraps git-related clone commands for easier initialization of HkUp. -// // Returns error if issue with cloning repository or initializing HkUp. func Root(cmd *cobra.Command, args []string) error { - // Tries to run git command in the terminal if err := util.RunCommandInTerminal(args[0], args[1:]...); err != nil { return err } @@ -21,9 +19,9 @@ func Root(cmd *cobra.Command, args []string) error { possibleRepoUrl := args[len(args)-2] possibleCustomDir := args[len(args)-1] - // Loop through the args to see if "--" is used. - // Gets the two previous args and sets them to the repoUrl and - // possibleCustomDir variables, respectively. + // INFO: Since gh command can use the syntax of: + // gh repo clone [] -- + // Need to parse for "--" and update possible repo url and custom directory for i, v := range args { if v == "--" { possibleRepoUrl = args[i-2] @@ -32,18 +30,16 @@ func Root(cmd *cobra.Command, args []string) error { } } - // Tries to cd into the created directory if err := cdLogic(possibleRepoUrl, possibleCustomDir); err != nil { return err } - // Tries to initialize HkUp return Init(cmd, nil) } // cdLogic implements the HkUp wrapper logic around cloning for both 'git' and // 'gh' command. -// Returns error if issue with changing directory +// Returns error if issue with changing directory. func cdLogic(possibleRepoUrl, possibleCustomDir string) error { // No custom directory name provided when using git command usedDefaultGit := strings.HasSuffix(possibleCustomDir, ".git") @@ -54,33 +50,30 @@ func cdLogic(possibleRepoUrl, possibleCustomDir string) error { // Starting index of the remote repo name start := strings.LastIndex(possibleCustomDir, "/") + 1 - // Checks if user did not provide a custom directory name - if usedDefaultGit { // git command - // If the repo is bare then just take the remote repo name + var createdDir string // Holds the name of the cloned directory + + if usedDefaultGit { if isBare, _ := isBareRepo(possibleCustomDir[start:]); isBare { - possibleCustomDir = possibleCustomDir[start:] - } else { // Repo is not bare ie regular clone + createdDir = possibleCustomDir[start:] + } else { end := strings.LastIndex(possibleCustomDir, ".git") - possibleCustomDir = possibleCustomDir[start:end] + createdDir = possibleCustomDir[start:end] } - } else if usedDefaultGh { // gh command - // If the repo is bare then just take the remote repo name + } else if usedDefaultGh { if isBare, _ := isBareRepo(possibleCustomDir[start:] + ".git"); isBare { - possibleCustomDir = possibleCustomDir[start:] + ".git" - } else { // Repo is not bare ie regular clone - possibleCustomDir = possibleCustomDir[start:] + createdDir = possibleCustomDir[start:] + ".git" + } else { + createdDir = possibleCustomDir[start:] } } - // Either successful or returns error if issue with changing directory - return os.Chdir(possibleCustomDir) + return os.Chdir(createdDir) } // isBareRepo reports if given directory (dir) is a bare git repository. // Additionally, returns error if the given directory is not a git repository // at all. func isBareRepo(dir string) (bool, error) { - // Checks if current working directory is git bare repo out, err := exec.Command("git", "-C", dir, "rev-parse", "--is-bare-repository").Output() if err != nil { return false, err diff --git a/internal/logic/template/copy.go b/internal/logic/template/copy.go index 6d60b83..3558560 100644 --- a/internal/logic/template/copy.go +++ b/internal/logic/template/copy.go @@ -21,7 +21,6 @@ func Copy(cmd *cobra.Command, args []string) error { configPath := util.GetConfigDirPath() var templateName string - // Only starts the process of copying if config path and .hkup directory exist switch { case !util.DoesDirectoryExist(configPath): return fmt.Errorf("%s directory does not exist", configPath) diff --git a/internal/logic/template/create.go b/internal/logic/template/create.go index 73d4f5f..efe49e1 100644 --- a/internal/logic/template/create.go +++ b/internal/logic/template/create.go @@ -52,7 +52,6 @@ func Create(cmd *cobra.Command, args []string) error { configPath := util.GetConfigDirPath() templatePath := util.GetTemplateDirPath() - // Makes the HkUp config directory if it does not exist if !util.DoesDirectoryExist(configPath) { cmd.Printf("Making HkUp config directory at %s...\n", configPath) @@ -61,7 +60,6 @@ func Create(cmd *cobra.Command, args []string) error { return err } - // Also makes the template subdirectory err = util.CreateDirectory(templatePath) if err != nil { return err @@ -72,12 +70,10 @@ func Create(cmd *cobra.Command, args []string) error { if err := displayPrompt(templatePath, args[0]); err != nil { return err } - } else if err := displayPrompt(templatePath); err != nil { // no args given + } else if err := displayPrompt(templatePath); err != nil { return err } - // Either creating the template is successful and returns nil or unsuccessful - // and returns error return createTemplate(templatePath) } @@ -86,49 +82,42 @@ func Create(cmd *cobra.Command, args []string) error { func createTemplate(templatePath string) error { fmt.Println() // Makes the output more distinct in regards to spacing - // Full path to created template - createdTemplate := filepath.Join(templatePath, template.name+"#"+template.hook) + createdTemplateFullPath := filepath.Join(templatePath, template.name+"#"+template.hook) - // Copies git hook from current working directory to template directory if template.useCwd { srcPath := util.GetHookFilePath(template.hook) - return util.CopyFile(srcPath, createdTemplate) // returns either nil or error + return util.CopyFile(srcPath, createdTemplateFullPath) } - // Creates the template file - file, err := util.CreateFile(createdTemplate) + file, err := util.CreateFile(createdTemplateFullPath) if err != nil { return err } defer file.Close() - // Gets language to use for template var fileContent string - if template.lang == "" { // Default to sh for the template language + if template.lang == "" { fileContent = "#!/bin/sh" } else { fileContent = fmt.Sprintf("#!/usr/bin/env %s", template.lang) } - // Writes the shebang for the template language _, err = file.WriteString(fileContent) if err != nil { return err } - // Opens template file in editor if template.edit { - if err := editTemplate(createdTemplate); err != nil { + if err := editTemplate(createdTemplateFullPath); err != nil { return err } fmt.Println("Template successfully edited!") } - // Copies the template file and makes it executable if template.copyHook { dstPath := filepath.Join(util.HkupDirName, template.hook) - err := util.CopyFile(createdTemplate, dstPath) + err := util.CopyFile(createdTemplateFullPath, dstPath) if err != nil { return err } @@ -149,7 +138,6 @@ func createTemplate(templatePath string) error { func displayPrompt(templatePath string, arg ...string) error { fmt.Println() // Makes the output more distinct in regards to spacing - // Takes user provided arg as hook name or asks for it if len(arg) == 1 { template.hook = arg[0] fmt.Printf("Creating template with %s hook...\n\n", template.hook) @@ -157,7 +145,6 @@ func displayPrompt(templatePath string, arg ...string) error { return err } - // Takes name if name flag used or asks for it if TemplateNameFlg != "" { if out, err := doesTemplateExist(templatePath, TemplateNameFlg); err != nil { return err @@ -169,8 +156,6 @@ func displayPrompt(templatePath string, arg ...string) error { return err } - // Uses the current working directory's git hook if flag given or asks to do so - // NOTE: If cwd flag is used then utilizes language of that existing hook if TemplateCwdFlg { if !util.DoesFileExist(filepath.Join(util.HkupDirName, template.hook)) { return fmt.Errorf("git hook %s does not exist in the current working directory", template.hook) @@ -182,7 +167,6 @@ func displayPrompt(templatePath string, arg ...string) error { return err } - // Takes language if lang flag used or asks for it if TemplateLangFlg != "" { if isValid := git.CheckLangSupported(TemplateLangFlg); !isValid { return fmt.Errorf("language not supported: %s", TemplateLangFlg) @@ -192,16 +176,14 @@ func displayPrompt(templatePath string, arg ...string) error { return err } - // Copies created template to cwd if copy flag used or asks to do so if TemplateCopyFlg { template.copyHook = true - } else if !template.useCwd { // Does not copy what is already in cwd + } else if !template.useCwd { if err = displayCopyPrompt(); err != nil { return err } } - // Created template will be opened in editor or asks to do so if TemplateEditFlg { template.edit = true } else if err = displayEditPrompt(); err != nil { @@ -229,7 +211,6 @@ func displayHookPrompt(attempts ...int) error { return err } - // Recursively calls this function until supplied with supported git hook if out := git.GetHookUrl(in); out == "" { attempt++ fmt.Println("Not a supported Git hook. Please try again") @@ -244,7 +225,6 @@ func displayHookPrompt(attempts ...int) error { // template. // Returns error if issue with reading response or after 3 incorrect attempts. func displayCwdPrompt() error { - // Does not display if the git hook type does not exist in the cwd if !util.DoesFileExist(filepath.Join(util.HkupDirName, template.hook)) { return nil } @@ -254,7 +234,6 @@ func displayCwdPrompt() error { return err } - // useCwd field is false by default so only need to check if "yes" template.useCwd = isYes return nil } @@ -271,7 +250,6 @@ func displayLangPrompt(attempts ...int) error { return fmt.Errorf("3 incorrect attempts") } - // Does not display if we are using the existing git hook in cwd if template.useCwd { return nil } @@ -279,10 +257,9 @@ func displayLangPrompt(attempts ...int) error { switch in, err := util.UserInputPrompt("Language (default sh):"); { case err != nil: return err - case in == "": // using the default sh as the language for the hook + case in == "": return nil default: - // Recursively calls this function until supplied with supported language if isValid := git.CheckLangSupported(in); !isValid { attempt++ fmt.Println("Not a supported language. Please try again") @@ -316,7 +293,7 @@ func displayNamePrompt(templatePath string, attempts ...int) error { if out, err := doesTemplateExist(templatePath, in); err != nil { return err - } else if out != "" { // Keeps asking until given a unique template name + } else if out != "" { attempt++ fmt.Println("Template name already exists. Please try again") return displayNamePrompt(templatePath, attempt) @@ -335,7 +312,6 @@ func displayCopyPrompt() error { return err } - // copyHook field is false by default so only need to check if "yes" template.copyHook = isYes return nil } @@ -348,7 +324,6 @@ func displayEditPrompt() error { return err } - // edit field is false by default so only need to check if "yes" template.edit = isYes return nil } diff --git a/internal/logic/template/edit.go b/internal/logic/template/edit.go index 6741bd8..0611566 100644 --- a/internal/logic/template/edit.go +++ b/internal/logic/template/edit.go @@ -17,7 +17,6 @@ import ( func Edit(cmd *cobra.Command, args []string) error { templatePath := util.GetTemplateDirPath() - // output (without error) will either give path to template or empty string out, err := doesTemplateExist(templatePath, args[0]) switch { case err != nil: @@ -37,14 +36,12 @@ func editTemplate(path string) error { return err } - // Run command to open template file with editor - return util.RunCommandInTerminal(editor, path) // Either success or return error + return util.RunCommandInTerminal(editor, path) } // getEditor makes best effort to find default editor for HkUp. // Returns editor name if found and error if issue with searching for editor. func getEditor() (string, error) { - // Check the HkUp config file editor, err := util.GetINIValue("editor") if err != nil { return "", err @@ -52,16 +49,12 @@ func getEditor() (string, error) { return editor, nil } - // Check in global gitconfig file if out, err := exec.Command("git", "config", "--global", "core.editor").CombinedOutput(); err != nil { return "", err } else if len(out) != 0 { - // The out has a newline character at the end so take elements up until the - // "\" of the "\n" - return string(out[0:(len(out) - 1)]), nil // Converts byte slice into string + return string(out[0:(len(out) - 1)]), nil } - // Check for EDITOR var if editor, exist := os.LookupEnv("EDITOR"); exist && editor != "" { return editor, nil } diff --git a/internal/logic/template/remove.go b/internal/logic/template/remove.go index 99eecd0..42d7177 100644 --- a/internal/logic/template/remove.go +++ b/internal/logic/template/remove.go @@ -15,20 +15,18 @@ import ( func Remove(cmd *cobra.Command, args []string) error { templatePath := util.GetTemplateDirPath() - // Cannot remove template if HkUp template config path does not exist if !util.DoesDirectoryExist(templatePath) { return fmt.Errorf("%s directory does not exist", templatePath) } templateName := args[0] - // Checks for template existence in HkUp template config directory switch file, err := doesTemplateExist(templatePath, templateName); { case err != nil: return err - case file == "": // Specified template does not exist + case file == "": return fmt.Errorf("template %s does not exist", templateName) - default: // Template exists and will try to remove - return os.Remove(file) // Either success and returns nil or returns error + default: + return os.Remove(file) } } diff --git a/internal/util/main.go b/internal/util/main.go index cae0500..cf9a2d8 100644 --- a/internal/util/main.go +++ b/internal/util/main.go @@ -97,13 +97,11 @@ func RunCommandInTerminal(root string, args ...string) error { cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr - // Starts the command if err := cmd.Start(); err != nil { return err } - // Waits for the command to finish - return cmd.Wait() // Either success and returns nil or returns error if issue + return cmd.Wait() } // GetConfigFilePath returns the HkUp file path that holds configuration settings. @@ -211,7 +209,6 @@ func GetINIValue(key string) (string, error) { } defer file.Close() - // Scanner to read the file line by line scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() @@ -246,14 +243,13 @@ func GetINIValue(key string) (string, error) { if err := scanner.Err(); err != nil { return "", err } - return "", fmt.Errorf("%s is not a valid key", key) // Returns empty string if key not found + return "", fmt.Errorf("%s is not a valid key", key) } // SetINIValue modifies the value of a key in the config settings INI file. // Returns error if key not found or issue with reading or wriiting to file. func SetINIValue(key, newValue string) error { filePath := GetConfigFilePath() - // Open the TOML file file, err := os.Open(filePath) if err != nil { return err @@ -261,7 +257,7 @@ func SetINIValue(key, newValue string) error { defer file.Close() updatedLines := []string{} - var keyFound bool // defaults to false + var keyFound bool // Scanner to read the file line by line scanner := bufio.NewScanner(file)