Skip to content

Commit

Permalink
Major rewrite
Browse files Browse the repository at this point in the history
This refactor brings major benefits in both parsing and autocompletion.
In the initial implementation, completion was added as side logic to the
existing parser code. In this implementation, completions are a first
class citizen and share the same parsing tree structure that the rest of
the library is using.

The parsing tree was refactored from the ground up to better accommodate
commands and subcommands and also the extra use cases that have been
popping up ever since autocompletion support was added.

The major user facing change is that instead of providing building
blocks to build a command and subcommand experience, a single
`opt.Parse` and `opt.Dispatch` call is required to handle options for
commands and subcommands at all levels.
  • Loading branch information
DavidGamba committed Jan 1, 2022
1 parent 1298991 commit 7969522
Show file tree
Hide file tree
Showing 68 changed files with 7,414 additions and 5,157 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ on:
jobs:
test:
name: Lib
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
matrix:
go: [1.14.x, 1.15.x, 1.16.x, 1.17.x]
# os: [ubuntu-latest, macos-latest, windows-latest]
os: [ubuntu-latest]
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v2
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
examples/mygit/mygit
examples/complex/complex
examples/myscript/myscript
examples/dag/dag
coverage.txt
coverage.html
18 changes: 16 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
.PHONY: test

test:
go test -coverprofile=coverage.txt -covermode=atomic ./ ./completion/ ./option ./help ./dag
go test -race -coverprofile=coverage.txt -covermode=atomic ./ ./internal/completion/ ./internal/option ./internal/help ./dag ./internal/sliceiterator ./text
cd examples/complex && go build . && cd ../..
cd examples/dag && go build . && cd ../..
cd examples/myscript && go build . && cd ../..
cd docs/complex && go build . && cd ../..
cd docs/script && go build . && cd ../..

race:
go test -race ./dag -count=1
Expand All @@ -12,8 +17,17 @@ view: test
# Assumes github.com/dgryski/semgrep-go is checked out in ../
rule-check:
semgrep -f ../semgrep-go .
for dir in ./ ./completion ./option ./help ./dag ; do \
for dir in ./ ./internal/completion ./internal/option ./internal/help ./dag ; do \
echo $$dir ; \
ruleguard -c=0 -rules ../semgrep-go/ruleguard.rules.go $$dir ; \
done


lint:
golangci-lint run --enable-all \
-D funlen \
-D dupl \
-D lll \
-D gocognit \
-D exhaustivestruct \
-D cyclop
44 changes: 21 additions & 23 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ Greeting List:
es=Hola Mundo
----

NOTE: If you are starting a new project, instead of copying the example code from above, use the code from the link:./docs/new-project-templates.adoc[New Project Templates].

== Examples

=== Simple script
Expand All @@ -153,23 +155,26 @@ Tab completion for this script is triggered for options only, so you need to hav

This is the other extreme, a large program that can separate each command in a separate go package.

The base is located at link:./examples/mygit/main.go[]
The base is located at link:./examples/complex/main.go[]

The commands are located at:

* link:./examples/mygit/log/log.go[]
* link:./examples/mygit/show/show.go[]
* link:./examples/mygit/slow/slow.go[]
* link:./examples/complex/greet/greet.go[]
* link:./examples/complex/log/log.go[]
* link:./examples/complex/show/show.go[]
* link:./examples/complex/slow/slow.go[]

To use the autocompletion, cd to the link:./examples/mygit[] dir and run: `source sourceme.bash`
The run `go build` and `./mygit`.
To use the autocompletion, cd to the link:./examples/complex[] dir and run: `source sourceme.bash`
The run `go build` and `./complex`.

Tab completion without arguments triggers completion for commands, for option completion add a dash `-` and trigger it: `./mygit -<tab><tab>`
Tab completion without arguments triggers completion for commands, for option completion add a dash `-` and trigger it: `./complex -<tab><tab>`

The link:./examples/mygit/slow/slow.go[slow] command shows an example of an slow command that can be cancelled with `Ctrl+C`.
The link:./examples/complex/slow/slow.go[slow] command shows an example of an slow command that can be cancelled with `Ctrl+C`.
The cancellation is passed to the command through `context.Context` and it is handled at the command to stop taking new work and trigger a cleanup routine.
Running `Ctrl+C` twice cancels the cancellation routine and fully cancels the program.

The link:./examples/complex/greet/greet.go[greet] command shows an example of using commands and subcommands.

=== Directed Acyclic Graph Build System

This example shows task dependency orchestration and parallelization link:./examples/dag/main.go[].
Expand Down Expand Up @@ -208,10 +213,6 @@ A single line of bash is all it takes.

• Boolean, String, Int, Float64, Slice and Map type options.

• Negatable Boolean options.
+
For example: `--verbose`, `--no-verbose` or `--noverbose`.

• Options with Array arguments.
The same option can be used multiple times with different arguments.
The list of arguments will be saved into an Slice.
Expand Down Expand Up @@ -892,32 +893,29 @@ StringMap and StringMapVar:: Comma separated key=value?
[[roadmap]]
== ROADMAP

* Create new error description for errors when parsing integer ranges (`1..3`).
* Generate compilation errors for commands without a defined `CommandFn`.

* Option that runs a function?
* Create new error description for errors when parsing integer ranges (`1..3`).

* Case insensitive matching.

* prefix and prefix_pattern.
The string that starts options.
Defaults to "--" and "-" but could include "/" to support Win32 style argument handling.

* Supports argument dividers other than '='.
For example: You could define ':' and use `--string=mystring`, `--string:mystring` and `--string mystring`.
* Allow grouping commands so they can have a different order other than alphabetical in the help output.

* Remove need for `opt.HelpCommand("")` when dispatch is defined.
+
Currently we have to define the `opt.Bool("help", false)` flag, then `opt.HelpCommand("")`, and finally `opt.Dispatch(ctx, "help", remaining)`.
`opt.HelpCommand` is redundant.
Additionally `opt.HelpCommand` has the `help` command name hardcoded in it.
* DAG concurrency tests sporadically fail in macos when testing for race conditions.
Testing concurrency and completion order is very difficult in Go.

* Allow grouping commands so they can have a different order other than alphabetical
* Some Windows tests fail because the binary name includes .exe at the end.
Update test suite to accommodate for Windows.

== License

This file is part of go-getoptions.

Copyright (C) 2015-2021 David Gamba Rios
Copyright (C) 2015-2022 David Gamba Rios

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
Expand Down
Loading

0 comments on commit 7969522

Please sign in to comment.