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

[chore][chloggen] Run tests end-to-end #369

Merged
merged 1 commit into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions chloggen/cmd/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
package cmd

import (
"bytes"
"fmt"
"io"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -126,3 +128,24 @@ func writeEntryYAML(ctx chlog.Context, filename string, entry *chlog.Entry) erro
path := filepath.Join(ctx.ChloggenDir, filename)
return os.WriteFile(path, entryBytes, os.FileMode(0755))
}

func runCobra(t *testing.T, args ...string) (string, string) {
cmd := rootCmd()

outBytes := bytes.NewBufferString("")
cmd.SetOut(outBytes)

errBytes := bytes.NewBufferString("")
cmd.SetErr(errBytes)

cmd.SetArgs(args)
cmd.Execute() // nolint:errcheck

out, ioErr := io.ReadAll(outBytes)
require.NoError(t, ioErr, "read stdout")

err, ioErr := io.ReadAll(errBytes)
require.NoError(t, ioErr, "read stderr")

return string(out), string(err)
}
69 changes: 31 additions & 38 deletions chloggen/cmd/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,61 +15,54 @@
package cmd

import (
"fmt"
"log"
"os"
"path/filepath"
"strings"

"github.com/spf13/cobra"

"go.opentelemetry.io/build-tools/chloggen/internal/chlog"
)

var (
filename string
)

var newCmd = &cobra.Command{
Use: "new",
Short: "Creates new change file",
RunE: func(cmd *cobra.Command, args []string) error {
return initialize(chlogCtx, filename)
},
}

func initialize(ctx chlog.Context, filename string) error {
path := filepath.Join(ctx.ChloggenDir, cleanFileName(filename))
var pathWithExt string
switch ext := filepath.Ext(path); ext {
case ".yaml":
pathWithExt = path
case ".yml":
pathWithExt = strings.TrimSuffix(path, ".yml") + ".yaml"
default:
pathWithExt = path + ".yaml"
}
func newCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "new",
Short: "Creates new change file",
RunE: func(cmd *cobra.Command, args []string) error {
path := filepath.Join(chlogCtx.ChloggenDir, cleanFileName(filename))
var pathWithExt string
switch ext := filepath.Ext(path); ext {
case ".yaml":
pathWithExt = path
case ".yml":
pathWithExt = strings.TrimSuffix(path, ".yml") + ".yaml"
default:
pathWithExt = path + ".yaml"
}

templateBytes, err := os.ReadFile(filepath.Clean(ctx.TemplateYAML))
if err != nil {
return err
templateBytes, err := os.ReadFile(filepath.Clean(chlogCtx.TemplateYAML))
if err != nil {
return err
}
err = os.WriteFile(pathWithExt, templateBytes, os.FileMode(0755))
if err != nil {
return err
}

Check warning on line 52 in chloggen/cmd/new.go

View check run for this annotation

Codecov / codecov/patch

chloggen/cmd/new.go#L51-L52

Added lines #L51 - L52 were not covered by tests
cmd.Printf("Changelog entry template copied to: %s\n", pathWithExt)
return nil
},
}
err = os.WriteFile(pathWithExt, templateBytes, os.FileMode(0755))
if err != nil {
return err
cmd.Flags().StringVarP(&filename, "filename", "f", "", "name of the file to add")
if err := cmd.MarkFlagRequired("filename"); err != nil {
cmd.PrintErrf("could not mark filename flag as required: %v", err)
os.Exit(1)

Check warning on line 60 in chloggen/cmd/new.go

View check run for this annotation

Codecov / codecov/patch

chloggen/cmd/new.go#L59-L60

Added lines #L59 - L60 were not covered by tests
}
fmt.Printf("Changelog entry template copied to: %s\n", pathWithExt)
return nil
return cmd
}

func cleanFileName(filename string) string {
replace := strings.NewReplacer("/", "_", "\\", "_")
return replace.Replace(filename)
}

func init() {
newCmd.Flags().StringVarP(&filename, "filename", "f", "", "name of the file to add")
if err := newCmd.MarkFlagRequired("filename"); err != nil {
log.Fatalf("could not mark filename flag as required: %v", err)
}
}
96 changes: 56 additions & 40 deletions chloggen/cmd/new_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,53 +15,69 @@
package cmd

import (
"fmt"
"path/filepath"
"testing"

"github.com/stretchr/testify/require"
"github.com/stretchr/testify/assert"

"go.opentelemetry.io/build-tools/chloggen/internal/chlog"
)

func TestNew(t *testing.T) {
tests := []struct {
name string
filename string
}{
{
name: "no_extension",
filename: "my-change",
},
{
name: "yaml_extension",
filename: "some-change.yaml",
},
{
name: "yml_extension",
filename: "some-change.yml",
},
{
name: "replace_forward_slash",
filename: "replace/forward/slash",
},
{
name: "name_with_period",
filename: "not.an.extension",
},
{
name: "bad_extension",
filename: "my-change.txt",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
ctx := setupTestDir(t, []*chlog.Entry{})
require.NoError(t, initialize(ctx, tc.filename))
require.Error(t, validate(ctx), "The new entry should not be valid without user input")
})
}
const newUsage = `Usage:
chloggen new [flags]

Flags:
-f, --filename string name of the file to add
-h, --help help for new

Global Flags:
--chloggen-directory string directory containing unreleased change log entries (default: .chloggen)`

func TestNewCommand(t *testing.T) {
var out, err string

out, err = runCobra(t, "new", "--help")
assert.Contains(t, out, newUsage)
assert.Empty(t, err)

out, err = runCobra(t, "new")
assert.Contains(t, out, newUsage)
assert.Contains(t, err, `required flag(s) "filename" not set`)

out, err = runCobra(t, "new", "--filename", "my-change")
assert.Contains(t, out, newUsage)
assert.Contains(t, err, `no such file or directory`)

// Set up a test directory to which we will write new files
chlogCtx = setupTestDir(t, []*chlog.Entry{})

out, err = runCobra(t, "new", "--filename", "my-change")
assert.Contains(t, out, fmt.Sprintf("Changelog entry template copied to: %s", filepath.Join(chlogCtx.ChloggenDir, "my-change.yaml")))
assert.Empty(t, err)

out, err = runCobra(t, "new", "--filename", "some-change.yaml")
assert.Contains(t, out, fmt.Sprintf("Changelog entry template copied to: %s", filepath.Join(chlogCtx.ChloggenDir, "some-change.yaml")))
assert.Empty(t, err)

out, err = runCobra(t, "new", "--filename", "some-change.yml")
assert.Contains(t, out, fmt.Sprintf("Changelog entry template copied to: %s", filepath.Join(chlogCtx.ChloggenDir, "some-change.yaml")))
assert.Empty(t, err)

out, err = runCobra(t, "new", "--filename", "replace/forward/slash")
assert.Contains(t, out, fmt.Sprintf("Changelog entry template copied to: %s", filepath.Join(chlogCtx.ChloggenDir, "replace_forward_slash.yaml")))
assert.Empty(t, err)

out, err = runCobra(t, "new", "--filename", "not.an.extension")
assert.Contains(t, out, fmt.Sprintf("Changelog entry template copied to: %s", filepath.Join(chlogCtx.ChloggenDir, "not.an.extension.yaml")))
assert.Empty(t, err)

out, err = runCobra(t, "new", "--filename", "my-change.txt")
assert.Contains(t, out, fmt.Sprintf("Changelog entry template copied to: %s", filepath.Join(chlogCtx.ChloggenDir, "my-change.txt.yaml")))
assert.Empty(t, err)
}

func TestCleanFilename(t *testing.T) {
require.Equal(t, "fix_some_bug", cleanFileName("fix/some_bug"))
require.Equal(t, "fix_some_bug", cleanFileName("fix\\some_bug"))
assert.Equal(t, "fix_some_bug", cleanFileName("fix/some_bug"))
assert.Equal(t, "fix_some_bug", cleanFileName("fix\\some_bug"))
}
37 changes: 22 additions & 15 deletions chloggen/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,36 @@
chlogCtx chlog.Context
)

