Compare commits

...

30 Commits
v0.5.0 ... main

Author SHA1 Message Date
DataHearth 06d09e1be6
chore(ci): use new runner image label
build / Build and test (push) Successful in 35s Details
2023-07-18 14:10:14 +02:00
DataHearth 9ab934eb4d
chore(process): update justfile
build / Build and test (push) Successful in 10m10s Details
2023-07-18 11:04:52 +02:00
DataHearth c61a8e4a4d
chore(process): force use of gitea token goreleaser
release / Build and test (push) Successful in 10m5s Details
build / Build and test (push) Successful in 10m12s Details
release / Release (push) Successful in 14m0s Details
2023-07-18 00:33:02 +02:00
DataHearth f8ef48e57a
chore(ci): update build workflow with latest go version
build / Build and test (push) Successful in 10m1s Details
release / Build and test (push) Successful in 9m46s Details
release / Release (push) Failing after 6m40s Details
2023-07-17 23:42:21 +02:00
DataHearth 4f66244e9a
chore(ci): update goreleaser and ci
build / build (push) Successful in 10m12s Details
2023-07-17 23:36:05 +02:00
DataHearth fac6dd5b69
chore(doc): remove build status README.md 2023-07-17 23:35:18 +02:00
DataHearth ef93dd8db7
chore(changelog): release v0.6.2
release / release (push) Failing after 5m44s Details
build / build (push) Successful in 6m10s Details
2023-07-15 23:25:25 +02:00
DataHearth 35c3c41ec7
chore(process): add dotenv-load instruction to justfile
build / build (push) Successful in 6m6s Details
2023-07-15 23:24:21 +02:00
Antoine Langlois d0b19e61f6 Update 'LICENSE'
build / build (push) Failing after 1m38s Details
2023-05-24 10:02:31 +02:00
DataHearth d444de44f1
chore(ci): use gitea actions instead of droneCI 2023-03-31 18:59:19 +02:00
DataHearth 8a4932aa72
chore(doc): update readme
continuous-integration/drone/push Build is passing Details
2023-03-02 18:52:07 +01:00
DataHearth a568ca9bb8
chore(logging): use charmbracelet/log instead of custom logging
continuous-integration/drone/push Build is passing Details
2023-03-02 18:35:26 +01:00
DataHearth f627f8e199
chore(ci): update secret name 2023-02-10 17:57:12 +01:00
DataHearth bcc4faae27
chore(ci): add DroneCI 2023-02-10 17:45:02 +01:00
DataHearth 7c1c71ad55
chore: update CHANGELOG v0.6.1 2022-10-04 22:47:06 +02:00
DataHearth 5682db8ac9
chore(process): add just and goreleaser 2022-10-02 21:15:10 +02:00
DataHearth 29e0be566c
chore(doc): update README.md 2022-09-12 18:47:10 +02:00
DataHearth b27c1f9e89
feat(ssh): add possibilty to use multiple SSH configurations 2022-09-12 18:40:40 +02:00
DataHearth dd6eeb3041
v0.6.0 2022-08-21 01:40:20 +02:00
DataHearth 68f263e245
chore(release): update release process using python script 2022-08-21 01:39:27 +02:00
DataHearth fe4ff05d5d
chore(release): update release process 2022-08-20 18:35:56 +02:00
DataHearth 8efdca8fe4
chore(changelog): update git repository url 2022-08-20 16:38:59 +02:00
DataHearth f85fc9d39c
fix(pkgs): update command building 2022-07-20 18:03:31 +02:00
DataHearth 8051912b35
feat(packages): add nala package manager 2022-07-20 13:33:04 +02:00
DataHearth 224754870d
fix(pkgs): add pkg manager validation check and parsing cli arguments 2022-07-20 11:35:19 +02:00
DataHearth 0f1019774d
fix(items): fix stdout when no path is available 2022-07-20 11:33:51 +02:00
DataHearth 42d2152f8e chore(template): update brew key 2022-07-17 23:17:37 +02:00
DataHearth 66f0fe3042 fix(configuration): remove installation-order default value 2022-07-17 23:15:38 +02:00
DataHearth 21c031d8fc chore(deps): update go.mod dependencies 2022-07-16 15:46:17 +02:00
DataHearth 6e5ede992a chore(release): fix release version creation 2022-07-10 12:44:53 +02:00
23 changed files with 464 additions and 268 deletions

View File

@ -2,7 +2,7 @@ style: github
template: CHANGELOG.tpl.md
info:
title: CHANGELOG
repository_url: https://github.com/DataHearth/config-mapper
repository_url: https://gitea.antoine-langlois.net/DataHearth/config-mapper
options:
commits:
filters:

View File

@ -29,8 +29,10 @@ folders:
linux: "$LOCATION/macos/.config:~/.config"
package-managers:
installation-order: ["homebrew"] # available: brew, pip (pip check also for pip3), cargo, apt, npm, go
homebrew:
# available: brew, pip (pip check also for pip3), cargo, apt, npm, go
installation-order:
- brew
brew:
- bat
- hexyl
- fd

View File

@ -0,0 +1,21 @@
name: build
run-name: Build and test
on:
push:
branches:
- "*"
jobs:
build:
name: Build and test
runs-on: debian-go
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Build
run: go build -v ./...

View File

