From 32a1b40013c56570df272f95a20f1196546f429a Mon Sep 17 00:00:00 2001 From: Nguyen Tran Hau Date: Sun, 11 Apr 2021 16:11:41 +0700 Subject: [PATCH] refactor: use better commands and flags name (#7) * build: update go.mod * refactor: replace debug with verbose * refactor: split action from main * refactor: move all cli app inside pkg cli * chore(readme): use generate command Co-authored-by: Tran Hau --- .gitignore | 3 + README.md | 4 +- go.mod | 7 +- go.sum | 19 +-- main.go | 241 +------------------------------------ pkg/cli/action.go | 71 +++++++++++ pkg/cli/action_generate.go | 120 ++++++++++++++++++ pkg/cli/app.go | 93 ++++++++++++++ 8 files changed, 307 insertions(+), 251 deletions(-) create mode 100644 pkg/cli/action.go create mode 100644 pkg/cli/action_generate.go create mode 100644 pkg/cli/app.go diff --git a/.gitignore b/.gitignore index c36342d..bf285d5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ # macOS .DS_Store +# Window +*.exe + # IntelliJ .idea/ diff --git a/README.md b/README.md index 66c9b94..59ad314 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,10 @@ GO111module=on go get github.com/haunt98/changeloguru changeloguru --help # Generate changelog v1.0.0 -changeloguru --version v1.0.0 +changeloguru generate --version v1.0.0 # Generate changelog v2.0.0 from HEAD to tag v1.0.0 -changeloguru --to v1.0.0 --version v2.0.0 +changeloguru generate --to v1.0.0 --version v2.0.0 ``` ## Thanks diff --git a/go.mod b/go.mod index 3f26be5..34647d9 100644 --- a/go.mod +++ b/go.mod @@ -6,15 +6,16 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/fatih/color v1.10.0 github.com/go-git/go-git/v5 v5.3.0 - github.com/google/go-cmp v0.5.4 // indirect + github.com/google/go-cmp v0.5.5 // indirect github.com/kevinburke/ssh_config v1.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sebdah/goldie/v2 v2.5.3 + github.com/sergi/go-diff v1.2.0 // indirect github.com/stretchr/testify v1.7.0 github.com/urfave/cli/v2 v2.3.0 golang.org/x/mod v0.4.2 - golang.org/x/net v0.0.0-20210326220855-61e056675ecf // indirect - golang.org/x/sys v0.0.0-20210326220804-49726bf1d181 // indirect + golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1 // indirect + golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index e1a511b..744ac2d 100644 --- a/go.sum +++ b/go.sum @@ -32,8 +32,8 @@ github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod github.com/go-git/go-git/v5 v5.3.0 h1:8WKMtJR2j8RntEXR/uvTKagfEt4GYlwQ7mntE4+0GWc= github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= @@ -68,8 +68,9 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y= github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= 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/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -94,8 +95,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= -golang.org/x/net v0.0.0-20210326220855-61e056675ecf h1:WUcCxqQqDT0aXO4VnQbfMvp4zh7m1Gb2clVuHUAGGRE= -golang.org/x/net v0.0.0-20210326220855-61e056675ecf/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1 h1:4qWs8cYYH6PoEFy4dfhDFgoMGkwAcETd+MmPdCPMzUc= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -108,13 +109,15 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210326220804-49726bf1d181 h1:64ChN/hjER/taL4YJuA+gpLfIMT+/NFherRZixbxOhg= -golang.org/x/sys v0.0.0-20210326220804-49726bf1d181/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/main.go b/main.go index 4a0a0ae..0c44d06 100644 --- a/main.go +++ b/main.go @@ -2,40 +2,10 @@ package main import ( "fmt" - "log" "os" - "path/filepath" - "strings" - "time" "github.com/fatih/color" - "github.com/haunt98/changeloguru/pkg/changelog" - "github.com/haunt98/changeloguru/pkg/convention" - "github.com/haunt98/changeloguru/pkg/git" - "github.com/urfave/cli/v2" - "golang.org/x/mod/semver" -) - -const ( - appName = "changeloguru" - - currentDir = "." - markdownFiletype = "md" - - defaultRepository = currentDir - defaultOutput = currentDir - defaultFilename = "CHANGELOG" - defaultFiletype = markdownFiletype - - fromFlag = "from" - toFlag = "to" - versionFlag = "version" - scopeFlag = "scope" - repositoryFlag = "repository" - outputFlag = "output" - filenameFlag = "filename" - filetypeFlag = "filetype" - debugFlag = "debug" + "github.com/haunt98/changeloguru/pkg/cli" ) var ( @@ -43,215 +13,10 @@ var ( ) func main() { - a := &action{} - - app := &cli.App{ - Name: appName, - Usage: "generate changelog from conventional commits", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: fromFlag, - Usage: "generate from `COMMIT`", - }, - &cli.StringFlag{ - Name: toFlag, - Usage: "generate to `COMMIT`", - }, - &cli.StringFlag{ - Name: versionFlag, - Usage: "`VERSION` to generate, follow Semantic Versioning", - }, - &cli.StringSliceFlag{ - Name: scopeFlag, - Usage: "scope to generate", - }, - &cli.StringFlag{ - Name: repositoryFlag, - Usage: "`REPOSITORY` directory path", - DefaultText: defaultRepository, - }, - &cli.StringFlag{ - Name: outputFlag, - Usage: "`OUTPUT` directory path", - DefaultText: defaultOutput, - }, - &cli.StringFlag{ - Name: filenameFlag, - Usage: "output `FILENAME`", - DefaultText: defaultFilename, - }, - &cli.StringFlag{ - Name: filetypeFlag, - Usage: "output `FILETYPE`", - DefaultText: defaultFiletype, - }, - &cli.BoolFlag{ - Name: debugFlag, - Aliases: []string{"d"}, - Usage: "show debugging info", - }, - }, - Action: a.Run, - } - + app := cli.NewApp() if err := app.Run(os.Args); err != nil { // Highlight error - fmtErr.Printf("[%s error]: ", appName) + fmtErr.Printf("[%s error]: ", cli.AppName) fmt.Printf("%s\n", err.Error()) } } - -type action struct { - flags struct { - debug bool - from string - to string - version string - scopes map[string]struct{} - repository string - output string - filename string - filetype string - } -} - -func (a *action) Run(c *cli.Context) error { - // Show help if there is nothing - if c.NArg() == 0 && c.NumFlags() == 0 { - return cli.ShowAppHelp(c) - } - - a.getFlags(c) - - commits, err := a.getCommits() - if err != nil { - return err - } - - conventionalCommits := a.getConventionalCommits(commits) - - if err := a.generateChangelog(conventionalCommits); err != nil { - return err - } - - return nil -} - -func (a *action) getFlags(c *cli.Context) { - a.flags.debug = c.Bool(debugFlag) - a.flags.from = c.String(fromFlag) - a.flags.to = c.String(toFlag) - a.flags.version = c.String(versionFlag) - - a.flags.scopes = make(map[string]struct{}) - for _, scope := range c.StringSlice(scopeFlag) { - a.flags.scopes[scope] = struct{}{} - } - - a.flags.repository = a.getFlagValue(c, repositoryFlag, defaultRepository) - a.flags.output = a.getFlagValue(c, outputFlag, defaultOutput) - a.flags.filename = a.getFlagValue(c, filenameFlag, defaultFilename) - a.flags.filetype = a.getFlagValue(c, filetypeFlag, defaultFiletype) - - if a.flags.debug { - a.logDebug("flags %+v", a.flags) - } -} - -func (a *action) getFlagValue(c *cli.Context, flag, fallback string) string { - value := c.String(flag) - if value == "" { - value = fallback - } - - return value -} - -func (a *action) getCommits() ([]git.Commit, error) { - r, err := git.NewRepository(a.flags.repository) - if err != nil { - return nil, err - } - - return r.Log(a.flags.from, a.flags.to) -} - -func (a *action) getConventionalCommits(commits []git.Commit) []convention.Commit { - conventionalCommits := make([]convention.Commit, 0, len(commits)) - for _, commit := range commits { - conventionalCommit, err := convention.NewCommit(commit) - if err != nil { - a.logDebug("failed to new conventional commits %+v: %s", commit, err) - continue - } - - conventionalCommits = append(conventionalCommits, conventionalCommit) - } - - return conventionalCommits -} - -func (a *action) generateChangelog(commits []convention.Commit) error { - realOutput := a.getRealOutput() - - version, err := a.getVersion() - if err != nil { - return err - } - - switch a.flags.filetype { - case markdownFiletype: - return a.generateMarkdownChangelog(realOutput, version, commits) - default: - return fmt.Errorf("unknown filetype %s", a.flags.filetype) - } -} - -func (a *action) getRealOutput() string { - nameWithExt := a.flags.filename + "." + a.flags.filetype - realOutput := filepath.Join(a.flags.output, nameWithExt) - - return realOutput -} - -func (a *action) getVersion() (string, error) { - if a.flags.version == "" { - return "", fmt.Errorf("empty version") - } - - if !strings.HasPrefix(a.flags.version, "v") { - a.flags.version = "v" + a.flags.version - } - - if !semver.IsValid(a.flags.version) { - return "", fmt.Errorf("invalid semver %s", a.flags.version) - } - - a.logDebug("version %s", a.flags.version) - - return a.flags.version, nil -} - -func (a *action) generateMarkdownChangelog(output, version string, commits []convention.Commit) error { - // If CHANGELOG file already exist - var oldData string - bytes, err := os.ReadFile(output) - if err == nil { - oldData = string(bytes) - } - - markdownGenerator := changelog.NewMarkdownGenerator(oldData, version, time.Now()) - newData := markdownGenerator.Generate(commits, a.flags.scopes) - - if err := os.WriteFile(output, []byte(newData), 0o644); err != nil { - return fmt.Errorf("failed to write file %s: %w", output, err) - } - - return nil -} - -func (a *action) logDebug(format string, v ...interface{}) { - if a.flags.debug { - log.Printf(format, v...) - } -} diff --git a/pkg/cli/action.go b/pkg/cli/action.go new file mode 100644 index 0000000..c06aaba --- /dev/null +++ b/pkg/cli/action.go @@ -0,0 +1,71 @@ +package cli + +import ( + "log" + + "github.com/urfave/cli/v2" +) + +const ( + currentDir = "." + markdownFiletype = "md" + + defaultRepository = currentDir + defaultOutput = currentDir + defaultFilename = "CHANGELOG" + defaultFiletype = markdownFiletype +) + +type action struct { + flags struct { + verbose bool + from string + to string + version string + scopes map[string]struct{} + repository string + output string + filename string + filetype string + } +} + +func (a *action) RunHelp(c *cli.Context) error { + return cli.ShowAppHelp(c) +} + +func (a *action) getFlags(c *cli.Context) { + a.flags.verbose = c.Bool(verboseFlag) + a.flags.from = c.String(fromFlag) + a.flags.to = c.String(toFlag) + a.flags.version = c.String(versionFlag) + + a.flags.scopes = make(map[string]struct{}) + for _, scope := range c.StringSlice(scopeFlag) { + a.flags.scopes[scope] = struct{}{} + } + + a.flags.repository = a.getFlagValue(c, repositoryFlag, defaultRepository) + a.flags.output = a.getFlagValue(c, outputFlag, defaultOutput) + a.flags.filename = a.getFlagValue(c, filenameFlag, defaultFilename) + a.flags.filetype = a.getFlagValue(c, filetypeFlag, defaultFiletype) + + if a.flags.verbose { + a.log("flags %+v", a.flags) + } +} + +func (a *action) getFlagValue(c *cli.Context, flag, fallback string) string { + value := c.String(flag) + if value == "" { + value = fallback + } + + return value +} + +func (a *action) log(format string, v ...interface{}) { + if a.flags.verbose { + log.Printf(format, v...) + } +} diff --git a/pkg/cli/action_generate.go b/pkg/cli/action_generate.go new file mode 100644 index 0000000..db4436c --- /dev/null +++ b/pkg/cli/action_generate.go @@ -0,0 +1,120 @@ +package cli + +import ( + "fmt" + "os" + "path/filepath" + "strings" + "time" + + "github.com/haunt98/changeloguru/pkg/changelog" + "github.com/haunt98/changeloguru/pkg/convention" + "github.com/haunt98/changeloguru/pkg/git" + "github.com/urfave/cli/v2" + "golang.org/x/mod/semver" +) + +func (a *action) RunGenerate(c *cli.Context) error { + // Show help if there is nothing + if c.NumFlags() == 0 { + return cli.ShowAppHelp(c) + } + + a.getFlags(c) + + commits, err := a.getCommits() + if err != nil { + return err + } + + conventionalCommits := a.getConventionalCommits(commits) + + if err := a.generateChangelog(conventionalCommits); err != nil { + return err + } + + return nil +} + +func (a *action) getCommits() ([]git.Commit, error) { + r, err := git.NewRepository(a.flags.repository) + if err != nil { + return nil, err + } + + return r.Log(a.flags.from, a.flags.to) +} + +func (a *action) getConventionalCommits(commits []git.Commit) []convention.Commit { + conventionalCommits := make([]convention.Commit, 0, len(commits)) + for _, commit := range commits { + conventionalCommit, err := convention.NewCommit(commit) + if err != nil { + a.log("failed to new conventional commits %+v: %s", commit, err) + continue + } + + conventionalCommits = append(conventionalCommits, conventionalCommit) + } + + return conventionalCommits +} + +func (a *action) generateChangelog(commits []convention.Commit) error { + realOutput := a.getRealOutput() + + version, err := a.getVersion() + if err != nil { + return err + } + + switch a.flags.filetype { + case markdownFiletype: + return a.generateMarkdownChangelog(realOutput, version, commits) + default: + return fmt.Errorf("unknown filetype %s", a.flags.filetype) + } +} + +func (a *action) getRealOutput() string { + nameWithExt := a.flags.filename + "." + a.flags.filetype + realOutput := filepath.Join(a.flags.output, nameWithExt) + + return realOutput +} + +func (a *action) getVersion() (string, error) { + if a.flags.version == "" { + return "", fmt.Errorf("empty version") + } + + if !strings.HasPrefix(a.flags.version, "v") { + a.flags.version = "v" + a.flags.version + } + + if !semver.IsValid(a.flags.version) { + return "", fmt.Errorf("invalid semver %s", a.flags.version) + } + + a.log("version %s", a.flags.version) + + return a.flags.version, nil +} + +func (a *action) generateMarkdownChangelog(output, version string, commits []convention.Commit) error { + // If CHANGELOG file already exist + var oldData string + bytes, err := os.ReadFile(output) + if err == nil { + oldData = string(bytes) + } + + markdownGenerator := changelog.NewMarkdownGenerator(oldData, version, time.Now()) + newData := markdownGenerator.Generate(commits, a.flags.scopes) + + if err := os.WriteFile(output, []byte(newData), 0o644); err != nil { + return fmt.Errorf("failed to write file %s: %w", output, err) + } + + return nil +} diff --git a/pkg/cli/app.go b/pkg/cli/app.go new file mode 100644 index 0000000..3724e55 --- /dev/null +++ b/pkg/cli/app.go @@ -0,0 +1,93 @@ +package cli + +import "github.com/urfave/cli/v2" + +const ( + AppName = "changeloguru" + + // flags + fromFlag = "from" + toFlag = "to" + versionFlag = "version" + scopeFlag = "scope" + repositoryFlag = "repository" + outputFlag = "output" + filenameFlag = "filename" + filetypeFlag = "filetype" + verboseFlag = "verbose" + + // commands + generateCommand = "generate" +) + +var ( + // flags + verboseAliases = []string{"v"} + + // commands + generateAliases = []string{"gen"} +) + +func NewApp() *cli.App { + a := &action{} + + app := &cli.App{ + Name: AppName, + Usage: "generate changelog from conventional commits", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: verboseFlag, + Aliases: verboseAliases, + Usage: "show what is going on", + }, + }, + Commands: []*cli.Command{ + { + Name: generateCommand, + Aliases: generateAliases, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: fromFlag, + Usage: "generate from `COMMIT`", + }, + &cli.StringFlag{ + Name: toFlag, + Usage: "generate to `COMMIT`", + }, + &cli.StringFlag{ + Name: versionFlag, + Usage: "`VERSION` to generate, follow Semantic Versioning", + }, + &cli.StringSliceFlag{ + Name: scopeFlag, + Usage: "scope to generate", + }, + &cli.StringFlag{ + Name: repositoryFlag, + Usage: "`REPOSITORY` directory path", + DefaultText: defaultRepository, + }, + &cli.StringFlag{ + Name: outputFlag, + Usage: "`OUTPUT` directory path", + DefaultText: defaultOutput, + }, + &cli.StringFlag{ + Name: filenameFlag, + Usage: "output `FILENAME`", + DefaultText: defaultFilename, + }, + &cli.StringFlag{ + Name: filetypeFlag, + Usage: "output `FILETYPE`", + DefaultText: defaultFiletype, + }, + }, + Action: a.RunGenerate, + }, + }, + Action: a.RunHelp, + } + + return app +}