Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new command to create a change-file #3

Merged
merged 14 commits into from
Oct 5, 2024
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.54.1
version: v1.61.0
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ coverage.xml

# Gorelease output
dist/

# VSCode configurations.
.vscode/launch.json
9 changes: 4 additions & 5 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
run:
go: '1.21.3'
go: '1.23.2'

linters:
disable-all: false
Expand All @@ -14,21 +14,21 @@ linters:
- bodyclose
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- err113
- errcheck
- errchkjson
- errname
- errorlint
- execinquery
- exhaustive
- exhaustruct
- exportloopref
- forbidigo
- forcetypeassert
- funlen
Expand All @@ -42,12 +42,10 @@ linters:
- gocyclo
- godot
- godox
- goerr113
- gofmt
- gofumpt
- goheader
- goimports
- gomnd
- gomoddirectives
- gomodguard
- goprintffuncname
Expand All @@ -66,6 +64,7 @@ linters:
- makezero
- mirror
- misspell
- mnd
- musttag
- nakedret
- nestif
Expand Down
44 changes: 34 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,38 +50,62 @@ Usage: conflictless <command> [flags]
The commands are:

check Checks that change-files are valid
create Creates a new change-file
generate Generates a version entry to changelog file
help Prints this help message

Use "conflictless help <topic>" for more information about that topic.
```

`conflictless help generate`
`conflictless help check`

``` txt
Usage: conflictless generate [flags]
Usage: conflictless check [flags]

The flags are:

-b, --bump
Bump version patch/minor/major (default: minor)
-c, --changelog
Changelog file (default: CHANGELOG.md)
-d, --dir
Directory where to look for change-files (default: changes)
-s, --skip-version-links
Skip version links in changelog file (default: false)
```

`conflictless help check`
`conflictless help create`

```txt
Usage: conflictless check [flags]
Usage: conflictless create [flags]

The flags are:

-d, --dir
Directory where the change-file should be created (default: changes)
-f, --format
File format and extension yml/yaml/json for the change-file (default: yml)
-t, --types
Types of changes you want for the change-file (default: changed)

Multiple values can be given by separating values with commas.
Example: '--format added,changed,deprecated,removed,fixed,security'.
-n, --name
Name for the change-file without file extension

If this flag is not given the name will be derived from the name of the
current git branch you're on.
```

`conflictless help generate`

``` txt
Usage: conflictless generate [flags]

The flags are:

-b, --bump
Bump version patch/minor/major (default: minor)
-c, --changelog
Changelog file (default: CHANGELOG.md)
-d, --dir
Directory where to look for change-files (default: changes)
-s, --skip-version-links
Skip version links in changelog file (default: false)
```

## Suggested workflow
Expand Down
3 changes: 3 additions & 0 deletions changes/2-create-a-change-file.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
added:
- "New command 'create'"
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/ypjama/conflictless-keepachangelog

go 1.21.3
go 1.23.2

require (
github.com/stretchr/testify v1.3.0
Expand All @@ -13,4 +13,5 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
golang.org/x/text v0.19.0 // indirect
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
3 changes: 0 additions & 3 deletions internal/pkg/conflictless/bump_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ func TestInitialVersion(t *testing.T) {
{"major", conflictless.BumpMajor, "1.0.0"},
{"unknown", conflictless.Bump(123), "0.1.0"},
} {
// Reinitialise testCase for parallel testing.
testCase := testCase

t.Run(testCase.description, func(t *testing.T) {
t.Parallel()

Expand Down
1 change: 0 additions & 1 deletion internal/pkg/conflictless/changelog.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (

const (
minSemverParts = 3
writeFileMode = 0o644
)

type Changelog struct {
Expand Down
60 changes: 48 additions & 12 deletions internal/pkg/conflictless/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,43 @@ import (
)

const (
argIdxCommand = 1
argIdxHelpTopic = 2
exitCodeSuccess = 0
exitCodeGeneralError = 1
exitCodeMisuseError = 2
commandCheck = "check"
commandGen = "generate"
commandHelp = "help"
defaultBump = BumpMinor
minArguments = 2
argIdxCommand = 1
argIdxHelpTopic = 2
commandCheck = "check"
commandCreate = "create"
commandGen = "generate"
commandHelp = "help"
defaultBump = BumpMinor
defaultChangeFileFormat = "yml"
defaultChangeTypesCSV = "changed"
defaultDirectory = "changes"
exitCodeGeneralError = 1
exitCodeMisuseError = 2
exitCodeSuccess = 0
minArguments = 2
)

func CLI() {
cfg := Config{
Flags: FlagCollection{
Bump: new(string),
ChangeFileFormat: new(string),
ChangeFileName: new(string),
ChangelogFile: new(string),
ChangeTypesCsv: new(string),
Command: "",
Directory: new(string),
SkipVersionLinks: false,
},
Bump: defaultBump,
Changelog: nil,
ChangelogFile: "CHANGELOG.md",
ChangeFile: "",
ChangeTypesCsv: defaultChangeTypesCSV,
ChangeFileFormat: defaultChangeFileFormat,
Directory: defaultDirectory,
RepositoryConfigFile: ".git/config",
Changelog: nil,
Directory: "changes",
RepositoryHeadFile: ".git/HEAD",
}
parseCLIFlags(&cfg)

Expand All @@ -44,6 +55,8 @@ func CLI() {
switch cfg.Flags.Command {
case commandCheck:
Check(&cfg)
case commandCreate:
Create(&cfg)
case commandGen:
Generate(&cfg)
case commandHelp:
Expand Down Expand Up @@ -95,6 +108,14 @@ func parseCLIFlags(cfg *Config) {
cmd.Usage = usageCheckOnError

defineDirFlags(cfg, cmd)
case commandCreate:
cmd = flag.NewFlagSet(commandCreate, flag.ExitOnError)
cmd.Usage = usageCreateOnError

defineFormatFlags(cfg, cmd)
defineCreateTypeFlags(cfg, cmd)
defineDirFlags(cfg, cmd)
defineChangeFileNameFlags(cfg, cmd)
}

if cmd != nil {
Expand Down Expand Up @@ -126,6 +147,21 @@ func defineDirFlags(cfg *Config, fs *flag.FlagSet) {
fs.StringVar(cfg.Flags.Directory, "d", defaultDir, "")
}

func defineFormatFlags(cfg *Config, fs *flag.FlagSet) {
fs.StringVar(cfg.Flags.ChangeFileFormat, "format", defaultChangeFileFormat, "")
fs.StringVar(cfg.Flags.ChangeFileFormat, "f", defaultChangeFileFormat, "")
}

func defineCreateTypeFlags(cfg *Config, fs *flag.FlagSet) {
fs.StringVar(cfg.Flags.ChangeTypesCsv, "types", defaultChangeTypesCSV, "")
fs.StringVar(cfg.Flags.ChangeTypesCsv, "t", defaultChangeTypesCSV, "")
}

func defineChangeFileNameFlags(cfg *Config, fs *flag.FlagSet) {
fs.StringVar(cfg.Flags.ChangeFileName, "name", "", "")
fs.StringVar(cfg.Flags.ChangeFileName, "n", "", "")
}

func defineSkipFlags(cfg *Config, fs *flag.FlagSet) {
fs.BoolVar(&cfg.Flags.SkipVersionLinks, "skip-version-links", false, "")
fs.BoolVar(&cfg.Flags.SkipVersionLinks, "s", false, "")
Expand Down
61 changes: 58 additions & 3 deletions internal/pkg/conflictless/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,10 @@ func TestCLIHelp(t *testing.T) {
}{
{"help", []string{"help"}, false},
{"help check", []string{"help", "check"}, false},
{"help create", []string{"help", "create"}, false},
{"help generate", []string{"help", "generate"}, false},
{"help unknown", []string{"help", "unknown"}, true},
} {
// Reinitialise testCase for parallel testing.
testCase := testCase

t.Run(testCase.description, func(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -213,3 +211,60 @@ func TestCLIGenerateWithInvalidFlags(t *testing.T) {
assert.Empty(t, string(stdoutData))
assert.NotEmpty(t, string(stderrData))
}

func TestCLICreateWithInvalidFlags(t *testing.T) {
t.Parallel()

if os.Getenv("TEST_CLI_CREATE_INVALID_FLAGS") != "" {
conflictless.CLI()

return
}

stdoutFile := createTempFile(t, os.TempDir(), "test-cli-create-with-invalid-flags-stdout")
defer os.Remove(stdoutFile.Name())

stderrFile := createTempFile(t, os.TempDir(), "test-cli-create-with-invalid-flags-stderr")
defer os.Remove(stderrFile.Name())

//nolint:gosec // this is a test package so G204 doesn't really matter here.
cmd := exec.Command(
os.Args[0],
"-test.run=^TestCLICreateWithInvalidFlags$",
"create",
"--dir",
"jaybird",
"--format",
"xml",
"--types",
"added,changed",
"--name",
"harmless-catfish",
)

cmd.Stdout = stdoutFile
cmd.Stderr = stderrFile

cmd.Env = append(os.Environ(), "TEST_CLI_CREATE_INVALID_FLAGS=1")
err := cmd.Run()

assert.Error(t, err)
assert.IsType(t, new(exec.ExitError), err)

exitErr := new(*exec.ExitError)
errors.As(err, exitErr)

expectedCode := 2
exitCode := (*exitErr).ExitCode()

assert.Equal(t, expectedCode, exitCode, "process exited with %d, want exit status %d", expectedCode, exitCode)

stdoutData, err := os.ReadFile(stdoutFile.Name())
assert.NoError(t, err)

stderrData, err := os.ReadFile(stderrFile.Name())
assert.NoError(t, err)

assert.Empty(t, string(stdoutData))
assert.NotEmpty(t, string(stderrData))
}
Loading
Loading