@ -0,0 +1,45 @@
name: release
on:
push:
tags:
- "v*.*.*"
jobs:
build:
name: Build and test
runs-on: debian-go
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Build
run: go build -v ./...
release:
name: Release
needs: build
runs-on: debian-go
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Fetch tags
run: git fetch --force --tags
- name: Build
run: go build -v ./...
- name: Release
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
go install github.com/goreleaser/goreleaser@latest
go install github.com/git-chglog/git-chglog/cmd/git-chglog@latest
goreleaser release --clean --release-notes <(git-chglog -t .chglog/RELEASE_CHANGELOG.tpl.md)

7
.gitignore vendored
View File

@ -1,4 +1,5 @@
.config-mapper.yml
.env
.DS_STORE
build
.DS_Store
.env
dist/
.config-mapper.yml

47
.goreleaser.yaml Normal file
View File

@ -0,0 +1,47 @@
before:
hooks:
- go mod tidy
builds:
- env:
- CGO_ENABLED=0
goos:
- 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

View File

@ -3,8 +3,29 @@
## [Unreleased]
<a name="v0.6.2"></a>
## [v0.6.2] - 2023-07-15
<a name="v0.6.1"></a>
## [v0.6.1] - 2022-10-04
### Features
- **ssh:** add possibilty to use multiple SSH configurations
<a name="v0.6.0"></a>
## [v0.6.0] - 2022-08-21
### Bug Fixes
- **configuration:** remove installation-order default value
- **items:** fix stdout when no path is available
- **pkgs:** update command building
- **pkgs:** add pkg manager validation check and parsing cli arguments
### Features
- **packages:** add nala package manager
<a name="v0.5.0"></a>
## [v0.5.0] - 2022-07-10
## [v0.5.0] - 2022-08-01
### Bug Fixes
- **git:** use go-git for adding removed file (workaround)
@ -13,7 +34,7 @@
<a name="v0.4.0"></a>
## [v0.4.0] - 2022-06-16
## [v0.4.0] - 2022-08-01
### Bug Fixes
- **config:** don't throw error when file not available on OS
- **save:** remove folder before copy (avoid unwanted files)
@ -24,17 +45,15 @@
<a name="v0.3.0"></a>
## [v0.3.0] - 2022-06-01
## [v0.3.0] - 2022-08-01
### Features
- **cli:** packages are disabled by default
- **sync:** add .ignore file to filter folder's content
<a name="v0.2.0"></a>
## [v0.2.0] - 2022-05-23
## [v0.2.0] - 2022-08-01
### Bug Fixes
- **config:** fix config path check
- **copy:** use io.Copy instead of custom copy
- **git:** use git binary for "git add"
- **git:** deleted files are not pushed
- **git:** add error handling and repo URL from config
@ -44,24 +63,15 @@
### Code Refactoring
- **archi:** reduce base code to one struct
- **cli:** separate functions from CLI for lisibility
- **config:** unmarshal configuration instead of raw read
- **logging:** drop pterm
### Features
- **cli:** add configuration-file persistant flag
- **cli:** add git push option with message
- **cli:** add save and load features
- **cli:** add init sub-command
- **cli:** add copy folder
- **cli:** add save command
- **cli:** implement pkgs installation
- **config:** update git configuration
- **config:** add yaml tags for yaml.v3
- **index:** add indexing system
<a name="v0.1.0"></a>
## v0.1.0 - 2022-02-27
## v0.1.0 - 2022-07-31
### Bug Fixes
- **config:** fix config path check
- **copy:** use io.Copy instead of custom copy
@ -71,17 +81,20 @@
### Features
- **cli:** add save and load features
- **cli:** add init sub-command
- **cli:** add copy folder
- **cli:** add save command
- **cli:** add configuration-file persistant flag
- **cli:** implement pkgs installation
- **config:** update git configuration
- **cli:** add init sub-command
- **config:** add yaml tags for yaml.v3
- **config:** update git configuration
[Unreleased]: https://github.com/DataHearth/config-mapper/compare/v0.5.0...HEAD
[v0.5.0]: https://github.com/DataHearth/config-mapper/compare/v0.4.0...v0.5.0
[v0.4.0]: https://github.com/DataHearth/config-mapper/compare/v0.3.0...v0.4.0
[v0.3.0]: https://github.com/DataHearth/config-mapper/compare/v0.2.0...v0.3.0
[v0.2.0]: https://github.com/DataHearth/config-mapper/compare/v0.1.0...v0.2.0
[Unreleased]: https://gitea.antoine-langlois.net/DataHearth/config-mapper/compare/v0.6.2...HEAD
[v0.6.2]: https://gitea.antoine-langlois.net/DataHearth/config-mapper/compare/v0.6.1...v0.6.2
[v0.6.1]: https://gitea.antoine-langlois.net/DataHearth/config-mapper/compare/v0.6.0...v0.6.1
[v0.6.0]: https://gitea.antoine-langlois.net/DataHearth/config-mapper/compare/v0.5.0...v0.6.0
[v0.5.0]: https://gitea.antoine-langlois.net/DataHearth/config-mapper/compare/v0.4.0...v0.5.0
[v0.4.0]: https://gitea.antoine-langlois.net/DataHearth/config-mapper/compare/v0.3.0...v0.4.0
[v0.3.0]: https://gitea.antoine-langlois.net/DataHearth/config-mapper/compare/v0.2.0...v0.3.0
[v0.2.0]: https://gitea.antoine-langlois.net/DataHearth/config-mapper/compare/v0.1.0...v0.2.0

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2022 Antoine Langlois
Copyright (c) 2022 Antoine Langlois "antoine.l@antoine-langlois.net"
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,8 @@
# config-mapper
[![License](https://img.shields.io/badge/license-MIT-blue)](https://gitea.antoine-langlois.net/DataHearth/config-mapper/src/branch/main/LICENSE)
[![Version](https://img.shields.io/badge/version-v0.6.2-blue)](https://gitea.antoine-langlois.net/DataHearth/config-mapper/tags)
`config-mapper` is CLI utility tool to help you manage your configuration between UNIX systems.
It provides a set of tools to load your configuration from a system, save it into a git repository and then save it to a new system. This configuration can be a set of files, folders or even dependencies.
@ -11,32 +14,28 @@ When copying a file from your configuration repository to your system, it's perf
The system is detected automatically. You just need to specify whether the related field in case of `files` or folders `sections` (fields: `darwin` | `linux`).
You can get a configuration template [here](https://raw.githubusercontent.com/DataHearth/config-mapper/main/.config-mapper.yml.template).
You can get a configuration template [here](https://gitea.antoine-langlois.net/DataHearth/config-mapper/raw/branch/main/.config-mapper.yml.template).
### Installation
Using a pre-build binary:
- Using a pre-build binary
- `wget`
Binaries are available in the `release` section at [https://gitea.antoine-langlois.net/DataHearth/config-mapper/releases](https://gitea.antoine-langlois.net/DataHearth/config-mapper/releases).
- Building from source:
```bash
wget https://github.com/DataHearth/config-mapper/releases/download/{RELEASE}/x86-x64_{linux|darwin}_config-mapper -O $HOME/.local/bin/
```
- `gh`
```bash
gh release download -r DataHearth/config-mapper {RELEASE} -d $HOME/.local/bin/ -p "x86-x64_{linux|darwin}_config-mapper"
```
Building from source:
```bash
git clone git@github.com:datahearth/config-mapper.git
git clone https://gitea.antoine-langlois.net/DataHearth/config-mapper.git
cd config-mapper
go build -o $HOME/.local/bin/config-mapper
```
- With Golang cli
```bash
go install gitea.antoine-langlois.net/datahearth/config-mapper@latest
```
### Setup
Create a file called `.config-mapper.yml` in your `home` directory (it is the default search path for config-mapper).
@ -98,7 +97,7 @@ drwxr-xr-x - antoine 1 Jun 20:27 └── foo
`.ignore` content:
```
```text
# bar file will be ignored
foo/bar

View File

@ -1,30 +1,23 @@
package cmd
import (
"log"
"os"
"strconv"
"time"
mapper "github.com/datahearth/config-mapper/internal"
"github.com/datahearth/config-mapper/internal/configuration"
"github.com/datahearth/config-mapper/internal/git"
"github.com/fatih/color"
mapper "gitea.antoine-langlois.net/datahearth/config-mapper/internal"
"gitea.antoine-langlois.net/datahearth/config-mapper/internal/configuration"
"gitea.antoine-langlois.net/datahearth/config-mapper/internal/git"
"github.com/charmbracelet/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var (
errLogger = log.New(os.Stderr, "", 0)
logger = log.New(os.Stderr, "", 0)
)
var rootCmd = &cobra.Command{
Use: "config-mapper",
Short: "Manage your systems configuration",
Long: `config-mapper aims to help you manage your configurations between systems
with a single configuration file.`,
Version: "v0.5.0",
Version: "v0.6.2",
}
var initCmd = &cobra.Command{
Use: "init",
@ -47,6 +40,14 @@ var saveCmd = &cobra.Command{
saved location based on your configuration file`,
Run: save,
}
var installCmd = &cobra.Command{
Use: "install",
Short: "install additional tools",
Long: `install additional tools like package managers, programming languages, etc.`,
Run: func(cmd *cobra.Command, args []string) {
log.Fatal("install command not implemented yet")
},
}
func init() {
cobra.OnInitialize(configuration.InitConfig)
@ -54,6 +55,7 @@ func init() {
rootCmd.AddCommand(initCmd)
rootCmd.AddCommand(loadCmd)
rootCmd.AddCommand(saveCmd)
rootCmd.AddCommand(installCmd)
rootCmd.PersistentFlags().BoolP("verbose", "v", false, "STDOUT will be more verbose")
rootCmd.PersistentFlags().StringP("configuration-file", "c", "", "location of configuration file")
@ -69,9 +71,11 @@ func init() {
loadCmd.Flags().Bool("disable-files", false, "files will be ignored")
loadCmd.Flags().Bool("disable-folders", false, "folders will be ignored")
loadCmd.Flags().Bool("pkgs", false, "packages will be installed")
loadCmd.Flags().StringSlice("exclude-pkg-managers", []string{}, "package managers to exclude (comma separated)")
viper.BindPFlag("load-disable-files", loadCmd.Flags().Lookup("disable-files"))
viper.BindPFlag("load-disable-folders", loadCmd.Flags().Lookup("disable-folders"))
viper.BindPFlag("load-enable-pkgs", loadCmd.Flags().Lookup("pkgs"))
viper.BindPFlag("exclude-pkg-managers", loadCmd.Flags().Lookup("exclude-pkg-managers"))
saveCmd.Flags().Bool("disable-files", false, "files will be ignored")
saveCmd.Flags().Bool("disable-folders", false, "folders will be ignored")
@ -87,28 +91,24 @@ func init() {
func Execute() {
if err := rootCmd.Execute(); err != nil {
errLogger.Printf("an error occured while running command: %v\n", err)
os.Exit(1)
log.Fatal("an error occured while running command", "err", err)
}
}
func save(cmd *cobra.Command, args []string) {
var c configuration.Configuration
if err := viper.Unmarshal(&c); err != nil {
mapper.PrintError("failed to decode configuration: %v\n", err)
os.Exit(1)
log.Fatal("failed to decode configuration", "err", err)
}
indexer, err := mapper.NewIndexer(c.Storage.Path)
if err != nil {
mapper.PrintError("failed to open the indexer: %v\n", err)
os.Exit(1)
log.Fatal("failed to open the indexer", "err", err)
}
r, err := git.NewRepository(c.Storage.Git, c.Storage.Path)
if err != nil {
mapper.PrintError("failed to open repository at %s: %v\n", c.Storage.Path, err)
os.Exit(1)
log.Fatal("failed to open repository", "path", c.Storage.Path, "err", err)
}
el := mapper.NewItemsActions(nil, c.Storage.Path, r, indexer)
@ -123,39 +123,32 @@ func save(cmd *cobra.Command, args []string) {
el.Action("save")
if err := el.CleanUp(indexer.RemovedLines()); err != nil {
mapper.PrintError("failed to clean repository: %v\n", err)
os.Exit(1)
log.Fatal("failed to clean repository", "err", err)
}
if viper.GetBool("push") {
color.Blue("# Pushing items")
log.Info("pushing changes...")
if err := r.PushChanges(viper.GetString("message"), indexer.Lines(), indexer.RemovedLines()); err != nil {
mapper.PrintError("failed to push changes to repository: %v\n", err)
os.Exit(1)
log.Fatal("failed to push changes to repository", "err", err)
}
color.Green("Items pushed")
}
}
func load(cmd *cobra.Command, args []string) {
var c configuration.Configuration
if err := viper.Unmarshal(&c); err != nil {
mapper.PrintError("failed to decode configuration: %v\n", err)
os.Exit(1)
log.Fatal("failed to decode configuration", "err", err)
}
i, err := mapper.NewIndexer(c.Storage.Path)
if err != nil {
mapper.PrintError("failed to open the indexer: %v\n", err)
os.Exit(1)
log.Fatal("failed to open the indexer", "err", err)
}
r, err := git.NewRepository(c.Storage.Git, c.Storage.Path)
if err != nil {
mapper.PrintError("failed to open repository at %s: %v\n", c.Storage.Path, err)
os.Exit(1)
log.Fatal("failed to open repository", "path", c.Storage.Path, "err", err)
}
el := mapper.NewItemsActions(nil, c.Storage.Path, r, i)
@ -171,8 +164,7 @@ func load(cmd *cobra.Command, args []string) {
if viper.GetBool("load-enable-pkgs") {
if err := mapper.InstallPackages(c.PackageManagers); err != nil {
mapper.PrintError(err.Error())
os.Exit(1)
log.Fatal(err)
}
}
}
@ -180,16 +172,14 @@ func load(cmd *cobra.Command, args []string) {
func initCommand(cmd *cobra.Command, args []string) {
var c configuration.Configuration
if err := viper.Unmarshal(&c); err != nil {
mapper.PrintError("failed to decode configuration: %v\n", err)
os.Exit(1)
log.Fatal("failed to decode configuration", "err", err)
}
logger.Println("initializing config-mapper folder from configuration...")
log.Info("initializing config-mapper folder from configuration...")
if _, err := git.NewRepository(c.Storage.Git, c.Storage.Path); err != nil {
mapper.PrintError("failed to initialize folder: %v\n", err)
os.Exit(1)
log.Fatal("failed to initialize folder", "err", err)
}
logger.Printf("repository initialized at \"%v\"\n", viper.GetString("storage.location"))
log.Info("repository initialized", "path", viper.GetString("storage.location"))
}

19
go.mod
View File

@ -1,36 +1,41 @@
module github.com/datahearth/config-mapper
module gitea.antoine-langlois.net/datahearth/config-mapper
go 1.17
require (
github.com/fatih/color v1.13.0
github.com/gernest/wow v0.1.0
github.com/go-git/go-git/v5 v5.4.2
github.com/mitchellh/mapstructure v1.5.0
github.com/spf13/cobra v1.3.0
github.com/spf13/viper v1.10.1
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
github.com/charmbracelet/log v0.1.2
)
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/charmbracelet/lipgloss v0.6.0 // indirect
github.com/emirpasic/gods v1.12.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/go-logfmt/logfmt v0.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // 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/lucasb-eyer/go-colorful v1.2.0 // 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.14 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 // indirect
github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect
github.com/rivo/uniseg v0.2.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
@ -39,7 +44,7 @@ require (
github.com/subosito/gotenv v1.2.0 // indirect
github.com/xanzy/ssh-agent v0.3.0 // indirect
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect
golang.org/x/sys v0.0.0-20211210111614-af8b64212486 // indirect
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/ini.v1 v1.66.2 // indirect

39
go.sum
View File

@ -80,6 +80,10 @@ github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/charmbracelet/lipgloss v0.6.0 h1:1StyZB9vBSOyuZxQUcUwGr17JmojPNm87inij9N3wJY=
github.com/charmbracelet/lipgloss v0.6.0/go.mod h1:tHh2wr34xcHjC2HCXIlGSG1jaDF0S0atAUvBMP6Ppuk=
github.com/charmbracelet/log v0.1.2 h1:xmKMxo0T/lcftgggQOhUkS32exku2/ID55FGYbr4nKQ=
github.com/charmbracelet/log v0.1.2/go.mod h1:86XdIdmrubqtL/6u0z+jGFol1bQejBGG/qPSTwGZuQQ=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@ -118,7 +122,6 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
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=
@ -144,6 +147,8 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@ -285,6 +290,8 @@ 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/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
@ -294,15 +301,18 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
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.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
@ -313,13 +323,18 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
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/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 h1:y1p/ycavWjGT9FnmSjdbWUlLGvcxrY0Rw3ATltrxOhk=
github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ=
github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0 h1:STjmj0uFfRryL9fzRA/OupNppeAID6QJYPMavTL7jtY=
github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
@ -347,6 +362,9 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@ -376,13 +394,18 @@ github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk=
github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU=
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/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
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/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
@ -598,8 +621,9 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486 h1:5hpz5aRr+W1erYCL5JRhSUBJRph7l9XkNveoExlrKYk=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@ -841,8 +865,9 @@ 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.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@ -2,21 +2,18 @@ package configuration
import (
"fmt"
"log"
"os"
"path"
"strings"
"github.com/fatih/color"
"github.com/charmbracelet/log"
"github.com/spf13/viper"
)
var errLogger = log.New(os.Stderr, "", 0)
func InitConfig() {
h, err := os.UserHomeDir()
if err != nil {
errLogger.Fatalln(err)
log.Fatal(err)
}
if c := viper.GetString("configuration-file"); c != "" {
@ -27,7 +24,7 @@ func InitConfig() {
viper.SetConfigName(".config-mapper")
if err := loadConfigSSH(c); err != nil {
errLogger.Fatalln(err)
log.Fatal(err)
}
return
}
@ -51,16 +48,16 @@ func InitConfig() {
viper.SetConfigName(".config-mapper")
viper.SetDefault("storage.location", fmt.Sprintf("%s/config-mapper", os.TempDir()))
viper.SetDefault("package-managers.installation-order", []string{"apt", "homebrew"})
if err := viper.ReadInConfig(); err != nil {
var errMsg string
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
color.Error.Write([]byte(color.RedString("no configuration file found: %v\n", err)))
errMsg = "no configuration file found"
} else {
color.Error.Write([]byte(color.RedString("failed to read config: %v\n", err)))
errMsg = "failed to read config"
}
os.Exit(1)
log.Fatal(errMsg, "err", err)
}
viper.Set("configuration-file", viper.ConfigFileUsed())

View File

@ -22,7 +22,7 @@ type Git struct {
Name string `mapstructure:"name" yaml:"name"`
Email string `mapstructure:"email" yaml:"email"`
BasicAuth BasicAuth `mapstructure:"basic-auth" yaml:"basic-auth"`
SSH Ssh `mapstructure:"ssh" yaml:"ssh"`
SSH interface{} `mapstructure:"ssh" yaml:"ssh"`
}
type BasicAuth struct {
@ -43,4 +43,5 @@ type PkgManagers struct {
Pip []string `mapstructure:"pip" yaml:"pip"`
Npm []string `mapstructure:"npm" yaml:"npm"`
Go []string `mapstructure:"go" yaml:"go"`
Nala []string `mapstructure:"nala" yaml:"nala"`
}

View File

@ -4,12 +4,11 @@ import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
osUser "os/user"
"strings"
"github.com/fatih/color"
"github.com/charmbracelet/log"
"github.com/spf13/viper"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/knownhosts"
@ -84,7 +83,7 @@ func getSSHConfig(uriFlag string) (*ssh.ClientConfig, string, string, error) {
}
if user == "" {
color.Yellow("WARNING: no user was found in either the URI and flags. Current user will be used")
log.Warn("no user was found in either the URI and flags. Current user will be used")
var currentUser *osUser.User
currentUser, err = osUser.Current()
@ -156,7 +155,7 @@ func getUriContent(uri string) (string, string, error) {
func createPubKeyAuth(key string) (ssh.AuthMethod, error) {
var signer ssh.Signer
privateKey, err := ioutil.ReadFile(key)
privateKey, err := os.ReadFile(key)
if err != nil {
return nil, err
}

View File

@ -2,16 +2,18 @@ package git
import (
"errors"
"fmt"
"os"
"time"
"github.com/datahearth/config-mapper/internal/configuration"
"github.com/datahearth/config-mapper/internal/misc"
"gitea.antoine-langlois.net/datahearth/config-mapper/internal/configuration"
"gitea.antoine-langlois.net/datahearth/config-mapper/internal/misc"
"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/mitchellh/mapstructure"
)
var (
@ -48,25 +50,45 @@ func NewRepository(config configuration.Git, repoPath string) (RepositoryActions
return nil, err
}
if config.SSH.Passphrase != "" && config.SSH.PrivateKey != "" {
privateKey, err := misc.AbsolutePath(config.SSH.PrivateKey)
if err != nil {
switch sshConfig := config.SSH.(type) {
case map[string]interface{}:
var outConfig configuration.Ssh
if err := mapstructure.Decode(sshConfig, &outConfig); err != nil {
return nil, err
}
if _, err := os.Stat(privateKey); err != nil {
return nil, err
}
auth, err = ssh.NewPublicKeysFromFile("git", privateKey, config.SSH.Passphrase)
auth, err = getSSHAuthMethod(outConfig)
if err != nil {
return nil, err
}
} else {
auth = &http.BasicAuth{
Username: config.BasicAuth.Username,
Password: config.BasicAuth.Password,
case []interface{}:
for i, c := range sshConfig {
if _, ok := c.(map[interface{}]interface{}); !ok {
fmt.Printf("invalid format for configuration n°%d", i)
continue
}
var outConfig configuration.Ssh
if err := mapstructure.Decode(c, &outConfig); err != nil {
fmt.Printf("failed to decode ssh configuration n°%d: %v\n", i, err)
continue
}
auth, err = getSSHAuthMethod(outConfig)
if err != nil {
fmt.Printf("failed to create SSH authentication method for configuration n°%d: %v\n", i, err)
continue
}
}
if auth == nil {
auth = &http.BasicAuth{
Username: config.BasicAuth.Username,
Password: config.BasicAuth.Password,
}
}
default:
return nil, errors.New("git ssh configuration canno't be unmarshaled. Please, pass a valid configuration")
}
repo := &Repository{
@ -170,3 +192,25 @@ func (r *Repository) GetAuthor() *object.Signature {
When: time.Now(),
}
}
func getSSHAuthMethod(config configuration.Ssh) (transport.AuthMethod, error) {
if config.Passphrase == "" && config.PrivateKey == "" {
return nil, errors.New("passphrase and private are empty")
}
privateKey, err := misc.AbsolutePath(config.PrivateKey)
if err != nil {
return nil, err
}
if _, err := os.Stat(privateKey); err != nil {
return nil, err
}
auth, err := ssh.NewPublicKeysFromFile("git", privateKey, config.Passphrase)
if err != nil {
return nil, err
}
return auth, nil
}

View File

@ -6,7 +6,7 @@ import (
"os"
"strings"
"github.com/datahearth/config-mapper/internal/misc"
"gitea.antoine-langlois.net/datahearth/config-mapper/internal/misc"
)
type Index struct {

View File

@ -7,10 +7,10 @@ import (
"path"
"strings"
"github.com/datahearth/config-mapper/internal/configuration"
"github.com/datahearth/config-mapper/internal/git"
"github.com/datahearth/config-mapper/internal/misc"
"github.com/fatih/color"
"gitea.antoine-langlois.net/datahearth/config-mapper/internal/configuration"
"gitea.antoine-langlois.net/datahearth/config-mapper/internal/git"
"gitea.antoine-langlois.net/datahearth/config-mapper/internal/misc"
"github.com/charmbracelet/log"
"github.com/spf13/viper"
)
@ -46,41 +46,36 @@ func NewItemsActions(items []configuration.OSLocation, storage string, repositor
//
// If the performed action is "save", it'll also write the `.index` file with all new items.
func (e *Items) Action(action string) {
color.Blue("# %s files and folders\n", action)
log.Info("performing action", "action", action)
newLines := []string{}
for i, l := range e.locations {
var src string
storagePath, systemPath, err := misc.ConfigPaths(l, e.storage)
if err != nil {
PrintError("[%d] failed to resolve item paths \"%v\": %v", i, l, err)
log.Error("failed to resolve item paths", "item", i, "location", l, "err", err)
continue
}
if storagePath == "" && systemPath == "" {
color.Blue("[%d] file doesn't have configuration path for current OS. Skipping...")
log.Info("item is empty", "item", i, "location", l)
continue
}
if action == "save" {
src = systemPath
if newItem := e.saveItem(systemPath, storagePath, i); newItem != "" {
newLines = append(newLines, newItem)
} else {
continue
}
} else {
src = storagePath
e.loadItem(storagePath, systemPath, i)
}
color.Green("[%d] %s copied", i, src)
log.Info("item processed", "action", action, "item", i, "location", l)
}
if action == "save" && !viper.GetBool("disable-index-update") {
if err := e.indexer.Write(newLines); err != nil {
PrintError(err.Error())
os.Exit(1)
log.Fatal(err)
}
}
}
@ -94,13 +89,13 @@ func (e *Items) Action(action string) {
// (E.g: /home/user/.config => .config)
func (e *Items) saveItem(src, dst string, index int) string {
if err := os.MkdirAll(path.Dir(dst), 0755); err != nil {
PrintError("[%d] failed to create directory architecture for destination path \"%s\": %v", index, path.Dir(dst), err)
log.Error("failed to create directory architecture for destination path", "path", path.Dir(dst), "err", err)
return ""
}
s, err := os.Stat(src)
if err != nil {
PrintError("[%d] failed to check if source path is a folder \"%s\": %v", index, src, err)
log.Error("failed to check if source path is a folder", "path", src, "err", err)
return ""
}
@ -109,7 +104,7 @@ func (e *Items) saveItem(src, dst string, index int) string {
s, err := os.Stat(dst)
if err != nil {
if !os.IsNotExist(err) {
PrintError("[%d] failed to check if destination folder \"%s\" exists: %v", index, dst, err)
log.Error("failed to check if destination folder exists", "path", dst, "err", err)
return ""
}
} else {
@ -118,29 +113,29 @@ func (e *Items) saveItem(src, dst string, index int) string {
// remove the destination if it exists. It cleans up the saved location from unused files
if err := os.RemoveAll(dst); err != nil {
PrintError("[%d] failed to truncate destination folder \"%s\": %v", index, dst, err)
log.Error("failed to truncate destination folder", "path", dst, "err", err)
}
if err := os.Mkdir(dst, dstPerms); err != nil {
if !os.IsExist(err) {
PrintError("[%d] failed to create destination folder \"%s\": %v", index, dst, err)
log.Error("failed to create destination folder", "path", dst, "err", err)
return ""
}
}
if err := misc.CopyFolder(src, dst, true); err != nil {
PrintError("[%d] failed to save folder from \"%s\" to \"%s\": %v", index, src, dst, err)
log.Error("failed to save folder from source to destination", "source", src, "destination", dst, "err", err)
return ""
}
} else {
if err := misc.CopyFile(src, dst); err != nil {
PrintError("[%d] failed to save file from \"%s\" to \"%s\": %v", index, src, dst, err)
log.Error("failed to save file from source to destination", "source", src, "destination", dst, "err", err)
return ""
}
}
p, err := misc.AbsolutePath(e.storage)
if err != nil {
PrintError("[%d] failed resolve absolute path from configuration storage: %v", index, err)
log.Error("failed resolve absolute path from configuration storage", "err", err)
return ""
}
@ -153,13 +148,13 @@ func (e *Items) saveItem(src, dst string, index int) string {
// (meaning the item hasn't been saved) and prints the error in STDERR.
func (e *Items) loadItem(src, dst string, index int) {
if err := os.MkdirAll(path.Dir(dst), 0755); err != nil {
PrintError("[%d] failed to create directory architecture for destination path \"%s\": %v", index, path.Dir(dst), err)
log.Error("failed to create directory architecture for destination path", "path", path.Dir(dst), "err", err)
return
}
s, err := os.Stat(src)
if err != nil {
PrintError("[%d] failed to check if source path is a folder \"%s\": %v", index, src, err)
log.Error("failed to check if source path is a folder", "path", src, "err", err)
return
}
@ -168,7 +163,7 @@ func (e *Items) loadItem(src, dst string, index int) {
s, err := os.Stat(dst)
if err != nil {
if !os.IsNotExist(err) {
PrintError("[%d] failed to check if destination folder \"%s\" exists: %v", index, dst, err)
log.Error("failed to check if destination folder exists", "path", dst, "err", err)
return
}
} else {
@ -177,17 +172,17 @@ func (e *Items) loadItem(src, dst string, index int) {
if err := os.Mkdir(dst, dstPerms); err != nil {
if !os.IsExist(err) {
PrintError("[%d] failed to create destination folder \"%s\": %v", index, dst, err)
log.Error("failed to create destination folder", "path", dst, "err", err)
return
}
}
if err := misc.CopyFolder(src, dst, false); err != nil {
PrintError("[%d] failed to load folder from \"%s\" to \"%s\": %v", index, src, dst, err)
log.Error("failed to load folder from source to destination", "source", src, "destination", dst, "err", err)
return
}
} else {
if err := misc.CopyFile(src, dst); err != nil {
PrintError("[%d] failed to load file from \"%s\" to \"%s\": %v", index, src, dst, err)
log.Error("failed to load file from source to destination", "source", src, "destination", dst, "err", err)
return
}
}
@ -211,7 +206,3 @@ func (e *Items) CleanUp(removedLines []string) error {
return nil
}
func PrintError(err string, values ...interface{}) {
color.Error.Write([]byte(color.RedString(err+"\n", values...)))
}

View File

@ -9,7 +9,7 @@ import (
"runtime"
"strings"
"github.com/datahearth/config-mapper/internal/configuration"
"gitea.antoine-langlois.net/datahearth/config-mapper/internal/configuration"
)
func AbsolutePath(p string) (string, error) {

View File

@ -4,9 +4,11 @@ import (
"fmt"
"os"
"os/exec"
"runtime"
"strings"
"github.com/datahearth/config-mapper/internal/configuration"
"github.com/fatih/color"
"gitea.antoine-langlois.net/datahearth/config-mapper/internal/configuration"
"github.com/charmbracelet/log"
"github.com/gernest/wow"
"github.com/gernest/wow/spin"
"github.com/spf13/viper"
@ -14,9 +16,18 @@ import (
// InstallPackages install all packages from the configuration file by installation order
func InstallPackages(c configuration.PkgManagers) error {
color.Blue("\n# Installing packages")
pkgManagers := map[string]bool{}
for _, pkgManager := range viper.GetStringSlice("exclude-pkg-managers") {
pkgManagers[pkgManager] = true
}
for _, pkgManager := range c.InstallationOrder {
log.Info("installing packages", "package-manager", pkgManager)
if _, ok := pkgManagers[pkgManager]; ok {
log.Info("skipping package manager", "package-manager", pkgManager)
continue
}
var pkgs []string
switch pkgManager {
case "brew":
@ -31,53 +42,116 @@ func InstallPackages(c configuration.PkgManagers) error {
pkgs = c.Pip
case "go":
pkgs = c.Go
case "nala":
pkgs = c.Nala
default:
PrintError("package manager not supported: %s", pkgManager)
log.Error("package manager not supported", "package-manager", pkgManager)
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 {
return fmt.Errorf("%s and pip3 are not available on your system", pkgManager)
log.Error("pip and pip3 are not available on your system", "package-manager", pkgManager)
continue
}
pkgManager = "pip3"
} else {
return fmt.Errorf("%s is not available on your system", pkgManager)
log.Error("package manager not available on your system", "package-manager", pkgManager)
continue
}
}
// * for some reason, apt binary is available on darwin. Exclude it to avoid errors
if pkgManager == "apt" && runtime.GOOS == "darwin" {
log.Error("package manager not available on your system", "package-manager", pkgManager)
continue
}
if len(pkgs) == 0 {
fmt.Printf("%s: nothing to do\n", pkgManager)
return nil
fmt.Printf("✔️ nothing to do\n\n")
continue
}
cmd := exec.Command(pkgManager, "install")
cmd.Args = append(cmd.Args, pkgs...)
color.Blue("\n## Installing %s packages", pkgManager)
spinner := wow.New(os.Stdout, spin.Get(spin.Dots3), " Running...")
v := viper.GetBool("verbose")
if v {
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
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 {
spinner.Start()
commands = append(commands, buildDefaultCommand([]string{pkgManager, "install"}, pkgs, v))
}
if err := cmd.Run(); err != nil {
spinner.Stop()
PrintError("\n%s command failed: %v", pkgManager, err)
return err
}
for i, cmd := range commands {
spinner := wow.New(os.Stdout, spin.Get(spin.Dots3), " Installing...")
if !v {
spinner.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)
}
spinner.PersistWith(spin.Spinner{Frames: []string{"❌"}}, msg)
}
continue
}
if v {
// todo: find a way to clear spinner when done
spinner.Stop()
if !v {
// msg := fmt.Sprintf(" %s %s", color.GreenString("Success\t"), cmd.Args)
msg := fmt.Sprintf(" %s", cmd.Args)
if i == len(commands)-1 {
msg = fmt.Sprintf("%s\n", msg)
}
spinner.PersistWith(spin.Spinner{Frames: []string{"✔️"}}, msg)
}
}
color.Green("\n%s Packages intalled succesfully !", pkgManager)
}
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
}

17
justfile Normal file
View File

@ -0,0 +1,17 @@
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}}"
git tag -a {{version}} -m "{{version}}"
git push --follow-tags
bump-files-version version:
sd {{latest-tag}} {{version}} cmd/cli.go
sd {{latest-tag}} "version-{{version}}-blue" CHANGELOG.md

View File

@ -1,6 +1,6 @@
package main
import "github.com/datahearth/config-mapper/cmd"
import "gitea.antoine-langlois.net/datahearth/config-mapper/cmd"
func main() {
cmd.Execute()

View File

@ -1,75 +0,0 @@
#!/bin/bash
VERSION=v0.5.0
log() {
NTR=$'\033[0m' # * Neutral
INF=$'\033[0;34m' # * Blue (info)
WRN=$'\033[1;33m' # * Yellow (warning)
ERR=$'\033[1;31m' # * Red (error)
log_lvl=""
case $1 in
INFO)
log_lvl="${INF}$1"
;;
WARNING)
log_lvl="${WRN}$1"
;;
ERROR)
log_lvl="${ERR}$1"
;;
esac
log_lvl="${log_lvl}${NTR}"
msg="${log_lvl}\t$2"
echo -e "${msg}"
}
log "INFO" "checking required dependencies to create release"
if ! type git 1> /dev/null; then
log "ERROR" "\"git\" binary not available"
exit 1
fi
if ! type sd 1> /dev/null; then
log "ERROR" "\"sd\" binary not available"
exit 1
fi
if ! type gh 1> /dev/null; then
log "ERROR" "\"gh\" binary not available"
exit 1
fi
if ! type go 1> /dev/null; then
log "ERROR" "\"go\" binary not available"
exit 1
fi
if ! type git-chglog 1> /dev/null; then
log "ERROR" "\"git-chglog\" binary not available"
exit 1
fi
read -p "Enter a release version (vX.Y.Z): " release
log "INFO" "updating release version in files"
sd "Version: \"$VERSION\"" "Version: \"$release\"" cmd/cli.go
sd "VERSION=$VERSION" "VERSION=$release" release.sh
log "INFO" "updating changelog"
git-chglog --next-tag $release --output CHANGELOG.md
log "INFO" "commit & push changes"
git add .
git commit -m "$release"
git push
git tag -a $release -m $release
git push --tags
log "INFO" "building Linux binary"
GOOS=linux go build -o build/x86-x64_linux_config-mapper
log "INFO" "building Darwin binary"
GOOS=darwin go build -o build/x86-x64_darwin_config-mapper
log "INFO" "creating release"
git-chglog -t .chglog/RELEASE_CHANGELOG.tpl.md | gh release create -F - v0.4.0 build/x86-x64_*