start refactoring
This commit is contained in:
parent
2d07590dbf
commit
01932bdfc7
|
@ -1,12 +1,20 @@
|
|||
# OPTIONAL: where your configuration is stored locally [default: $HOME/.config/config-mapper]
|
||||
path: /path/to/folder
|
||||
logging:
|
||||
log-level: info # OPTIONAL: [default: info] available: debug, info, warn, error, fatal
|
||||
time: true # OPTIONAL: [default: false] display time in logs
|
||||
time-format: 02/01/2006 15:04:05 # OPTIONAL: [default: 02/01/2006 15:04:05] format of time displayed in logs
|
||||
file: /path/to/logfile # OPTIONAL: [default: no file logging] path to log file
|
||||
disable-console: false # OPTIONAL: [default: false] should logs be printed in the terminal
|
||||
# ! REQUIRED: id used to identify your configuration folder (should be unique).
|
||||
# * NOTE: you can generate a UUIDv4 using "config-mapper gen-uuid --write".
|
||||
# * It will generate a UUIDv4 and write it to this file.
|
||||
# * If you initialize your configuration folder using "config-mapper init",
|
||||
# * this field automatically gets filled with a brand new UUIDv4.
|
||||
uuid: 2893211a-fac2-42a6-8f9d-9a8f692a8f04
|
||||
# ? OPTIONAL: where your configuration is stored locally.
|
||||
# * DEFAULT: $HOME/.local/state/config-mapper
|
||||
path: $HOME/.local/state/config-mapper
|
||||
|
||||
# ? OPTIONAL: log level
|
||||
# * DEFAULT: info
|
||||
# * OPTIONS: debug, info, warn, error
|
||||
log-level: info
|
||||
|
||||
# ! REQUIRED: list of storage provider to use. At least one is required.
|
||||
# * OPTIONS: git, (TODO: AWS, GCP, AZURE)
|
||||
storage:
|
||||
git:
|
||||
pull: true # OPTIONAL: [default: false] should git repository be pulled before any operation
|
||||
|
@ -29,51 +37,6 @@ storage:
|
|||
- private-key: /path/to/private/key
|
||||
passphrase: PASSPHRASE
|
||||
|
||||
# REQUIRED: list of items to save in configuration repository
|
||||
# ! REQUIRED: list of paths
|
||||
items:
|
||||
- name: .zshrc # OPTIONAL: [default: name of last path segment in "(universal|darwin|windows|linux).local" key]
|
||||
# REQUIRED (if any of "darwin|windows|linux" keys aren't set): universal location for all operating systems
|
||||
universal:
|
||||
# REQUIRED: path to local file
|
||||
local: /path/to/file
|
||||
# REQUIRED: path to remote file (absolute path where "/" is the root of the repository)
|
||||
remote: /remote/path
|
||||
# REQUIRED (if "universal" key is not set): location for darwin operating system
|
||||
darwin:
|
||||
# REQUIRED: path to local file
|
||||
local: /path/to/file
|
||||
# REQUIRED: path to remote file (absolute path where "/" is the root of the repository)
|
||||
remote: /remote/path
|
||||
# REQUIRED (if "universal" key is not set): location for windows operating system
|
||||
windows:
|
||||
# REQUIRED: path to local file
|
||||
local: /path/to/file
|
||||
# REQUIRED: path to remote file (absolute path where "/" is the root of the repository)
|
||||
remote: /remote/path
|
||||
# REQUIRED (if "universal" key is not set): location for linux operating system
|
||||
linux:
|
||||
# REQUIRED: path to local file
|
||||
local: /path/to/file
|
||||
# REQUIRED: path to remote file (absolute path where "/" is the root of the repository)
|
||||
remote: /remote/path
|
||||
|
||||
package-managers:
|
||||
# available: brew, pip (pip check also for pip3), cargo, apt, npm, go
|
||||
installation-order:
|
||||
- brew
|
||||
brew:
|
||||
- bat
|
||||
- hexyl
|
||||
- fd
|
||||
- hyperfine
|
||||
- diskus
|
||||
- jq
|
||||
- k9s
|
||||
- go
|
||||
- starship
|
||||
- exa
|
||||
- httpie
|
||||
- neovim
|
||||
- nmap
|
||||
- pinentry
|
||||
- zsh
|
||||
- $HOME/.config/nvim
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.env
|
||||
.DS_STORE
|
||||
build
|
||||
/.env
|
||||
/.DS_STORE
|
||||
/build
|
||||
/dist
|
||||
/.config-mapper.yml
|
||||
dist/
|
||||
.config-mapper.yml
|
||||
config/
|
|
@ -1,6 +1,9 @@
|
|||
version: 1
|
||||
|
||||
before:
|
||||
hooks:
|
||||
- go mod tidy
|
||||
|
||||
builds:
|
||||
- env:
|
||||
- CGO_ENABLED=0
|
||||
|
@ -8,40 +11,19 @@ builds:
|
|||
- linux
|
||||
- windows
|
||||
- darwin
|
||||
goarch:
|
||||
- "386"
|
||||
- amd64
|
||||
- arm
|
||||
- arm64
|
||||
|
||||
archives:
|
||||
- format: tar.gz
|
||||
files:
|
||||
- LICENSE
|
||||
- README.md
|
||||
- .config-mapper.yml.template
|
||||
- CHANGELOG.md
|
||||
name_template: >-
|
||||
{{ .ProjectName }}_
|
||||
{{ .Version }}_
|
||||
{{- title .Os }}_
|
||||
{{- if eq .Arch "amd64" }}x86_64
|
||||
{{- else if eq .Arch "386" }}i386
|
||||
{{- else }}{{ .Arch }}{{ end }}
|
||||
|
||||
gitea_urls:
|
||||
api: https://gitea.antoine-langlois.net/api/v1
|
||||
download: https://gitea.antoine-langlois.net
|
||||
|
||||
release:
|
||||
gitea:
|
||||
owner: DataHearth
|
||||
name: config-mapper
|
||||
mode: append
|
||||
|
||||
checksum:
|
||||
name_template: "checksums.txt"
|
||||
|
||||
snapshot:
|
||||
name_template: "{{ incpatch .Version }}-next"
|
||||
|
||||
force_token: gitea
|
||||
{{- if .Arm }}v{{ .Arm }}{{ end }}
|
||||
format_overrides:
|
||||
- goos: windows
|
||||
format: zip
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"files.associations": {
|
||||
".config-mapper.yml.template": "yaml"
|
||||
}
|
||||
}
|
54
go.mod
54
go.mod
|
@ -1,53 +1,13 @@
|
|||
module gitea.antoine-langlois.net/datahearth/config-mapper
|
||||
|
||||
go 1.21
|
||||
go 1.21.5
|
||||
|
||||
require github.com/urfave/cli/v2 v2.25.7
|
||||
|
||||
require (
|
||||
github.com/briandowns/spinner v1.23.0
|
||||
github.com/go-git/go-git/v5 v5.4.2
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/viper v1.10.0
|
||||
github.com/urfave/cli/v2 v2.25.7
|
||||
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/google/uuid v1.5.0
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.4.16 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect
|
||||
github.com/acomagu/bufpipe v1.0.3 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/emirpasic/gods v1.12.0 // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
||||
github.com/go-git/gcfg v1.5.0 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.3.1 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
|
||||
github.com/magiconair/properties v1.8.5 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/mattn/go-isatty v0.0.18 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.3 // indirect
|
||||
github.com/pelletier/go-toml v1.9.4 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sergi/go-diff v1.1.0 // indirect
|
||||
github.com/spf13/afero v1.6.0 // indirect
|
||||
github.com/spf13/cast v1.4.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
github.com/subosito/gotenv v1.2.0 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.0 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect
|
||||
golang.org/x/sys v0.11.0 // indirect
|
||||
golang.org/x/term v0.1.0 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
gopkg.in/ini.v1 v1.66.2 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
|
162
go.sum
162
go.sum
|
@ -1,171 +1,13 @@
|
|||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
|
||||
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
|
||||
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
|
||||
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/briandowns/spinner v1.23.0 h1:alDF2guRWqa/FOZZYWjlMIx2L6H0wyewPxo/CH4Pt2A=
|
||||
github.com/briandowns/spinner v1.23.0/go.mod h1:rPG4gmXeN3wQV/TsAY4w8lPdIM6RX3yqeBQJSrbXjuE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
|
||||
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
||||
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
|
||||
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
||||
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
|
||||
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||
github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34=
|
||||
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0=
|
||||
github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4=
|
||||
github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
|
||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
|
||||
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
|
||||
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
|
||||
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=
|
||||
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
|
||||
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
|
||||
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||
github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
|
||||
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.10.0 h1:mXH0UwHS4D2HwWZa75im4xIQynLfblmWV7qcWpfv0yk=
|
||||
github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
|
||||
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
|
||||
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
|
||||
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
|
||||
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c=
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI=
|
||||
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
cmLog "gitea.antoine-langlois.net/datahearth/config-mapper/internal/logger"
|
||||
"github.com/google/uuid"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type Definition struct {
|
||||
UUID uuid.UUID `yaml:"uuid"`
|
||||
Path string `yaml:"path,omitempty"`
|
||||
LogLevel string `yaml:"log-level,omitempty"`
|
||||
Storage Storage `yaml:"storage"`
|
||||
Items []string `yaml:"items"`
|
||||
}
|
||||
|
||||
func Load(logger *cmLog.Logger) (*Definition, error) {
|
||||
env := "$HOME/.config/config-mapper.yml"
|
||||
if v := os.Getenv("CFG_MAPPER_CONFIG_PATH"); v != "" {
|
||||
env = v
|
||||
}
|
||||
|
||||
logger.Debug("Loading config from %s", env)
|
||||
f, err := os.Open(env)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
cfg := Definition{}
|
||||
d, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := yaml.Unmarshal(d, &cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package config
|
||||
|
||||
type Storage struct {
|
||||
Git interface{} `yaml:"git"`
|
||||
AWS interface{}
|
||||
GCP interface{}
|
||||
}
|
||||
|
||||
type Git struct {
|
||||
Repository string `yaml:"repository"`
|
||||
Authentication struct {
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
} `yaml:"authentication"`
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
package internal
|
||||
|
||||
type Configuration struct {
|
||||
Path string `yaml:"path"`
|
||||
Storage Storage `yaml:"storage"`
|
||||
Items []Item `yaml:"items"`
|
||||
PackageManagers PkgManagers `yaml:"package-managers"`
|
||||
Logging Logging `yaml:"logging"`
|
||||
}
|
||||
|
||||
type Logging struct {
|
||||
Level string `yaml:"log-level,omitempty"`
|
||||
EnableTime bool `yaml:"time,omitempty"`
|
||||
TimeFormat string `yaml:"time-format,omitempty"`
|
||||
File string `yaml:"file,omitempty"`
|
||||
DisableConsole bool `yaml:"disable-console"`
|
||||
}
|
||||
|
||||
type Item struct {
|
||||
Name string `yaml:"name"`
|
||||
Universal ItemLocation `yaml:"universal"`
|
||||
Darwin ItemLocation `yaml:"darwin"`
|
||||
Linux ItemLocation `yaml:"linux"`
|
||||
Windows ItemLocation `yaml:"windows"`
|
||||
}
|
||||
|
||||
type ItemLocation struct {
|
||||
Local string `yaml:"local"`
|
||||
Remote string `yaml:"remote"`
|
||||
}
|
||||
|
||||
type Storage struct {
|
||||
Git Git `yaml:"git"`
|
||||
}
|
||||
|
||||
type Git struct {
|
||||
Repository string `yaml:"repository"`
|
||||
Name string `yaml:"name"`
|
||||
Email string `yaml:"email"`
|
||||
BasicAuth BasicAuth `yaml:"basic"`
|
||||
SshAuth []SshAuth `yaml:"ssh"`
|
||||
Pull bool `yaml:"pull"`
|
||||
}
|
||||
|
||||
type BasicAuth struct {
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
}
|
||||
|
||||
type SshAuth struct {
|
||||
PrivateKey string `yaml:"private-key"`
|
||||
Passphrase string `yaml:"passphrase"`
|
||||
}
|
||||
|
||||
type PkgManagers struct {
|
||||
InstallationOrder []string `yaml:"installation-order"`
|
||||
Brew []string `yaml:"brew"`
|
||||
Apt []string `yaml:"apt"`
|
||||
Cargo []string `yaml:"cargo"`
|
||||
Pip []string `yaml:"pip"`
|
||||
Npm []string `yaml:"npm"`
|
||||
Go []string `yaml:"go"`
|
||||
Nala []string `yaml:"nala"`
|
||||
}
|
261
internal/git.go
261
internal/git.go
|
@ -1,261 +0,0 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing/object"
|
||||
"github.com/go-git/go-git/v5/plumbing/transport"
|
||||
"github.com/go-git/go-git/v5/plumbing/transport/http"
|
||||
"github.com/go-git/go-git/v5/plumbing/transport/ssh"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type Repository struct {
|
||||
availableAuth []transport.AuthMethod
|
||||
auth transport.AuthMethod
|
||||
repository *git.Repository
|
||||
repoPath string
|
||||
url string
|
||||
author *object.Signature
|
||||
}
|
||||
|
||||
// NewRepository creates a new repository struct by either cloning or opening the repository
|
||||
func NewRepository(config Git, repoPath string, clone bool) (*Repository, error) {
|
||||
var auth []transport.AuthMethod = nil
|
||||
if config.Repository == "" {
|
||||
return nil, errors.New("a repository URI is needed (either using GIT protocol or HTTPS)")
|
||||
}
|
||||
|
||||
repoPath, err := ResolvePath(repoPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i, c := range config.SshAuth {
|
||||
sshAuth, err := getSSHAuthMethod(c)
|
||||
if err != nil {
|
||||
fmt.Printf("failed to create SSH authentication method for configuration n°%d: %v\n", i, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if auth == nil {
|
||||
auth = []transport.AuthMethod{}
|
||||
}
|
||||
auth = append(auth, sshAuth)
|
||||
}
|
||||
|
||||
if len(auth) == 0 {
|
||||
auth = append(auth, &http.BasicAuth{
|
||||
Username: config.BasicAuth.Username,
|
||||
Password: config.BasicAuth.Password,
|
||||
})
|
||||
}
|
||||
|
||||
repo := &Repository{
|
||||
availableAuth: auth,
|
||||
auth: nil,
|
||||
repository: nil,
|
||||
repoPath: repoPath,
|
||||
url: config.Repository,
|
||||
author: &object.Signature{
|
||||
Name: config.Name,
|
||||
Email: config.Email,
|
||||
},
|
||||
}
|
||||
|
||||
if clone {
|
||||
if err := repo.cloneRepository(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if err := repo.openRepository(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return repo, nil
|
||||
}
|
||||
|
||||
// openRepository opens the repository at the given path
|
||||
func (r *Repository) openRepository() error {
|
||||
repo, err := git.PlainOpen(r.repoPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w, err := repo.Worktree()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if r.availableAuth != nil {
|
||||
pulled := false
|
||||
for _, auth := range r.availableAuth {
|
||||
err := w.Pull(&git.PullOptions{
|
||||
Auth: auth,
|
||||
})
|
||||
if err != nil {
|
||||
if err == git.NoErrAlreadyUpToDate {
|
||||
pulled = true
|
||||
break
|
||||
} else if checkAuthErr(err) {
|
||||
logrus.WithField("auth", auth.String()).Warn("failed to authenticate. Trying next auth if exists")
|
||||
continue
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
pulled = true
|
||||
r.auth = auth
|
||||
break
|
||||
}
|
||||
|
||||
if !pulled {
|
||||
return fmt.Errorf("authentication failed for git repository")
|
||||
}
|
||||
} else {
|
||||
if err := w.Pull(&git.PullOptions{}); err != nil && err != git.NoErrAlreadyUpToDate {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
r.repository = repo
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PushChanges pushes changes to the remote repository
|
||||
func (r *Repository) PushChanges(msg string, newLines, removedLines []string) error {
|
||||
w, err := r.repository.Worktree()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
status, err := w.Status()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for file := range status {
|
||||
if _, err := w.Add(file); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
author := r.author
|
||||
author.When = time.Now()
|
||||
if _, err := w.Commit(msg, &git.CommitOptions{
|
||||
Author: author,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return r.repository.Push(&git.PushOptions{
|
||||
Auth: r.auth,
|
||||
})
|
||||
}
|
||||
|
||||
// FetchChanges fetches changes from the remote repository. If changes are fetched,
|
||||
// the function returns true, otherwise false.
|
||||
func (r *Repository) FetchChanges() (bool, error) {
|
||||
if err := r.repository.Fetch(&git.FetchOptions{
|
||||
Auth: r.auth,
|
||||
}); err != nil {
|
||||
if err == git.NoErrAlreadyUpToDate {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// cloneRepository clones the repository into the given path
|
||||
func (r *Repository) cloneRepository() error {
|
||||
var repo *git.Repository
|
||||
var err error
|
||||
if r.availableAuth != nil {
|
||||
for _, auth := range r.availableAuth {
|
||||
repo, err = git.PlainClone(r.repoPath, false, &git.CloneOptions{
|
||||
URL: r.url,
|
||||
Auth: auth,
|
||||
})
|
||||
if err != nil {
|
||||
if checkAuthErr(err) {
|
||||
logrus.WithField("auth", auth.String()).Warn("failed to authenticate. Trying next auth if exists")
|
||||
continue
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
r.auth = auth
|
||||
break
|
||||
}
|
||||
|
||||
if repo == nil {
|
||||
return fmt.Errorf("authentication failed for git repository")
|
||||
}
|
||||
} else {
|
||||
repo, err = git.PlainClone(r.repoPath, false, &git.CloneOptions{
|
||||
URL: r.url,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
r.repository = repo
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Pull pulls changes from the remote repository
|
||||
func (r *Repository) Pull() error {
|
||||
w, err := r.repository.Worktree()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return w.Pull(&git.PullOptions{
|
||||
Auth: r.auth,
|
||||
})
|
||||
}
|
||||
|
||||
// getSSHAuthMethod returns an authentication method for SSH
|
||||
func getSSHAuthMethod(config SshAuth) (transport.AuthMethod, error) {
|
||||
if config.PrivateKey == "" {
|
||||
return nil, errors.New("\"private-key\" field is empty")
|
||||
}
|
||||
|
||||
privateKey, err := ResolvePath(config.PrivateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s, err := os.Stat(privateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if s.IsDir() {
|
||||
return nil, errors.New("private key is a directory")
|
||||
}
|
||||
|
||||
auth, err := ssh.NewPublicKeysFromFile("git", privateKey, config.Passphrase)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return auth, nil
|
||||
}
|
||||
|
||||
// checkAuthErr checks if the error is an authentication error
|
||||
func checkAuthErr(err error) bool {
|
||||
return err == transport.ErrAuthorizationFailed || err == transport.ErrAuthenticationRequired
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
package internal
|
|
@ -1,89 +0,0 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
red = 31
|
||||
green = 32
|
||||
yellow = 33
|
||||
blue = 36
|
||||
gray = 37
|
||||
)
|
||||
|
||||
const (
|
||||
PanicLevel logrus.Level = iota
|
||||
FatalLevel
|
||||
ErrorLevel
|
||||
WarnLevel
|
||||
InfoLevel
|
||||
DebugLevel
|
||||
TraceLevel
|
||||
)
|
||||
|
||||
type LoggerFormatter struct {
|
||||
TimeFormat string
|
||||
}
|
||||
|
||||
// Format gather all the data from the log entry and format it to return the final log message
|
||||
func (f *LoggerFormatter) Format(e *logrus.Entry) ([]byte, error) {
|
||||
msg := f.printColored(e)
|
||||
|
||||
if len(e.Data) != 0 {
|
||||
var fields string
|
||||
for k, v := range e.Data {
|
||||
if fields == "" {
|
||||
fields = fmt.Sprintf("%s=%v", k, v)
|
||||
} else {
|
||||
fields = fmt.Sprintf("%s %s=%v", fields, k, v)
|
||||
}
|
||||
}
|
||||
|
||||
msg = fmt.Sprintf("%s %s %s\n", msg, e.Message, fields)
|
||||
} else {
|
||||
msg = fmt.Sprintf("%s %s\n", msg, e.Message)
|
||||
}
|
||||
|
||||
if f.TimeFormat != "" {
|
||||
msg = fmt.Sprintf("[%s] %s", time.Now().Format(f.TimeFormat), msg)
|
||||
}
|
||||
|
||||
return []byte(msg), nil
|
||||
}
|
||||
|
||||
// printColored returns the prefix for log message with correct log level color and name
|
||||
func (f *LoggerFormatter) printColored(e *logrus.Entry) string {
|
||||
var levelColor int
|
||||
var levelText string
|
||||
switch e.Level {
|
||||
case TraceLevel:
|
||||
levelText = "TRACE:"
|
||||
levelColor = gray
|
||||
case DebugLevel:
|
||||
levelText = "DEBUG:"
|
||||
levelColor = blue
|
||||
case InfoLevel:
|
||||
levelText = "INFO:"
|
||||
levelColor = green
|
||||
case WarnLevel:
|
||||
levelText = "WARNING:"
|
||||
levelColor = yellow
|
||||
case ErrorLevel:
|
||||
levelText = "ERROR:"
|
||||
levelColor = red
|
||||
case FatalLevel:
|
||||
levelText = "FATAL:"
|
||||
levelColor = red
|
||||
case PanicLevel:
|
||||
levelText = "PANIC:"
|
||||
levelColor = red
|
||||
default:
|
||||
levelColor = blue
|
||||
}
|
||||
|
||||
return fmt.Sprintf("\x1b[%dm%s\x1b[0m", levelColor, levelText)
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ClassicLogFormat is the format used to print user logs.
|
||||
//
|
||||
// Format: "LEVEL MESSAGE"
|
||||
const ClassicLogFormat = "%s %s"
|
||||
|
||||
type Level uint8
|
||||
|
||||
const (
|
||||
Error Level = iota
|
||||
Warn
|
||||
Info
|
||||
Debug
|
||||
)
|
||||
|
||||
var (
|
||||
Reset = "\033[0m"
|
||||
Red = "\033[31m"
|
||||
Green = "\033[32m"
|
||||
Yellow = "\033[33m"
|
||||
Blue = "\033[34m"
|
||||
)
|
||||
|
||||
func (l Level) String() string {
|
||||
switch l {
|
||||
case Error:
|
||||
return fmt.Sprintf("%s%s%s", Red, "ERROR", Reset)
|
||||
case Warn:
|
||||
return fmt.Sprintf("%s%s%s", Yellow, "WARN", Reset)
|
||||
case Info:
|
||||
return fmt.Sprintf("%s%s%s", Green, "INFO", Reset)
|
||||
case Debug:
|
||||
return fmt.Sprintf("%s%s%s", Blue, "DEBUG", Reset)
|
||||
default:
|
||||
panic("invalid logger level")
|
||||
}
|
||||
}
|
||||
|
||||
func LevelFromString(lvl string) Level {
|
||||
switch strings.ToUpper(lvl) {
|
||||
case "ERROR":
|
||||
return Error
|
||||
case "WARN":
|
||||
return Warn
|
||||
case "INFO":
|
||||
return Info
|
||||
case "DEBUG":
|
||||
return Debug
|
||||
default:
|
||||
panic("invalid logger level")
|
||||
}
|
||||
}
|
||||
|
||||
type Logger struct {
|
||||
Lvl Level
|
||||
}
|
||||
|
||||
// New instanciates a new Logger. It takes a Level as argument.
|
||||
func New(level Level) *Logger {
|
||||
return &Logger{
|
||||
Lvl: level,
|
||||
}
|
||||
}
|
||||
|
||||
// Error logs an error message.
|
||||
func (l Logger) Error(msg string, args ...interface{}) {
|
||||
l.log(Error, msg, args...)
|
||||
}
|
||||
|
||||
// Warn logs a warning message.
|
||||
func (l Logger) Warn(msg string, args ...interface{}) {
|
||||
l.log(Warn, msg, args...)
|
||||
}
|
||||
|
||||
// Info logs an info message.
|
||||
func (l Logger) Info(msg string, args ...interface{}) {
|
||||
l.log(Info, msg, args...)
|
||||
}
|
||||
|
||||
// Debug logs a debug message.
|
||||
func (l Logger) Debug(msg string, args ...interface{}) {
|
||||
l.log(Debug, msg, args...)
|
||||
}
|
||||
|
||||
func (l Logger) log(level Level, msg string, args ...interface{}) {
|
||||
if l.Lvl >= level {
|
||||
fmt.Printf(ClassicLogFormat, l.Lvl, fmt.Sprintf(msg, args...))
|
||||
}
|
||||
}
|
160
internal/pkgs.go
160
internal/pkgs.go
|
@ -1,160 +0,0 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/briandowns/spinner"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// InstallPackages install all packages from the configuration file by installation order
|
||||
func InstallPackages(c PkgManagers) error {
|
||||
pkgManagers := map[string]bool{}
|
||||
for _, pkgManager := range viper.GetStringSlice("exclude-pkg-managers") {
|
||||
pkgManagers[pkgManager] = true
|
||||
}
|
||||
|
||||
for _, pkgManager := range c.InstallationOrder {
|
||||
log := logrus.WithField("package manager", pkgManager)
|
||||
log.Infoln("Installing packages")
|
||||
if _, ok := pkgManagers[pkgManager]; ok {
|
||||
log.Infoln("Skipping...")
|
||||
continue
|
||||
}
|
||||
|
||||
var pkgs []string
|
||||
switch pkgManager {
|
||||
case "brew":
|
||||
pkgs = c.Brew
|
||||
case "apt":
|
||||
pkgs = c.Apt
|
||||
case "cargo":
|
||||
pkgs = c.Cargo
|
||||
case "npm":
|
||||
pkgs = c.Npm
|
||||
case "pip":
|
||||
pkgs = c.Pip
|
||||
case "go":
|
||||
pkgs = c.Go
|
||||
case "nala":
|
||||
pkgs = c.Nala
|
||||
default:
|
||||
log.Error("Package manager not supported")
|
||||
continue
|
||||
}
|
||||
|
||||
if _, err := exec.LookPath(pkgManager); err != nil {
|
||||
// * pip might not be available on the system but pip3 is
|
||||
if pkgManager == "pip" {
|
||||
if _, err := exec.LookPath("pip3"); err != nil {
|
||||
log.Error("\"pip\" & \"pip3\" are not available on your system")
|
||||
continue
|
||||
}
|
||||
pkgManager = "pip3"
|
||||
} else {
|
||||
log.Error("Package manager not available. Please, install it first")
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// * for some reason, apt binary is available on darwin. Exclude it to avoid errors
|
||||
if pkgManager == "apt" && runtime.GOOS == "darwin" {
|
||||
log.Error("\"apt\" is not available on Darwin")
|
||||
continue
|
||||
}
|
||||
|
||||
if len(pkgs) == 0 {
|
||||
log.Infoln("Nothing to do")
|
||||
continue
|
||||
}
|
||||
|
||||
v := viper.GetBool("verbose")
|
||||
commands := []*exec.Cmd{}
|
||||
// * package managers requiring sudo permission
|
||||
if pkgManager == "apt" || pkgManager == "nala" {
|
||||
commands = append(commands, buildDefaultCommand([]string{"sudo", pkgManager, "install", "-y"}, pkgs, v))
|
||||
} else if pkgManager == "cargo" {
|
||||
commands = buildCargoCommand(pkgs, v)
|
||||
} else {
|
||||
commands = append(commands, buildDefaultCommand([]string{pkgManager, "install"}, pkgs, v))
|
||||
}
|
||||
|
||||
for i, cmd := range commands {
|
||||
s := spinner.New(spinner.CharSets[14], 100*time.Millisecond)
|
||||
s.Suffix = "Installing..."
|
||||
if !v {
|
||||
s.Start()
|
||||
}
|
||||
if err := cmd.Run(); err != nil {
|
||||
if v {
|
||||
log.Error(err)
|
||||
} else {
|
||||
msg := fmt.Sprintf(" %s", cmd.Args)
|
||||
if i == len(commands)-1 {
|
||||
msg = fmt.Sprintf("%s\n", msg)
|
||||
}
|
||||
s.FinalMSG = fmt.Sprintf("\x1b[31mFailed: %s\x1b[0m", msg)
|
||||
s.Stop()
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if !v {
|
||||
msg := fmt.Sprintf(" %s", cmd.Args)
|
||||
if i == len(commands)-1 {
|
||||
msg = fmt.Sprintf("%s\n", msg)
|
||||
}
|
||||
s.FinalMSG = fmt.Sprintf("\x1b[32mInstalled: %s\x1b[0m", msg)
|
||||
s.Stop()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildCargoCommand(packages []string, verbose bool) []*exec.Cmd {
|
||||
commands := []*exec.Cmd{}
|
||||
|
||||
cmd := exec.Command("cargo", "install")
|
||||
for _, pkg := range packages {
|
||||
if strings.Contains(pkg, " ") {
|
||||
customCmd := exec.Command("cargo", "install")
|
||||
customCmd.Args = append(cmd.Args, strings.Split(pkg, " ")...)
|
||||
if verbose {
|
||||
customCmd.Stderr = os.Stderr
|
||||
customCmd.Stdout = os.Stdout
|
||||
}
|
||||
commands = append(commands, customCmd)
|
||||
} else {
|
||||
cmd.Args = append(cmd.Args, pkg)
|
||||
}
|
||||
}
|
||||
|
||||
if verbose {
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Stdout = os.Stdout
|
||||
}
|
||||
if len(cmd.Args) > 2 {
|
||||
commands = append(commands, cmd)
|
||||
}
|
||||
|
||||
return commands
|
||||
}
|
||||
|
||||
func buildDefaultCommand(command, packages []string, verbose bool) *exec.Cmd {
|
||||
cmd := exec.Command(command[0], command[1:]...)
|
||||
cmd.Args = append(cmd.Args, packages...)
|
||||
if verbose {
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Stdout = os.Stdout
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package git
|
||||
|
||||
import "gitea.antoine-langlois.net/datahearth/config-mapper/internal/providers"
|
||||
|
||||
type Git struct {
|
||||
rootDir string
|
||||
remoteDir string
|
||||
}
|
||||
|
||||
func New(rootDir string, remoteDir string) providers.Provider {
|
||||
return Git{
|
||||
rootDir: rootDir,
|
||||
remoteDir: remoteDir,
|
||||
}
|
||||
}
|
||||
|
||||
func (g Git) Upload() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g Git) Download() error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package providers
|
||||
|
||||
type Provider interface {
|
||||
Upload() error
|
||||
Download() error
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
package internal
|
|
@ -1,23 +0,0 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ResolvePath resolves the path using environment variables and "~"
|
||||
func ResolvePath(path string) (string, error) {
|
||||
path = os.ExpandEnv(path)
|
||||
if strings.Contains(path, "~") {
|
||||
usr, err := user.Current()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
path = filepath.Join(usr.HomeDir, strings.Replace(path, "~", "", 1))
|
||||
}
|
||||
|
||||
return path, nil
|
||||
}
|
6
justfile
6
justfile
|
@ -1,11 +1,5 @@
|
|||
set dotenv-load
|
||||
set shell := ["zsh", "-uc"]
|
||||
|
||||
latest-tag := `git describe --tags --abbrev=0`
|
||||
|
||||
default:
|
||||
@just --list
|
||||
|
||||
publish version: (bump-files-version version)
|
||||
git-chglog --next-tag {{version}} --output CHANGELOG.md
|
||||
git add CHANGELOG.md cmd/cli.go && git commit -m "chore(changelog): release {{version}}"
|
||||
|
|
320
main.go
320
main.go
|
@ -1,304 +1,50 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"gitea.antoine-langlois.net/datahearth/config-mapper/internal"
|
||||
"github.com/sirupsen/logrus"
|
||||
cmConfig "gitea.antoine-langlois.net/datahearth/config-mapper/internal/config"
|
||||
cmLog "gitea.antoine-langlois.net/datahearth/config-mapper/internal/logger"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/exp/slices"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
var (
|
||||
configuration internal.Configuration
|
||||
logFormatter = new(internal.LoggerFormatter)
|
||||
app = &cli.App{
|
||||
Version: "v0.6.2",
|
||||
Name: "config-mapper",
|
||||
Description: "Manage your systems configuration",
|
||||
UsageText: `config-mapper aims to help you manage your configurations between systems
|
||||
with a single configuration file.`,
|
||||
Authors: []*cli.Author{
|
||||
{
|
||||
Name: "Antoine Langlois",
|
||||
Email: "antoine.l@antoine-langlois.net",
|
||||
},
|
||||
var app = &cli.App{
|
||||
Version: "v1.0.0-alpha",
|
||||
Name: "config-mapper",
|
||||
Description: "Manage your systems configurations",
|
||||
UsageText: `config-mapper aims to help you manage your configurations between systems
|
||||
with a single configuration file.`,
|
||||
Authors: []*cli.Author{
|
||||
{
|
||||
Name: "Antoine Langlois",
|
||||
Email: "antoine.l@antoine-langlois.net",
|
||||
},
|
||||
Suggest: true,
|
||||
EnableBashCompletion: true,
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "config",
|
||||
Aliases: []string{"c"},
|
||||
Usage: "location of configuration file",
|
||||
Value: "$HOME/.config-mapper.yml",
|
||||
Action: func(ctx *cli.Context, s string) error {
|
||||
path, err := internal.ResolvePath(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stat, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
},
|
||||
Suggest: true,
|
||||
EnableBashCompletion: true,
|
||||
Flags: []cli.Flag{},
|
||||
Before: func(ctx *cli.Context) error {
|
||||
var err error
|
||||
config, err = cmConfig.Load(logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if stat.IsDir() {
|
||||
return fmt.Errorf("--config must be a file. Found directory")
|
||||
}
|
||||
if config.LogLevel != "" {
|
||||
logger.Lvl = cmLog.LevelFromString(config.LogLevel)
|
||||
}
|
||||
|
||||
if !slices.Contains([]string{".yml", ".yaml"}, filepath.Ext(path)) {
|
||||
return fmt.Errorf("--config must be a \".yml|yaml\" file")
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
Commands: []*cli.Command{
|
||||
{
|
||||
Name: "init",
|
||||
Aliases: []string{"i"},
|
||||
Usage: "Initialize your configuration folder",
|
||||
UsageText: `Initialize will retrieve your configuration folder from the source location and
|
||||
copy it into the destination field`,
|
||||
Action: initCommand,
|
||||
Before: beforeAction,
|
||||
},
|
||||
{
|
||||
Name: "load",
|
||||
Aliases: []string{"l"},
|
||||
Usage: "Load your configurations onto your system",
|
||||
UsageText: `Load your items and package managers dependencies onto your new
|
||||
system based on your configuration file`,
|
||||
Action: loadCommand,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "items",
|
||||
Usage: "Items will not be loaded",
|
||||
Aliases: []string{"i"},
|
||||
Category: "Exclude",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "packages",
|
||||
Usage: "Packages will be installed",
|
||||
Aliases: []string{"p"},
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "package-managers",
|
||||
Usage: "Exclude packages from specified package managers to be installed",
|
||||
Category: "Exclude",
|
||||
Aliases: []string{"P"},
|
||||
Action: func(ctx *cli.Context, s []string) error {
|
||||
if !ctx.Bool("packages") {
|
||||
return fmt.Errorf("--packages is required to exclude package managers")
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
Before: beforeAction,
|
||||
},
|
||||
{
|
||||
Name: "save",
|
||||
Aliases: []string{"s"},
|
||||
Usage: "save your configurations onto your saved location",
|
||||
UsageText: `Save your items onto your saved location based on your configuration file`,
|
||||
Action: saveCommand,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "push",
|
||||
Usage: "Push changes to remote repository",
|
||||
Aliases: []string{"p"},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "message",
|
||||
Usage: "Commit message when pushing repository",
|
||||
Aliases: []string{"m"},
|
||||
Action: func(ctx *cli.Context, s string) error {
|
||||
if !ctx.Bool("push") {
|
||||
return fmt.Errorf("--push option is required to set a message")
|
||||
}
|
||||
if len(strings.Trim(s, " ")) == 0 {
|
||||
return fmt.Errorf("message must contain at least one character")
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
Before: beforeAction,
|
||||
},
|
||||
{
|
||||
Name: "install",
|
||||
Usage: "Install additional tools",
|
||||
UsageText: `Install additional tools like package managers (brew, nala),
|
||||
programming language (golang, rust, python)`,
|
||||
ArgsUsage: "TOOLS",
|
||||
Action: installCommand,
|
||||
},
|
||||
{
|
||||
Name: "check",
|
||||
Aliases: []string{"c"},
|
||||
Usage: "Check if remote has updates",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "pull",
|
||||
Usage: "Pull updates if any",
|
||||
},
|
||||
},
|
||||
Action: checkCommand,
|
||||
Before: beforeAction,
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
logrus.SetFormatter(logFormatter)
|
||||
return nil
|
||||
},
|
||||
Commands: []*cli.Command{},
|
||||
}
|
||||
var (
|
||||
logger = cmLog.New(cmLog.Info)
|
||||
config *cmConfig.Definition
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
logrus.Fatalln(err)
|
||||
logger.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func initCommand(ctx *cli.Context) error {
|
||||
if _, err := os.Stat(configuration.Path); err == nil {
|
||||
logrus.Warnf("configuration folder already exists at %s", configuration.Path)
|
||||
return nil
|
||||
}
|
||||
|
||||
logrus.WithField("path", configuration.Path).Infoln("initializing configuration folder...")
|
||||
|
||||
if _, err := internal.NewRepository(configuration.Storage.Git, configuration.Path, true); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Infoln("Everything is ready to go!")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func saveCommand(ctx *cli.Context) error {
|
||||
repo, err := internal.NewRepository(configuration.Storage.Git, configuration.Path, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if configuration.Storage.Git.Pull {
|
||||
if err := repo.Pull(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Debugln("Changes pulled")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadCommand(ctx *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func installCommand(ctx *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkCommand(ctx *cli.Context) error {
|
||||
repo, err := internal.NewRepository(configuration.Storage.Git, configuration.Path, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
changes, err := repo.FetchChanges()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if changes {
|
||||
logrus.Infoln("Configuration has changed upstream")
|
||||
if ctx.Bool("pull") {
|
||||
logrus.Infoln("Pulling changes...")
|
||||
if err := repo.Pull(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logrus.Infoln("Configuration is up-to-date")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func beforeAction(ctx *cli.Context) error {
|
||||
configPath, err := internal.ResolvePath(ctx.String("config"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := yaml.Unmarshal(f, &configuration); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if configuration.Logging.Level != "" {
|
||||
lvl, err := logrus.ParseLevel(configuration.Logging.Level)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.SetLevel(lvl)
|
||||
}
|
||||
if configuration.Logging.File != "" {
|
||||
loggingFile := configuration.Logging.File
|
||||
s, err := os.Stat(filepath.Dir(loggingFile))
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(filepath.Dir(loggingFile), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if !s.IsDir() {
|
||||
return fmt.Errorf("parent path segment of \"log-file\" field is a file")
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(configuration.Logging.File, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var out io.Writer
|
||||
if configuration.Logging.DisableConsole {
|
||||
out = f
|
||||
} else {
|
||||
out = io.MultiWriter(os.Stdout, f)
|
||||
}
|
||||
|
||||
logrus.SetOutput(out)
|
||||
}
|
||||
|
||||
if configuration.Logging.EnableTime {
|
||||
format := "02/01/2006 15:04:05"
|
||||
if configuration.Logging.TimeFormat != "" {
|
||||
format = configuration.Logging.TimeFormat
|
||||
}
|
||||
|
||||
logFormatter.TimeFormat = format
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Reference in New Issue