Add --directory/-d options to `helm create`

Signed-off-by: quantumsheep <nathanael.dmc@outlook.fr>
pull/9847/head
quantumsheep 4 years ago
parent fa558f7843
commit 8b050bb9ea
No known key found for this signature in database
GPG Key ID: D3CA3911FBA1E8BF

@ -52,6 +52,7 @@ will be overwritten, but other files will be left alone.
type createOptions struct { type createOptions struct {
starter string // --starter starter string // --starter
directory string // --directory
name string name string
starterDir string starterDir string
} }
@ -81,6 +82,7 @@ func newCreateCmd(out io.Writer) *cobra.Command {
} }
cmd.Flags().StringVarP(&o.starter, "starter", "p", "", "the name or absolute path to Helm starter scaffold") cmd.Flags().StringVarP(&o.starter, "starter", "p", "", "the name or absolute path to Helm starter scaffold")
cmd.Flags().StringVarP(&o.directory, "directory", "d", "", "the location of the created chart")
return cmd return cmd
} }
@ -97,6 +99,11 @@ func (o *createOptions) run(out io.Writer) error {
APIVersion: chart.APIVersionV2, APIVersion: chart.APIVersionV2,
} }
destination := o.directory
if destination == "" {
destination = o.name
}
if o.starter != "" { if o.starter != "" {
// Create from the starter // Create from the starter
lstarter := filepath.Join(o.starterDir, o.starter) lstarter := filepath.Join(o.starterDir, o.starter)
@ -104,10 +111,10 @@ func (o *createOptions) run(out io.Writer) error {
if filepath.IsAbs(o.starter) { if filepath.IsAbs(o.starter) {
lstarter = o.starter lstarter = o.starter
} }
return chartutil.CreateFrom(cfile, filepath.Dir(o.name), lstarter) return chartutil.CreateFrom(cfile, destination, lstarter)
} }
chartutil.Stderr = out chartutil.Stderr = out
_, err := chartutil.Create(chartname, filepath.Dir(o.name)) _, err := chartutil.Create(chartname, destination)
return err return err
} }