var rootCmd = &cobra.Command{
Use: "chloggen",
Short: "Updates CHANGELOG.MD to include all new changes",
Long: `chloggen is a tool used to automate the generation of CHANGELOG files using individual yaml files as the source.`,
func rootCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "chloggen",
Short: "Updates CHANGELOG.MD to include all new changes",
Long: `chloggen is a tool used to automate the generation of CHANGELOG files using individual yaml files as the source.`,
}
cmd.PersistentFlags().StringVar(&chloggenDir, "chloggen-directory", "", "directory containing unreleased change log entries (default: .chloggen)")
cmd.AddCommand(newCmd())
cmd.AddCommand(updateCmd())
cmd.AddCommand(validateCmd())
return cmd
}

func Execute() {
cobra.CheckErr(rootCmd.Execute())
cobra.CheckErr(rootCmd().Execute())

Check warning on line 42 in chloggen/cmd/root.go

View check run for this annotation

Codecov / codecov/patch

chloggen/cmd/root.go#L42

Added line #L42 was not covered by tests
}

func init() {
cobra.OnInitialize(initConfig)
}

func initConfig() {
// Don't override if already set in tests
var uninitialized chlog.Context
if chlogCtx != uninitialized {
return
}

if chloggenDir == "" {
chloggenDir = ".chloggen"
}
chlogCtx = chlog.New(chlog.RepoRoot(), chlog.WithChloggenDir(chloggenDir))
}

func init() {
cobra.OnInitialize(initConfig)

rootCmd.PersistentFlags().StringVar(&chloggenDir, "chloggen-directory", "", "directory containing unreleased change log entries (default: .chloggen)")

rootCmd.AddCommand(newCmd)
rootCmd.AddCommand(updateCmd)
rootCmd.AddCommand(validateCmd)
}
51 changes: 51 additions & 0 deletions chloggen/cmd/root_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
"testing"

"github.com/stretchr/testify/assert"
)

const rootUsage = `chloggen is a tool used to automate the generation of CHANGELOG files using individual yaml files as the source.

Usage:
chloggen [command]

Available Commands:
completion Generate the autocompletion script for the specified shell
help Help about any command
new Creates new change file
update Updates CHANGELOG.MD to include all new changes
validate Validates the files in the changelog directory

Flags:
--chloggen-directory string directory containing unreleased change log entries (default: .chloggen)
-h, --help help for chloggen

Use "chloggen [command] --help" for more information about a command.`

func TestRootCommand(t *testing.T) {
var out, err string

out, err = runCobra(t)
assert.Contains(t, out, rootUsage)
assert.Empty(t, err)

out, err = runCobra(t, "--help")
assert.Contains(t, out, rootUsage)
assert.Empty(t, err)
}
Loading
Loading