Skip to content
This repository has been archived by the owner on Aug 20, 2022. It is now read-only.

Commit

Permalink
refactor: restructure packages
Browse files Browse the repository at this point in the history
  • Loading branch information
celicoo committed Jul 12, 2019
1 parent 633dd8a commit 8daa68b
Show file tree
Hide file tree
Showing 14 changed files with 68 additions and 48 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Expand Up @@ -21,5 +21,5 @@ install:

script:
- test -z "$(go fmt ./...)"
- godog -f progress
- cd internal/docstring && godog -f progress
- cd pkg/args/ && godog -f progress
- cd ../docstring/ && godog -f progress
18 changes: 5 additions & 13 deletions docli.go
@@ -1,17 +1,9 @@
package docli

import (
"os"
"strings"
import "github.com/celicoo/docli/pkg/args"

"github.com/celicoo/docli/internal/reger"
)

// Args returns the command-line arguments, starting after the program name.
func Args() (a args) {
// Concatenate the command-line arguments using the U+001F character as
// separator.
s := strings.Join(os.Args[1:], "\u0009")
reger.Build(&a).ParseString(s, &a)
return
// Args returns the AST of the command-line arguments, starting after the
// program name.
func Args() args.Args {
return args.Parse()
}
4 changes: 3 additions & 1 deletion docs/content/docs/tutorial/index.md
Expand Up @@ -246,7 +246,7 @@ The Error method will run when the user passes an argument or command that is no
{{<highlight go>}}
func (g *Git) Error(err error) {
switch err.(type) {
case *docli.InvalidArgumentError:
case *args.InvalidArgumentError:
// Ignore InvalidArgumentError.
g.Run()
default:
Expand All @@ -255,6 +255,8 @@ func (g *Git) Error(err error) {
}
{{</highlight>}}

The `InvalidArgumentError` is within the `args` package, so make sure to add `"github.com/celicoo/docli/args"` to the import declarations.

#### **Help method**

The Help method will run when the user passes the `help` argument. Usually, you'll just print the docstring to `stdout`; that’s what we’ll do in our example:
Expand Down
3 changes: 2 additions & 1 deletion examples/git/cmd/root.go
Expand Up @@ -5,6 +5,7 @@ import (
"log"

"github.com/celicoo/docli"
"github.com/celicoo/docli/pkg/args"
)

const version = "0.0.1"
Expand Down Expand Up @@ -41,7 +42,7 @@ func (g *Git) Help() {

func (g *Git) Error(err error) {
switch err.(type) {
case *docli.InvalidArgumentError:
case *args.InvalidArgumentError:
// Ignore InvalidArgumentError.
g.Run()
default:
Expand Down
25 changes: 25 additions & 0 deletions pkg/args/args.go
@@ -0,0 +1,25 @@
package args

import (
"os"
"strings"

"github.com/celicoo/docli/internal/reger"
)

// args returns the command-line arguments, starting after the program name.
func args() string {
// Concatenate the command-line arguments using the U+001F character as
// separator.
return strings.Join(os.Args[1:], "\u0009")
}

// Parse returns the AST of the command-line arguments, starting after the
// program name.
func Parse() (a Args) {
// We ignore any errors that might happen when parsing the command-line
// arguments. Although this looks odd, it's preferable over the bad error
// handling of Participle.
reger.Build(&a).ParseString(args(), &a)
return
}
8 changes: 4 additions & 4 deletions docli_test.go → pkg/args/args_test.go
@@ -1,4 +1,4 @@
package docli_test
package args_test

import (
"fmt"
Expand All @@ -7,18 +7,18 @@ import (

"github.com/DATA-DOG/godog"
"github.com/DATA-DOG/godog/gherkin"
. "github.com/celicoo/docli"
. "github.com/celicoo/docli/pkg/args"
)

var args interface{}
var args Args

func theArguments(d *gherkin.DocString) error {
os.Args = append(os.Args[:1], strings.Split(d.Content, " ")...)
return nil
}

func iCallTheParser() error {
args = Args()
args = Parse()
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion command.go → pkg/args/command.go
@@ -1,4 +1,4 @@
package docli
package args

type command interface {
// Doc returns the doc string of the [command].
Expand Down
2 changes: 1 addition & 1 deletion error.go → pkg/args/error.go
@@ -1,4 +1,4 @@
package docli
package args

import "fmt"

Expand Down
6 changes: 3 additions & 3 deletions features/docli.feature → pkg/args/features/args.feature
@@ -1,10 +1,10 @@
Feature: command-line parser
In order to have a reliable parser
As a test suite
I need to snapshot test the arguments
I need to snapshot test the command-line arguments

Scenario: should correctly parse the arguments
Given the arguments:
Scenario: should correctly parse the command-line arguments
Given the command-line arguments:
"""
git clone -v -q --progress -n --bare --mirror -l --no-hardlinks -s --recurse-submodules=path/spec -j=10 --template=template/directory --reference="git@github.com:celicoo/docli.git" --dissociate -o=name -b=branch -u=path --depth=1 --shallow-since=2019-16-05 --single-branch --no-tags --shallow-submodules -4 -6
"""
Expand Down
18 changes: 9 additions & 9 deletions args.go → pkg/args/grammar.go
@@ -1,31 +1,31 @@
package docli
package args

import (
"fmt"
"reflect"

"github.com/celicoo/docli/internal/docstring"
"github.com/celicoo/docli/pkg/docstring"
)

// args is both used as the grammar and the tree representation of the abstract
// Args is both used as the grammar and the tree representation of the abstract
// syntactic structure of the command-line arguments.
type args struct {
Arguments []argument `(@@|`
type Args struct {
Arguments []Argument `(@@|`
_ string `Pun|Sym|Oth|'\u0009')*`
}

type argument struct {
type Argument struct {
Identifier string `@('-'|Let|Num)+`
Value value `@@?`
Value Value `@@?`
}

type value struct {
type Value struct {
Assignment string `@'='`
String string `@(Let|Num|Pun|Sym|Sep)+`
}

// Bind binds the fields of the given struct with matching argument values.
func (a *args) Bind(c command) {
func (a *Args) Bind(c command) {
v := reflect.ValueOf(c)
// Validate that given parameter is a pointer.
if v.Kind() != reflect.Ptr {
Expand Down
Expand Up @@ -3,7 +3,7 @@ package docstring
import "github.com/celicoo/docli/internal/reger"

// Parse returns the AST of the given doc string.
func Parse(s string) (d docstring) {
func Parse(s string) (d Docstring) {
if err := reger.Build(&d).ParseString(s, &d); err != nil {
panic(err)
}
Expand Down
Expand Up @@ -5,12 +5,12 @@ import (

"github.com/DATA-DOG/godog"
"github.com/DATA-DOG/godog/gherkin"
. "github.com/celicoo/docli/internal/docstring"
. "github.com/celicoo/docli/pkg/docstring"
)

var (
doc string
docstring interface{}
docstring Docstring
)

func theDocstring(d *gherkin.DocString) error {
Expand Down
20 changes: 10 additions & 10 deletions internal/docstring/ast.go → pkg/docstring/grammar.go
Expand Up @@ -2,37 +2,37 @@ package docstring

import "github.com/iancoleman/strcase"

// docstring is both used as the grammar and the tree representation of the abstract
// Docstring is both used as the grammar and the tree representation of the abstract
// syntactic structure of a doc string.
type docstring struct {
Arguments []argument `(@@|`
type Docstring struct {
Arguments []Argument `(@@|`
_ string `Let|Num|Pun|Sym|Sep|Oth)*`
}

type argument struct {
type Argument struct {
Indentation string `@('\n' (' '|'\t')+)`
Identifiers []identifier `@@+`
Identifiers []Identifier `@@+`
}

type identifier struct {
type Identifier struct {
Name string `@('-'|Let|Num)+`
Separator string `@(',' ' ')?`
}

func (d *docstring) argument(name string) argument {
func (d *Docstring) argument(name string) Argument {
for _, a := range d.Arguments {
for _, i := range a.Identifiers {
if i.Name == name {
return a
}
}
}
return argument{}
return Argument{}
}

// Identifiers returns all identifiers of an argument if any of them match the
// given value.
func (d *docstring) Identifiers(name string) (identifiers []identifier) {
func (d *Docstring) Identifiers(name string) (identifiers []Identifier) {
a := d.argument(name)
for _, i := range a.Identifiers {
identifiers = append(identifiers, i)
Expand All @@ -42,6 +42,6 @@ func (d *docstring) Identifiers(name string) (identifiers []identifier) {

// NameAsCamelCase returns the identifier's name as camel case.
// TODO(celicoo): improve this.
func (i *identifier) NameAsCamelCase() string {
func (i *Identifier) NameAsCamelCase() string {
return strcase.ToCamel(i.Name)
}

0 comments on commit 8daa68b

Please sign in to comment.