@ -71,12 +71,13 @@ func TestCreateStarterCmd(t *testing.T) {
// Create a starter. // Create a starter.
starterchart := helmpath.DataPath("starters") starterchart := helmpath.DataPath("starters")
os.MkdirAll(starterchart, 0755) os.MkdirAll(starterchart, 0755)
if dest, err := chartutil.Create("starterchart", starterchart); err != nil { destination := filepath.Join(starterchart, "starterchart")
if dest, err := chartutil.Create("starterchart", destination); err != nil {
t.Fatalf("Could not create chart: %s", err) t.Fatalf("Could not create chart: %s", err)
} else { } else {
t.Logf("Created %s", dest) t.Logf("Created %s", dest)
} }
tplpath := filepath.Join(starterchart, "starterchart", "templates", "foo.tpl") tplpath := filepath.Join(destination, "templates", "foo.tpl")
if err := ioutil.WriteFile(tplpath, []byte("test"), 0644); err != nil { if err := ioutil.WriteFile(tplpath, []byte("test"), 0644); err != nil {
t.Fatalf("Could not write template: %s", err) t.Fatalf("Could not write template: %s", err)
} }
@ -134,12 +135,13 @@ func TestCreateStarterAbsoluteCmd(t *testing.T) {
// Create a starter. // Create a starter.
starterchart := helmpath.DataPath("starters") starterchart := helmpath.DataPath("starters")
os.MkdirAll(starterchart, 0755) os.MkdirAll(starterchart, 0755)
if dest, err := chartutil.Create("starterchart", starterchart); err != nil { destination := filepath.Join(starterchart, "starterchart")
if dest, err := chartutil.Create("starterchart", destination); err != nil {
t.Fatalf("Could not create chart: %s", err) t.Fatalf("Could not create chart: %s", err)
} else { } else {
t.Logf("Created %s", dest) t.Logf("Created %s", dest)
} }
tplpath := filepath.Join(starterchart, "starterchart", "templates", "foo.tpl") tplpath := filepath.Join(destination, "templates", "foo.tpl")
if err := ioutil.WriteFile(tplpath, []byte("test"), 0644); err != nil { if err := ioutil.WriteFile(tplpath, []byte("test"), 0644); err != nil {
t.Fatalf("Could not write template: %s", err) t.Fatalf("Could not write template: %s", err)
} }
@ -147,10 +149,8 @@ func TestCreateStarterAbsoluteCmd(t *testing.T) {
os.MkdirAll(helmpath.CachePath(), 0755) os.MkdirAll(helmpath.CachePath(), 0755)
defer testChdir(t, helmpath.CachePath())() defer testChdir(t, helmpath.CachePath())()
starterChartPath := filepath.Join(starterchart, "starterchart")
// Run a create // Run a create
if _, _, err := executeActionCommand(fmt.Sprintf("create --starter=%s %s", starterChartPath, cname)); err != nil { if _, _, err := executeActionCommand(fmt.Sprintf("create --starter=%s %s", destination, cname)); err != nil {
t.Errorf("Failed to run create: %s", err) t.Errorf("Failed to run create: %s", err)
return return
} }

@ -547,7 +547,7 @@ func CreateFrom(chartfile *chart.Metadata, dest, src string) error {
} }
} }
return SaveDir(schart, dest) return SaveDirCustom(schart, dest)
} }
// Create creates a new chart in a directory. // Create creates a new chart in a directory.
@ -575,15 +575,11 @@ func Create(name, dir string) (string, error) {
return path, err return path, err
} }
if fi, err := os.Stat(path); err != nil { parentPath := filepath.Dir(path)
return path, err if fi, err := os.Stat(parentPath); err != nil {
return parentPath, err
} else if !fi.IsDir() { } else if !fi.IsDir() {
return path, errors.Errorf("no such directory %s", path) return parentPath, errors.Errorf("no such directory %s", parentPath)
}
cdir := filepath.Join(path, name)
if fi, err := os.Stat(cdir); err == nil && !fi.IsDir() {
return cdir, errors.Errorf("file %s already exists and is not a directory", cdir)
} }
files := []struct { files := []struct {
@ -592,57 +588,57 @@ func Create(name, dir string) (string, error) {
}{ }{
{ {
// Chart.yaml // Chart.yaml
path: filepath.Join(cdir, ChartfileName), path: filepath.Join(path, ChartfileName),
content: []byte(fmt.Sprintf(defaultChartfile, name)), content: []byte(fmt.Sprintf(defaultChartfile, name)),
}, },
{ {
// values.yaml // values.yaml
path: filepath.Join(cdir, ValuesfileName), path: filepath.Join(path, ValuesfileName),
content: []byte(fmt.Sprintf(defaultValues, name)), content: []byte(fmt.Sprintf(defaultValues, name)),
}, },
{ {
// .helmignore // .helmignore
path: filepath.Join(cdir, IgnorefileName), path: filepath.Join(path, IgnorefileName),
content: []byte(defaultIgnore), content: []byte(defaultIgnore),
}, },
{ {
// ingress.yaml // ingress.yaml
path: filepath.Join(cdir, IngressFileName), path: filepath.Join(path, IngressFileName),
content: transform(defaultIngress, name), content: transform(defaultIngress, name),
}, },
{ {
// deployment.yaml // deployment.yaml
path: filepath.Join(cdir, DeploymentName), path: filepath.Join(path, DeploymentName),
content: transform(defaultDeployment, name), content: transform(defaultDeployment, name),
}, },
{ {
// service.yaml // service.yaml
path: filepath.Join(cdir, ServiceName), path: filepath.Join(path, ServiceName),
content: transform(defaultService, name), content: transform(defaultService, name),
}, },
{ {
// serviceaccount.yaml // serviceaccount.yaml
path: filepath.Join(cdir, ServiceAccountName), path: filepath.Join(path, ServiceAccountName),
content: transform(defaultServiceAccount, name), content: transform(defaultServiceAccount, name),
}, },
{ {
// hpa.yaml // hpa.yaml
path: filepath.Join(cdir, HorizontalPodAutoscalerName), path: filepath.Join(path, HorizontalPodAutoscalerName),
content: transform(defaultHorizontalPodAutoscaler, name), content: transform(defaultHorizontalPodAutoscaler, name),
}, },
{ {
// NOTES.txt // NOTES.txt
path: filepath.Join(cdir, NotesName), path: filepath.Join(path, NotesName),
content: transform(defaultNotes, name), content: transform(defaultNotes, name),
}, },
{ {
// _helpers.tpl // _helpers.tpl
path: filepath.Join(cdir, HelpersName), path: filepath.Join(path, HelpersName),
content: transform(defaultHelpers, name), content: transform(defaultHelpers, name),
}, },
{ {
// test-connection.yaml // test-connection.yaml
path: filepath.Join(cdir, TestConnectionName), path: filepath.Join(path, TestConnectionName),
content: transform(defaultTestConnection, name), content: transform(defaultTestConnection, name),
}, },
} }
@ -653,14 +649,14 @@ func Create(name, dir string) (string, error) {
fmt.Fprintf(Stderr, "WARNING: File %q already exists. Overwriting.\n", file.path) fmt.Fprintf(Stderr, "WARNING: File %q already exists. Overwriting.\n", file.path)
} }
if err := writeFile(file.path, file.content); err != nil { if err := writeFile(file.path, file.content); err != nil {
return cdir, err return path, err
} }
} }
// Need to add the ChartsDir explicitly as it does not contain any file OOTB // Need to add the ChartsDir explicitly as it does not contain any file OOTB
if err := os.MkdirAll(filepath.Join(cdir, ChartsDir), 0755); err != nil { if err := os.MkdirAll(filepath.Join(path, ChartsDir), 0755); err != nil {
return cdir, err return path, err
} }
return cdir, nil return path, nil
} }
// transform performs a string replacement of the specified source for // transform performs a string replacement of the specified source for

