diff --git a/CHANGELOG.md b/CHANGELOG.md index 9328f95..e3bef6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.0] - 2024-10-06 + +[0.3.0]: https://github.com/ypjama/conflictless-keepachangelog/releases/tag/v0.3.0 + +### Added + +- New command 'preview' which prints a preview of the next changelog entry. + ## [0.2.0] - 2024-10-05 [0.2.0]: https://github.com/ypjama/conflictless-keepachangelog/releases/tag/v0.2.0 diff --git a/README.md b/README.md index 4484ec0..e7b51f5 100644 --- a/README.md +++ b/README.md @@ -59,61 +59,11 @@ The commands are: create Creates a new change-file generate Generates a version entry to changelog file help Prints this help message + preview Prints a preview of the next changelog entry Use "conflictless help " for more information about that topic. ``` -`conflictless help check` - -``` txt -Usage: conflictless check [flags] - -The flags are: - - -d, --dir - Directory where to look for change-files (default: changes) -``` - -`conflictless help create` - -```txt -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 Each project should have a directory for storing unreleased changes, e.g. a directory named `changes`. In this directory developers can create _YAML_ or _JSON_ files for each merge/pull request. The filename can be freely chosen and can be derived from the branch name, e.g. `fix-broken-dependency.yml`. This way each merge/pull request would have its own `changes` file and there would not be any merge conflicts regarding the changelog. diff --git a/internal/pkg/conflictless/cli.go b/internal/pkg/conflictless/cli.go index b556eb6..d873d32 100644 --- a/internal/pkg/conflictless/cli.go +++ b/internal/pkg/conflictless/cli.go @@ -14,6 +14,7 @@ const ( commandCreate = "create" commandGen = "generate" commandHelp = "help" + commandPreview = "preview" defaultBump = BumpMinor defaultChangeFileFormat = "yml" defaultChangeTypesCSV = "changed" @@ -59,6 +60,8 @@ func CLI() { Create(&cfg) case commandGen: Generate(&cfg) + case commandPreview: + Preview(&cfg) case commandHelp: Help() default: @@ -116,6 +119,14 @@ func parseCLIFlags(cfg *Config) { defineCreateTypeFlags(cfg, cmd) defineDirFlags(cfg, cmd) defineChangeFileNameFlags(cfg, cmd) + case commandPreview: + cmd = flag.NewFlagSet(commandPreview, flag.ExitOnError) + cmd.Usage = usagePreviewOnError + + defineBumpFlags(cfg, cmd) + defineChangeLogFlags(cfg, cmd) + defineDirFlags(cfg, cmd) + defineSkipFlags(cfg, cmd) } if cmd != nil { @@ -126,43 +137,67 @@ func parseCLIFlags(cfg *Config) { } } -func defineChangeLogFlags(cfg *Config, fs *flag.FlagSet) { +func defineChangeLogFlags(cfg *Config, flagset *flag.FlagSet) { defaultChangelogFile := "CHANGELOG.md" - fs.StringVar(cfg.Flags.ChangelogFile, "changelog", defaultChangelogFile, "") - fs.StringVar(cfg.Flags.ChangelogFile, "c", defaultChangelogFile, "") + if cfg.Flags.ChangelogFile == nil { + cfg.Flags.ChangelogFile = new(string) + } + + flagset.StringVar(cfg.Flags.ChangelogFile, "changelog", defaultChangelogFile, "") + flagset.StringVar(cfg.Flags.ChangelogFile, "c", defaultChangelogFile, "") } -func defineBumpFlags(cfg *Config, fs *flag.FlagSet) { +func defineBumpFlags(cfg *Config, flagset *flag.FlagSet) { defaultBumpStr := "minor" - fs.StringVar(cfg.Flags.Bump, "bump", defaultBumpStr, "") - fs.StringVar(cfg.Flags.Bump, "b", defaultBumpStr, "") + if cfg.Flags.Bump == nil { + cfg.Flags.Bump = new(string) + } + + flagset.StringVar(cfg.Flags.Bump, "bump", defaultBumpStr, "") + flagset.StringVar(cfg.Flags.Bump, "b", defaultBumpStr, "") } -func defineDirFlags(cfg *Config, fs *flag.FlagSet) { +func defineDirFlags(cfg *Config, flagset *flag.FlagSet) { defaultDir := "changes" - fs.StringVar(cfg.Flags.Directory, "dir", defaultDir, "") - fs.StringVar(cfg.Flags.Directory, "d", defaultDir, "") + if cfg.Flags.Directory == nil { + cfg.Flags.Directory = new(string) + } + + flagset.StringVar(cfg.Flags.Directory, "dir", defaultDir, "") + flagset.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 defineFormatFlags(cfg *Config, flagset *flag.FlagSet) { + if cfg.Flags.ChangeFileFormat == nil { + cfg.Flags.ChangeFileFormat = new(string) + } + + flagset.StringVar(cfg.Flags.ChangeFileFormat, "format", defaultChangeFileFormat, "") + flagset.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 defineCreateTypeFlags(cfg *Config, flagset *flag.FlagSet) { + if cfg.Flags.ChangeTypesCsv == nil { + cfg.Flags.ChangeTypesCsv = new(string) + } + + flagset.StringVar(cfg.Flags.ChangeTypesCsv, "types", defaultChangeTypesCSV, "") + flagset.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 defineChangeFileNameFlags(cfg *Config, flagset *flag.FlagSet) { + if cfg.Flags.ChangeFileName == nil { + cfg.Flags.ChangeFileName = new(string) + } + + flagset.StringVar(cfg.Flags.ChangeFileName, "name", "", "") + flagset.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, "") +func defineSkipFlags(cfg *Config, flagset *flag.FlagSet) { + flagset.BoolVar(&cfg.Flags.SkipVersionLinks, "skip-version-links", false, "") + flagset.BoolVar(&cfg.Flags.SkipVersionLinks, "s", false, "") } diff --git a/internal/pkg/conflictless/cli_test.go b/internal/pkg/conflictless/cli_test.go index 6898a09..ecee737 100644 --- a/internal/pkg/conflictless/cli_test.go +++ b/internal/pkg/conflictless/cli_test.go @@ -5,12 +5,121 @@ import ( "net/url" "os" "os/exec" + "path/filepath" "testing" "github.com/stretchr/testify/assert" "github.com/ypjama/conflictless-keepachangelog/internal/pkg/conflictless" ) +type parseCliFlagsTestCase struct { + description string + argsAfterMain []string + expectedFlags conflictless.FlagCollection +} + +//nolint:funlen +func TestParseCLIFlags(t *testing.T) { + t.Parallel() + + originalArgs := os.Args + + bump := "major" + changelog := "changelog-for-cli-parse-test.md" + dir := "directory-for-cli-parse-test" + format := "json" + name := "foo-bar-baz" + types := "added,changed,removed" + + for _, testCase := range []parseCliFlagsTestCase{ + { + "check", + []string{"check", "--dir", dir}, + conflictless.FlagCollection{ + Bump: nil, + ChangeFileFormat: nil, + ChangeFileName: nil, + ChangelogFile: nil, + ChangeTypesCsv: nil, + Command: "check", + Directory: &dir, + SkipVersionLinks: false, + }, + }, + { + "create", + []string{"create", "-d", dir, "-f", format, "-t", types, "-n", name}, + conflictless.FlagCollection{ + Bump: nil, + ChangeFileFormat: &format, + ChangeFileName: &name, + ChangelogFile: nil, + ChangeTypesCsv: &types, + Command: "create", + Directory: &dir, + SkipVersionLinks: false, + }, + }, + { + "generate", + []string{"generate", "-c", changelog, "-s", "-d", dir, "-b", bump}, + conflictless.FlagCollection{ + Bump: &bump, + ChangeFileFormat: nil, + ChangeFileName: nil, + ChangelogFile: &changelog, + ChangeTypesCsv: nil, + Command: "generate", + Directory: &dir, + SkipVersionLinks: true, + }, + }, + { + "help", + []string{"help"}, + conflictless.FlagCollection{ + Bump: nil, + ChangeFileFormat: nil, + ChangeFileName: nil, + ChangelogFile: nil, + ChangeTypesCsv: nil, + Command: "help", + Directory: nil, + SkipVersionLinks: false, + }, + }, + { + "preview", + []string{"preview", "--changelog", changelog, "--skip-version-links", "--dir", dir, "--bump", bump}, + conflictless.FlagCollection{ + Bump: &bump, + ChangeFileFormat: nil, + ChangeFileName: nil, + ChangelogFile: &changelog, + ChangeTypesCsv: nil, + Command: "preview", + Directory: &dir, + SkipVersionLinks: true, + }, + }, + } { + t.Run(testCase.description, func(t *testing.T) { + t.Parallel() + + args := []string{"conflictless"} + args = append(args, testCase.argsAfterMain...) + os.Args = args + + cfg := new(conflictless.Config) + conflictless.ParseCLIFlags(cfg) + + os.Args = originalArgs + + assert.EqualValues(t, testCase.expectedFlags, cfg.Flags) + }) + } +} + func TestCLIWithoutArguments(t *testing.T) { t.Parallel() @@ -113,6 +222,7 @@ func TestCLIHelp(t *testing.T) { {"help check", []string{"help", "check"}, false}, {"help create", []string{"help", "create"}, false}, {"help generate", []string{"help", "generate"}, false}, + {"help preview", []string{"help", "preview"}, false}, {"help unknown", []string{"help", "unknown"}, true}, } { t.Run(testCase.description, func(t *testing.T) { @@ -156,60 +266,61 @@ func TestCLIHelp(t *testing.T) { } } -func TestCLIGenerateWithInvalidFlags(t *testing.T) { +func TestCLIWithInvalidDirFlag(t *testing.T) { t.Parallel() - if os.Getenv("TEST_CLI_GENERATE_INVALID_FLAGS") != "" { + if os.Getenv("TEST_CLI_INVALID_DIR_FLAG") != "" { conflictless.CLI() return } - stdoutFile := createTempFile(t, os.TempDir(), "test-cli-generate-with-invalid-flags-stdout") - defer os.Remove(stdoutFile.Name()) - - stderrFile := createTempFile(t, os.TempDir(), "test-cli-generate-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=^TestCLIGenerateWithInvalidFlags$", + for _, command := range []string{ + "check", "generate", - "--dir", - "rhymenocerous", - "--changelog", - "HIPPOPOTAMUS.md", - "--bump", - "steve", - ) - - cmd.Stdout = stdoutFile - cmd.Stderr = stderrFile - - cmd.Env = append(os.Environ(), "TEST_CLI_GENERATE_INVALID_FLAGS=1") - err := cmd.Run() + "preview", + } { + t.Run("invalid_dir_flag_with_command_"+command, func(t *testing.T) { + t.Parallel() - assert.Error(t, err) + stdoutFile := createTempFile(t, os.TempDir(), "test-cli-generate-with-invalid-flags-stdout") + defer os.Remove(stdoutFile.Name()) - assert.IsType(t, new(exec.ExitError), err) + stderrFile := createTempFile(t, os.TempDir(), "test-cli-generate-with-invalid-flags-stderr") + defer os.Remove(stderrFile.Name()) - exitErr := new(*exec.ExitError) - errors.As(err, exitErr) + //nolint:gosec // this is a test package so G204 doesn't really matter here. + cmd := exec.Command( + os.Args[0], + "-test.run=^TestCLIWithInvalidDirFlag$", + command, + "--dir", + "rhymenocerous", + ) - expectedCode := 2 - exitCode := (*exitErr).ExitCode() + cmd.Stdout = stdoutFile + cmd.Stderr = stderrFile - assert.Equal(t, expectedCode, exitCode, "process exited with %d, want exit status %d", expectedCode, exitCode) + cmd.Env = append(os.Environ(), "TEST_CLI_INVALID_DIR_FLAG=1") + err := cmd.Run() - stdoutData, err := os.ReadFile(stdoutFile.Name()) - assert.NoError(t, err) + assert.Error(t, err) + assert.IsType(t, new(exec.ExitError), err) - stderrData, err := os.ReadFile(stderrFile.Name()) - assert.NoError(t, err) + exitErr := new(*exec.ExitError) + errors.As(err, exitErr) + exitCode := (*exitErr).ExitCode() + expectedCode := 2 + assert.Equal(t, expectedCode, exitCode, "process exited with %d, want exit status %d", expectedCode, exitCode) - assert.Empty(t, string(stdoutData)) - assert.NotEmpty(t, string(stderrData)) + 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)) + }) + } } func TestCLICreateWithInvalidFlags(t *testing.T) { @@ -268,3 +379,64 @@ func TestCLICreateWithInvalidFlags(t *testing.T) { assert.Empty(t, string(stdoutData)) assert.NotEmpty(t, string(stderrData)) } + +func TestCliPreview(t *testing.T) { + t.Parallel() + + if os.Getenv("TEST_CLI_PREVIEW") != "" { + conflictless.CLI() + + return + } + + tmpDir := filepath.Join(os.TempDir(), "conflictless-cli-preview-test") + changesDir := filepath.Join(tmpDir, "changes-test") + + err := os.MkdirAll(changesDir, mkdirFileMode) + assert.NoError(t, err) + changelogFile := createFile(t, tmpDir, "test-cli-preview-CHANGELOG.md") + changesFile := createFile(t, changesDir, "thing-removed.json") + + defer os.RemoveAll(tmpDir) + writeDataToFile(t, []byte(`{"removed":["that thing"]}`), changesFile) + writeDataToFile(t, []byte(changelogContent), changelogFile) + + stdoutFile := createTempFile(t, os.TempDir(), "test-cli-preview-stdout") + defer os.Remove(stdoutFile.Name()) + + stderrFile := createTempFile(t, os.TempDir(), "test-cli-preview-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=^TestCliPreview$", + "preview", + "--skip-version-links", + "--dir", + changesDir, + "--changelog", + changelogFile.Name(), + "--bump", + "minor", + ) + + cmd.Stdout = stdoutFile + cmd.Stderr = stderrFile + + cmd.Env = append(os.Environ(), "TEST_CLI_PREVIEW=1") + err = cmd.Run() + + assert.NoError(t, err) + + stdoutData, err := os.ReadFile(stdoutFile.Name()) + assert.NoError(t, err) + + stderrData, err := os.ReadFile(stderrFile.Name()) + assert.NoError(t, err) + + assert.NotEmpty(t, string(stdoutData)) + assert.Empty(t, string(stderrData)) + + assert.Contains(t, string(stdoutData), "### Removed\n\n- that thing\n") +} diff --git a/internal/pkg/conflictless/config.go b/internal/pkg/conflictless/config.go index c3f5209..5a2d853 100644 --- a/internal/pkg/conflictless/config.go +++ b/internal/pkg/conflictless/config.go @@ -50,6 +50,13 @@ func (cfg *Config) SetCheckConfigsFromFlags() { cfg.SetDirectoryFromFlags() } +func (cfg *Config) SetPreviewConfigsFromFlags() error { + cfg.SetChangelogFileFromFlags() + cfg.SetDirectoryFromFlags() + + return cfg.SetBumpFromFlags() +} + func (cfg *Config) SetDirectoryFromFlags() { if cfg.Flags.Directory != nil { cfg.Directory = *cfg.Flags.Directory @@ -117,3 +124,28 @@ func (cfg *Config) SetChangeFileFormatFromFlags() error { return nil } + +func (cfg *Config) GenerateNewSection() string { + var err error + + cfg.Changelog, err = ReadChangelog(cfg) + if err != nil { + PrintErrorAndExit(err.Error(), func() {}) + } + + combined, err := scanDir(cfg.Directory) + if err != nil { + PrintErrorAndExit(err.Error(), func() {}) + } + + if combined.IsEmpty() { + PrintErrorAndExit("no changelog entries found", func() {}) + } + + newSection := DataToMarkdown(cfg, combined) + if newSection == "" { + PrintErrorAndExit("failed to generate a new version section", func() {}) + } + + return newSection +} diff --git a/internal/pkg/conflictless/conflictless_test.go b/internal/pkg/conflictless/conflictless_test.go index 61ba63c..439bd0f 100644 --- a/internal/pkg/conflictless/conflictless_test.go +++ b/internal/pkg/conflictless/conflictless_test.go @@ -1,15 +1,27 @@ package conflictless_test import ( + "bytes" + "io" "os" "testing" ) +type readWriteCapture struct { + original *os.File + read *os.File + write *os.File + outChannel chan string +} + const ( mkdirFileMode = 0o755 writeFileMode = 0o644 ) +//nolint:gochecknoglobals +var stdoutCapture *readWriteCapture + func writeDataToFile(t *testing.T, data []byte, file *os.File) { t.Helper() @@ -40,3 +52,46 @@ func createTempFile(t *testing.T, dir, pattern string) *os.File { return file } + +func startStdoutCapture(t *testing.T) { + t.Helper() + + stdoutCapture = new(readWriteCapture) + stdoutCapture.original = os.Stdout + + read, write, _ := os.Pipe() + stdoutCapture.read = read + stdoutCapture.write = write + + os.Stdout = stdoutCapture.write + + stdoutCapture.outChannel = make(chan string) + + go func() { + var buf bytes.Buffer + + _, err := io.Copy(&buf, read) + if err != nil { + t.Error(err.Error()) + } + + stdoutCapture.outChannel <- buf.String() + }() +} + +func stopStdoutCapture(t *testing.T) string { + t.Helper() + + if stdoutCapture == nil { + t.Fatal("could not stop stdout capture because stdout capture wasn't initialized") + } + + stdoutCapture.write.Close() + os.Stdout = stdoutCapture.original + + output := <-stdoutCapture.outChannel + + stdoutCapture = nil + + return output +} diff --git a/internal/pkg/conflictless/export_test.go b/internal/pkg/conflictless/export_test.go new file mode 100644 index 0000000..c1cc051 --- /dev/null +++ b/internal/pkg/conflictless/export_test.go @@ -0,0 +1,6 @@ +package conflictless + +// Export functions for tests + +//nolint:gochecknoglobals +var ParseCLIFlags = parseCLIFlags diff --git a/internal/pkg/conflictless/generate.go b/internal/pkg/conflictless/generate.go index e6dda7b..8f6ec68 100644 --- a/internal/pkg/conflictless/generate.go +++ b/internal/pkg/conflictless/generate.go @@ -15,24 +15,7 @@ func Generate(cfg *Config) { PrintErrorAndExit(err.Error(), usageGenerateOnError) } - cfg.Changelog, err = ReadChangelog(cfg) - if err != nil { - PrintErrorAndExit(err.Error(), func() {}) - } - - combined, err := scanDir(cfg.Directory) - if err != nil { - PrintErrorAndExit(err.Error(), func() {}) - } - - if combined.IsEmpty() { - PrintErrorAndExit("no changelog entries found", func() {}) - } - - newSection := DataToMarkdown(cfg, combined) - if newSection == "" { - PrintErrorAndExit("failed to generate a new version section", func() {}) - } + newSection := cfg.GenerateNewSection() err = cfg.Changelog.WriteSection(newSection) if err != nil { diff --git a/internal/pkg/conflictless/generate_test.go b/internal/pkg/conflictless/generate_test.go index c6b6b41..37803d8 100644 --- a/internal/pkg/conflictless/generate_test.go +++ b/internal/pkg/conflictless/generate_test.go @@ -16,8 +16,6 @@ func TestGenerate(t *testing.T) { defer os.RemoveAll(changesDir) - os.TempDir() - changesFile := createFile(t, changesDir, "test-generate.json") defer os.Remove(changesFile.Name()) @@ -36,6 +34,7 @@ func TestGenerate(t *testing.T) { cfg := new(conflictless.Config) cfg.Flags.Directory = &changesDir cfg.Flags.Bump = &flagValueBumpPatch + cfg.Flags.SkipVersionLinks = true cfg.ChangelogFile = changelogFile.Name() cfg.RepositoryConfigFile = gitConfigFile.Name() diff --git a/internal/pkg/conflictless/help.go b/internal/pkg/conflictless/help.go index c7fbac5..950234a 100644 --- a/internal/pkg/conflictless/help.go +++ b/internal/pkg/conflictless/help.go @@ -22,6 +22,8 @@ func Help() { usageCreate() case commandGen: usageGenerate() + case commandPreview: + usagePreview() case "": usage() default: diff --git a/internal/pkg/conflictless/preview.go b/internal/pkg/conflictless/preview.go new file mode 100644 index 0000000..be04b75 --- /dev/null +++ b/internal/pkg/conflictless/preview.go @@ -0,0 +1,11 @@ +package conflictless + +// Preview prints a preview of unreleased changes. +func Preview(cfg *Config) { + err := cfg.SetPreviewConfigsFromFlags() + if err != nil { + PrintErrorAndExit(err.Error(), usagePreviewOnError) + } + + PrintPreviewSuccess(cfg.GenerateNewSection()) +} diff --git a/internal/pkg/conflictless/preview_test.go b/internal/pkg/conflictless/preview_test.go new file mode 100644 index 0000000..749982f --- /dev/null +++ b/internal/pkg/conflictless/preview_test.go @@ -0,0 +1,50 @@ +package conflictless_test + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/ypjama/conflictless-keepachangelog/internal/pkg/conflictless" +) + +func TestPreview(t *testing.T) { + t.Parallel() + + changesDir, err := os.MkdirTemp(os.TempDir(), "changes") + assert.NoError(t, err) + + defer os.RemoveAll(changesDir) + + changesFile := createFile(t, changesDir, "test-preview.json") + defer os.Remove(changesFile.Name()) + + changelogFile := createTempFile(t, os.TempDir(), "test-preview-CHANGELOG.md") + defer os.Remove(changelogFile.Name()) + + gitConfigFile := createTempFile(t, os.TempDir(), "test-preview.gitconfig") + defer os.Remove(gitConfigFile.Name()) + + writeDataToFile(t, []byte(`{"added":["New major feature"]}`), changesFile) + writeDataToFile(t, []byte(changelogContent), changelogFile) + writeDataToFile(t, []byte(gitConfig), gitConfigFile) + + flagValueBumpPatch := "major" + + cfg := new(conflictless.Config) + cfg.Flags.Directory = &changesDir + cfg.Flags.Bump = &flagValueBumpPatch + cfg.Flags.SkipVersionLinks = true + cfg.ChangelogFile = changelogFile.Name() + cfg.RepositoryConfigFile = gitConfigFile.Name() + + startStdoutCapture(t) + + conflictless.Preview(cfg) + + output := stopStdoutCapture(t) + + assert.Contains(t, output, "```md\n") + assert.Contains(t, output, "## [2.0.0]") + assert.Contains(t, output, "### Added\n\n- New major feature\n") +} diff --git a/internal/pkg/conflictless/print.go b/internal/pkg/conflictless/print.go index dd0ceb0..ed0f965 100644 --- a/internal/pkg/conflictless/print.go +++ b/internal/pkg/conflictless/print.go @@ -60,3 +60,8 @@ func PrintCreateSuccess(cfg *Config) { //nolint:forbidigo fmt.Printf("Created new change-file '%s' successfully!\n", filepath.Join(cfg.Directory, cfg.ChangeFile)) } + +func PrintPreviewSuccess(section string) { + //nolint:forbidigo + fmt.Printf("```md\n%s```\n", section) +} diff --git a/internal/pkg/conflictless/usage.go b/internal/pkg/conflictless/usage.go index 619b284..99a0206 100644 --- a/internal/pkg/conflictless/usage.go +++ b/internal/pkg/conflictless/usage.go @@ -60,6 +60,7 @@ The commands are: create Creates a new change-file generate Generates a version entry to changelog file help Prints this help message + preview Prints a preview of the next changelog entry Use "conflictless help " for more information about that topic. ` @@ -110,6 +111,23 @@ The flags are: ) } +func usageTextForPreview() string { + return fmt.Sprintf(`Usage: conflictless preview [flags] + +The flags are: + +%s +%s +%s +%s +`, + flagDescriptionBump, + flagDescriptionChangelog, + flagDescriptionDir, + flagDescriptionSkipVersionLinks, + ) +} + func usage() { fmt.Fprint(os.Stdout, usageText()) } @@ -141,3 +159,11 @@ func usageGenerate() { func usageGenerateOnError() { fmt.Fprint(os.Stderr, usageTextForGenerate()) } + +func usagePreview() { + fmt.Fprint(os.Stdout, usageTextForPreview()) +} + +func usagePreviewOnError() { + fmt.Fprint(os.Stderr, usageTextForPreview()) +}