diff --git a/CHANGELOG.md b/CHANGELOG.md index 60bada9..38d3df1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,9 +3,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -## [Unreleased] - DATE +## [1.3.2 - Unreleased] - DATE ### Added ### Changed +- ghorg configuration location to $HOME/.config/ghorg or $XDG_CONFIG_HOME https://github.com/gabrie30/ghorg/issues/65; thanks @liljenstolpe ### Deprecated ### Removed ### Fixed diff --git a/README.md b/README.md index 86f3050..c87a72b 100644 --- a/README.md +++ b/README.md @@ -37,9 +37,9 @@ $ brew upgrade git ```bash $ brew install gabrie30/utils/ghorg -$ mkdir -p $HOME/ghorg -$ curl https://raw.githubusercontent.com/gabrie30/ghorg/master/sample-conf.yaml > $HOME/ghorg/conf.yaml -$ vi $HOME/ghorg/conf.yaml # (optional but recommended) +$ mkdir -p $HOME/.config/ghorg +$ curl https://raw.githubusercontent.com/gabrie30/ghorg/master/sample-conf.yaml > $HOME/.config/ghorg/conf.yaml +$ vi $HOME/.config/ghorg/conf.yaml # (optional but recommended) ``` ### Golang @@ -47,9 +47,9 @@ $ vi $HOME/ghorg/conf.yaml # (optional but recommended) ```bash # ensure $HOME/go/bin is in your path ($ echo $PATH | grep $HOME/go/bin) $ go get -u github.com/gabrie30/ghorg -$ mkdir -p $HOME/ghorg -$ curl https://raw.githubusercontent.com/gabrie30/ghorg/master/sample-conf.yaml > $HOME/ghorg/conf.yaml -$ vi $HOME/ghorg/conf.yaml # (optional but recommended) +$ mkdir -p $HOME/.config/ghorg +$ curl https://raw.githubusercontent.com/gabrie30/ghorg/master/sample-conf.yaml > $HOME/.config/ghorg/conf.yaml +$ vi $HOME/.config/ghorg/conf.yaml # (optional but recommended) ``` ## Use @@ -66,7 +66,7 @@ $ ghorg clone --help ## Configuration -Configuration can be set in two ways. The first is in `$HOME/ghorg/conf.yaml`. This file will be created from the [sample-conf.yaml](https://github.com/gabrie30/ghorg/blob/master/sample-conf.yaml) and copied into `$HOME/ghorg/conf.yaml`. The second is setting flags via the cli, run `$ ghorg clone --help` for a list of flags. Any flag set on the command line will overwrite anything in the conf.yaml +Configuration can be set in two ways. The first is in `$HOME/.config/ghorg/conf.yaml`. This file will be created from the [sample-conf.yaml](https://github.com/gabrie30/ghorg/blob/master/sample-conf.yaml) and copied into `$HOME/.config/ghorg/conf.yaml`. The second is setting flags via the cli, run `$ ghorg clone --help` for a list of flags. Any flag set on the command line will overwrite anything in the conf.yaml ## Default GitHub/GitLab Token Used @@ -77,7 +77,7 @@ $ security find-internet-password -s github.com | grep "acct" | awk -F\" '{ pri $ security find-internet-password -s gitlab.com | grep "acct" | awk -F\" '{ print $4 }' ``` -> It's recommended to store github/gitlab tokens in the osxkeychain, if this command returns anything other than your token see Troubleshooting section below. However, you can always add your token to the $HOME/ghorg/conf.yaml or use the (--token, -t) flags. +> It's recommended to store github/gitlab tokens in the osxkeychain, if this command returns anything other than your token see Troubleshooting section below. However, you can always add your token to the $HOME/.config/ghorg/conf.yaml or use the (--token, -t) flags. ## Auth through SSO @@ -90,14 +90,14 @@ To configure with bitbucket you will need to create a new [app password](https:/ ## Ignoring Repos - To ignore any archived repos while cloning use the `--skip-archived` flag (github/gitlab only) -- To ignore specific repos create a `ghorgignore` file inside `$HOME/ghorg`. Each line in this file is considered a substring and will be compared against each repos clone url. If the clone url contains a substring in the `ghorgignore` it will be excluded from cloning. To prevent accidentally excluding a repo, you should make each line as specific as possible, eg. `https://github.com/gabrie30/ghorg.git` or `git@github.com:gabrie30/ghorg.git` depending on how you clone. +- To ignore specific repos create a `ghorgignore` file inside `$HOME/.config/ghorg`. Each line in this file is considered a substring and will be compared against each repos clone url. If the clone url contains a substring in the `ghorgignore` it will be excluded from cloning. To prevent accidentally excluding a repo, you should make each line as specific as possible, eg. `https://github.com/gabrie30/ghorg.git` or `git@github.com:gabrie30/ghorg.git` depending on how you clone. ```bash # Create ghorgignore - touch $HOME/ghorg/ghorgignore + touch $HOME/.config/ghorg/ghorgignore # update file - vi $HOME/ghorg/ghorgignore + vi $HOME/.config/ghorg/ghorgignore ``` ## Known issues diff --git a/cmd/clone.go b/cmd/clone.go index ca53365..69a9e9b 100644 --- a/cmd/clone.go +++ b/cmd/clone.go @@ -66,7 +66,7 @@ type Repo struct { var cloneCmd = &cobra.Command{ Use: "clone", Short: "Clone user or org repos from GitHub, GitLab, or Bitbucket", - Long: `Clone user or org repos from GitHub, GitLab, or Bitbucket. See $HOME/ghorg/conf.yaml for defaults, its likely you will need to update some of these values of use the flags to overwrite them. Values are set first by a default value, then based off what is set in $HOME/ghorg/conf.yaml, finally the cli flags, which have the highest level of precedence.`, + Long: `Clone user or org repos from GitHub, GitLab, or Bitbucket. See $HOME/.config/ghorg/conf.yaml for defaults, its likely you will need to update some of these values of use the flags to overwrite them. Values are set first by a default value, then based off what is set in $HOME/.config/ghorg/conf.yaml, finally the cli flags, which have the highest level of precedence.`, Run: func(cmd *cobra.Command, argz []string) { if cmd.Flags().Changed("color") { diff --git a/cmd/version.go b/cmd/version.go index a6f8886..65e1864 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -15,6 +15,6 @@ var versionCmd = &cobra.Command{ Short: "Print the version number of Ghorg", Long: `All software has versions. This is Ghorg's`, Run: func(cmd *cobra.Command, args []string) { - fmt.Println("1.2.2") + fmt.Println("1.3.2") }, } diff --git a/configs/configs.go b/configs/configs.go index 210c060..81cdad8 100644 --- a/configs/configs.go +++ b/configs/configs.go @@ -17,10 +17,10 @@ import ( var ( // ErrNoGitHubToken error message when token is not found - ErrNoGitHubToken = errors.New("Could not find a valid github token. GHORG_GITHUB_TOKEN or (--token, -t) flag must be set. Create a personal access token, then set it in your $HOME/ghorg/conf.yaml or use the (--token, -t) flag...For best results read the troubleshooting section of README.md https://github.com/gabrie30/ghorg to properly store your token in the osx keychain") + ErrNoGitHubToken = errors.New("Could not find a valid github token. GHORG_GITHUB_TOKEN or (--token, -t) flag must be set. Create a personal access token, then set it in your $HOME/.config/ghorg/conf.yaml or use the (--token, -t) flag...For best results read the troubleshooting section of README.md https://github.com/gabrie30/ghorg to properly store your token in the osx keychain") // ErrNoGitLabToken error message when token is not found - ErrNoGitLabToken = errors.New("Could not find a valid gitlab token. GHORG_GITLAB_TOKEN or (--token, -t) flag must be set. Create a token from gitlab then set it in your $HOME/ghorg/conf.yaml or use the (--token, -t) flag...For best results read the troubleshooting section of README.md https://github.com/gabrie30/ghorg to properly store your token in the osx keychain") + ErrNoGitLabToken = errors.New("Could not find a valid gitlab token. GHORG_GITLAB_TOKEN or (--token, -t) flag must be set. Create a token from gitlab then set it in your $HOME/.config/ghorg/conf.yaml or use the (--token, -t) flag...For best results read the troubleshooting section of README.md https://github.com/gabrie30/ghorg to properly store your token in the osx keychain") // ErrNoBitbucketUsername error message when no username found ErrNoBitbucketUsername = errors.New("Could not find bitbucket username. GHORG_BITBUCKET_USERNAME or (--bitbucket-username) must be set to clone repos from bitbucket, see 'BitBucket Setup' in README.md") @@ -47,16 +47,26 @@ func initConfig() { viper.SetConfigType("yaml") viper.AddConfigPath(GhorgDir()) viper.SetConfigName("conf") + ghorgDir := GhorgDir() if err := viper.ReadInConfig(); err != nil { + if _, ok := err.(viper.ConfigFileNotFoundError); ok { // Config file not found; ignore error if desired - fmt.Println(err) - fmt.Println("Could not find $HOME/ghorg/conf.yaml file, please add one") + + if XConfigHomeSet() { + colorlog.PrintError("Found XDG_CONFIG_HOME set") + } + + fmt.Println("") + colorlog.PrintError(err) + + colorlog.PrintError(fmt.Sprintf("Could not find %s/conf.yaml file, add one by running the following \n \n $ mkdir -p %s \n $ curl https://raw.githubusercontent.com/gabrie30/ghorg/master/sample-conf.yaml > %s/conf.yaml \n", ghorgDir, ghorgDir, ghorgDir)) + log.Fatal("Exiting due to improper configuration") + } else { // Config file was found but another error was produced - fmt.Println(err) - fmt.Println("Something unexpected happened") + colorlog.PrintError(fmt.Sprintf("Something unexpected happened reading configuration file %s/conf.yaml, err: %s", ghorgDir, err)) } } @@ -99,7 +109,7 @@ func isZero(value interface{}) bool { func getOrSetDefaults(envVar string) { - // When a user does not set value in $HOME/ghorg/conf.yaml set the default values, else set env to what they have added to the file. + // When a user does not set value in $HOME/.config/ghorg/conf.yaml set the default values, else set env to what they have added to the file. if viper.GetString(envVar) == "" { switch envVar { case "GHORG_ABSOLUTE_PATH_TO_CLONE_TO": @@ -142,7 +152,20 @@ func GhorgIgnoreLocation() string { // GhorgDir returns the ghorg directory path func GhorgDir() string { - return HomeDir() + "/ghorg" + if XConfigHomeSet() { + return os.Getenv("XDG_CONFIG_HOME") + "/ghorg" + } + + return HomeDir() + "/.config/ghorg" +} + +// XConfigHomeSet checks for XDG_CONFIG_HOME env set +func XConfigHomeSet() bool { + if os.Getenv("XDG_CONFIG_HOME") != "" { + return true + } + + return false } // HomeDir finds the users home directory diff --git a/sample-conf.yaml b/sample-conf.yaml index 84aaed7..f750da3 100644 --- a/sample-conf.yaml +++ b/sample-conf.yaml @@ -1,4 +1,55 @@ --- +# +-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +# |G|I|T|H|U|B| |S|P|E|C|I|F|I|C| +# +-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ + + +# Add your GitHub token +# Defaults to using key returned by +# $ security find-internet-password -s github.com | grep "acct" | awk -F\" '{ print $4 }' +# flag (--token, -t) eg: --token=bGVhdmUgYSBjb21tZW50IG9uIGlzc3VlIDY2 +GHORG_GITHUB_TOKEN: + + +# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +# |G|I|T|L|A|B| |S|P|E|C|I|F|I|C| +# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +# Add your GitLab token +# Defaults to using key returned by +# $ security find-internet-password -s gitlab.com | grep "acct" | awk -F\" '{ print $4 }' +# flag (--token, -t) eg: --token=bGVhdmUgYSBjb21tZW50IG9uIGlzc3VlIDY2 +GHORG_GITLAB_TOKEN: + +# flag (--namespace, -n) +GHORG_GITLAB_DEFAULT_NAMESPACE: + +# clones repos in a directory structure that matches gitlab namespaces eg company/unit/subunit/app would clone into *_ghorg/unit/subunit/app +# default: false +# flag (--preserve-dir) +GHORG_PRESERVE_DIRECTORY_STRUCTURE: + + +# +-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +# |B|I|T|B|U|C|K|E|T| |S|P|E|C|I|F|I|C| +# +-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ + + +# Add your Bitbucket app password +# https://confluence.atlassian.com/bitbucket/app-passwords-828781300.html +# flag (--token, -t) eg: --token=bGVhdmUgYSBjb21tZW50IG9uIGlzc3VlIDY2 +GHORG_BITBUCKET_APP_PASSWORD: + +# flag (--bitbucket-username) +GHORG_BITBUCKET_USERNAME: + + +# +-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+ +# |G|E|N|E|R|A|L| |C|O|N|F|I|G|U|R|A|T|I|O|N| +# +-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+ + + # This is where your *_ghorg directory will be created, use absolute pathing. Must end with /, if not one will be added for you # default: $HOME/Desktop/ # flag (--path, -p) @@ -49,36 +100,3 @@ GHORG_BACKUP: # flag (--concurrency) GHORG_CONCURRENCY: -# --- GITHUB SPECIFIC --- - -# Add your GitHub token -# Defaults to using key returned by -# $ security find-internet-password -s github.com | grep "acct" | awk -F\" '{ print $4 }' -# flag (--token, -t) -GHORG_GITHUB_TOKEN: - -# --- GITLAB SPECIFIC --- - -# Add your GitLab token -# Defaults to using key returned by -# $ security find-internet-password -s gitlab.com | grep "acct" | awk -F\" '{ print $4 }' -# flag (--token, -t) -GHORG_GITLAB_TOKEN: - -# flag (--namespace, -n) -GHORG_GITLAB_DEFAULT_NAMESPACE: - -# clones repos in a directory structure that matches gitlab namespaces eg company/unit/subunit/app would clone into *_ghorg/unit/subunit/app -# default: false -# flag (--preserve-dir) -GHORG_PRESERVE_DIRECTORY_STRUCTURE: - -# --- BITBUCKET SPECIFIC --- - -# Add your Bitbucket app password -# https://confluence.atlassian.com/bitbucket/app-passwords-828781300.html -# flag (--token, -t) -GHORG_BITBUCKET_APP_PASSWORD: - -# flag (--bitbucket-username) -GHORG_BITBUCKET_USERNAME: