From a6900d53aea0cd46c31bc964af5c4858860348cd Mon Sep 17 00:00:00 2001 From: half-shell Date: Wed, 21 Dec 2022 15:40:28 +0100 Subject: [PATCH 1/6] feat: add an interactive flag to override configuration setting --- src/arguments/arguments.go | 1 + src/arguments/configuration.go | 2 +- src/arguments/flags.go | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/arguments/arguments.go b/src/arguments/arguments.go index 29a1edb..bb32989 100644 --- a/src/arguments/arguments.go +++ b/src/arguments/arguments.go @@ -14,6 +14,7 @@ type Arguments struct { BricksNames []string BricksSpecifiers []string NonInteractive bool + Interactive bool Format string Modules map[string]string OtherOptions []string diff --git a/src/arguments/configuration.go b/src/arguments/configuration.go index a20ef7d..c054028 100644 --- a/src/arguments/configuration.go +++ b/src/arguments/configuration.go @@ -164,7 +164,7 @@ func FromArguments(args Arguments) (configuration Configuration, err error) { BricksSpecifiers: extools.Deduplicate(append(conf.BricksSpecifiers, args.BricksSpecifiers...)), ConfigurationFile: args.ConfigurationFile, Format: args.Format, - Interactive: !args.NonInteractive, + Interactive: (conf.Interactive && !args.NonInteractive) || args.Interactive, Modules: modules, Rooms: rooms, OtherOptions: other_options, diff --git a/src/arguments/flags.go b/src/arguments/flags.go index 91ad7d1..bdf20fb 100644 --- a/src/arguments/flags.go +++ b/src/arguments/flags.go @@ -19,6 +19,9 @@ Includes: %v`, AvailableBricksSpecifiers)) flag.BoolVarP(&Args.NonInteractive, "non-interactive", "I", false, "Allows for exeiac to run without user input") + flag.BoolVarP(&Args.Interactive, "interactive", "i", false, + "Forces exeiac to wait for user input when needed. Overwrites the --non-interactive (-I) flag.") + flag.StringVarP(&Args.Format, "format", "f", "all", fmt.Sprintf(`Define the format of the output. It matches the brick's specifiers values Includes: %v`, AvailableBricksSpecifiers)) From d55485d095e6dae9d6db7370d6a5f8f9d0f95740 Mon Sep 17 00:00:00 2001 From: half-shell Date: Wed, 21 Dec 2022 15:39:38 +0100 Subject: [PATCH 2/6] refactor: remove --non-interactive flag from conf's OtherOptions --- src/actions/default.go | 10 +++++++++- src/actions/lay.go | 11 +++++++++-- src/actions/plan.go | 11 +++++++++-- src/actions/remove.go | 11 +++++++++-- src/arguments/configuration.go | 2 +- 5 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/actions/default.go b/src/actions/default.go index 0883175..70f8fe9 100644 --- a/src/actions/default.go +++ b/src/actions/default.go @@ -29,7 +29,15 @@ func PassthroughAction( for i, b := range bricksToExecute { report := ExecReport{Brick: b} - statusCode, err = b.Module.Exec(b, conf.Action, conf.OtherOptions, []string{}) + // TODO(half-shell): Work around to avoid polluting conf's OtherOptions. + // Ideally, we would have a flexible way of providing a "non-interactive" flag + // to a module. + args := conf.OtherOptions + if !conf.Interactive { + args = append(args, "--non-interactive") + } + + statusCode, err = b.Module.Exec(b, conf.Action, args, []string{}) if err != nil { if actionNotImplementedError, isActionNotImplemented := err.(exinfra.ActionNotImplementedError); isActionNotImplemented { diff --git a/src/actions/lay.go b/src/actions/lay.go index 9ce4c8d..250687b 100644 --- a/src/actions/lay.go +++ b/src/actions/lay.go @@ -63,8 +63,15 @@ func Lay( return 3, err } - // lay and manage error - exitStatus, err := b.Module.Exec(b, "lay", conf.OtherOptions, envs) + // TODO(half-shell): Work around to avoid polluting conf's OtherOptions. + // Ideally, we would have a flexible way of providing a "non-interactive" flag + // to a module. + args := conf.OtherOptions + if !conf.Interactive { + args = append(args, "--non-interactive") + } + + exitStatus, err := b.Module.Exec(b, "lay", args, envs) if err != nil { skipFollowing = true report.Error = err diff --git a/src/actions/plan.go b/src/actions/plan.go index d301775..579a052 100644 --- a/src/actions/plan.go +++ b/src/actions/plan.go @@ -38,8 +38,15 @@ func Plan( return 3, err } - // lay and manage error - exitStatus, err := b.Module.Exec(b, "plan", conf.OtherOptions, envs) + // TODO(half-shell): Work around to avoid polluting conf's OtherOptions. + // Ideally, we would have a flexible way of providing a "non-interactive" flag + // to a module. + args := conf.OtherOptions + if !conf.Interactive { + args = append(args, "--non-interactive") + } + + exitStatus, err := b.Module.Exec(b, "plan", args, envs) if err != nil { report.Error = err report.Status = TAG_ERROR diff --git a/src/actions/remove.go b/src/actions/remove.go index 83757d8..71ef6a6 100644 --- a/src/actions/remove.go +++ b/src/actions/remove.go @@ -66,8 +66,15 @@ func Remove( return 3, err } - // lay and manage error - exitStatus, err := b.Module.Exec(b, "remove", conf.OtherOptions, envs) + // TODO(half-shell): Work around to avoid polluting conf's OtherOptions. + // Ideally, we would have a flexible way of providing a "non-interactive" flag + // to a module. + args := conf.OtherOptions + if !conf.Interactive { + args = append(args, "--non-interactive") + } + + exitStatus, err := b.Module.Exec(b, "remove", args, envs) if err != nil { skipFollowing = true report.Error = err diff --git a/src/arguments/configuration.go b/src/arguments/configuration.go index c054028..666cb6a 100644 --- a/src/arguments/configuration.go +++ b/src/arguments/configuration.go @@ -167,7 +167,7 @@ func FromArguments(args Arguments) (configuration Configuration, err error) { Interactive: (conf.Interactive && !args.NonInteractive) || args.Interactive, Modules: modules, Rooms: rooms, - OtherOptions: other_options, + OtherOptions: extools.Deduplicate(append(conf.OtherOptions, args.OtherOptions...)), } return From 2404381b35620e6c376f585baae8d4117433c3d6 Mon Sep 17 00:00:00 2001 From: half-shell Date: Wed, 21 Dec 2022 14:41:09 +0100 Subject: [PATCH 3/6] refactor: check that bricks will be provided to be acted on --- src/main.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main.go b/src/main.go index 28280b3..0a93038 100644 --- a/src/main.go +++ b/src/main.go @@ -75,6 +75,13 @@ func main() { os.Exit(1) } + if len(bricksToExecute) == 0 { + err = fmt.Errorf("No bricks was found to need actions. Check the provided brick(s) and selectors (if any).") + fmt.Fprintln(os.Stderr, err) + + os.Exit(3) + } + // executeAction // if exargs.Args.action is in the list do that else use otherAction if behaviour, ok := exaction.BehaviourMap[configuration.Action]; ok { From 26542799f976cb3e9a86e134109720598c896a2a Mon Sep 17 00:00:00 2001 From: half-shell Date: Wed, 21 Dec 2022 17:05:15 +0100 Subject: [PATCH 4/6] chore: make CreateConfiguration public --- src/arguments/configuration.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/arguments/configuration.go b/src/arguments/configuration.go index 666cb6a..f2242aa 100644 --- a/src/arguments/configuration.go +++ b/src/arguments/configuration.go @@ -66,7 +66,7 @@ func (a Configuration) String() string { return sb.String() } -func createConfiguration(confFilePath string) (configuration Configuration, err error) { +func CreateConfiguration(confFilePath string) (configuration Configuration, err error) { file, err := os.ReadFile(confFilePath) if err != nil { return @@ -113,13 +113,13 @@ func FromArguments(args Arguments) (configuration Configuration, err error) { var conf Configuration if args.ConfigurationFile != "" { - conf, err = createConfiguration(args.ConfigurationFile) + conf, err = CreateConfiguration(args.ConfigurationFile) } else { var configFilePath string configFilePath, err = xdg.SearchConfigFile(CONFIG_FILE) if err == nil { - conf, err = createConfiguration(configFilePath) + conf, err = CreateConfiguration(configFilePath) } } From 3eedd27e00a0255eb5ad593d29204e3ed8603dc6 Mon Sep 17 00:00:00 2001 From: half-shell Date: Wed, 21 Dec 2022 17:06:26 +0100 Subject: [PATCH 5/6] WIP: feat: add completion module and completion for fish shell --- go.work.sum | 6 ++++++ src/arguments/arguments.go | 1 + src/arguments/flags.go | 2 ++ src/completion/README.md | 21 +++++++++++++++++++++ src/completion/completion.go | 22 ++++++++++++++++++++++ src/completion/scripts/exeiac.fish | 11 +++++++++++ src/main.go | 22 ++++++++++++++++++---- 7 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 go.work.sum create mode 100644 src/completion/README.md create mode 100644 src/completion/completion.go create mode 100644 src/completion/scripts/exeiac.fish diff --git a/go.work.sum b/go.work.sum new file mode 100644 index 0000000..55e0d8d --- /dev/null +++ b/go.work.sum @@ -0,0 +1,6 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= diff --git a/src/arguments/arguments.go b/src/arguments/arguments.go index bb32989..f6d82d7 100644 --- a/src/arguments/arguments.go +++ b/src/arguments/arguments.go @@ -21,6 +21,7 @@ type Arguments struct { Rooms map[string]string ConfigurationFile string ShowUsage bool + ListBricks bool } func (a Arguments) String() string { diff --git a/src/arguments/flags.go b/src/arguments/flags.go index bdf20fb..f9f522d 100644 --- a/src/arguments/flags.go +++ b/src/arguments/flags.go @@ -48,6 +48,8 @@ to it. Flag with arguments need to be enclosed in double quotes flag.BoolVarP(&Args.ShowUsage, "help", "h", false, "Show exeiac's help") + flag.BoolVarP(&Args.ListBricks, "list-bricks", "l", false, "List all the bricks from all rooms") + flag.Usage = func() { fmt.Println("Usage: exeiac ACTION (BRICK_PATH|BRICK_NAME) [OPTION...]") fmt.Println() diff --git a/src/completion/README.md b/src/completion/README.md new file mode 100644 index 0000000..11e70b1 --- /dev/null +++ b/src/completion/README.md @@ -0,0 +1,21 @@ +# Exeiac completion +A small package to provide an auto-completion to different shells (bash, zsh, fish). + +It justs references all brick's in a configuration file's "Rooms" section, and return them. + +## Setup +*Instructions on how to build the binary used for brick's auto-completion.* +```bash +$ go install completion +``` + +## Bash + +## Zsh + +## Fish +To enable the fish auto-completion, you can just copy the `./scripts/exeiac.fish` file to `~/.config/fish/completions/exeiac.fish`. +```fish +$ cp ./scripts/exeiac.fish ~/.config/fish/completions/exeiac.fish +``` +You should have completion enabled once diff --git a/src/completion/completion.go b/src/completion/completion.go new file mode 100644 index 0000000..31168de --- /dev/null +++ b/src/completion/completion.go @@ -0,0 +1,22 @@ +package completion + +import ( + "fmt" + "os" + exargs "src/exeiac/arguments" + "src/exeiac/infra" +) + +func ListBricks(configuration exargs.Configuration) { + var bricks infra.Bricks + for roomName, roomPath := range configuration.Rooms { + bs, err := infra.GetBricks(roomName, roomPath) + if err == nil { + bricks = append(bricks, bs...) + } + } + + for _, b := range bricks { + fmt.Fprintln(os.Stdout, b.Name) + } +} diff --git a/src/completion/scripts/exeiac.fish b/src/completion/scripts/exeiac.fish new file mode 100644 index 0000000..86b12e5 --- /dev/null +++ b/src/completion/scripts/exeiac.fish @@ -0,0 +1,11 @@ +set -l actions init plan lay remove help validate_code show clean + +# Prevent file auto completion +complete -c exeiac -f + +# Auto completion for sub-commands (actions) +complete -c exeiac -n "not __fish_seen_subcommand_from $commands" -a "$actions" + +# Auto completion for bricks +# TODO(half-shell): Replace with a GOPATH or a go command +complete -c exeiac -n "__fish_seen_subcommand_from $actions" -a "(exeiac -l)" diff --git a/src/main.go b/src/main.go index 0a93038..2622da3 100644 --- a/src/main.go +++ b/src/main.go @@ -5,6 +5,7 @@ import ( "os" exaction "src/exeiac/actions" exargs "src/exeiac/arguments" + excompletion "src/exeiac/completion" exinfra "src/exeiac/infra" flag "github.com/spf13/pflag" @@ -26,11 +27,18 @@ func main() { // The only remaining arguments are not flags. They match the action and the brickNames nonFlagArgs := flag.Args() - if len(nonFlagArgs) == 0 { - fmt.Fprintln(os.Stderr, "argument missing: you need at least to specify one action") - os.Exit(2) + + // NOTE(half-shell): We need the configuration created to list all bricks so we bypass + // the check made on the action and bricks if the "list bricks" flag is provided. + if !exargs.Args.ListBricks { + if len(nonFlagArgs) == 0 { + fmt.Fprintln(os.Stderr, "argument missing: you need at least to specify one action") + + os.Exit(2) + } + + exargs.Args.Action, exargs.Args.BricksNames = nonFlagArgs[0], nonFlagArgs[1:] } - exargs.Args.Action, exargs.Args.BricksNames = nonFlagArgs[0], nonFlagArgs[1:] configuration, err := exargs.FromArguments(exargs.Args) if err != nil { @@ -39,6 +47,12 @@ func main() { os.Exit(2) } + if exargs.Args.ListBricks { + excompletion.ListBricks(configuration) + + os.Exit(0) + } + // build infra representation infra, err := exinfra.CreateInfra(configuration) if err != nil { From 2504f289e10657f23d372579b064ed188792f274 Mon Sep 17 00:00:00 2001 From: half-shell Date: Mon, 2 Jan 2023 15:55:43 +0100 Subject: [PATCH 6/6] chore: add GH workflow with goreleaser --- .github/workflows/main.yml | 30 +++++++++++++++++++++++++ .gitignore | 2 ++ .goreleaser.yaml | 46 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 .github/workflows/main.yml create mode 100644 .goreleaser.yaml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..c9a0c3a --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,30 @@ +name: goreleaser + +on: + pull_request: + push: + +jobs: + goreleaser: + runs-on: ubuntu-latest + environment: release + permissions: + contents: write + steps: + - + name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - + name: Set up Go + uses: actions/setup-go@v3 + - + name: Run GoReleaser + uses: goreleaser/goreleaser-action@v4 + with: + distribution: goreleaser + version: latest + args: release --rm-dist + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 67dffc5..85986d1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ bin pkg src/pkg + +dist/ diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..8571729 --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,46 @@ +builds: + - env: + - CGO_ENABLED=0 + goos: + - linux + goarch: + - amd64 + main: "./src/main.go" + binary: "exeiac" +archives: + - id: foo + name_template: >- + {{ .ProjectName }}_ + {{ .Os }}_ + {{ .Arch }} +checksum: + name_template: 'checksums.txt' +snapshot: + name_template: "{{ incpatch .Version }}-next" +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' +nfpms: + - + package_name: exeiac + formats: + - deb + - archlinux + prerelease: alpha1 + contents: + - src: ./src/completion/scripts/exeiac.fish + dst: /usr/share/fish/vendor_completions.d/ + file_info: + mode: 0644 +release: + github: + owner: half-shell + name: exeiac + mode: append + +# modelines, feel free to remove those if you don't want/use them: +# yaml-language-server: $schema=https://goreleaser.com/static/schema.json +# vim: set ts=2 sw=2 tw=0 fo=cnqoj