feat: add --repository and --output-dir
parent
357e869028
commit
0f47650484
98
main.go
98
main.go
|
@ -21,10 +21,11 @@ const (
|
||||||
name = "changeloguru"
|
name = "changeloguru"
|
||||||
description = "generate changelog from conventional commits"
|
description = "generate changelog from conventional commits"
|
||||||
|
|
||||||
currentPath = "."
|
currentDir = "."
|
||||||
markdownFiletype = "md"
|
markdownFiletype = "md"
|
||||||
|
|
||||||
defaultPath = currentPath
|
defaultRepositry = currentDir
|
||||||
|
defaultOutputDir = currentDir
|
||||||
defaultFilename = "CHANGELOG"
|
defaultFilename = "CHANGELOG"
|
||||||
defaultFiletype = markdownFiletype
|
defaultFiletype = markdownFiletype
|
||||||
defaultVersion = "0.1.0"
|
defaultVersion = "0.1.0"
|
||||||
|
@ -33,16 +34,15 @@ const (
|
||||||
excludeToFlag = "exclude-to"
|
excludeToFlag = "exclude-to"
|
||||||
includeToFlag = "include-to"
|
includeToFlag = "include-to"
|
||||||
versionFlag = "version"
|
versionFlag = "version"
|
||||||
|
repositoryFlag = "repository"
|
||||||
|
outputDirFlag = "output-dir"
|
||||||
filenameFlag = "filename"
|
filenameFlag = "filename"
|
||||||
filetypeFlag = "filetype"
|
filetypeFlag = "filetype"
|
||||||
verboseFlag = "verbose"
|
verboseFlag = "verbose"
|
||||||
|
|
||||||
pathArgs = "path"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
a := &action{
|
a := &action{
|
||||||
verbose: false,
|
|
||||||
flags: make(map[string]string),
|
flags: make(map[string]string),
|
||||||
args: make(map[string]string),
|
args: make(map[string]string),
|
||||||
}
|
}
|
||||||
|
@ -65,18 +65,26 @@ func main() {
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: versionFlag,
|
Name: versionFlag,
|
||||||
Usage: "generate new `VERSION`",
|
Usage: fmt.Sprintf("`VERSION` to generate, follow Semantic Versioning, example 1.0.0 (default is %s)", defaultVersion),
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: repositoryFlag,
|
||||||
|
Usage: fmt.Sprintf("`REPOSITORY` path, example /go/src/myapp (default is %s)", defaultRepositry),
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: outputDirFlag,
|
||||||
|
Usage: fmt.Sprintf("`OUTPUT_DIR` path, example /go/src/myapp (default is %s)", defaultOutputDir),
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: filenameFlag,
|
Name: filenameFlag,
|
||||||
Usage: fmt.Sprintf("output `FILENAME`, default is %s", defaultFilename),
|
Usage: fmt.Sprintf("output `FILENAME` (default is %s)", defaultFilename),
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: filetypeFlag,
|
Name: filetypeFlag,
|
||||||
Usage: fmt.Sprintf("output `FILETYPE`, default is %s", defaultFiletype),
|
Usage: fmt.Sprintf("output `FILETYPE` support md (markdown) (default is %s)", defaultFiletype),
|
||||||
},
|
},
|
||||||
&cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "verbose",
|
Name: verboseFlag,
|
||||||
Aliases: []string{"v"},
|
Aliases: []string{"v"},
|
||||||
Usage: "show what is going on",
|
Usage: "show what is going on",
|
||||||
},
|
},
|
||||||
|
@ -96,9 +104,8 @@ type action struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *action) Run(c *cli.Context) error {
|
func (a *action) Run(c *cli.Context) error {
|
||||||
// set up
|
// Set up
|
||||||
a.getFlags(c)
|
a.getFlags(c)
|
||||||
a.getArgs(c)
|
|
||||||
|
|
||||||
commits, err := a.getCommits()
|
commits, err := a.getCommits()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -116,28 +123,32 @@ func (a *action) Run(c *cli.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *action) getArgs(c *cli.Context) {
|
|
||||||
a.args[pathArgs] = defaultPath
|
|
||||||
if c.NArg() > 0 {
|
|
||||||
a.args[pathArgs] = c.Args().Get(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *action) getFlags(c *cli.Context) {
|
func (a *action) getFlags(c *cli.Context) {
|
||||||
a.verbose = c.Bool(verboseFlag)
|
a.verbose = c.Bool(verboseFlag)
|
||||||
a.flags[fromFlag] = c.String(fromFlag)
|
a.flags[fromFlag] = c.String(fromFlag)
|
||||||
a.flags[excludeToFlag] = c.String(excludeToFlag)
|
a.flags[excludeToFlag] = c.String(excludeToFlag)
|
||||||
a.flags[includeToFlag] = c.String(includeToFlag)
|
a.flags[includeToFlag] = c.String(includeToFlag)
|
||||||
a.flags[versionFlag] = c.String(versionFlag)
|
a.flags[versionFlag] = a.getFlagValue(c, versionFlag, defaultVersion)
|
||||||
a.flags[filenameFlag] = c.String(filenameFlag)
|
a.flags[repositoryFlag] = a.getFlagValue(c, repositoryFlag, defaultRepositry)
|
||||||
a.flags[filetypeFlag] = c.String(filetypeFlag)
|
a.flags[outputDirFlag] = a.getFlagValue(c, outputDirFlag, defaultOutputDir)
|
||||||
|
a.flags[filenameFlag] = a.getFlagValue(c, filenameFlag, defaultFilename)
|
||||||
|
a.flags[filetypeFlag] = a.getFlagValue(c, filetypeFlag, defaultFiletype)
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
func (a *action) getCommits() ([]git.Commit, error) {
|
||||||
path := a.args[pathArgs]
|
repository := a.flags[repositoryFlag]
|
||||||
a.log("path %s", path)
|
a.log("repository %s", repository)
|
||||||
|
|
||||||
r, err := git.NewRepository(path)
|
r, err := git.NewRepository(repository)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -168,7 +179,6 @@ func (a *action) getCommits() ([]git.Commit, error) {
|
||||||
|
|
||||||
func (a *action) getConventionalCommits(commits []git.Commit) []convention.Commit {
|
func (a *action) getConventionalCommits(commits []git.Commit) []convention.Commit {
|
||||||
conventionalCommits := make([]convention.Commit, 0, len(commits))
|
conventionalCommits := make([]convention.Commit, 0, len(commits))
|
||||||
|
|
||||||
for _, commit := range commits {
|
for _, commit := range commits {
|
||||||
conventionalCommit, err := convention.NewCommit(commit)
|
conventionalCommit, err := convention.NewCommit(commit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -183,7 +193,7 @@ func (a *action) getConventionalCommits(commits []git.Commit) []convention.Commi
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *action) generateChangelog(commits []convention.Commit) error {
|
func (a *action) generateChangelog(commits []convention.Commit) error {
|
||||||
changelogPath, _, filetype := a.getChangelogPath()
|
outputPath, _, filetype := a.getOutputPath()
|
||||||
|
|
||||||
version, err := a.getVersion()
|
version, err := a.getVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -192,39 +202,26 @@ func (a *action) generateChangelog(commits []convention.Commit) error {
|
||||||
|
|
||||||
switch filetype {
|
switch filetype {
|
||||||
case markdownFiletype:
|
case markdownFiletype:
|
||||||
return a.generateMarkdownChangelog(changelogPath, version, commits)
|
return a.generateMarkdownChangelog(outputPath, version, commits)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown filetype %s", filetype)
|
return fmt.Errorf("unknown filetype %s", filetype)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *action) getChangelogPath() (string, string, string) {
|
func (a *action) getOutputPath() (string, string, string) {
|
||||||
path := a.args[pathArgs]
|
outputDir := a.flags[outputDirFlag]
|
||||||
|
|
||||||
filename := a.flags[filenameFlag]
|
filename := a.flags[filenameFlag]
|
||||||
if filename == "" {
|
|
||||||
filename = defaultFilename
|
|
||||||
}
|
|
||||||
|
|
||||||
filetype := a.flags[filetypeFlag]
|
filetype := a.flags[filetypeFlag]
|
||||||
if filetype == "" {
|
|
||||||
filetype = defaultFiletype
|
|
||||||
}
|
|
||||||
|
|
||||||
changelogName := filename + "." + filetype
|
nameWithExt := filename + "." + filetype
|
||||||
changelogPath := filepath.Join(path, changelogName)
|
path := filepath.Join(outputDir, nameWithExt)
|
||||||
|
a.log("output path %s", path)
|
||||||
|
|
||||||
a.log("changelog path %s", changelogPath)
|
return path, filename, filetype
|
||||||
|
|
||||||
return changelogPath, filename, filetype
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *action) getVersion() (string, error) {
|
func (a *action) getVersion() (string, error) {
|
||||||
version := a.flags[versionFlag]
|
version := a.flags[versionFlag]
|
||||||
if version == "" {
|
|
||||||
version = defaultVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.HasPrefix(version, "v") {
|
if !strings.HasPrefix(version, "v") {
|
||||||
version = "v" + version
|
version = "v" + version
|
||||||
}
|
}
|
||||||
|
@ -238,9 +235,10 @@ func (a *action) getVersion() (string, error) {
|
||||||
return version, nil
|
return version, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *action) generateMarkdownChangelog(path, version string, commits []convention.Commit) error {
|
func (a *action) generateMarkdownChangelog(outputPath, version string, commits []convention.Commit) error {
|
||||||
|
// If CHANGELOG file already exist
|
||||||
var oldData string
|
var oldData string
|
||||||
bytes, err := ioutil.ReadFile(path)
|
bytes, err := ioutil.ReadFile(outputPath)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
oldData = string(bytes)
|
oldData = string(bytes)
|
||||||
}
|
}
|
||||||
|
@ -248,8 +246,8 @@ func (a *action) generateMarkdownChangelog(path, version string, commits []conve
|
||||||
markdownGenerator := changelog.NewMarkdownGenerator(oldData, version, time.Now())
|
markdownGenerator := changelog.NewMarkdownGenerator(oldData, version, time.Now())
|
||||||
newData := markdownGenerator.Generate(commits)
|
newData := markdownGenerator.Generate(commits)
|
||||||
|
|
||||||
if err := ioutil.WriteFile(path, []byte(newData), 0644); err != nil {
|
if err := ioutil.WriteFile(outputPath, []byte(newData), 0644); err != nil {
|
||||||
return fmt.Errorf("failed to write file %s: %w", path, err)
|
return fmt.Errorf("failed to write file %s: %w", outputPath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue