refactor: rename dependencies to require

This commit is contained in:
Kevin Franklin Kim 2023-01-06 10:29:05 +01:00
parent c6dad4b9ce
commit fe8eac3511
20 changed files with 182 additions and 135 deletions

View File

@ -5,9 +5,9 @@ import (
"path"
"github.com/foomo/posh/embed"
"github.com/foomo/posh/internal/git"
scaffold2 "github.com/foomo/posh/integration/scaffold"
"github.com/foomo/posh/internal/util/git"
"github.com/foomo/posh/pkg/env"
"github.com/foomo/posh/pkg/scaffold"
"github.com/spf13/cobra"
)
@ -41,11 +41,11 @@ Posh init must be run inside of a go module (please run "go mod init <MODNAME> f
return err
}
sc, err := scaffold.New(
sc, err := scaffold2.New(
l,
scaffold.WithDry(initCmdFlagDry),
scaffold.WithOverride(initCmdFlagOverride),
scaffold.WithDirectories(scaffold.Directory{
scaffold2.WithDry(initCmdFlagDry),
scaffold2.WithOverride(initCmdFlagOverride),
scaffold2.WithDirectories(scaffold2.Directory{
Source: fs,
Target: os.Getenv(env.ProjectRoot),
Data: data,

View File

@ -20,9 +20,9 @@ var versionCmd = &cobra.Command{
buildTime = time.Unix(value, 0).String()
}
if l.IsLevel(log.LevelDebug) {
l.Print("v%s, Commit: %s, BuildTime: %s", intversion.Version, intversion.CommitHash, buildTime)
l.Printf("v%s, Commit: %s, BuildTime: %s", intversion.Version, intversion.CommitHash, buildTime)
} else {
l.Print("v%s", intversion.Version)
l.Printf("v%s", intversion.Version)
}
},
}

View File

@ -0,0 +1,7 @@
module {{.module}}
go 1.19
replace (
github.com/c-bata/go-prompt v0.2.6 => github.com/franklinkim/go-prompt v0.2.7-0.20210427061716-a8f4995d7aa5
)

3
go.mod
View File

@ -8,6 +8,7 @@ require (
github.com/Masterminds/sprig/v3 v3.2.3
github.com/alecthomas/chroma v0.10.0
github.com/c-bata/go-prompt v0.2.6
github.com/charlievieth/fastwalk v1.0.1
github.com/foomo/fender v0.4.4
github.com/go-git/go-git/v5 v5.5.1
github.com/gofrs/flock v0.8.1
@ -15,6 +16,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/pterm/pterm v0.12.51
github.com/spf13/cobra v1.6.1
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.14.0
github.com/whilp/git-urls v1.0.0
)
@ -66,7 +68,6 @@ require (
github.com/spf13/afero v1.9.2 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
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

3
go.sum
View File

@ -77,6 +77,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY
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/charlievieth/fastwalk v1.0.1 h1:jW01w8OCFdKS9JvAcnI+JHhWU/FuIEmNb24Ri9p7OVg=
github.com/charlievieth/fastwalk v1.0.1/go.mod h1:dryXgMJyGHbMrAmmnF0/EJNBbZaihlwcNud5IuGyogU=
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=
@ -219,6 +221,7 @@ github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwA
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/karrick/godirwalk v1.17.0 h1:b4kY7nqDdioR/6qnbHQyDvmA17u5G1cZ6J+CZXwSWoI=
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=

View File

@ -12,8 +12,8 @@ import (
"strings"
"time"
"github.com/alecthomas/chroma/quick"
"github.com/foomo/posh/pkg/log"
"github.com/foomo/posh/pkg/util/prints"
"github.com/pkg/errors"
)
@ -194,7 +194,7 @@ func (o *Ownbrew) installLocal(ctx context.Context, pkg Package) error {
if value, err := os.ReadFile(filename); err != nil {
return errors.Wrap(err, "failed to read file")
} else {
o.print(filename, string(value))
prints.Code(o.l, filename, string(value), "sh")
}
return nil
}
@ -250,7 +250,7 @@ func (o *Ownbrew) installRemote(ctx context.Context, pkg Package) error {
if value, err := io.ReadAll(resp.Body); err != nil {
return err
} else {
o.print(url, string(value))
prints.Code(o.l, url, string(value), "sh")
}
return nil
}
@ -279,15 +279,6 @@ func (o *Ownbrew) installRemote(ctx context.Context, pkg Package) error {
return nil
}
func (o *Ownbrew) print(source, value string) {
border := strings.Repeat("-", 80)
o.l.Infof("\n%s\n%s\n%s", border, source, border)
if err := quick.Highlight(os.Stdout, value, "sh", "terminal", "monokai"); err != nil {
o.l.Debug(err.Error())
o.l.Print(value)
}
}
func (o *Ownbrew) localTapExists(filename string) (bool, error) {
if stat, err := os.Stat(filename); errors.Is(err, os.ErrNotExist) {
return false, nil

View File

@ -11,8 +11,8 @@ import (
"text/template"
"github.com/Masterminds/sprig/v3"
"github.com/alecthomas/chroma/quick"
"github.com/foomo/posh/pkg/log"
"github.com/foomo/posh/pkg/util/prints"
"github.com/pkg/errors"
)
@ -85,6 +85,7 @@ func (s *Scaffold) Render(ctx context.Context) error {
// ------------------------------------------------------------------------------------------------
// ~ 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) {
@ -114,14 +115,12 @@ func (s *Scaffold) scaffoldTemplate(target string, tpl *template.Template, data
}
func (s *Scaffold) printTemplate(msg, target string, tpl *template.Template, data any) error {
border := strings.Repeat("-", 80)
s.l.Infof("\n%s\n%s: %s\n%s", border, msg, target, border)
var out bytes.Buffer
if err := tpl.Execute(&out, data); err != nil {
return err
}
return quick.Highlight(os.Stdout, out.String(), filepath.Ext(target), "terminal", "monokai")
prints.Code(s.l, fmt.Sprintf("%s: %s", msg, target), out.String(), filepath.Ext(target))
return nil
}
func (s *Scaffold) renderDirectories() error {

View File

@ -5,7 +5,13 @@ import "github.com/c-bata/go-prompt"
type MemoryNamespace map[string]interface{}
func (c MemoryNamespace) Delete(key string) {
delete(c, key)
if key == "" {
for key := range c {
delete(c, key)
}
} else {
delete(c, key)
}
}
func (c MemoryNamespace) Get(key string, cb func() interface{}) interface{} {

View File

@ -5,21 +5,21 @@ import (
)
type (
Dependencies struct {
Envs []DependenciesEnv `json:"envs" yaml:"envs"`
Scripts []DependenciesScript `json:"script" yaml:"script"`
Packages []DependenciesPackage `json:"packages" yaml:"packages"`
Require struct {
Envs []RequireEnv `json:"envs" yaml:"envs"`
Scripts []RequireScript `json:"scripts" yaml:"scripts"`
Packages []RequirePackage `json:"packages" yaml:"packages"`
}
DependenciesEnv struct {
RequireEnv struct {
Name string `json:"name" yaml:"name"`
Help string `json:"help" yaml:"help"`
}
DependenciesScript struct {
RequireScript struct {
Name string `json:"name" yaml:"name"`
Command string `json:"command" yaml:"command"`
Help string `json:"help" yaml:"help"`
}
DependenciesPackage struct {
RequirePackage struct {
Name string `json:"name" yaml:"name"`
Version string `json:"version" yaml:"version"`
Command string `json:"command" yaml:"command"`
@ -27,14 +27,14 @@ type (
}
)
func (c DependenciesEnv) String() string {
func (c RequireEnv) String() string {
return fmt.Sprintf("Name: %s", c.Name)
}
func (c DependenciesScript) String() string {
func (c RequireScript) String() string {
return fmt.Sprintf("Name: %s, Command: %s", c.Name, c.Command)
}
func (c DependenciesPackage) String() string {
func (c RequirePackage) String() string {
return fmt.Sprintf("Name: %s, Version: %s Command: %s", c.Name, c.Version, c.Command)
}

View File

@ -10,5 +10,5 @@ type Plugin interface {
Prompt(ctx context.Context, cfg config.Prompt) error
Execute(ctx context.Context, args []string) error
Brew(ctx context.Context, cfg config.Ownbrew) error
Dependencies(ctx context.Context, cfg config.Dependencies) error
Require(ctx context.Context, cfg config.Require) error
}

View File

@ -14,6 +14,14 @@ func (a Args) At(v int) string {
}
}
func (a Args) Shift() (string, Args) {
if a.HasIndex(0) {
return a[0], a[1:]
} else {
return "", nil
}
}
func (a Args) Empty() bool {
return a == nil || a.LenIs(0)
}

73
pkg/readline/flagset.go Normal file
View File

@ -0,0 +1,73 @@
package readline
import (
"strconv"
"github.com/spf13/pflag"
)
type FlagSet struct {
*pflag.FlagSet
}
func NewFlagSet(handler func(set *FlagSet)) *FlagSet {
inst := &FlagSet{
FlagSet: pflag.NewFlagSet("readline", pflag.ContinueOnError),
}
if handler != nil {
handler(inst)
}
return inst
}
func (a *FlagSet) GetString(name string) string {
if f := a.FlagSet.Lookup(name); f == nil {
return ""
} else if !a.flagIsSet(name) {
return f.DefValue
} else {
return f.Value.String()
}
}
func (a *FlagSet) GetInt64(name string) int64 {
if value := a.GetString(name); value == "" {
return 0
} else if v, err := strconv.ParseInt(value, 10, 64); err != nil {
return 0
} else {
return v
}
}
func (a *FlagSet) GetFloat64(name string) float64 {
if value := a.GetString(name); value == "" {
return 0
} else if v, err := strconv.ParseFloat(value, 64); err != nil {
return 0
} else {
return v
}
}
func (a *FlagSet) GetBool(name string) bool {
if value := a.GetString(name); value == "" {
return false
} else if v, err := strconv.ParseBool(value); err != nil {
return false
} else {
return v
}
}
func (a *FlagSet) flagIsSet(name string) bool {
found := false
if fs := a.FlagSet; fs != nil {
fs.Visit(func(f *pflag.Flag) {
if f.Name == name {
found = true
}
})
}
return found
}

View File

@ -1,13 +1,12 @@
package readline
import (
"flag"
"fmt"
"regexp"
"strconv"
"sync"
"github.com/foomo/posh/pkg/log"
"github.com/spf13/pflag"
)
type (
@ -219,30 +218,30 @@ func (a *Readline) IsModeAdditional() bool {
return a.Mode() == ModeAdditionalArgs
}
func (a *Readline) AllFlags() []*flag.Flag {
var ret []*flag.Flag
func (a *Readline) AllFlags() []*pflag.Flag {
var ret []*pflag.Flag
if fs := a.FlagSet(); fs != nil {
fs.VisitAll(func(f *flag.Flag) {
fs.VisitAll(func(f *pflag.Flag) {
ret = append(ret, f)
})
}
return ret
}
func (a *Readline) VisitedFlags() []*flag.Flag {
var ret []*flag.Flag
func (a *Readline) VisitedFlags() []*pflag.Flag {
var ret []*pflag.Flag
if fs := a.FlagSet(); fs != nil {
fs.Visit(func(f *flag.Flag) {
fs.Visit(func(f *pflag.Flag) {
ret = append(ret, f)
})
}
return ret
}
func (a *Readline) AllPassThroughFlags() []*flag.Flag {
var ret []*flag.Flag
func (a *Readline) AllPassThroughFlags() []*pflag.Flag {
var ret []*pflag.Flag
if fs := a.PassThroughFlagSet(); fs != nil {
fs.VisitAll(func(f *flag.Flag) {
fs.VisitAll(func(f *pflag.Flag) {
ret = append(ret, f)
})
}
@ -264,69 +263,3 @@ func (a *Readline) reset() {
a.passThroughFlagSet = nil
a.additionalArgs = nil
}
type FlagSet struct {
*flag.FlagSet
}
func NewFlagSet(handler func(set *FlagSet)) *FlagSet {
inst := &FlagSet{
FlagSet: flag.NewFlagSet("readline", flag.ContinueOnError),
}
if handler != nil {
handler(inst)
}
return inst
}
func (a *FlagSet) GetString(name string) string {
if f := a.FlagSet.Lookup(name); f == nil {
return ""
} else if !a.flagIsSet(name) {
return f.DefValue
} else {
return f.Value.String()
}
}
func (a *FlagSet) GetInt64(name string) int64 {
if value := a.GetString(name); value == "" {
return 0
} else if v, err := strconv.ParseInt(value, 10, 64); err != nil {
return 0
} else {
return v
}
}
func (a *FlagSet) GetFloat64(name string) float64 {
if value := a.GetString(name); value == "" {
return 0
} else if v, err := strconv.ParseFloat(value, 64); err != nil {
return 0
} else {
return v
}
}
func (a *FlagSet) GetBool(name string) bool {
if value := a.GetString(name); value == "" {
return false
} else if v, err := strconv.ParseBool(value); err != nil {
return false
} else {
return v
}
}
func (a *FlagSet) flagIsSet(name string) bool {
found := false
if fs := a.FlagSet; fs != nil {
fs.Visit(func(f *flag.Flag) {
if f.Name == name {
found = true
}
})
}
return found
}

View File

@ -1,4 +1,4 @@
package validate
package require
import (
"errors"
@ -10,17 +10,17 @@ import (
"github.com/foomo/posh/pkg/log"
)
type DependenciesEnvRule func(l log.Logger, v config.DependenciesEnv) rule.Rule
type EnvRule func(l log.Logger, v config.RequireEnv) rule.Rule
func DependenciesEnvs(l log.Logger, v []config.DependenciesEnv) []fend.Fend {
func Envs(l log.Logger, v []config.RequireEnv) []fend.Fend {
ret := make([]fend.Fend, len(v))
for i, vv := range v {
ret[i] = DependenciesEnv(l, vv, DependenciesEnvExists)
ret[i] = Env(l, vv, EnvExists)
}
return ret
}
func DependenciesEnv(l log.Logger, v config.DependenciesEnv, rules ...DependenciesEnvRule) fend.Fend {
func Env(l log.Logger, v config.RequireEnv, rules ...EnvRule) fend.Fend {
return func() []rule.Rule {
ret := make([]rule.Rule, len(rules))
for i, r := range rules {
@ -30,7 +30,7 @@ func DependenciesEnv(l log.Logger, v config.DependenciesEnv, rules ...Dependenci
}
}
func DependenciesEnvExists(l log.Logger, v config.DependenciesEnv) rule.Rule {
func EnvExists(l log.Logger, v config.RequireEnv) rule.Rule {
return func() (*rule.Error, error) {
l.Debug("validate env exists:", v.String())
if value := os.Getenv(v.Name); value == "" {

View File

@ -1,4 +1,4 @@
package validate
package require
import (
"context"

View File

@ -1,4 +1,4 @@
package validate
package require
import (
"context"
@ -14,17 +14,17 @@ import (
"github.com/pkg/errors"
)
type DependenciesPackageRule func(ctx context.Context, l log.Logger, v config.DependenciesPackage) rule.Rule
type PackageRule func(ctx context.Context, l log.Logger, v config.RequirePackage) rule.Rule
func DependenciesPackages(ctx context.Context, l log.Logger, v []config.DependenciesPackage) []fend.Fend {
func Packages(ctx context.Context, l log.Logger, v []config.RequirePackage) []fend.Fend {
ret := make([]fend.Fend, len(v))
for i, vv := range v {
ret[i] = DependenciesPackage(ctx, l, vv, DependenciesPackageExists, DependenciesPackageVersion)
ret[i] = Package(ctx, l, vv, PackageExists, PackageVersion)
}
return ret
}
func DependenciesPackage(ctx context.Context, l log.Logger, v config.DependenciesPackage, rules ...DependenciesPackageRule) fend.Fend {
func Package(ctx context.Context, l log.Logger, v config.RequirePackage, rules ...PackageRule) fend.Fend {
return func() []rule.Rule {
ret := make([]rule.Rule, len(rules))
for i, r := range rules {
@ -34,7 +34,7 @@ func DependenciesPackage(ctx context.Context, l log.Logger, v config.Dependencie
}
}
func DependenciesPackageExists(ctx context.Context, l log.Logger, v config.DependenciesPackage) rule.Rule {
func PackageExists(ctx context.Context, l log.Logger, v config.RequirePackage) rule.Rule {
return func() (*rule.Error, error) {
l.Debug("validate package exists:", v.String())
if output, err := exec.LookPath(v.Name); err != nil {
@ -49,7 +49,7 @@ func DependenciesPackageExists(ctx context.Context, l log.Logger, v config.Depen
}
}
func DependenciesPackageVersion(ctx context.Context, l log.Logger, v config.DependenciesPackage) rule.Rule {
func PackageVersion(ctx context.Context, l log.Logger, v config.RequirePackage) rule.Rule {
return func() (*rule.Error, error) {
l.Debug("validate package version:", v.String())
if output, err := exec.CommandContext(ctx, "sh", "-c", v.Command).CombinedOutput(); err != nil {

26
pkg/require/require.go Normal file
View File

@ -0,0 +1,26 @@
package require
import (
"github.com/foomo/fender/fend"
"github.com/foomo/posh/pkg/log"
)
func First(l log.Logger, fends ...any) error {
var allFends []fend.Fend
for _, value := range fends {
switch v := value.(type) {
case fend.Fend:
allFends = append(allFends, v)
case []fend.Fend:
allFends = append(allFends, v...)
default:
l.Warn("unknown type:", v)
}
}
if fendErr, err := fend.First(allFends...); err != nil {
return err
} else if fendErr != nil {
return fendErr
}
return nil
}

View File

@ -1,4 +1,4 @@
package validate
package require
import (
"context"
@ -11,17 +11,17 @@ import (
"github.com/pkg/errors"
)
type DependenciesScriptRule func(ctx context.Context, l log.Logger, v config.DependenciesScript) rule.Rule
type ScriptRule func(ctx context.Context, l log.Logger, v config.RequireScript) rule.Rule
func DependenciesScripts(ctx context.Context, l log.Logger, v []config.DependenciesScript) []fend.Fend {
func Scripts(ctx context.Context, l log.Logger, v []config.RequireScript) []fend.Fend {
ret := make([]fend.Fend, len(v))
for i, vv := range v {
ret[i] = DependenciesScript(ctx, l, vv, DependenciesScriptStatus)
ret[i] = Script(ctx, l, vv, ScriptStatus)
}
return ret
}
func DependenciesScript(ctx context.Context, l log.Logger, v config.DependenciesScript, rules ...DependenciesScriptRule) fend.Fend {
func Script(ctx context.Context, l log.Logger, v config.RequireScript, rules ...ScriptRule) fend.Fend {
return func() []rule.Rule {
ret := make([]rule.Rule, len(rules))
for i, r := range rules {
@ -31,7 +31,7 @@ func DependenciesScript(ctx context.Context, l log.Logger, v config.Dependencies
}
}
func DependenciesScriptStatus(ctx context.Context, l log.Logger, v config.DependenciesScript) rule.Rule {
func ScriptStatus(ctx context.Context, l log.Logger, v config.RequireScript) rule.Rule {
return func() (*rule.Error, error) {
l.Debug("validate script status:", v.String())
if output, err := exec.CommandContext(ctx, "sh", "-c", v.Command).CombinedOutput(); err != nil {