From b30e883e671477ebfa217df03e6825778e84a3df Mon Sep 17 00:00:00 2001 From: Luke Kingland Date: Wed, 9 Jun 2021 01:07:08 +0900 Subject: [PATCH] refactor!: function signatures implied from trigger Renames trigger to template, removing it as an unnecessary configuration. This reiterates that a Function implementation can change function sig implemented at any time, and it is not part of the configuration. This sets the stage for renaming 'templates', and the finalization of the use cases enabling extensible templates. --- client.go | 17 ++++++++----- client_test.go | 9 +------ cmd/create.go | 42 +++++++++++++++++--------------- cmd/delete_test.go | 2 -- config.go | 5 +--- docs/guides/commands.md | 6 ++--- docs/guides/func_yaml.md | 4 --- docs/guides/golang.md | 1 - docs/guides/integrators_guide.md | 1 - docs/guides/nodejs.md | 1 - docs/guides/python.md | 1 - docs/guides/quarkus.md | 1 - docs/guides/typescript.md | 1 - function.go | 6 ++--- templates.go | 5 ---- templates_test.go | 4 +-- test/_e2e/cmd_create_test.go | 4 +-- test/_e2e/cmd_emit_test.go | 16 ++++++------ test/_e2e/func_test_proj.go | 15 ++++++------ test/_e2e/trigger_events_test.go | 15 ++++++------ test/_e2e/trigger_http_test.go | 28 ++++++++++----------- test/_e2e/update_test.go | 17 ++++++------- 22 files changed, 88 insertions(+), 113 deletions(-) diff --git a/client.go b/client.go index cbaae365..9f3b6655 100644 --- a/client.go +++ b/client.go @@ -15,7 +15,12 @@ import ( const ( DefaultRegistry = "docker.io" DefaultRuntime = "node" - DefaultTrigger = "http" + + // DefautlTemplate is the default Function signature / environmental context + // of the resultant function. All runtimes are expected to have at least + // one implementation of each supported funciton sinagure. Currently that + // includes an HTTP Handler ("http") and Cloud Events handler ("events") + DefaultTemplate = "http" ) // Client for managing Function instances. @@ -348,15 +353,15 @@ func (c *Client) Create(cfg Function) (err error) { f.Runtime = DefaultRuntime } - // Assert trigger was provided, or default. - f.Trigger = cfg.Trigger - if f.Trigger == "" { - f.Trigger = DefaultTrigger + // Assert template was provided, or default. + f.Template = cfg.Template + if f.Template == "" { + f.Template = DefaultTemplate } // Write out a template. w := templateWriter{templates: c.templates, verbose: c.verbose} - if err = w.Write(f.Runtime, f.Trigger, f.Root); err != nil { + if err = w.Write(f.Runtime, f.Template, f.Root); err != nil { return } diff --git a/client_test.go b/client_test.go index 8a4430b1..6a3c30d5 100644 --- a/client_test.go +++ b/client_test.go @@ -154,13 +154,6 @@ func TestDefaultRuntime(t *testing.T) { } } -// TestDefaultTemplate ensures that the default template is -// applied when not provided. -func TestDefaultTrigger(t *testing.T) { - // TODO: need to either expose accessor for introspection, or compare - // the files written to those in the embedded repisotory? -} - // TestExtensibleTemplates templates. Ensures that templates are extensible // using a custom path to a template repository on disk. Custom repository // location is not defined herein but expected to be provided because, for @@ -184,7 +177,7 @@ func TestExtensibleTemplates(t *testing.T) { bosonFunc.WithRegistry(TestRegistry)) // Create a Function specifying a template, 'json' that only exists in the extensible set - if err := client.New(context.Background(), bosonFunc.Function{Root: root, Trigger: "boson-experimental/json"}); err != nil { + if err := client.New(context.Background(), bosonFunc.Function{Root: root, Template: "boson-experimental/json"}); err != nil { t.Fatal(err) } diff --git a/cmd/create.go b/cmd/create.go index f1cc8a7b..3b03e4a8 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -17,7 +17,7 @@ func init() { createCmd.Flags().BoolP("confirm", "c", false, "Prompt to confirm all configuration options (Env: $FUNC_CONFIRM)") createCmd.Flags().StringP("runtime", "l", bosonFunc.DefaultRuntime, "Function runtime language/framework. Available runtimes: "+utils.RuntimeList()+" (Env: $FUNC_RUNTIME)") createCmd.Flags().StringP("templates", "", filepath.Join(configPath(), "templates"), "Path to additional templates (Env: $FUNC_TEMPLATES)") - createCmd.Flags().StringP("trigger", "t", bosonFunc.DefaultTrigger, "Function trigger. Available triggers: 'http' and 'events' (Env: $FUNC_TRIGGER)") + createCmd.Flags().StringP("template", "t", bosonFunc.DefaultTemplate, "Function template. For eample 'http' or 'events' (Env: $FUNC_TEMPLATE)") if err := createCmd.RegisterFlagCompletionFunc("runtime", CompleteRuntimeList); err != nil { fmt.Println("internal: error while calling RegisterFlagCompletionFunc: ", err) @@ -43,12 +43,12 @@ kn func create kn func create --runtime quarkus myfunc # Create a function project that uses a CloudEvent based function signature -kn func create --trigger events myfunc +kn func create -t events myfunc `, SuggestFor: []string{"inti", "new"}, - PreRunE: bindEnv("runtime", "templates", "trigger", "confirm"), + PreRunE: bindEnv("runtime", "templates", "template", "confirm"), RunE: runCreate, - // TODO: autocomplate Functions for runtime and trigger. + // TODO: autocomplate or interactive prompt for runtime and template. } func runCreate(cmd *cobra.Command, args []string) error { @@ -61,10 +61,10 @@ func runCreate(cmd *cobra.Command, args []string) error { config = config.Prompt() function := bosonFunc.Function{ - Name: config.Name, - Root: config.Path, - Runtime: config.Runtime, - Trigger: config.Trigger, + Name: config.Name, + Root: config.Path, + Runtime: config.Runtime, + Template: config.Template, } client := bosonFunc.New( @@ -90,11 +90,14 @@ type createConfig struct { // location is $XDG_CONFIG_HOME/templates ($HOME/.config/func/templates) Templates string - // Trigger is the form of the resultant Function, i.e. the Function signature - // and contextually avaialable resources. For example 'http' for a Function - // expected to be invoked via straight HTTP requests, or 'events' for a - // Function which will be invoked with CloudEvents. - Trigger string + // Template is the code written into the new Function project, including + // an implementation adhering to one of the supported function signatures. + // May also include additional configuration settings or examples. + // For example, embedded are 'http' for a Function whose funciton signature + // is invoked via straight HTTP requests, or 'events' for a Function which + // will be invoked with CloudEvents. These embedded templates contain a + // minimum implementation of the signature itself and example tests. + Template string // Verbose output Verbose bool @@ -118,7 +121,7 @@ func newCreateConfig(args []string) createConfig { Path: derivedPath, Runtime: viper.GetString("runtime"), Templates: viper.GetString("templates"), - Trigger: viper.GetString("trigger"), + Template: viper.GetString("template"), Confirm: viper.GetBool("confirm"), Verbose: viper.GetBool("verbose"), } @@ -133,7 +136,7 @@ func (c createConfig) Prompt() createConfig { fmt.Printf("Project path: %v\n", c.Path) fmt.Printf("Function name: %v\n", c.Name) fmt.Printf("Runtime: %v\n", c.Runtime) - fmt.Printf("Trigger: %v\n", c.Trigger) + fmt.Printf("Template: %v\n", c.Template) return c } @@ -148,10 +151,9 @@ func (c createConfig) Prompt() createConfig { } return createConfig{ - Name: derivedName, - Path: derivedPath, - Runtime: prompt.ForString("Runtime", c.Runtime), - Trigger: prompt.ForString("Trigger", c.Trigger), - // Templates intentionally omitted from prompt for being an edge case. + Name: derivedName, + Path: derivedPath, + Runtime: prompt.ForString("Runtime", c.Runtime), + Template: prompt.ForString("Template", c.Template), } } diff --git a/cmd/delete_test.go b/cmd/delete_test.go index 9bcafa54..510acecd 100644 --- a/cmd/delete_test.go +++ b/cmd/delete_test.go @@ -47,7 +47,6 @@ namespace: "" runtime: go image: "" imageDigest: "" -trigger: http builder: quay.io/boson/faas-go-builder builderMap: default: quay.io/boson/faas-go-builder @@ -72,7 +71,6 @@ annotations: {} } f.Close() - oldWD, err := os.Getwd() if err != nil { t.Fatal(err) diff --git a/config.go b/config.go index 73538198..0e880496 100644 --- a/config.go +++ b/config.go @@ -36,7 +36,6 @@ type config struct { Runtime string `yaml:"runtime"` Image string `yaml:"image"` ImageDigest string `yaml:"imageDigest"` - Trigger string `yaml:"trigger"` Builder string `yaml:"builder"` BuilderMap map[string]string `yaml:"builderMap"` Volumes Volumes `yaml:"volumes"` @@ -128,7 +127,6 @@ func fromConfig(c config) (f Function) { Runtime: c.Runtime, Image: c.Image, ImageDigest: c.ImageDigest, - Trigger: c.Trigger, Builder: c.Builder, BuilderMap: c.BuilderMap, Volumes: c.Volumes, @@ -145,7 +143,6 @@ func toConfig(f Function) config { Runtime: f.Runtime, Image: f.Image, ImageDigest: f.ImageDigest, - Trigger: f.Trigger, Builder: f.Builder, BuilderMap: f.BuilderMap, Volumes: f.Volumes, @@ -227,7 +224,7 @@ func ValidateEnvs(envs Envs) (errors []string) { // all key-pair values from secret are set as ENV; {{ secret.secretName }} or {{ configMap.configMapName }} if !regWholeSecret.MatchString(*env.Value) && !regWholeConfigMap.MatchString(*env.Value) { errors = append(errors, fmt.Sprintf("env entry #%d has invalid value field set, it has '%s', but allowed is only '{{ secret.secretName }}' or '{{ configMap.configMapName }}'", - i, *env.Value)) + i, *env.Value)) } } else { if strings.HasPrefix(*env.Value, "{{") { diff --git a/docs/guides/commands.md b/docs/guides/commands.md index fc39f521..5b8e4cff 100644 --- a/docs/guides/commands.md +++ b/docs/guides/commands.md @@ -2,20 +2,20 @@ ## `create` -Creates a new Function project at _`path`_. If _`path`_ is unspecified, assumes the current directory. If _`path`_ does not exist, it will be created. The function name is the name of the leaf directory at path. The user can specify the runtime and trigger with flags. +Creates a new Function project at _`path`_. If _`path`_ is unspecified, assumes the current directory. If _`path`_ does not exist, it will be created. The function name is the name of the leaf directory at path. The user can specify the runtime and template with flags. Function name must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?'). Similar `kn` command: none. ```console -func create [-l -t ] +func create [-l -t