Fixes #220, uses FN_REGISTRY and --registry flag on push and deploy. Also, cleanup.

This commit is contained in:
Travis Reeder
2017-08-18 16:27:11 -07:00
parent d773db51d4
commit d3f349804e
16 changed files with 192 additions and 187 deletions

View File

@@ -4,6 +4,9 @@ all: vendor build
build:
go build -o fn
install:
go build -o ${GOPATH}/bin/fn
docker: vendor
GOOS=linux go build -o fn
docker build -t treeder/fn .
@@ -23,3 +26,5 @@ release:
GOOS=darwin go build -o fn_mac
GOOS=windows go build -o fn.exe
docker run --rm -v ${PWD}:/go/src/github.com/fnproject/fn/cli -w /go/src/github.com/fnproject/fn/cli funcy/go:dev go build -o fn_alpine
.PHONY: install

View File

@@ -12,13 +12,13 @@ if you are using Node, put the code that you want to execute in the file `func.j
Run:
```sh
fn init <DOCKER_HUB_USERNAME>/<FUNCTION_NAME>
fn init [<FUNCTION_NAME>]
```
If you want to override the convention with configuration, you can do that as well using:
```sh
fn init [--runtime node] [--entrypoint "node hello.js"] <DOCKER_HUB_USERNAME>/<FUNCTION_NAME>
fn init [--runtime node] [--entrypoint "node hello.js"] [<FUNCTION_NAME>]
```
Or, if you want full control, just make a Dockerfile. If `init` finds a Dockerfile, it will use that instead of runtime and entrypoint.

View File

@@ -40,8 +40,6 @@ func (b *buildcmd) flags() []cli.Flag {
// build will take the found valid function and build it
func (b *buildcmd) build(c *cli.Context) error {
verbwriter := verbwriter(b.verbose)
path, err := os.Getwd()
if err != nil {
return err
@@ -51,11 +49,11 @@ func (b *buildcmd) build(c *cli.Context) error {
return err
}
ff, err := buildfunc(verbwriter, fn, b.noCache)
ff, err := buildfunc(fn, b.noCache)
if err != nil {
return err
}
fmt.Printf("Function %v built successfully.\n", ff.FullName())
fmt.Printf("Function %v built successfully.\n", ff.ImageName())
return nil
}

View File

@@ -41,7 +41,6 @@ func (b *bumpcmd) flags() []cli.Flag {
// bump will take the found valid function and bump its version
func (b *bumpcmd) bump(c *cli.Context) error {
verbwriter := verbwriter(b.verbose)
path, err := os.Getwd()
if err != nil {
@@ -52,7 +51,7 @@ func (b *bumpcmd) bump(c *cli.Context) error {
return err
}
fmt.Fprintln(verbwriter, "bumping version for", fn)
fmt.Println("bumping version for", fn)
funcfile, err := parsefuncfile(fn)
if err != nil {

View File

@@ -11,6 +11,10 @@ import (
"github.com/go-openapi/strfmt"
)
const (
envFnToken = "FN_TOKEN"
)
func Host() string {
apiURL := os.Getenv("API_URL")
if apiURL == "" {
@@ -26,8 +30,8 @@ func Host() string {
func APIClient() *fnclient.Functions {
transport := httptransport.New(Host(), "/v1", []string{"http"})
if os.Getenv("FN_TOKEN") != "" {
transport.DefaultAuthentication = httptransport.BearerToken(os.Getenv("FN_TOKEN"))
if os.Getenv(envFnToken) != "" {
transport.DefaultAuthentication = httptransport.BearerToken(os.Getenv(envFnToken))
}
// create the API client, with the transport

View File

@@ -7,6 +7,7 @@ import (
"fmt"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"os/signal"
@@ -22,18 +23,23 @@ import (
const (
functionsDockerImage = "funcy/functions"
minRequiredDockerVersion = "17.5.0"
envFnRegistry = "FN_REGISTRY"
)
func verbwriter(verbose bool) io.Writer {
// this is too limiting, removes all logs which isn't what we want
// verbwriter := ioutil.Discard
// if verbose {
verbwriter := os.Stderr
// }
return verbwriter
type HasRegistry interface {
Registry() string
}
func buildfunc(verbwriter io.Writer, fn string, noCache bool) (*funcfile, error) {
func setRegistryEnv(hr HasRegistry) {
if hr.Registry() != "" {
err := os.Setenv(envFnRegistry, hr.Registry())
if err != nil {
log.Fatalf("Couldn't set %s env var: %v\n", envFnRegistry, err)
}
}
}
func buildfunc(fn string, noCache bool) (*funcfile, error) {
funcfile, err := parsefuncfile(fn)
if err != nil {
return nil, err
@@ -53,23 +59,21 @@ func buildfunc(verbwriter io.Writer, fn string, noCache bool) (*funcfile, error)
}
}
if err := localbuild(verbwriter, fn, funcfile.Build); err != nil {
if err := localbuild(fn, funcfile.Build); err != nil {
return nil, err
}
if err := dockerbuild(verbwriter, fn, funcfile, noCache); err != nil {
if err := dockerbuild(fn, funcfile, noCache); err != nil {
return nil, err
}
return funcfile, nil
}
func localbuild(verbwriter io.Writer, path string, steps []string) error {
func localbuild(path string, steps []string) error {
for _, cmd := range steps {
exe := exec.Command("/bin/sh", "-c", cmd)
exe.Dir = filepath.Dir(path)
exe.Stderr = verbwriter
exe.Stdout = verbwriter
if err := exe.Run(); err != nil {
return fmt.Errorf("error running command %v (%v)", cmd, err)
}
@@ -78,7 +82,7 @@ func localbuild(verbwriter io.Writer, path string, steps []string) error {
return nil
}
func dockerbuild(verbwriter io.Writer, path string, ff *funcfile, noCache bool) error {
func dockerbuild(path string, ff *funcfile, noCache bool) error {
err := dockerVersionCheck()
if err != nil {
return err
@@ -89,9 +93,9 @@ func dockerbuild(verbwriter io.Writer, path string, ff *funcfile, noCache bool)
var helper langs.LangHelper
dockerfile := filepath.Join(dir, "Dockerfile")
if !exists(dockerfile) {
helper = langs.GetLangHelper(*ff.Runtime)
helper = langs.GetLangHelper(ff.Runtime)
if helper == nil {
return fmt.Errorf("Cannot build, no language helper found for %v", *ff.Runtime)
return fmt.Errorf("Cannot build, no language helper found for %v", ff.Runtime)
}
dockerfile, err = writeTmpDockerfile(helper, dir, ff)
if err != nil {
@@ -106,7 +110,7 @@ func dockerbuild(verbwriter io.Writer, path string, ff *funcfile, noCache bool)
}
}
fmt.Printf("Building image %v\n", ff.FullName())
fmt.Printf("Building image %v\n", ff.ImageName())
cancel := make(chan os.Signal, 3)
signal.Notify(cancel, os.Interrupt) // and others perhaps
@@ -117,7 +121,7 @@ func dockerbuild(verbwriter io.Writer, path string, ff *funcfile, noCache bool)
go func(done chan<- error) {
args := []string{
"build",
"-t", ff.FullName(),
"-t", ff.ImageName(),
"-f", dockerfile,
}
if noCache {
@@ -261,8 +265,12 @@ func extractEnvConfig(configs []string) map[string]string {
}
func dockerpush(ff *funcfile) error {
fmt.Println("Pushing to docker registry...")
cmd := exec.Command("docker", "push", ff.FullName())
err := validImageName(ff.ImageName())
if err != nil {
return err
}
fmt.Printf("Pushing %v to docker registry...", ff.ImageName())
cmd := exec.Command("docker", "push", ff.ImageName())
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
if err := cmd.Run(); err != nil {
@@ -271,6 +279,19 @@ func dockerpush(ff *funcfile) error {
return nil
}
func validImageName(n string) error {
// must have at least owner name and a tag
split := strings.Split(n, ":")
if len(split) < 2 {
return errors.New("image name must have a tag")
}
split2 := strings.Split(split[0], "/")
if len(split2) < 2 {
return errors.New("image name must have an owner and name, eg: username/myfunc. Be sure to set FN_REGISTRY env var or pass in --registry.")
}
return nil
}
func appNamePath(img string) (string, string) {
sep := strings.Index(img, "/")
if sep < 0 {

View File

@@ -3,7 +3,6 @@ package main
import (
"errors"
"fmt"
"io"
"log"
"os"
"path"
@@ -40,8 +39,11 @@ type deploycmd struct {
incremental bool
skippush bool
noCache bool
registry string
}
verbwriter io.Writer
func (cmd *deploycmd) Registry() string {
return cmd.registry
}
func (p *deploycmd) flags() []cli.Flag {
@@ -73,18 +75,23 @@ func (p *deploycmd) flags() []cli.Flag {
Usage: "does not push Docker built images onto Docker Hub - useful for local development.",
Destination: &p.skippush,
},
cli.StringFlag{
Name: "registry",
Usage: "Sets the Docker owner for images and optionally the registry. This will be prefixed to your function name for pushing to Docker registries. eg: `--registry username` will set your Docker Hub owner. `--registry registry.hub.docker.com/username` will set the registry and owner.",
Destination: &p.registry,
},
}
}
func (p *deploycmd) scan(c *cli.Context) error {
p.appName = c.Args().First()
p.verbwriter = verbwriter(p.verbose)
var walked bool
wd, err := os.Getwd()
if err != nil {
log.Fatalln("Couldn't get working directory:", err)
}
setRegistryEnv(p)
err = filepath.Walk(wd, func(path string, info os.FileInfo, err error) error {
if path != wd && info.IsDir() {
@@ -101,7 +108,7 @@ func (p *deploycmd) scan(c *cli.Context) error {
e := p.deploy(c, path)
if err != nil {
fmt.Fprintln(p.verbwriter, path, e)
fmt.Println(path, e)
}
now := time.Now()
@@ -110,7 +117,7 @@ func (p *deploycmd) scan(c *cli.Context) error {
return e
})
if err != nil {
fmt.Fprintf(p.verbwriter, "error: %s\n", err)
fmt.Printf("error: %s\n", err)
}
if !walked {
@@ -132,7 +139,7 @@ func (p *deploycmd) deploy(c *cli.Context, funcFilePath string) error {
return err
}
funcfile, err := buildfunc(p.verbwriter, funcFileName, p.noCache)
funcfile, err := buildfunc(funcFileName, p.noCache)
if err != nil {
return err
}
@@ -152,7 +159,7 @@ func (p *deploycmd) deploy(c *cli.Context, funcFilePath string) error {
}
func (p *deploycmd) route(c *cli.Context, ff *funcfile) error {
fmt.Printf("Updating route %s using image %s...\n", ff.Path, ff.FullName())
fmt.Printf("Updating route %s using image %s...\n", ff.Path, ff.ImageName())
if err := resetBasePath(p.Configuration); err != nil {
return fmt.Errorf("error setting endpoint: %v", err)
}

View File

@@ -9,7 +9,6 @@ import (
"path/filepath"
"strings"
fnmodels "github.com/funcy/functions_go/models"
yaml "gopkg.in/yaml.v2"
)
@@ -39,43 +38,9 @@ type fftest struct {
}
type funcfile struct {
fnmodels.Route
Name string `yaml:"name,omitempty" json:"name,omitempty"`
Version string `yaml:"version,omitempty" json:"version,omitempty"`
Runtime *string `yaml:"runtime,omitempty" json:"runtime,omitempty"`
Entrypoint string `yaml:"entrypoint,omitempty" json:"entrypoint,omitempty"`
Cmd string `yaml:"cmd,omitempty" json:"cmd,omitempty"`
Build []string `yaml:"build,omitempty" json:"build,omitempty"`
Tests []fftest `yaml:"tests,omitempty" json:"tests,omitempty"`
}
func (ff *funcfile) FullName() string {
fname := ff.Name
if ff.Version != "" {
fname = fmt.Sprintf("%s:%s", fname, ff.Version)
}
return fname
}
func (ff *funcfile) RuntimeTag() (runtime, tag string) {
if ff.Runtime == nil {
return "", ""
}
rt := *ff.Runtime
tagpos := strings.Index(rt, ":")
if tagpos == -1 {
return rt, ""
}
return rt[:tagpos], rt[tagpos+1:]
}
type flatfuncfile struct {
Name string `yaml:"name,omitempty" json:"name,omitempty"`
Version string `yaml:"version,omitempty" json:"version,omitempty"`
Runtime *string `yaml:"runtime,omitempty" json:"runtime,omitempty"`
Runtime string `yaml:"runtime,omitempty" json:"runtime,omitempty"`
Entrypoint string `yaml:"entrypoint,omitempty" json:"entrypoint,omitempty"`
Cmd string `yaml:"cmd,omitempty" json:"cmd,omitempty"`
Build []string `yaml:"build,omitempty" json:"build,omitempty"`
@@ -91,44 +56,36 @@ type flatfuncfile struct {
Headers map[string][]string `yaml:"headers,omitempty" json:"headers,omitempty"`
}
func (ff *funcfile) MakeFlat() flatfuncfile {
return flatfuncfile{
Name: ff.Name,
Version: ff.Version,
Runtime: ff.Runtime,
Entrypoint: ff.Entrypoint,
Cmd: ff.Cmd,
Build: ff.Build,
Tests: ff.Tests,
// route-specific
Type: ff.Type,
Memory: ff.Memory,
Format: ff.Format,
Timeout: ff.Timeout,
Path: ff.Path,
Config: ff.Config,
Headers: ff.Headers,
func (ff *funcfile) ImageName() string {
fname := ff.Name
if !strings.Contains(fname, "/") {
// then we'll prefix FN_REGISTRY
reg := os.Getenv(envFnRegistry)
if reg != "" {
if reg[len(reg)-1] != '/' {
reg += "/"
}
fname = fmt.Sprintf("%s%s", reg, fname)
}
}
if ff.Version != "" {
fname = fmt.Sprintf("%s:%s", fname, ff.Version)
}
return fname
}
func (fff *flatfuncfile) MakeFuncFile() *funcfile {
ff := &funcfile{
Name: fff.Name,
Version: fff.Version,
Runtime: fff.Runtime,
Entrypoint: fff.Entrypoint,
Cmd: fff.Cmd,
Build: fff.Build,
Tests: fff.Tests,
func (ff *funcfile) RuntimeTag() (runtime, tag string) {
if ff.Runtime == "" {
return "", ""
}
ff.Type = fff.Type
ff.Memory = fff.Memory
ff.Format = fff.Format
ff.Timeout = fff.Timeout
ff.Path = fff.Path
ff.Config = fff.Config
ff.Headers = fff.Headers
return ff
rt := ff.Runtime
tagpos := strings.Index(rt, ":")
if tagpos == -1 {
return rt, ""
}
return rt[:tagpos], rt[tagpos+1:]
}
func findFuncfile(path string) (string, error) {
@@ -176,9 +133,10 @@ func decodeFuncfileJSON(path string) (*funcfile, error) {
if err != nil {
return nil, fmt.Errorf("could not open %s for parsing. Error: %v", path, err)
}
fff := new(flatfuncfile)
err = json.NewDecoder(f).Decode(fff)
ff := fff.MakeFuncFile()
ff := &funcfile{}
// ff.Route = &fnmodels.Route{}
err = json.NewDecoder(f).Decode(ff)
// ff := fff.MakeFuncFile()
return ff, err
}
@@ -187,9 +145,9 @@ func decodeFuncfileYAML(path string) (*funcfile, error) {
if err != nil {
return nil, fmt.Errorf("could not open %s for parsing. Error: %v", path, err)
}
fff := new(flatfuncfile)
err = yaml.Unmarshal(b, fff)
ff := fff.MakeFuncFile()
ff := &funcfile{}
err = yaml.Unmarshal(b, ff)
// ff := fff.MakeFuncFile()
return ff, err
}
@@ -198,11 +156,11 @@ func encodeFuncfileJSON(path string, ff *funcfile) error {
if err != nil {
return fmt.Errorf("could not open %s for encoding. Error: %v", path, err)
}
return json.NewEncoder(f).Encode(ff.MakeFlat())
return json.NewEncoder(f).Encode(ff)
}
func encodeFuncfileYAML(path string, ff *funcfile) error {
b, err := yaml.Marshal(ff.MakeFlat())
b, err := yaml.Marshal(ff)
if err != nil {
return fmt.Errorf("could not encode function file. Error: %v", err)
}

View File

@@ -45,12 +45,8 @@ func init() {
}
type initFnCmd struct {
name string
force bool
runtime string
entrypoint string
cmd string
version string
force bool
funcfile
}
func initFlags(a *initFnCmd) []cli.Flag {
@@ -63,17 +59,22 @@ func initFlags(a *initFnCmd) []cli.Flag {
cli.StringFlag{
Name: "runtime",
Usage: "choose an existing runtime - " + strings.Join(fnInitRuntimes, ", "),
Destination: &a.runtime,
Destination: &a.Runtime,
},
cli.StringFlag{
Name: "entrypoint",
Usage: "entrypoint is the command to run to start this function - equivalent to Dockerfile ENTRYPOINT.",
Destination: &a.entrypoint,
Destination: &a.Entrypoint,
},
cli.StringFlag{
Name: "cmd",
Usage: "command to run to start this function - equivalent to Dockerfile CMD.",
Destination: &a.Entrypoint,
},
cli.StringFlag{
Name: "version",
Usage: "function version",
Destination: &a.version,
Destination: &a.Version,
Value: initialVersion,
},
}
@@ -82,15 +83,16 @@ func initFlags(a *initFnCmd) []cli.Flag {
}
func initFn() cli.Command {
a := initFnCmd{}
a := &initFnCmd{}
// funcfile := &funcfile{}
return cli.Command{
Name: "init",
Usage: "create a local func.yaml file",
Description: "Creates a func.yaml file in the current directory. ",
ArgsUsage: "<DOCKERHUB_USERNAME/FUNCTION_NAME>",
Description: "Creates a func.yaml file in the current directory.",
ArgsUsage: "[FUNCTION_NAME]",
Action: a.init,
Flags: initFlags(&a),
Flags: initFlags(a),
}
}
@@ -109,13 +111,13 @@ func (a *initFnCmd) init(c *cli.Context) error {
}
}
runtimeSpecified := a.runtime != ""
err := a.buildFuncFile(c)
if err != nil {
return err
}
runtimeSpecified := a.Runtime != ""
if runtimeSpecified {
err := a.generateBoilerplate()
if err != nil {
@@ -123,21 +125,12 @@ func (a *initFnCmd) init(c *cli.Context) error {
}
}
ff := &funcfile{
*rt,
a.name,
a.version,
&a.runtime,
a.entrypoint,
a.cmd,
[]string{},
[]fftest{},
}
ff := a.funcfile
_, path := appNamePath(ff.FullName())
_, path := appNamePath(ff.ImageName())
ff.Path = path
if err := encodeFuncfileYAML("func.yaml", ff); err != nil {
if err := encodeFuncfileYAML("func.yaml", &ff); err != nil {
return err
}
@@ -146,7 +139,7 @@ func (a *initFnCmd) init(c *cli.Context) error {
}
func (a *initFnCmd) generateBoilerplate() error {
helper := langs.GetLangHelper(a.runtime)
helper := langs.GetLangHelper(a.Runtime)
if helper != nil && helper.HasBoilerplate() {
if err := helper.GenerateBoilerplate(); err != nil {
if err == langs.ErrBoilerplateExists {
@@ -162,47 +155,52 @@ func (a *initFnCmd) generateBoilerplate() error {
func (a *initFnCmd) buildFuncFile(c *cli.Context) error {
pwd, err := os.Getwd()
if err != nil {
return fmt.Errorf("error detecting current working directory: %s", err)
return fmt.Errorf("error detecting current working directory: %v", err)
}
a.name = c.Args().First()
if a.name == "" || strings.Contains(a.name, ":") {
return errors.New("please specify a name for your function in the following format <DOCKERHUB_USERNAME>/<FUNCTION_NAME>.\nTry: fn init <DOCKERHUB_USERNAME>/<FUNCTION_NAME>")
a.Name = c.Args().First()
// if a.name == "" {
// // return errors.New("please specify a name for your function.\nTry: fn init <FUNCTION_NAME>")
// } else
if a.Name == "" {
// then use current directory for name
a.Name = filepath.Base(pwd)
} else if strings.Contains(a.Name, ":") {
return errors.New("function name cannot contain a colon")
}
if exists("Dockerfile") {
fmt.Println("Dockerfile found. Let's use that to build...")
return nil
}
var rt string
if a.runtime == "" {
if a.Runtime == "" {
rt, err = detectRuntime(pwd)
if err != nil {
return err
}
a.runtime = rt
a.Runtime = rt
fmt.Printf("Found %v, assuming %v runtime.\n", rt, rt)
} else {
fmt.Println("Runtime:", a.runtime)
fmt.Println("Runtime:", a.Runtime)
}
helper := langs.GetLangHelper(a.runtime)
helper := langs.GetLangHelper(a.Runtime)
if helper == nil {
fmt.Printf("init does not support the %s runtime, you'll have to create your own Dockerfile for this function", a.runtime)
fmt.Printf("init does not support the %s runtime, you'll have to create your own Dockerfile for this function", a.Runtime)
}
if a.entrypoint == "" {
if a.Entrypoint == "" {
if helper != nil {
a.entrypoint = helper.Entrypoint()
a.Entrypoint = helper.Entrypoint()
}
}
if a.cmd == "" {
if a.Cmd == "" {
if helper != nil {
a.cmd = helper.Cmd()
a.Cmd = helper.Cmd()
}
}
if a.entrypoint == "" && a.cmd == "" {
return fmt.Errorf("could not detect entrypoint or cmd for %v, use --entrypoint and/or --cmd to set them explicitly", a.runtime)
if a.Entrypoint == "" && a.Cmd == "" {
return fmt.Errorf("could not detect entrypoint or cmd for %v, use --entrypoint and/or --cmd to set them explicitly", a.Runtime)
}
return nil
@@ -221,5 +219,5 @@ func detectRuntime(path string) (runtime string, err error) {
}
}
}
return "", fmt.Errorf("no supported files found to guess runtime, please set runtime explicitly with --runtime flag.")
return "", fmt.Errorf("no supported files found to guess runtime, please set runtime explicitly with --runtime flag")
}

View File

@@ -181,7 +181,7 @@ func createFunctionYaml(opts createImageOptions, functionName string) error {
funcDesc := &funcfile{
Name: opts.Name,
Version: "0.0.1",
Runtime: &opts.Base,
Runtime: opts.Base,
Cmd: opts.Handler,
}
funcDesc.Config = opts.Config

View File

@@ -132,7 +132,7 @@ func main() {
err := app.Run(os.Args)
if err != nil {
// TODO: this doesn't seem to get called even when an error returns from a command, but maybe urfave is doing a non zero exit anyways? nope: https://github.com/urfave/cli/issues/610
fmt.Printf("Error occurred: %v, exiting...\n", err)
fmt.Fprintf(os.Stderr, "Error occurred: %v, exiting...\n", err)
os.Exit(1)
}
}

View File

@@ -20,7 +20,12 @@ func push() cli.Command {
}
type pushcmd struct {
verbose bool
verbose bool
registry string
}
func (cmd *pushcmd) Registry() string {
return cmd.registry
}
func (p *pushcmd) flags() []cli.Flag {
@@ -30,6 +35,11 @@ func (p *pushcmd) flags() []cli.Flag {
Usage: "verbose mode",
Destination: &p.verbose,
},
cli.StringFlag{
Name: "registry",
Usage: "Sets the Docker owner for images and optionally the registry. This will be prefixed to your function name for pushing to Docker registries. eg: `--registry username` will set your Docker Hub owner. `--registry registry.hub.docker.com/username` will set the registry and owner.",
Destination: &p.registry,
},
}
}
@@ -38,7 +48,7 @@ func (p *pushcmd) flags() []cli.Flag {
// push the container, and finally it will update function's route. Optionally,
// the route can be overriden inside the functions file.
func (p *pushcmd) push(c *cli.Context) error {
verbwriter := verbwriter(p.verbose)
setRegistryEnv(p)
ff, err := loadFuncfile()
if err != nil {
@@ -48,12 +58,12 @@ func (p *pushcmd) push(c *cli.Context) error {
return err
}
fmt.Fprintln(verbwriter, "pushing", ff.FullName())
fmt.Println("pushing", ff.ImageName())
if err := dockerpush(ff); err != nil {
return err
}
fmt.Printf("Function %v pushed successfully to Docker Hub.\n", ff.FullName())
fmt.Printf("Function %v pushed successfully to Docker Hub.\n", ff.ImageName())
return nil
}

View File

@@ -268,8 +268,8 @@ func routeWithFuncFile(c *cli.Context, ff *funcfile, rt *fnmodels.Route) error {
return err
}
}
if ff.FullName() != "" { // args take precedence
rt.Image = ff.FullName()
if ff.ImageName() != "" { // args take precedence
rt.Image = ff.ImageName()
}
if ff.Format != "" {
rt.Format = ff.Format

View File

@@ -176,7 +176,7 @@ func runff(ff *funcfile, stdin io.Reader, stdout, stderr io.Writer, method strin
stdin = strings.NewReader(body)
}
sh = append(sh, ff.FullName())
sh = append(sh, ff.ImageName())
cmd := exec.Command(sh[0], sh[1:]...)
cmd.Stdin = stdin
cmd.Stdout = stdout

View File

@@ -95,7 +95,7 @@ func (t *testcmd) test(c *cli.Context) error {
fmt.Printf("Running %v tests...", len(tests))
target := ff.FullName()
target := ff.ImageName()
runtest := runlocaltest
if t.remote != "" {
if ff.Path == "" {
@@ -116,7 +116,7 @@ func (t *testcmd) test(c *cli.Context) error {
}
errorCount := 0
fmt.Println("running tests on", ff.FullName(), ":")
fmt.Println("running tests on", ff.ImageName(), ":")
for i, tt := range tests {
fmt.Printf("\nTest %v\n", i+1)
start := time.Now()