Skip to content

Commit

Permalink
[chore][chloggen] Run tests end-to-end (#369)
Browse files Browse the repository at this point in the history
  • Loading branch information
djaglowski committed Jul 18, 2023
1 parent db501f8 commit 9228e92
Show file tree
Hide file tree
Showing 9 changed files with 294 additions and 192 deletions.
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
}
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)
}
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 @@ var (
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())
}

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

0 comments on commit 9228e92

Please sign in to comment.