refactor!: change --trigger and --templates flags

This commit is a breaking change.

Change the `--trigger` flag to be `--template` and the `--templates` flag
to be `--packages`. This is being done in anticipation of future work focused
on making `func` extensibility friendlier, and in an attempt to finalized some
of the naming conventions we have used to date.

In fact, the `--trigger` flag used to be `--template` but we decided to
change that a few months ago. This commit reverses that decision. The reason
behind this is twofold.

1. Using 'trigger' has proved to be confusing. Even if I create a function
with an HTTP trigger, it will still be invoked when a CloudEvent is sent
to the function process. Or alternatively, it is possible to send a raw
HTTP request to a function with an event trigger. Using 'template' instead
implies that the incoming request does not determine how the function is
invoked - rather it is the structure of the function signature that informs
the invocation.

2. The `trigger` terminology is not inclusive enough for our use cases. For
example, a third party provider of function templates may provide a template
for multiplexing incoming HTTP requests in Go using `gorilla-mux`. It doesn't
really make sense to say that `gorilla-mux` is the trigger. It's just a
defining feature of how the template is structured. I think this:

```sh
func create --runtime go --template gorilla-mux
```

Makes more sense than this:

```sh
func create --runtime go --trigger gorilla-mux
```

In changing this flag to be `--template`, we then need to come up with
another name for our existing `--templates` flag. I chose `--packages`
because what is being specified here is more than just the template. The
user sees only the function template when they run `func create...` but
the filesystem from which this template is pulled also contains metadata
about the template - most importantly right now, `.builders.yaml`. It is
conceivable that we may ultimately want to stuff these directories with
event more metadata in the future.

Something like `--packages` makes sense to me, but I am open to suggestion.

Thinking of these as a package also allows for better extensibility features
down the road. For example, users could reference packages at a URI like so.

```
func create --packages https://mycompany.com/function/templates.tgz
```

This would result in `func` downloading the tarball, extracting it to the
config directory, and using it for additional templates.

Signed-off-by: Lance Ball <lball@redhat.com>
This commit is contained in:
Lance Ball 2021-06-08 13:41:32 -04:00 committed by drekar
parent b30e883e67
commit ce29ff6285
No known key found for this signature in database
GPG Key ID: CE6540D7C34159FF
8 changed files with 35 additions and 36 deletions

View File