@ -34,13 +34,12 @@ func TestCreate(t *testing.T) {
} }
defer os.RemoveAll(tdir) defer os.RemoveAll(tdir)
c, err := Create("foo", tdir) destination := filepath.Join(tdir, "foo")
c, err := Create("foo", destination)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
dir := filepath.Join(tdir, "foo")
mychart, err := loader.LoadDir(c) mychart, err := loader.LoadDir(c)
if err != nil { if err != nil {
t.Fatalf("Failed to load newly created chart %q: %s", c, err) t.Fatalf("Failed to load newly created chart %q: %s", c, err)
@ -63,7 +62,7 @@ func TestCreate(t *testing.T) {
TestConnectionName, TestConnectionName,
ValuesfileName, ValuesfileName,
} { } {
if _, err := os.Stat(filepath.Join(dir, f)); err != nil { if _, err := os.Stat(filepath.Join(destination, f)); err != nil {
t.Errorf("Expected %s file: %s", f, err) t.Errorf("Expected %s file: %s", f, err)
} }
} }
@ -83,15 +82,14 @@ func TestCreateFrom(t *testing.T) {
} }
srcdir := "./testdata/frobnitz/charts/mariner" srcdir := "./testdata/frobnitz/charts/mariner"
if err := CreateFrom(cf, tdir, srcdir); err != nil { destination := filepath.Join(tdir, cf.Name)
if err := CreateFrom(cf, destination, srcdir); err != nil {
t.Fatal(err) t.Fatal(err)
} }
dir := filepath.Join(tdir, "foo") mychart, err := loader.LoadDir(destination)
c := filepath.Join(tdir, cf.Name)
mychart, err := loader.LoadDir(c)
if err != nil { if err != nil {
t.Fatalf("Failed to load newly created chart %q: %s", c, err) t.Fatalf("Failed to load newly created chart %q: %s", destination, err)
} }
if mychart.Name() != "foo" { if mychart.Name() != "foo" {
@ -103,12 +101,12 @@ func TestCreateFrom(t *testing.T) {
ValuesfileName, ValuesfileName,
filepath.Join(TemplatesDir, "placeholder.tpl"), filepath.Join(TemplatesDir, "placeholder.tpl"),
} { } {
if _, err := os.Stat(filepath.Join(dir, f)); err != nil { if _, err := os.Stat(filepath.Join(destination, f)); err != nil {
t.Errorf("Expected %s file: %s", f, err) t.Errorf("Expected %s file: %s", f, err)
} }
// Check each file to make sure <CHARTNAME> has been replaced // Check each file to make sure <CHARTNAME> has been replaced
b, err := ioutil.ReadFile(filepath.Join(dir, f)) b, err := ioutil.ReadFile(filepath.Join(destination, f))
if err != nil { if err != nil {
t.Errorf("Unable to read file %s: %s", f, err) t.Errorf("Unable to read file %s: %s", f, err)
} }
@ -128,18 +126,17 @@ func TestCreate_Overwrite(t *testing.T) {
var errlog bytes.Buffer var errlog bytes.Buffer
if _, err := Create("foo", tdir); err != nil { destination := filepath.Join(tdir, "foo")
if _, err := Create("foo", destination); err != nil {
t.Fatal(err) t.Fatal(err)
} }
dir := filepath.Join(tdir, "foo") tplname := filepath.Join(destination, "templates/hpa.yaml")
tplname := filepath.Join(dir, "templates/hpa.yaml")
writeFile(tplname, []byte("FOO")) writeFile(tplname, []byte("FOO"))
// Now re-run the create // Now re-run the create
Stderr = &errlog Stderr = &errlog
if _, err := Create("foo", tdir); err != nil { if _, err := Create("foo", destination); err != nil {
t.Fatal(err) t.Fatal(err)
} }

@ -40,6 +40,14 @@ var headerBytes = []byte("+aHR0cHM6Ly95b3V0dS5iZS96OVV6MWljandyTQo=")
func SaveDir(c *chart.Chart, dest string) error { func SaveDir(c *chart.Chart, dest string) error {
// Create the chart directory // Create the chart directory
outdir := filepath.Join(dest, c.Name()) outdir := filepath.Join(dest, c.Name())
return SaveDirCustom(c, outdir)
}
// SaveDirCustom saves a chart as files in a custom directory.
//
// This takes the chart name and the output directory, writing the chart's contents
// to that directory.
func SaveDirCustom(c *chart.Chart, outdir string) error {
if fi, err := os.Stat(outdir); err == nil && !fi.IsDir() { if fi, err := os.Stat(outdir); err == nil && !fi.IsDir() {
return errors.Errorf("file %s already exists and is not a directory", outdir) return errors.Errorf("file %s already exists and is not a directory", outdir)
} }

@ -19,6 +19,7 @@ package lint
import ( import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath"
"strings" "strings"
"testing" "testing"
@ -125,7 +126,8 @@ func TestHelmCreateChart(t *testing.T) {
} }
defer os.RemoveAll(dir) defer os.RemoveAll(dir)
createdChart, err := chartutil.Create("testhelmcreatepasseslint", dir) destination := filepath.Join(dir, "testhelmcreatepasseslint")
createdChart, err := chartutil.Create("testhelmcreatepasseslint", destination)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
// Fatal is bad because of the defer. // Fatal is bad because of the defer.

Loading…
Cancel
Save