Compare commits
30 Commits
Author | SHA1 | Date |
---|---|---|
DataHearth | 06d09e1be6 | |
DataHearth | 9ab934eb4d | |
DataHearth | c61a8e4a4d | |
DataHearth | f8ef48e57a | |
DataHearth | 4f66244e9a | |
DataHearth | fac6dd5b69 | |
DataHearth | ef93dd8db7 | |
DataHearth | 35c3c41ec7 | |
Antoine Langlois | d0b19e61f6 | |
DataHearth | d444de44f1 | |
DataHearth | 8a4932aa72 | |
DataHearth | a568ca9bb8 | |
DataHearth | f627f8e199 | |
DataHearth | bcc4faae27 | |
DataHearth | 7c1c71ad55 | |
DataHearth | 5682db8ac9 | |
DataHearth | 29e0be566c | |
DataHearth | b27c1f9e89 | |
DataHearth | dd6eeb3041 | |
DataHearth | 68f263e245 | |
DataHearth | fe4ff05d5d | |
DataHearth | 8efdca8fe4 | |
DataHearth | f85fc9d39c | |
DataHearth | 8051912b35 | |
DataHearth | 224754870d | |
DataHearth | 0f1019774d | |
DataHearth | 42d2152f8e | |
DataHearth | 66f0fe3042 | |
DataHearth | 21c031d8fc | |
DataHearth | 6e5ede992a |
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ./...
|
|
@ -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)
|
|
@ -1,4 +1,5 @@
|
|||
.config-mapper.yml
|
||||
.env
|
||||
.DS_STORE
|
||||
build
|
||||
.DS_Store
|
||||
.env
|
||||
dist/
|
||||
.config-mapper.yml
|
|
@ -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
|
59
CHANGELOG.md
59
CHANGELOG.md
|
@ -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
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -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
|
||||
|
|
33
README.md
33
README.md
|
@ -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
|
||||
|
||||
|
|
72
cmd/cli.go
72
cmd/cli.go
|
@ -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
19
go.mod
|
@ -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
39
go.sum
|
@ -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=
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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"`
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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...)))
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
128
internal/pkgs.go
128
internal/pkgs.go
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
2
main.go
2
main.go
|
@ -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()
|
||||
|
|
75
release.sh
75
release.sh
|
@ -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_*
|
Reference in New Issue