@ -34,7 +34,7 @@ type Client struct {
lister Lister // Lists remote services
describer Describer
dnsProvider DNSProvider // Provider of DNS services
templates string // path to extensible templates
packages string // path to extensible templates
registry string // default registry for OCI image tags
progressListener ProgressListener // progress listener
emitter Emitter // Emits CloudEvents to functions
@ -247,12 +247,12 @@ func WithDNSProvider(provider DNSProvider) Option {
}
}
// WithTemplates sets the location to use for extensible templates.
// Extensible templates are additional templates that exist on disk and are
// WithPackages sets the location to use for extensible template packages.
// Extensible template packages are additional templates that exist on disk and are
// not built into the binary.
func WithTemplates(templates string) Option {
func WithPackages(packages string) Option {
return func(c *Client) {
c.templates = templates
c.packages = packages
}
}
@ -360,7 +360,7 @@ func (c *Client) Create(cfg Function) (err error) {
}
// Write out a template.
w := templateWriter{templates: c.templates, verbose: c.verbose}
w := templateWriter{templates: c.packages, verbose: c.verbose}
if err = w.Write(f.Runtime, f.Template, f.Root); err != nil {
return
}

View File

@ -154,8 +154,8 @@ func TestDefaultRuntime(t *testing.T) {
}
}
// TestExtensibleTemplates templates. Ensures that templates are extensible
// using a custom path to a template repository on disk. Custom repository
// TestExtensiblePackages ensures that template packages are extensible
// using a custom path to a template package repository on disk. Custom repository
// location is not defined herein but expected to be provided because, for
// example, a CLI may want to use XDG_CONFIG_HOME. Assuming a repository path
// $FUNC_TEMPLATES, a Go template named 'json' which is provided in the
@ -163,9 +163,9 @@ func TestDefaultRuntime(t *testing.T) {
// $FUNC_TEMPLATES/boson-experimental/go/json
// See the CLI for full details, but a standard default location is
// $HOME/.config/templates/boson-experimental/go/json
func TestExtensibleTemplates(t *testing.T) {
func TestExtensiblePackages(t *testing.T) {
// Create a directory for the new Function
root := "testdata/example.com/testExtensibleTemplates"
root := "testdata/example.com/testExtensiblePackages"
if err := os.MkdirAll(root, 0744); err != nil {
t.Fatal(err)
}
@ -173,7 +173,7 @@ func TestExtensibleTemplates(t *testing.T) {
// Create a new client with a path to the extensible templates
client := bosonFunc.New(
bosonFunc.WithTemplates("testdata/templates"),
bosonFunc.WithPackages("testdata/templates"),
bosonFunc.WithRegistry(TestRegistry))
// Create a Function specifying a template, 'json' that only exists in the extensible set

View File

@ -16,8 +16,8 @@ func init() {
root.AddCommand(createCmd)
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("template", "t", bosonFunc.DefaultTemplate, "Function template. For eample 'http' or 'events' (Env: $FUNC_TEMPLATE)")
createCmd.Flags().StringP("packages", "p", filepath.Join(configPath(), "packages"), "Path to additional template packages (Env: $FUNC_PACKAGES)")
createCmd.Flags().StringP("template", "t", bosonFunc.DefaultTemplate, "Function template. Available templates: 'http' and 'events' (Env: $FUNC_TEMPLATE)")
if err := createCmd.RegisterFlagCompletionFunc("runtime", CompleteRuntimeList); err != nil {
fmt.Println("internal: error while calling RegisterFlagCompletionFunc: ", err)
@ -43,10 +43,10 @@ kn func create
kn func create --runtime quarkus myfunc
# Create a function project that uses a CloudEvent based function signature
kn func create -t events myfunc
kn func create --template events myfunc
`,
SuggestFor: []string{"inti", "new"},
PreRunE: bindEnv("runtime", "templates", "template", "confirm"),
PreRunE: bindEnv("runtime", "template", "packages", "confirm"),
RunE: runCreate,
// TODO: autocomplate or interactive prompt for runtime and template.
}
@ -68,7 +68,7 @@ func runCreate(cmd *cobra.Command, args []string) error {
}
client := bosonFunc.New(
bosonFunc.WithTemplates(config.Templates),
bosonFunc.WithPackages(config.Packages),
bosonFunc.WithVerbose(config.Verbose))
return client.Create(function)
@ -84,11 +84,11 @@ type createConfig struct {
// Runtime language/framework.
Runtime string
// Templates is an optional path that, if it exists, will be used as a source
// for additional templates not included in the binary. If not provided
// explicitly as a flag (--templates) or env (FUNC_TEMPLATES), the default
// location is $XDG_CONFIG_HOME/templates ($HOME/.config/func/templates)
Templates string
// Packages is an optional path that, if it exists, will be used as a source
// for additional template packages not included in the binary. If not provided
// explicitly as a flag (--packages) or env (FUNC_PACKAGES), the default
// location is $XDG_CONFIG_HOME/packages ($HOME/.config/func/packages)
Packages string
// Template is the code written into the new Function project, including
// an implementation adhering to one of the supported function signatures.
@ -117,13 +117,13 @@ func newCreateConfig(args []string) createConfig {
derivedName, derivedPath := deriveNameAndAbsolutePathFromPath(path)
return createConfig{
Name: derivedName,
Path: derivedPath,
Runtime: viper.GetString("runtime"),
Templates: viper.GetString("templates"),
Template: viper.GetString("template"),
Confirm: viper.GetBool("confirm"),
Verbose: viper.GetBool("verbose"),
Name: derivedName,
Path: derivedPath,
Packages: viper.GetString("packages"),
Runtime: viper.GetString("runtime"),
Template: viper.GetString("template"),
Confirm: viper.GetBool("confirm"),
Verbose: viper.GetBool("verbose"),
}
}

View File

@ -2,11 +2,12 @@ package cmd
import (
"context"
fn "github.com/boson-project/func"
"io/ioutil"
"os"
"path/filepath"
"testing"
fn "github.com/boson-project/func"
)
type testRemover struct {

View File

@ -87,8 +87,6 @@ The Kubernetes namespace where your function will be deployed.
The language runtime for your function. For example `python`.
## Local Environment Variables
Any of the fields in `func.yaml` may contain a reference to an environment

View File

@ -39,9 +39,9 @@ func main() {
// Local implementation is written to the current working directory.
funcTest := bosonFunc.Function{
Runtime: "go",
Name: "my-function",
Image: "quay.io/alice/my-function",
Root: "my-function",
Name: "my-function",
Image: "quay.io/alice/my-function",
Root: "my-function",
}
if err := client.Create(funcTest); err != nil {
log.Fatal(err)

View File

@ -30,7 +30,7 @@ type file interface {
}
// When pkger is run, code analysis detects this Include statement,
// triggering the serializaation of the templates directory and all
// triggering the serialization of the templates directory and all
// its contents into pkged.go, which is then made available via
// a pkger fileAccessor.
// Path is relative to the go module root.

View File

@ -54,7 +54,7 @@ func TestTemplatesExtensibleFileMode(t *testing.T) {
}
defer os.RemoveAll(path)
client := New(WithTemplates(templates))
client := New(WithPackages(templates))
function := Function{Root: path, Runtime: "quarkus", Template: template}
if err := client.Create(function); err != nil {
t.Fatal(err)