feat(config): update git configuration

This commit is contained in:
DataHearth 2022-02-26 01:28:36 +01:00
parent b48a15ef3d
commit 09a524444c
4 changed files with 118 additions and 48 deletions

View File

@ -29,11 +29,20 @@ var initCmd = &cobra.Command{
Long: `Initialize will retrieve your configuration folder from the source location and
copy it into the destination field`,
Run: func(cmd *cobra.Command, args []string) {
var config mapper.Configuration
if err := viper.Unmarshal(&config); err != nil {
errLogger.Printf(pterm.Red(fmt.Sprintf("failed to decode configuration: %v\n", err)))
os.Exit(1)
}
logger.Println("initializing config-mapper folder from configuration...")
if _, err := mapper.OpenGitRepo(); err != nil {
if _, err := mapper.OpenGitRepo(config.Storage.Git, config.Storage.Location); err != nil {
errLogger.Printf(pterm.Red(fmt.Sprintf("failed to initialize folder: %v\n", err)))
os.Exit(1)
}
logger.Printf("repository initialized at \"%v\"\n", viper.GetString("storage.location"))
},
}

View File

@ -1,35 +1,44 @@
storage:
# Where will be the tmp folder located ? [DEFAULT: MacOS($TMPDIR/config-mapper) | Linux(/tmp/config-mapper)]
location: /path/to/local/repository
location: /path/to/folder
git:
username: USERNAME
password: PASSWORD
repository: https://github.com/user/some-repo.git
# * by default, if ssh dict is set with it's key filled, I'll try to clone with SSH
repository: git@github.com:DataHearth/my-config.git
basic-auth:
username: USERNAME
# * NOTE: if you're having trouble with error "authentication required", you should maybe use a token access
# * In some cases, it's due to 2FA authentication enabled on the git hosting provided
password: TOKEN
ssh:
passphrase: PASSPHRASE
# path can be relative and can contain environment variables
private-key: /path/to/private/key
files:
- "~/.zshrc"
- darwin: "$LOCATION/macos/.zshrc:~/.zshrc"
linux: "$LOCATION/linux/.zshrc:~/.zshrc"
folders:
- "~/.ssh"
- darwin: "~/.zshrc:~/.zshrc"
linux: "~/.zshrc:~/.zshrc"
package-managers:
# [DEFAULT: apt, homebrew]
installation-order: ["apt", "homebrew"]
installation-order: ["homebrew"]
homebrew:
- bat
# - hexyl
# - fd
# - hyperfine
# - diskus
# - jq
# - k9s
# - go
# - starship
# - exa
# - httpie
# - neovim
# - nmap
# - pinentry
# - zsh
- hexyl
- fd
- hyperfine
- diskus
- jq
- k9s
- go
- starship
- exa
- httpie
- neovim
- nmap
- pinentry
- zsh
apt-get:

View File

@ -26,9 +26,19 @@ type Storage struct {
}
type Git struct {
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
Repository string `mapstructure:"repository"`
SSH Ssh `mapstructure:"ssh"`
BasicAuth BasicAuth `mapstructure:"basic-auth"`
Repository string `mapstructure:"repository"`
}
type BasicAuth struct {
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
}
type Ssh struct {
Passphrase string `mapstructure:"passphrase"`
PrivateKey string `mapstructure:"private-key"`
}
type PkgManagers struct {

View File

@ -2,36 +2,53 @@ package mapper
import (
"errors"
"fmt"
"os"
"path"
"strings"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/transport"
"github.com/go-git/go-git/v5/plumbing/transport/http"
"github.com/spf13/viper"
"github.com/go-git/go-git/v5/plumbing/transport/ssh"
)
var (
ErrDirIsFile = errors.New("path is a file")
ErrEmptyGitConfig = errors.New("empty git configuration")
ErrDirIsFile = errors.New("path is a file")
ErrInvalidEnv = errors.New("found invalid environment variable in path")
)
func OpenGitRepo() (*git.Repository, error) {
configFolder := viper.GetString("storage.location")
s, err := os.Stat(configFolder)
func OpenGitRepo(c Git, l string) (*git.Repository, error) {
s, err := os.Stat(l)
if err != nil {
if os.IsNotExist(err) {
gitConfig := viper.GetStringMapString("storage.git")
if gitConfig == nil {
return nil, ErrEmptyGitConfig
var auth transport.AuthMethod
if c.SSH.Passphrase != "" && c.SSH.PrivateKey != "" {
privateKey, err := absolutePath(c.SSH.PrivateKey)
if err != nil {
return nil, err
}
if _, err := os.Stat(privateKey); err != nil {
return nil, err
}
auth, err = ssh.NewPublicKeysFromFile("git", privateKey, c.SSH.Passphrase)
if err != nil {
return nil, err
}
} else {
auth = &http.BasicAuth{
Username: c.BasicAuth.Username,
Password: c.BasicAuth.Password,
}
}
repo, err := git.PlainClone(viper.GetString("storage.location"), false, &git.CloneOptions{
URL: gitConfig["repository"],
repo, err := git.PlainClone(l, false, &git.CloneOptions{
URL: c.Repository,
Progress: os.Stdout,
Auth: &http.BasicAuth{
Username: gitConfig["username"],
Password: gitConfig["password"],
},
Auth: auth,
})
if err != nil {
return nil, err
@ -43,18 +60,43 @@ func OpenGitRepo() (*git.Repository, error) {
return nil, err
}
if s.IsDir() {
if !s.IsDir() {
return nil, ErrDirIsFile
}
repo, err := git.PlainOpen(configFolder)
repo, err := git.PlainOpen(l)
if err != nil {
if err == git.ErrRepositoryNotExists {
return nil, err
}
return nil, err
}
return repo, nil
}
func absolutePath(p string) (string, error) {
finalPath := p
if strings.Contains(finalPath, "~") {
h, err := os.UserHomeDir()
if err != nil {
return "", err
}
finalPath = strings.Replace(p, "~", h, 1)
}
splitted := strings.Split(finalPath, "/")
finalPath = ""
for _, s := range splitted {
pathPart := s
if strings.Contains(s, "$") {
env := os.Getenv(s)
if env == "" {
return "", ErrInvalidEnv
}
pathPart = env
}
finalPath += fmt.Sprintf("/%s", pathPart)
}
return path.Clean(finalPath), nil
}