mirror of
https://github.com/foomo/posh.git
synced 2025-10-16 12:45:38 +00:00
feat: add init command
This commit is contained in:
parent
8ae6b7ba33
commit
14b23c1edf
@ -1,7 +1,8 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/foomo/posh/internal/util"
|
||||
intconfig "github.com/foomo/posh/internal/config"
|
||||
intplugin "github.com/foomo/posh/internal/plugin"
|
||||
"github.com/foomo/posh/pkg/config"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
@ -11,15 +12,21 @@ import (
|
||||
var dependenciesCmd = &cobra.Command{
|
||||
Use: "dependencies",
|
||||
Short: "Run dependency validations",
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
SilenceErrors: true,
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := intconfig.Load(l, flagConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
var cfg config.Dependencies
|
||||
if err := viper.UnmarshalKey("dependencies", &cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
plg, err := util.LoadPlugin(cmd.Context(), m)
|
||||
plg, err := intplugin.Load(cmd.Context(), l)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -1,22 +1,31 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/foomo/posh/internal/util"
|
||||
intconfig "github.com/foomo/posh/internal/config"
|
||||
intplugin "github.com/foomo/posh/internal/plugin"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// execCmd represents the exec command
|
||||
var execCmd = &cobra.Command{
|
||||
Use: "execute",
|
||||
Short: "Execute a single Project Oriented Shell command",
|
||||
Args: cobra.ArbitraryArgs,
|
||||
Use: "execute",
|
||||
Short: "Execute a single Project Oriented Shell command",
|
||||
Args: cobra.ArbitraryArgs,
|
||||
SilenceUsage: true,
|
||||
SilenceErrors: true,
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := intconfig.Load(l, flagConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if len(args) == 0 {
|
||||
return errors.New("missing [cmd] argument")
|
||||
}
|
||||
|
||||
plg, err := util.LoadPlugin(cmd.Context(), m)
|
||||
plg, err := intplugin.Load(cmd.Context(), l)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
31
cmd/init.go
31
cmd/init.go
@ -2,16 +2,22 @@ package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"path"
|
||||
|
||||
"github.com/foomo/posh/embed"
|
||||
"github.com/foomo/posh/internal/util"
|
||||
"github.com/foomo/posh/pkg/env"
|
||||
"github.com/foomo/posh/pkg/scaffold"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
initCmdFlagDry bool
|
||||
)
|
||||
|
||||
// initCmd represents the init command
|
||||
var initCmd = &cobra.Command{
|
||||
Use: "init [path]",
|
||||
Use: "init",
|
||||
Short: "Initialize a Project Oriented Shell",
|
||||
Long: `Initialize (posh init) will create a new Project Oriented Shell with the appropriate structure.
|
||||
|
||||
@ -19,13 +25,13 @@ Posh init must be run inside of a go module (please run "go mod init <MODNAME> f
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data := map[string]interface{}{}
|
||||
|
||||
if len(args) > 0 && args[0] != "." {
|
||||
wd = filepath.Join(wd, args[0])
|
||||
// define module
|
||||
if gitRemoteURL, err := util.GitRemoteURL(); err == nil {
|
||||
data["module"] = gitRemoteURL
|
||||
} else {
|
||||
data["module"] = path.Base(os.Getenv(env.ProjectRoot))
|
||||
}
|
||||
|
||||
fs, err := embed.Scaffold("init")
|
||||
@ -35,15 +41,22 @@ Posh init must be run inside of a go module (please run "go mod init <MODNAME> f
|
||||
|
||||
sc, err := scaffold.New(
|
||||
scaffold.WithLogger(l),
|
||||
scaffold.WithDry(initCmdFlagDry),
|
||||
scaffold.WithDirectories(scaffold.Directory{
|
||||
Source: fs,
|
||||
Target: os.Getenv(env.ProjectRoot),
|
||||
Data: data,
|
||||
}),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sc.Render(fs, wd, nil)
|
||||
return sc.Render(cmd.Context())
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(initCmd)
|
||||
initCmd.Flags().BoolVar(&initCmdFlagDry, "dry", false, "don't render files")
|
||||
}
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/foomo/posh/internal/util"
|
||||
intconfig "github.com/foomo/posh/internal/config"
|
||||
intplugin "github.com/foomo/posh/internal/plugin"
|
||||
"github.com/foomo/posh/pkg/config"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
@ -11,15 +12,21 @@ import (
|
||||
var packagesCmd = &cobra.Command{
|
||||
Use: "packages",
|
||||
Short: "Check and install required packages.",
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
SilenceErrors: true,
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := intconfig.Load(l, flagConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
var cfg []config.Package
|
||||
if err := viper.UnmarshalKey("packages", &cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
plg, err := util.LoadPlugin(cmd.Context(), m)
|
||||
plg, err := intplugin.Load(cmd.Context(), l)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/foomo/posh/internal/util"
|
||||
intconfig "github.com/foomo/posh/internal/config"
|
||||
intplugin "github.com/foomo/posh/internal/plugin"
|
||||
"github.com/foomo/posh/pkg/config"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
@ -11,15 +12,21 @@ import (
|
||||
var promptCmd = &cobra.Command{
|
||||
Use: "prompt",
|
||||
Short: "Start the interactive Project Oriented Shell",
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
SilenceErrors: true,
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := intconfig.Load(l, flagConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
var cfg config.Prompt
|
||||
if err := viper.UnmarshalKey("prompt", &cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
plg, err := util.LoadPlugin(cmd.Context(), m)
|
||||
plg, err := intplugin.Load(cmd.Context(), l)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
75
cmd/root.go
75
cmd/root.go
@ -2,25 +2,18 @@ package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
|
||||
"github.com/foomo/posh/internal/env"
|
||||
log2 "github.com/foomo/posh/internal/log"
|
||||
"github.com/foomo/posh/pkg/log"
|
||||
"github.com/foomo/posh/pkg/plugin"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
EnvProjectRoot = "PROJECT_ROOT"
|
||||
)
|
||||
|
||||
var (
|
||||
l log.Logger
|
||||
m *plugin.Manager
|
||||
flagLevel string
|
||||
flagConfig string
|
||||
flagNoColor bool
|
||||
@ -65,69 +58,19 @@ func Execute() {
|
||||
|
||||
func init() {
|
||||
cobra.OnInitialize(initialize)
|
||||
|
||||
// Here you will define your flags and configuration settings.
|
||||
// Cobra supports persistent flags, which, if defined here,
|
||||
// will be global for your application.
|
||||
|
||||
rootCmd.PersistentFlags().BoolVar(&flagNoColor, "no-color", false, "disabled colors (default is false)")
|
||||
rootCmd.PersistentFlags().StringVar(&flagLevel, "level", "info", "set log level (default is warn)")
|
||||
rootCmd.PersistentFlags().StringVar(&flagConfig, "config", "", "config file (default is $HOME/.posh.yaml)")
|
||||
|
||||
// Cobra also supports local flags, which will only run
|
||||
// when this action is called directly.
|
||||
rootCmd.Flags().Bool("no-validate", false, "Skip validation")
|
||||
}
|
||||
|
||||
// initialize reads in config file and ENV variables if set.
|
||||
func initialize() {
|
||||
// setup logger
|
||||
if value, err := log.NewPTerm(
|
||||
log.PTermWithDisableColor(flagNoColor),
|
||||
log.PTermWithLevel(log.GetLevel(flagLevel)),
|
||||
); err != nil {
|
||||
cobra.CheckErr(err)
|
||||
} else {
|
||||
l = value
|
||||
}
|
||||
|
||||
// setup viper
|
||||
if flagConfig != "" {
|
||||
// Use config file from the flag.
|
||||
viper.SetConfigFile(flagConfig)
|
||||
} else {
|
||||
wd, err := os.Getwd()
|
||||
l.Must(err)
|
||||
viper.AddConfigPath(wd)
|
||||
viper.SetConfigType("yaml")
|
||||
viper.SetConfigName(".posh")
|
||||
}
|
||||
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||
viper.AutomaticEnv()
|
||||
|
||||
l.Must(viper.ReadInConfig())
|
||||
l.Debug("using config file:", viper.ConfigFileUsed())
|
||||
|
||||
// validate version
|
||||
if v := viper.GetString("version"); v != "v1.0" {
|
||||
l.Must(fmt.Errorf("invalid config version: %s (v1.0)", v))
|
||||
}
|
||||
|
||||
// setup env
|
||||
if value := os.Getenv(EnvProjectRoot); value != "" {
|
||||
// continue
|
||||
} else if value, err := os.Getwd(); err != nil {
|
||||
l.Must(errors.Wrap(err, "failed to retrieve project root"))
|
||||
} else if err := os.Setenv(EnvProjectRoot, value); err != nil {
|
||||
l.Must(errors.Wrap(err, "failed to set project root env"))
|
||||
}
|
||||
for key, value := range viper.GetStringMapString("env") {
|
||||
l.Must(os.Setenv(key, os.ExpandEnv(value)))
|
||||
}
|
||||
|
||||
// setup manager
|
||||
var err error
|
||||
m, err = plugin.NewManager(l)
|
||||
l.Must(err)
|
||||
|
||||
// init logger
|
||||
l, err = log2.Init(flagLevel, flagNoColor)
|
||||
cobra.CheckErr(err)
|
||||
|
||||
// init env
|
||||
l.Must(env.Init())
|
||||
}
|
||||
|
||||
3
embed/scaffold/init/$.posh/go.mod.gotext
Normal file
3
embed/scaffold/init/$.posh/go.mod.gotext
Normal file
@ -0,0 +1,3 @@
|
||||
module {{ .module }}/posh
|
||||
|
||||
go 1.19
|
||||
52
embed/scaffold/init/Makefile
Normal file
52
embed/scaffold/init/Makefile
Normal file
@ -0,0 +1,52 @@
|
||||
.DEFAULT_GOAL:=help
|
||||
|
||||
## === Tasks ===
|
||||
|
||||
.PHONY: dependencies
|
||||
## Validate dependencies
|
||||
dependencies:
|
||||
@posh dependencies
|
||||
|
||||
.PHONY: shell
|
||||
## Install project specific packages
|
||||
packages:
|
||||
@posh packages
|
||||
|
||||
.PHONY: shell
|
||||
## Start the interactive
|
||||
shell: dependencies packages
|
||||
@posh prompt
|
||||
|
||||
## === Utils ===
|
||||
|
||||
## Show help text
|
||||
help:
|
||||
@awk '{ \
|
||||
if ($$0 ~ /^.PHONY: [a-zA-Z\-\_0-9]+$$/) { \
|
||||
helpCommand = substr($$0, index($$0, ":") + 2); \
|
||||
if (helpMessage) { \
|
||||
printf "\033[36m%-23s\033[0m %s\n", \
|
||||
helpCommand, helpMessage; \
|
||||
helpMessage = ""; \
|
||||
} \
|
||||
} else if ($$0 ~ /^[a-zA-Z\-\_0-9.]+:/) { \
|
||||
helpCommand = substr($$0, 0, index($$0, ":")); \
|
||||
if (helpMessage) { \
|
||||
printf "\033[36m%-23s\033[0m %s\n", \
|
||||
helpCommand, helpMessage"\n"; \
|
||||
helpMessage = ""; \
|
||||
} \
|
||||
} else if ($$0 ~ /^##/) { \
|
||||
if (helpMessage) { \
|
||||
helpMessage = helpMessage"\n "substr($$0, 3); \
|
||||
} else { \
|
||||
helpMessage = substr($$0, 3); \
|
||||
} \
|
||||
} else { \
|
||||
if (helpMessage) { \
|
||||
print "\n "helpMessage"\n" \
|
||||
} \
|
||||
helpMessage = ""; \
|
||||
} \
|
||||
}' \
|
||||
$(MAKEFILE_LIST)
|
||||
@ -2,9 +2,19 @@
|
||||
|
||||
## === Tasks ===
|
||||
|
||||
.PHONY: posh
|
||||
posh:
|
||||
.PHONY: dependencies
|
||||
## Validate dependencies
|
||||
dependencies:
|
||||
@posh dependencies
|
||||
|
||||
.PHONY: shell
|
||||
## Install project specific packages
|
||||
packages:
|
||||
@posh packages
|
||||
|
||||
.PHONY: shell
|
||||
## Start the interactive
|
||||
shell: dependencies packages
|
||||
@posh prompt
|
||||
|
||||
## === Utils ===
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("hello")
|
||||
}
|
||||
19
go.mod
19
go.mod
@ -8,20 +8,29 @@ require (
|
||||
github.com/Masterminds/sprig/v3 v3.2.3
|
||||
github.com/c-bata/go-prompt v0.2.6
|
||||
github.com/foomo/fender v0.4.4
|
||||
github.com/go-git/go-git/v5 v5.5.1
|
||||
github.com/gofrs/flock v0.8.1
|
||||
github.com/joho/godotenv v1.4.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pterm/pterm v0.12.51
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/spf13/viper v1.14.0
|
||||
github.com/whilp/git-urls v1.0.0
|
||||
)
|
||||
|
||||
require (
|
||||
atomicgo.dev/cursor v0.1.1 // indirect
|
||||
atomicgo.dev/keyboard v0.2.8 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 // indirect
|
||||
github.com/acomagu/bufpipe v1.0.3 // indirect
|
||||
github.com/cloudflare/circl v1.1.0 // indirect
|
||||
github.com/containerd/console v1.0.3 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/go-git/gcfg v1.5.0 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.3.1 // indirect
|
||||
github.com/go-playground/locales v0.14.0 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.11.0 // indirect
|
||||
@ -29,8 +38,10 @@ require (
|
||||
github.com/gookit/color v1.5.2 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/huandu/xstrings v1.3.3 // indirect
|
||||
github.com/imdario/mergo v0.3.11 // indirect
|
||||
github.com/imdario/mergo v0.3.13 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/lithammer/fuzzysearch v1.1.5 // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
@ -44,9 +55,12 @@ require (
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
||||
github.com/pjbgf/sha1cd v0.2.3 // indirect
|
||||
github.com/pkg/term v1.1.0 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/sergi/go-diff v1.2.0 // indirect
|
||||
github.com/shopspring/decimal v1.2.0 // indirect
|
||||
github.com/skeema/knownhosts v1.1.0 // indirect
|
||||
github.com/spf13/afero v1.9.2 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
@ -54,13 +68,16 @@ require (
|
||||
github.com/subosito/gotenv v1.4.1 // indirect
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
golang.org/x/crypto v0.3.0 // indirect
|
||||
golang.org/x/net v0.2.0 // indirect
|
||||
golang.org/x/sys v0.2.0 // indirect
|
||||
golang.org/x/term v0.2.0 // indirect
|
||||
golang.org/x/text v0.4.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
61
go.sum
61
go.sum
@ -61,13 +61,26 @@ github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7Y
|
||||
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
|
||||
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
|
||||
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 h1:ra2OtmuW0AE5csawV4YXMNGNQQXvLRps3z2Z59OPO+I=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
|
||||
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
|
||||
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
|
||||
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk=
|
||||
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
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=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/circl v1.1.0 h1:bZgT/A+cikZnKIwn7xL2OBj012Bmvho/o6RpRvv3GKY=
|
||||
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
@ -78,6 +91,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
@ -92,6 +107,16 @@ github.com/franklinkim/go-prompt v0.2.7-0.20210427061716-a8f4995d7aa5 h1:kXNtle4
|
||||
github.com/franklinkim/go-prompt v0.2.7-0.20210427061716-a8f4995d7aa5/go.mod h1:+syUfnvYJUO5A+6QMQYXAyzkxHMNlj9dH2LIeQfBSjc=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
|
||||
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
|
||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||
github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34=
|
||||
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.1 h1:y5z6dd3qi8Hl+stezc8p3JxDkoTRqMAlKnXHuzrfjTQ=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo=
|
||||
github.com/go-git/go-git/v5 v5.5.1 h1:5vtv2TB5PM/gPM+EvsHJ16hJh4uAkdGcKilcwY7FYwo=
|
||||
github.com/go-git/go-git/v5 v5.5.1/go.mod h1:uz5PQ3d0gz7mSgzZhSJToM6ALPaKCdSnl58/Xb5hzr8=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
@ -143,6 +168,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
@ -176,15 +202,21 @@ github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4
|
||||
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
|
||||
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
|
||||
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
|
||||
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
|
||||
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
|
||||
@ -205,6 +237,8 @@ github.com/lithammer/fuzzysearch v1.1.5 h1:Ag7aKU08wp0R9QCfF4GoGST9HbmAIeLP7xwMr
|
||||
github.com/lithammer/fuzzysearch v1.1.5/go.mod h1:1R1LRNk7yKid1BaQkmuLQaHruxcC4HmAH30Dh61Ih1Q=
|
||||
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
|
||||
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
|
||||
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||
@ -234,6 +268,8 @@ github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3v
|
||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
|
||||
github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
|
||||
github.com/pjbgf/sha1cd v0.2.3 h1:uKQP/7QOzNtKYH7UTohZLcjF5/55EnTw0jO/Ru4jZwI=
|
||||
github.com/pjbgf/sha1cd v0.2.3/go.mod h1:HOK9QrgzdHpbc2Kzip0Q1yi3M2MFGPADtR6HjG65m5M=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@ -259,10 +295,14 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
|
||||
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0=
|
||||
github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag=
|
||||
github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw=
|
||||
github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
@ -294,6 +334,10 @@ github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaO
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/whilp/git-urls v1.0.0 h1:95f6UMWN5FKW71ECsXRUd3FVYiXdrE7aX4NZKcPmIjU=
|
||||
github.com/whilp/git-urls v1.0.0/go.mod h1:J16SAmobsqc3Qcy98brfl5f5+e0clUvg1krgwk/qCfE=
|
||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@ -318,6 +362,9 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@ -391,6 +438,8 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@ -424,6 +473,7 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -451,6 +501,7 @@ golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -458,10 +509,14 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -469,6 +524,7 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -639,6 +695,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
@ -646,6 +704,7 @@ 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/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0/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=
|
||||
|
||||
@ -65,7 +65,7 @@ func New(l log.Logger, cache cache.Cache, opts ...Option) (*OnePassword, error)
|
||||
}
|
||||
}
|
||||
if client, err := connect.NewClientFromEnvironment(); err != nil {
|
||||
l.Debug("not able to create connect client", err.Error())
|
||||
l.Debug("connect client:", err.Error())
|
||||
} else {
|
||||
inst.connect = client
|
||||
}
|
||||
|
||||
@ -1,55 +0,0 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type (
|
||||
Mod struct {
|
||||
Path, Dir, GoMod string
|
||||
}
|
||||
CurDir struct {
|
||||
Dir string
|
||||
}
|
||||
)
|
||||
|
||||
func GetModImportPath() string {
|
||||
mod, cd := parseModInfo()
|
||||
return path.Join(mod.Path, fileToURL(strings.TrimPrefix(cd.Dir, mod.Dir)))
|
||||
}
|
||||
|
||||
func parseModInfo() (Mod, CurDir) {
|
||||
var mod Mod
|
||||
var dir CurDir
|
||||
|
||||
m := modInfoJSON("-m")
|
||||
cobra.CheckErr(json.Unmarshal(m, &mod))
|
||||
|
||||
// Unsure why, but if no module is present Path is set to this string.
|
||||
if mod.Path == "command-line-arguments" {
|
||||
cobra.CheckErr("Please run `go mod init <MODNAME>` before `cobra-cli init`")
|
||||
}
|
||||
|
||||
e := modInfoJSON("-e")
|
||||
cobra.CheckErr(json.Unmarshal(e, &dir))
|
||||
|
||||
return mod, dir
|
||||
}
|
||||
|
||||
func fileToURL(in string) string {
|
||||
i := strings.Split(in, string(filepath.Separator))
|
||||
return path.Join(i...)
|
||||
}
|
||||
|
||||
func modInfoJSON(args ...string) []byte {
|
||||
cmdArgs := append([]string{"list", "-json"}, args...)
|
||||
out, err := exec.Command("go", cmdArgs...).Output()
|
||||
cobra.CheckErr(err)
|
||||
return out
|
||||
}
|
||||
44
internal/config/load.go
Normal file
44
internal/config/load.go
Normal file
@ -0,0 +1,44 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/foomo/posh/pkg/log"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func Load(l log.Logger, configFile string) error {
|
||||
// setup viper
|
||||
if configFile != "" {
|
||||
viper.SetConfigFile(configFile)
|
||||
} else {
|
||||
viper.AddConfigPath(".")
|
||||
viper.SetConfigType("yaml")
|
||||
viper.SetConfigName(".posh")
|
||||
}
|
||||
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||
viper.AutomaticEnv()
|
||||
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
l.Debug("using config file:", viper.ConfigFileUsed())
|
||||
}
|
||||
|
||||
// validate version
|
||||
if v := viper.GetString("version"); v != Version {
|
||||
return fmt.Errorf("invalid config version: %s (%s)", v, Version)
|
||||
}
|
||||
|
||||
// set configured env
|
||||
for key, value := range viper.GetStringMapString("env") {
|
||||
if err := os.Setenv(key, os.ExpandEnv(value)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
3
internal/config/version.go
Normal file
3
internal/config/version.go
Normal file
@ -0,0 +1,3 @@
|
||||
package config
|
||||
|
||||
const Version = "v1.0"
|
||||
20
internal/env/init.go
vendored
Normal file
20
internal/env/init.go
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
package env
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/foomo/posh/pkg/env"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func Init() error {
|
||||
// setup env
|
||||
if value := os.Getenv(env.ProjectRoot); value != "" {
|
||||
// continue
|
||||
} else if wd, err := os.Getwd(); err != nil {
|
||||
return errors.Wrap(err, "failed to retrieve project root")
|
||||
} else if err := os.Setenv(env.ProjectRoot, wd); err != nil {
|
||||
return errors.Wrap(err, "failed to set project root env")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
16
internal/log/init.go
Normal file
16
internal/log/init.go
Normal file
@ -0,0 +1,16 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"github.com/foomo/posh/pkg/log"
|
||||
)
|
||||
|
||||
func Init(level string, noColor bool) (log.Logger, error) {
|
||||
if value, err := log.NewPTerm(
|
||||
log.PTermWithDisableColor(noColor),
|
||||
log.PTermWithLevel(log.GetLevel(level)),
|
||||
); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return value, nil
|
||||
}
|
||||
}
|
||||
23
internal/plugin/load.go
Normal file
23
internal/plugin/load.go
Normal file
@ -0,0 +1,23 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/foomo/posh/pkg/config"
|
||||
"github.com/foomo/posh/pkg/log"
|
||||
"github.com/foomo/posh/pkg/plugin"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func Load(ctx context.Context, l log.Logger) (plugin.Plugin, error) {
|
||||
m, err := manager(l)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var cfg config.Plugin
|
||||
if err := viper.UnmarshalKey("plugin", &cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m.BuildAndLoadPlugin(ctx, cfg.Source, cfg.Provider)
|
||||
}
|
||||
19
internal/plugin/manager.go
Normal file
19
internal/plugin/manager.go
Normal file
@ -0,0 +1,19 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"github.com/foomo/posh/pkg/log"
|
||||
"github.com/foomo/posh/pkg/plugin"
|
||||
)
|
||||
|
||||
var m *plugin.Manager
|
||||
|
||||
func manager(l log.Logger) (*plugin.Manager, error) {
|
||||
if m == nil {
|
||||
if value, err := plugin.NewManager(l); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
m = value
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
@ -1,17 +1,26 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/foomo/posh/pkg/config"
|
||||
"github.com/foomo/posh/pkg/plugin"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/go-git/go-git/v5"
|
||||
giturls "github.com/whilp/git-urls"
|
||||
)
|
||||
|
||||
func LoadPlugin(ctx context.Context, m *plugin.Manager) (plugin.Plugin, error) {
|
||||
var cfg config.Plugin
|
||||
if err := viper.UnmarshalKey("plugin", &cfg); err != nil {
|
||||
return nil, err
|
||||
func GitRemoteURL() (string, error) {
|
||||
r, err := git.PlainOpen(".")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if value, err := r.Remote("origin"); err != nil {
|
||||
return "", err
|
||||
} else if len(value.Config().URLs) == 0 {
|
||||
return "", nil
|
||||
} else if value, err := giturls.Parse(value.Config().URLs[0]); err != nil {
|
||||
return "", err
|
||||
} else {
|
||||
return value.Hostname() + "/" + strings.TrimSuffix(value.Path, path.Ext(value.Path)), nil
|
||||
}
|
||||
return m.BuildAndLoadPlugin(ctx, cfg.Source, cfg.Provider)
|
||||
}
|
||||
|
||||
3
pkg/env/env.go
vendored
Normal file
3
pkg/env/env.go
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
package env
|
||||
|
||||
const ProjectRoot = "PROJECT_ROOT"
|
||||
@ -9,21 +9,10 @@ import (
|
||||
"plugin"
|
||||
"strings"
|
||||
|
||||
"github.com/foomo/posh/pkg/config"
|
||||
"github.com/foomo/posh/pkg/log"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type (
|
||||
Plugin interface {
|
||||
Prompt(ctx context.Context, cfg config.Prompt) error
|
||||
Execute(ctx context.Context, args []string) error
|
||||
Packages(ctx context.Context, cfg []config.Package) error
|
||||
Dependencies(ctx context.Context, cfg config.Dependencies) error
|
||||
}
|
||||
Provider func(l log.Logger) (Plugin, error)
|
||||
)
|
||||
|
||||
type Manager struct {
|
||||
l log.Logger
|
||||
plugins map[string]*plugin.Plugin
|
||||
@ -46,23 +35,34 @@ func NewManager(l log.Logger) (*Manager, error) {
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
func (m *Manager) BuildAndLoadPlugin(ctx context.Context, filename, provider string) (Plugin, error) {
|
||||
if err := m.Tidy(ctx, filename); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := m.Build(ctx, filename); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m.LoadPlugin(filename, provider)
|
||||
}
|
||||
|
||||
func (m *Manager) Tidy(ctx context.Context, filename string) error {
|
||||
m.l.Debug("tidying:", filename)
|
||||
cmd := exec.CommandContext(ctx, "go", "mod", "tidy")
|
||||
cmd.Dir = filepath.Dir(filename)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return errors.Wrap(err, string(output))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) Build(ctx context.Context, filename string) error {
|
||||
m.l.Debug("building:", filename)
|
||||
|
||||
dir := filepath.Dir(filename)
|
||||
base := path.Base(filename)
|
||||
cmd := exec.CommandContext(ctx, "go", "build",
|
||||
"-buildmode=plugin",
|
||||
"-o", strings.ReplaceAll(base, ".go", ".so"),
|
||||
base,
|
||||
)
|
||||
cmd.Dir = dir
|
||||
cmd.Dir = filepath.Dir(filename)
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return errors.Wrap(err, string(output))
|
||||
}
|
||||
|
||||
14
pkg/plugin/plugin.go
Normal file
14
pkg/plugin/plugin.go
Normal file
@ -0,0 +1,14 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/foomo/posh/pkg/config"
|
||||
)
|
||||
|
||||
type Plugin interface {
|
||||
Prompt(ctx context.Context, cfg config.Prompt) error
|
||||
Execute(ctx context.Context, args []string) error
|
||||
Packages(ctx context.Context, cfg []config.Package) error
|
||||
Dependencies(ctx context.Context, cfg config.Dependencies) error
|
||||
}
|
||||
7
pkg/plugin/provider.go
Normal file
7
pkg/plugin/provider.go
Normal file
@ -0,0 +1,7 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"github.com/foomo/posh/pkg/log"
|
||||
)
|
||||
|
||||
type Provider func(l log.Logger) (Plugin, error)
|
||||
11
pkg/scaffold/directory.go
Normal file
11
pkg/scaffold/directory.go
Normal file
@ -0,0 +1,11 @@
|
||||
package scaffold
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
)
|
||||
|
||||
type Directory struct {
|
||||
Source fs.FS
|
||||
Target string
|
||||
Data any
|
||||
}
|
||||
@ -1,11 +1,10 @@
|
||||
package scaffold
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
@ -16,9 +15,10 @@ import (
|
||||
|
||||
type (
|
||||
Scaffold struct {
|
||||
l log.Logger
|
||||
dry bool
|
||||
force bool
|
||||
l log.Logger
|
||||
dry bool
|
||||
override bool
|
||||
directories []Directory
|
||||
}
|
||||
Option func(*Scaffold) error
|
||||
)
|
||||
@ -34,9 +34,9 @@ func WithDry(v bool) Option {
|
||||
}
|
||||
}
|
||||
|
||||
func WithForce(v bool) Option {
|
||||
func WithOverride(v bool) Option {
|
||||
return func(o *Scaffold) error {
|
||||
o.force = v
|
||||
o.override = v
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -48,15 +48,22 @@ func WithLogger(v log.Logger) Option {
|
||||
}
|
||||
}
|
||||
|
||||
func WithDirectories(v ...Directory) Option {
|
||||
return func(o *Scaffold) error {
|
||||
o.directories = append(o.directories, v...)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ~ Constructor
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
func New(opts ...Option) (*Scaffold, error) {
|
||||
inst := &Scaffold{
|
||||
l: log.NewFmt(),
|
||||
dry: false,
|
||||
force: false,
|
||||
l: log.NewFmt(),
|
||||
dry: false,
|
||||
override: false,
|
||||
}
|
||||
for _, opt := range opts {
|
||||
if opt != nil {
|
||||
@ -68,72 +75,117 @@ func New(opts ...Option) (*Scaffold, error) {
|
||||
return inst, nil
|
||||
}
|
||||
|
||||
func (s *Scaffold) Render(source fs.FS, target string, vars any) error {
|
||||
// validate target
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ~ Public methods
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
func (s *Scaffold) Render(ctx context.Context) error {
|
||||
if err := s.renderDirectories(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ~ Private methods
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
func (s *Scaffold) scaffoldDir(target string) error {
|
||||
s.l.Info("mkdir:", s.filename(target))
|
||||
if stat, err := os.Stat(target); errors.Is(err, os.ErrNotExist) {
|
||||
s.l.Print("scaffold:", target)
|
||||
if err := os.MkdirAll(target, os.ModePerm); err != nil {
|
||||
return errors.Wrapf(err, "failed to create target folder (%s)", target)
|
||||
return err
|
||||
}
|
||||
} else if err != nil {
|
||||
return errors.Wrapf(err, "failed to stat target folder (%s)", target)
|
||||
} else if !stat.IsDir() {
|
||||
return fmt.Errorf("target not a directory (%s)", target)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// iterate source
|
||||
if err := fs.WalkDir(source, ".", func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to walk fs dir")
|
||||
func (s *Scaffold) scaffoldTemplate(target string, tpl *template.Template, data any) error {
|
||||
s.l.Info("file:", s.filename(target))
|
||||
file, err := os.Create(target)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to create target file (%s)", target)
|
||||
}
|
||||
defer func() {
|
||||
if err := file.Close(); err != nil {
|
||||
s.l.Warnf("failed to close file: %s", err.Error())
|
||||
}
|
||||
}()
|
||||
return tpl.Execute(file, data)
|
||||
}
|
||||
|
||||
filename := filepath.Join(target, strings.ReplaceAll(path, "$", ""))
|
||||
func (s *Scaffold) printTemplate(msg, target string, tpl *template.Template, data any) error {
|
||||
border := strings.Repeat("-", 80)
|
||||
s.l.Infof("%s\n%s: %s\n%s", border, msg, target, border)
|
||||
return tpl.Execute(os.Stdout, data)
|
||||
}
|
||||
|
||||
if path == "." {
|
||||
func (s *Scaffold) renderDirectories() error {
|
||||
for _, directory := range s.directories {
|
||||
if err := s.renderDirectory(directory); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Scaffold) renderDirectory(directory Directory) error {
|
||||
s.l.Info("scaffolding directory:", directory.Target)
|
||||
|
||||
if err := s.scaffoldDir(directory.Target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := fs.WalkDir(directory.Source, ".", func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
} else if path == "." {
|
||||
return nil
|
||||
} else if d.IsDir() {
|
||||
s.l.Print("scaffold:", filename)
|
||||
return os.MkdirAll(filename, os.ModePerm)
|
||||
return s.scaffoldDir(s.filename(path))
|
||||
}
|
||||
|
||||
filename := s.filename(path)
|
||||
|
||||
tpl, err := template.New(d.Name()).Funcs(sprig.FuncMap()).ParseFS(directory.Source, path)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse source file (%s)", path)
|
||||
}
|
||||
|
||||
if s.dry {
|
||||
return s.printTemplate("file", filename, tpl, directory.Data)
|
||||
} else if exists, err := s.fileExists(filename); err != nil {
|
||||
return s.printTemplate(err.Error(), filename, tpl, directory.Data)
|
||||
} else if exists && !s.override {
|
||||
return s.printTemplate("file exists", filename, tpl, directory.Data)
|
||||
} else {
|
||||
tpl, err := template.New(d.Name()).Funcs(sprig.FuncMap()).ParseFS(source, path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if stat, err := os.Stat(filename); errors.Is(err, fs.ErrNotExist) {
|
||||
// all good
|
||||
} else if err != nil {
|
||||
return errors.Wrapf(err, "failed to stat target (%s)", filename)
|
||||
} else if stat.IsDir() {
|
||||
return fmt.Errorf("target file is an existing directory (%s)", filename)
|
||||
} else if !s.force {
|
||||
return fmt.Errorf("target file already exists (%s)", filename)
|
||||
}
|
||||
|
||||
var out io.Writer
|
||||
if s.dry {
|
||||
out = os.Stdout
|
||||
} else {
|
||||
s.l.Print("scaffold:", filename)
|
||||
if file, err := os.Create(filename); err != nil {
|
||||
return errors.Wrapf(err, "failed to create target file (%s)", filename)
|
||||
} else {
|
||||
out = file
|
||||
defer func() {
|
||||
_ = file.Close()
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
if err := tpl.Execute(out, vars); err != nil {
|
||||
return errors.Wrapf(err, "failed to render target file (%s)", filename)
|
||||
}
|
||||
|
||||
return nil
|
||||
return s.scaffoldTemplate(filename, tpl, directory.Data)
|
||||
}
|
||||
}); err != nil {
|
||||
return errors.Wrapf(err, "failed to render scaffold to %s", target)
|
||||
return errors.Wrapf(err, "failed to render scaffold to %s", directory.Target)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Scaffold) fileExists(target string) (bool, error) {
|
||||
if stat, err := os.Stat(target); errors.Is(err, fs.ErrNotExist) {
|
||||
return false, nil
|
||||
} else if err != nil {
|
||||
return false, errors.Wrapf(err, "failed to stat target (%s)", target)
|
||||
} else if stat.IsDir() {
|
||||
return true, fmt.Errorf("target file is an existing directory (%s)", target)
|
||||
} else {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Scaffold) filename(v string) string {
|
||||
v = strings.ReplaceAll(v, "$", "")
|
||||
v = strings.TrimSuffix(v, ".gotext")
|
||||
v = strings.TrimSuffix(v, ".gohtml")
|
||||
return v
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user