Skip to content

Commit 38afc3b

Browse files
committed
feat: Have default functionglobs in config and use them if no glob is provided
1 parent 6518e79 commit 38afc3b

File tree

8 files changed

+167
-69
lines changed

8 files changed

+167
-69
lines changed

pkg/cmd/deployment/root.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,24 +52,27 @@ var deploymentApplyCmd = &cobra.Command{
5252
Use: "apply [handlerGlob]",
5353
Short: "Create or Update a new application deployment",
5454
Long: `Applies a Nitric application deployment.`,
55-
Example: `nitric deployment apply
55+
Example: `# use a nitric.yaml or configured default handlerGlob (stack in the current directory).
56+
nitric deployment apply -t aws
57+
58+
# use an explicit handlerGlob (stack in the current directory)
59+
nitric deployment apply -t aws "functions/*/*.go"
5660
57-
# When using a nitric.yaml
58-
nitric deployment apply -n prod-aws -s ../project/ -t prod
61+
# use an explicit handlerGlob and explicit stack directory
62+
nitric deployment apply -s ../projectX -t aws "functions/*/*.go"
5963
60-
# When using code-as-config, specify the functions.
61-
nitric deployment apply -n prod-aws -s ../project/ -t prod "functions/*.ts"
62-
`,
64+
# use a custom deployment name
65+
nitric deployment apply -n prod -t aws`,
6366
Run: func(cmd *cobra.Command, args []string) {
6467
t, err := target.FromOptions()
6568
cobra.CheckErr(err)
6669

67-
s, err := stack.FromOptions()
70+
s, err := stack.FromOptions(args)
6871
if err != nil && len(args) > 0 {
6972
codeAsConfig := tasklet.Runner{
7073
StartMsg: "Gathering configuration from code..",
7174
Runner: func(_ output.Progress) error {
72-
s, err = stack.FromGlobArgs(args)
75+
s, err = stack.FromOptions(args)
7376
if err != nil {
7477
return err
7578
}

pkg/cmd/root.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ import (
3131
"github.com/nitrictech/cli/pkg/cmd/deployment"
3232
"github.com/nitrictech/cli/pkg/cmd/provider"
3333
"github.com/nitrictech/cli/pkg/cmd/run"
34-
"github.com/nitrictech/cli/pkg/cmd/stack"
34+
cmdstack "github.com/nitrictech/cli/pkg/cmd/stack"
3535
cmdTarget "github.com/nitrictech/cli/pkg/cmd/target"
3636
"github.com/nitrictech/cli/pkg/output"
37+
"github.com/nitrictech/cli/pkg/stack"
3738
"github.com/nitrictech/cli/pkg/target"
3839
"github.com/nitrictech/cli/pkg/tasklet"
3940
"github.com/nitrictech/cli/pkg/utils"
@@ -96,7 +97,7 @@ func init() {
9697

9798
rootCmd.AddCommand(deployment.RootCommand())
9899
rootCmd.AddCommand(provider.RootCommand())
99-
rootCmd.AddCommand(stack.RootCommand())
100+
rootCmd.AddCommand(cmdstack.RootCommand())
100101
rootCmd.AddCommand(cmdTarget.RootCommand())
101102
rootCmd.AddCommand(run.RootCommand())
102103
rootCmd.AddCommand(versionCmd)
@@ -146,6 +147,10 @@ func ensureConfigDefaults() {
146147
needsWrite = true
147148
}
148149

150+
if stack.EnsureRuntimeDefaults() {
151+
needsWrite = true
152+
}
153+
149154
if needsWrite {
150155
tasklet.MustRun(tasklet.Runner{
151156
StartMsg: "Updating configfile to include defaults",

pkg/cmd/run/root.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,20 @@ var runCmd = &cobra.Command{
3939
Short: "run a nitric stack",
4040
Long: `Run a nitric stack locally for development or testing
4141
`,
42-
Example: `nitric run -s ../projectX "functions/*.ts"`,
42+
Example: `# use a nitric.yaml or configured default handlerGlob (stack in the current directory).
43+
nitric run
44+
45+
# use an explicit handlerGlob (stack in the current directory)
46+
nitric run "functions/*.ts"
47+
48+
# use an explicit handlerGlob and explicit stack directory
49+
nitric run -s ../projectX/ "functions/*.ts"`,
4350
Run: func(cmd *cobra.Command, args []string) {
4451
term := make(chan os.Signal, 1)
4552
signal.Notify(term, os.Interrupt, syscall.SIGTERM)
4653
signal.Notify(term, os.Interrupt, syscall.SIGINT)
4754

48-
s, err := stack.FromOptions()
49-
if err != nil && len(args) > 0 {
50-
s, err = stack.FromGlobArgs(args)
51-
}
55+
s, err := stack.FromOptions(args)
5256
cobra.CheckErr(err)
5357

5458
ce, err := containerengine.Discover()

pkg/cmd/stack/root.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,16 +120,24 @@ var stackDescribeCmd = &cobra.Command{
120120
Use: "describe [handlerGlob]",
121121
Short: "describe stack dependencies",
122122
Long: `Describes stack dependencies`,
123+
Example: `# use a nitric.yaml or configured default handlerGlob (stack in the current directory).
124+
nitric stack describe
125+
126+
# use an explicit handlerGlob (stack in the current directory)
127+
nitric stack describe "functions/*/*.go"
128+
129+
# use an explicit handlerGlob and explicit stack directory
130+
nitric stack describe -s ../projectX "functions/*/*.go"`,
123131
Run: func(cmd *cobra.Command, args []string) {
124-
s, err := stack.FromGlobArgs(args)
132+
s, err := stack.FromOptions(args)
125133
cobra.CheckErr(err)
126134

127135
s, err = codeconfig.Populate(s)
128136
cobra.CheckErr(err)
129137

130138
output.Print(s)
131139
},
132-
Args: cobra.MinimumNArgs(1),
140+
Args: cobra.MinimumNArgs(0),
133141
}
134142

135143
func RootCommand() *cobra.Command {

pkg/stack/options.go

Lines changed: 81 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@
1717
package stack
1818

1919
import (
20+
"fmt"
2021
"os"
2122
"path"
2223
"path/filepath"
24+
"strings"
2325

2426
"github.com/pkg/errors"
27+
"github.com/pterm/pterm"
2528
"github.com/spf13/cobra"
29+
"github.com/spf13/viper"
2630

2731
"github.com/nitrictech/cli/pkg/pflagext"
2832
"github.com/nitrictech/cli/pkg/runtime"
@@ -43,7 +47,7 @@ func wrapStatError(err error) error {
4347
return err
4448
}
4549

46-
func FromOptions() (*Stack, error) {
50+
func fromNitricFile() (*Stack, error) {
4751
configPath := stackPath
4852
ss, err := os.Stat(configPath)
4953
if err != nil {
@@ -60,44 +64,62 @@ func FromOptions() (*Stack, error) {
6064
return FromFile(configPath)
6165
}
6266

63-
func FunctionFromHandler(h, stackDir string) Function {
64-
rt, _ := runtime.NewRunTimeFromHandler(h)
65-
fn := Function{
66-
ComputeUnit: ComputeUnit{Name: rt.ContainerName()},
67-
Handler: h,
67+
func EnsureRuntimeDefaults() bool {
68+
defaults := map[string]map[string]interface{}{
69+
"ts": {
70+
"functionglob": "functions/*.ts",
71+
},
72+
"go": {
73+
"functionglob": "functions/*/*.go",
74+
},
6875
}
69-
fn.SetContextDirectory(stackDir)
70-
71-
return fn
72-
}
73-
74-
func FromOptionsMinimal() (*Stack, error) {
75-
ss, err := os.Stat(stackPath)
76+
written := false
77+
runtime, err := utils.ToStringMapStringMapStringE(viper.Get("runtime"))
7678
if err != nil {
77-
return nil, err
79+
fmt.Println("ERROR: runtime configuration in the wrong format")
80+
return false
7881
}
7982

80-
sDir := stackPath
81-
if !ss.IsDir() {
82-
sDir = filepath.Dir(stackPath)
83+
for rtName, rt := range defaults {
84+
if _, ok := runtime[rtName]; !ok {
85+
runtime[rtName] = rt
86+
written = true
87+
}
88+
}
89+
if written {
90+
viper.Set("runtime", runtime)
8391
}
92+
return written
93+
}
8494

85-
// get the abs dir in case user provides "."
86-
absDir, err := filepath.Abs(sDir)
95+
func defaultGlobsFromConfig() []string {
96+
globs := []string{}
97+
runtime, err := utils.ToStringMapStringMapStringE(viper.Get("runtime"))
8798
if err != nil {
88-
return nil, err
99+
return globs
100+
}
101+
for _, rt := range runtime {
102+
globs = append(globs, rt["functionglob"].(string))
89103
}
90-
s := New(path.Base(absDir), sDir)
91104

92-
return s, nil
105+
return globs
93106
}
94107

95-
func FromGlobArgs(glob []string) (*Stack, error) {
96-
s, err := FromOptionsMinimal()
108+
func FromOptions(glob []string) (*Stack, error) {
109+
s, err := fromNitricFile()
110+
if err == nil && s != nil {
111+
return s, err
112+
}
113+
114+
s, err = FromOptionsMinimal()
97115
if err != nil {
98116
return nil, err
99117
}
100118

119+
if len(glob) == 0 {
120+
glob = defaultGlobsFromConfig()
121+
}
122+
101123
for _, g := range glob {
102124
if _, err := os.Stat(g); err != nil {
103125
fs, err := utils.GlobInDir(stackPath, g)
@@ -113,13 +135,47 @@ func FromGlobArgs(glob []string) (*Stack, error) {
113135
s.Functions[fn.Name] = fn
114136
}
115137
}
138+
116139
if len(s.Functions) == 0 {
117-
return nil, errors.New("No files where found with glob, try a new pattern")
140+
return nil, fmt.Errorf("no functions were found with the glob '%s', try a new pattern", strings.Join(glob, ","))
141+
}
142+
143+
return s, nil
144+
}
145+
146+
func FromOptionsMinimal() (*Stack, error) {
147+
ss, err := os.Stat(stackPath)
148+
if err != nil {
149+
return nil, err
118150
}
119151

152+
sDir := stackPath
153+
if !ss.IsDir() {
154+
sDir = filepath.Dir(stackPath)
155+
}
156+
157+
// get the abs dir in case user provides "."
158+
absDir, err := filepath.Abs(sDir)
159+
if err != nil {
160+
return nil, err
161+
}
162+
s := New(path.Base(absDir), sDir)
163+
120164
return s, nil
121165
}
122166

167+
func FunctionFromHandler(h, stackDir string) Function {
168+
pterm.Debug.Println("Using function from " + h)
169+
rt, _ := runtime.NewRunTimeFromHandler(h)
170+
fn := Function{
171+
ComputeUnit: ComputeUnit{Name: rt.ContainerName()},
172+
Handler: h,
173+
}
174+
fn.SetContextDirectory(stackDir)
175+
176+
return fn
177+
}
178+
123179
func AddOptions(cmd *cobra.Command) {
124180
wd, err := os.Getwd()
125181
cobra.CheckErr(err)

pkg/stack/options_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ func TestFromOptions(t *testing.T) {
135135
}
136136

137137
stackPath = tmpDir
138-
newS, err := FromOptions()
138+
newS, err := FromOptions([]string{})
139139
if err != nil {
140140
t.Error(err)
141141
}
@@ -206,9 +206,9 @@ func TestFromGlobArgs(t *testing.T) {
206206
if err != nil {
207207
t.Fatal(err)
208208
}
209-
got, err := FromGlobArgs(tt.glob)
209+
got, err := FromOptions(tt.glob)
210210
if (err != nil) != tt.wantErr {
211-
t.Errorf("FromGlobArgs() error = %v, wantErr %v", err, tt.wantErr)
211+
t.Errorf("FromOptions() error = %v, wantErr %v", err, tt.wantErr)
212212
return
213213
}
214214
if !reflect.DeepEqual(want, got) {

pkg/target/options.go

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,14 @@ package target
1818

1919
import (
2020
"errors"
21-
"fmt"
2221
"strings"
2322

2423
"github.com/mitchellh/mapstructure"
25-
"github.com/spf13/cast"
2624
"github.com/spf13/cobra"
2725
"github.com/spf13/viper"
2826

2927
"github.com/nitrictech/cli/pkg/pflagext"
28+
"github.com/nitrictech/cli/pkg/utils"
3029
)
3130

3231
const (
@@ -46,30 +45,10 @@ var (
4645
Providers = []string{Aws, Azure, Gcp, Digitalocean}
4746
)
4847

49-
func ToStringMapStringMapStringE(i interface{}) (map[string]map[string]interface{}, error) {
50-
switch v := i.(type) {
51-
case map[string]map[string]interface{}:
52-
return v, nil
53-
case map[string]interface{}:
54-
var err error
55-
m := make(map[string]map[string]interface{})
56-
57-
for k, val := range v {
58-
m[k], err = cast.ToStringMapE(val)
59-
if err != nil {
60-
return nil, err
61-
}
62-
}
63-
return m, nil
64-
default:
65-
return nil, fmt.Errorf("unable to cast %#v of type %T to map[string]map[string]interface{}", i, i)
66-
}
67-
}
68-
6948
func EnsureDefaultConfig() bool {
7049
written := false
7150

72-
targets, err := ToStringMapStringMapStringE(viper.Get("targets"))
51+
targets, err := utils.ToStringMapStringMapStringE(viper.Get("targets"))
7352
if err != nil {
7453
targets = map[string]map[string]interface{}{}
7554
}
@@ -98,7 +77,7 @@ func EnsureDefaultConfig() bool {
9877
}
9978

10079
func AllFromConfig() (map[string]Target, error) {
101-
tsMap, err := ToStringMapStringMapStringE(viper.Get("targets"))
80+
tsMap, err := utils.ToStringMapStringMapStringE(viper.Get("targets"))
10281
if err != nil {
10382
return nil, err
10483
}

0 commit comments

Comments
 (0)