Compare commits

...

18 Commits
v0.6.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
21 changed files with 343 additions and 344 deletions

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,17 @@
## [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-20
## [v0.6.0] - 2022-08-21
### Bug Fixes
- **configuration:** remove installation-order default value
- **items:** fix stdout when no path is available
@ -72,16 +81,18 @@
### 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://gitea.antoine-langlois.net/DataHearth/config-mapper/compare/v0.6.0...HEAD
[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

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.6.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")
@ -89,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)
@ -125,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)
@ -173,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)
}
}
}
@ -182,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"))
}

18
go.mod
View File

@ -1,35 +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
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
@ -38,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
}
@ -53,13 +50,14 @@ func InitConfig() {
viper.SetDefault("storage.location", fmt.Sprintf("%s/config-mapper", os.TempDir()))
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 {

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) {
fmt.Printf("# %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("❌ 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 == "" {
fmt.Printf("⛔ Skipping %s\n", src)
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)
}
fmt.Printf("✔️ %s\n", 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("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("❌ 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("❌ 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("❌ 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("❌ 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("❌ 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("❌ 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("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("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("❌ 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("❌ 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("❌ 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("❌ 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("❌ 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

@ -7,7 +7,8 @@ import (
"runtime"
"strings"
"github.com/datahearth/config-mapper/internal/configuration"
"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"
@ -20,12 +21,10 @@ func InstallPackages(c configuration.PkgManagers) error {
pkgManagers[pkgManager] = true
}
fmt.Println()
for _, pkgManager := range c.InstallationOrder {
fmt.Printf("# Installing %s packages\n", pkgManager)
log.Info("installing packages", "package-manager", pkgManager)
if _, ok := pkgManagers[pkgManager]; ok {
fmt.Printf("⛔ Skipping %s packages\n", pkgManager)
fmt.Println()
log.Info("skipping package manager", "package-manager", pkgManager)
continue
}
@ -46,7 +45,7 @@ func InstallPackages(c configuration.PkgManagers) error {
case "nala":
pkgs = c.Nala
default:
PrintError("package manager not supported: %s\n", pkgManager)
log.Error("package manager not supported", "package-manager", pkgManager)
continue
}
@ -54,18 +53,18 @@ func InstallPackages(c configuration.PkgManagers) error {
// * pip might not be available on the system but pip3 is
if pkgManager == "pip" {
if _, err := exec.LookPath("pip3"); err != nil {
PrintError("%s and pip3 are not available on your system\n", pkgManager)
log.Error("pip and pip3 are not available on your system", "package-manager", pkgManager)
continue
}
pkgManager = "pip3"
} else {
PrintError("%s is not available on your system\n", 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" {
PrintError("%s is not available on your system\n", pkgManager)
log.Error("package manager not available on your system", "package-manager", pkgManager)
continue
}
@ -92,7 +91,7 @@ func InstallPackages(c configuration.PkgManagers) error {
}
if err := cmd.Run(); err != nil {
if v {
PrintError(err.Error())
log.Error(err)
} else {
msg := fmt.Sprintf(" %s", cmd.Args)
if i == len(commands)-1 {

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,192 +0,0 @@
import enum
import os
import sys
import re
import subprocess
from typing import Any, Dict
import requests
GITEA_API = "https://gitea.antoine-langlois.net/api/v1/repos/DataHearth/config-mapper"
NTR = "\033[0m" # * Neutral
INF = "\033[0;34m" # * Blue (info)
WRN = "\033[1;33m" # * Yellow (warning)
ERR = "\033[1;31m" # * Red (error)
version_regex = re.compile(r"Version: \"v\d*.\d*.\d*\"")
class LogLevel(enum.Enum):
INFO = "INFO"
WARNING = "WARNING"
ERROR = "ERROR"
def log(msg: str, level: LogLevel = LogLevel.INFO):
color_lvl = (
INF
if level == LogLevel.INFO
else WRN
if level == LogLevel.WARNING
else ERR
if level == LogLevel.ERROR
else INF
)
print(f"{color_lvl}{level.value}{NTR} {msg}")
if __name__ == "__main__":
release = input("Enter a release version (vX.Y.Z): ")
log("updating release version in files")
with open("cmd/cli.go") as f:
data = version_regex.sub(f'Version: "{release}"', f.read())
with open("cmd/cli.go", "w") as f:
f.write(data)
res = subprocess.run(
["git-chglog", "--next-tag", release, "--output", "CHANGELOG.md"],
stderr=subprocess.PIPE,
stdout=subprocess.DEVNULL,
)
if res.returncode != 0:
log(
f'failed to generate changelog: {res.stderr.decode("UTF-8")}',
LogLevel.ERROR,
)
sys.exit(1)
log("commit & push changes")
res = subprocess.run(
args=f"git add . && git commit -m {release}",
stderr=subprocess.PIPE,
stdout=subprocess.DEVNULL,
shell=True,
)
if res.returncode != 0:
log(
f'failed to commit changes: {res.stderr.decode("UTF-8")}',
LogLevel.ERROR,
)
sys.exit(1)
res = subprocess.run(
args=f"git tag -a {release} -m {release} && git push --follow-tags",
stderr=subprocess.PIPE,
stdout=subprocess.DEVNULL,
shell=True,
)
if res.returncode != 0:
log(
f'failed to tag and push changes: {res.stderr.decode("UTF-8")}',
LogLevel.ERROR,
)
sys.exit(1)
log("building Linux binary")
res = subprocess.run(
args=["go", "build", "-o", "build/x86-x64_linux_config-mapper"],
env=os.environ | {"GOOS": "linux"},
stderr=subprocess.PIPE,
stdout=subprocess.DEVNULL,
)
if res.returncode != 0:
log(
f'failed to build linux binary: {res.stderr.decode("UTF-8")}',
LogLevel.ERROR,
)
sys.exit(1)
log("building Darwin binary")
res = subprocess.run(
args=["go", "build", "-o", "build/x86-x64_darwin_config-mapper"],
env=os.environ | {"GOOS": "darwin"},
stderr=subprocess.PIPE,
stdout=subprocess.DEVNULL,
)
if res.returncode != 0:
log(
f'failed to build darwin binary: {res.stderr.decode("UTF-8")}',
LogLevel.ERROR,
)
sys.exit(1)
log("creating gitea release")
api_token: str
if len(sys.argv) > 1:
api_token = sys.argv.pop()
elif os.getenv("GIT_CFG_MAPPER_TOKEN"):
api_token = os.getenv("GIT_CFG_MAPPER_TOKEN")
else:
log("no gitea api token found in CLI params nor in ENV", LogLevel.ERROR)
sys.exit(1)
res = subprocess.run(
args=["git-chglog", "-t", ".chglog/RELEASE_CHANGELOG.tpl.md"],
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
)
if res.returncode != 0:
log(
f'failed to generate release body: {res.stderr.decode("UTF-8")}',
LogLevel.ERROR,
)
sys.exit(1)
response = requests.post(
url=f"{GITEA_API}/releases",
headers={"Authorization": f"token {api_token}"},
json={
"body": res.stdout.decode("UTF-8"),
"draft": False,
"prerelease": False,
"name": release,
"tag_name": release,
},
)
if not response.ok:
log(
f"failed to generate release (status {response.status_code}): {response.json()}",
LogLevel.ERROR,
)
sys.exit(1)
body: Dict[str, Any] = response.json()
release_id = body.get("id")
if not release_id:
log("no release id found in response body", LogLevel.ERROR)
sys.exit(1)
response = requests.post(
url=f"{GITEA_API}/releases/{release_id}/assets",
headers={"Authorization": f"token {api_token}"},
files={
"attachment": (
"x86-x64_linux_config-mapper",
open("build/x86-x64_linux_config-mapper", "rb"),
)
},
)
if not response.ok:
log(
f"failed to upload linux binary (status: {response.status_code}): {response.json()}",
LogLevel.ERROR,
)
sys.exit(1)
response = requests.post(
url=f"{GITEA_API}/releases/{release_id}/assets",
headers={"Authorization": f"token {api_token}"},
files={
"attachment": (
"x86-x64_darwin_config-mapper",
open("build/x86-x64_darwin_config-mapper", "rb"),
)
},
)
if not response.ok:
log(
f"failed to upload darwin binary (status: {response.status_code}): {response.json()}",
LogLevel.ERROR,
)
sys.exit(1)
log("Done !")