diff --git a/commands/operator-sdk/cmd/build.go b/commands/operator-sdk/cmd/build.go index 11269d671f..a060c7e876 100644 --- a/commands/operator-sdk/cmd/build.go +++ b/commands/operator-sdk/cmd/build.go @@ -22,6 +22,7 @@ import ( "log" "os" "os/exec" + "path/filepath" "strings" "github.com/operator-framework/operator-sdk/commands/operator-sdk/cmd/cmdutil" @@ -144,14 +145,20 @@ func buildFunc(cmd *cobra.Command, args []string) { cmdError.ExitWithError(cmdError.ExitBadArgs, fmt.Errorf("build command needs exactly 1 argument")) } + cmdutil.MustInProjectRoot() + goBuildEnv := append(os.Environ(), "GOOS=linux", "GOARCH=amd64", "CGO_ENABLED=0") + wd, err := os.Getwd() + if err != nil { + cmdError.ExitWithError(cmdError.ExitError, fmt.Errorf("could not identify current working directory: %v", err)) + } + // Don't need to buld go code if Ansible Operator if mainExists() { - bcmd := exec.Command(build) - bcmd.Env = append(os.Environ(), fmt.Sprintf("TEST_LOCATION=%v", testLocationBuild)) - bcmd.Env = append(bcmd.Env, fmt.Sprintf("ENABLE_TESTS=%v", enableTests)) - o, err := bcmd.CombinedOutput() + buildCmd := exec.Command("go", "build", "-o", filepath.Join(wd, "tmp/_output/bin", filepath.Base(wd)), filepath.Join(cmdutil.GetCurrPkg(), "cmd", filepath.Base(wd))) + buildCmd.Env = goBuildEnv + o, err := buildCmd.CombinedOutput() if err != nil { - cmdError.ExitWithError(cmdError.ExitError, fmt.Errorf("failed to build: (%v)", string(o))) + log.Fatalf("failed to build operator binary: %v (%v)", err, string(o)) } fmt.Fprintln(os.Stdout, string(o)) } @@ -173,6 +180,18 @@ func buildFunc(cmd *cobra.Command, args []string) { fmt.Fprintln(os.Stdout, string(o)) if enableTests { + buildTestCmd := exec.Command("go", "test", "-c", "-o", filepath.Join(wd, "tmp/_output/bin", filepath.Base(wd)+"-test"), testLocationBuild+"/...") + buildTestCmd.Env = goBuildEnv + o, err := buildTestCmd.CombinedOutput() + if err != nil { + log.Fatalf("failed to build test binary: %v (%v)", err, string(o)) + } + fmt.Fprintln(os.Stdout, string(o)) + // if a user is using an older sdk repo as their library, make sure they have required build files + _, err = os.Stat("tmp/build/test-framework/Dockerfile") + if err != nil { + generator.RenderTestingContainerFiles(filepath.Join(wd, "tmp/build"), filepath.Base(wd)) + } testDbcmd := exec.Command("docker", "build", ".", "-f", "tmp/build/test-framework/Dockerfile", "-t", image, "--build-arg", "NAMESPACEDMAN="+namespacedManBuild, "--build-arg", "BASEIMAGE="+baseImageName) o, err = testDbcmd.CombinedOutput() if err != nil { diff --git a/commands/operator-sdk/cmd/cmdutil/util.go b/commands/operator-sdk/cmd/cmdutil/util.go index 29816eefc8..b109799d7e 100644 --- a/commands/operator-sdk/cmd/cmdutil/util.go +++ b/commands/operator-sdk/cmd/cmdutil/util.go @@ -15,9 +15,13 @@ package cmdutil import ( + "errors" "fmt" + gobuild "go/build" "io/ioutil" "os" + "path/filepath" + "strings" cmdError "github.com/operator-framework/operator-sdk/commands/operator-sdk/error" "github.com/operator-framework/operator-sdk/pkg/generator" @@ -49,3 +53,23 @@ func GetConfig() *generator.Config { } return c } + +// GetCurrPkg returns the current directory's import path +// e.g: "github.com/example-inc/app-operator" +func GetCurrPkg() string { + gopath := os.Getenv("GOPATH") + if len(gopath) == 0 { + gopath = gobuild.Default.GOPATH + } + goSrc := filepath.Join(gopath, "src") + + wd, err := os.Getwd() + if err != nil { + cmdError.ExitWithError(cmdError.ExitError, fmt.Errorf("failed to get working directory: (%v)", err)) + } + if !strings.HasPrefix(filepath.Dir(wd), goSrc) { + cmdError.ExitWithError(cmdError.ExitError, errors.New("must run from gopath")) + } + currPkg := strings.Replace(wd, goSrc+string(filepath.Separator), "", 1) + return currPkg +} diff --git a/pkg/generator/generator.go b/pkg/generator/generator.go index a10eb5999a..1d11ffc142 100644 --- a/pkg/generator/generator.go +++ b/pkg/generator/generator.go @@ -503,22 +503,10 @@ func (g *Generator) renderVersion() error { } func renderBuildFiles(buildDir, repoPath, projectName, operatorType string, generatePlaybook bool) error { - buf := &bytes.Buffer{} - bTd := tmplData{ - ProjectName: projectName, - RepoPath: repoPath, - } - var dockerFileTmplName string switch operatorType { case goOperatorType: dockerFileTmplName = dockerFileTmpl - if err := renderFile(buf, "tmp/build/build.sh", buildTmpl, bTd); err != nil { - return err - } - if err := writeFileAndPrint(filepath.Join(buildDir, build), buf.Bytes(), defaultExecFileMode); err != nil { - return err - } case ansibleOperatorType: dockerFileTmplName = dockerFileAnsibleTmpl } @@ -532,11 +520,17 @@ func renderBuildFiles(buildDir, repoPath, projectName, operatorType string, gene return err } + return RenderTestingContainerFiles(buildDir, projectName) +} + +func RenderTestingContainerFiles(buildDir, projectName string) error { + dTd := tmplData{ + ProjectName: projectName, + } if err := renderWriteFile(filepath.Join(buildDir, "test-framework", testingDockerfile), "tmp/build/test-framework/Dockerfile", testingDockerFileTmpl, dTd); err != nil { return err } - - buf = &bytes.Buffer{} + buf := &bytes.Buffer{} if err := renderFile(buf, filepath.Join(buildDir, goTest), goTestScript, tmplData{}); err != nil { return err } diff --git a/pkg/generator/generator_test.go b/pkg/generator/generator_test.go index b5a619ff06..17e1655eea 100644 --- a/pkg/generator/generator_test.go +++ b/pkg/generator/generator_test.go @@ -593,21 +593,6 @@ COPY watches.yaml ${HOME}/watches.yaml func TestGenBuild(t *testing.T) { buf := &bytes.Buffer{} - bTd := tmplData{ - ProjectName: appProjectName, - RepoPath: appRepoPath, - } - if err := renderFile(buf, "tmp/build/build.sh", buildTmpl, bTd); err != nil { - t.Error(err) - return - } - if buildExp != buf.String() { - dmp := diffmatchpatch.New() - diffs := dmp.DiffMain(buildExp, buf.String(), false) - t.Errorf("\nTest failed. Below is the diff of the expected vs actual results.\nRed text is missing and green text is extra.\n\n" + dmp.DiffPrettyText(diffs)) - } - - buf = &bytes.Buffer{} dTd := tmplData{ ProjectName: appProjectName, } diff --git a/pkg/generator/templates.go b/pkg/generator/templates.go index 5e4126849c..f1774af24a 100644 --- a/pkg/generator/templates.go +++ b/pkg/generator/templates.go @@ -551,30 +551,6 @@ deepcopy \ {{.APIDirName}}:{{.Version}} \ --go-header-file "./tmp/codegen/boilerplate.go.txt" ` -const buildTmpl = `#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -if ! which go > /dev/null; then - echo "golang needs to be installed" - exit 1 -fi - -BIN_DIR="$(pwd)/tmp/_output/bin" -mkdir -p ${BIN_DIR} -PROJECT_NAME="{{.ProjectName}}" -REPO_PATH="{{.RepoPath}}" -BUILD_PATH="${REPO_PATH}/cmd/${PROJECT_NAME}" -TEST_PATH="${REPO_PATH}/${TEST_LOCATION}" -echo "building "${PROJECT_NAME}"..." -GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o ${BIN_DIR}/${PROJECT_NAME} $BUILD_PATH -if $ENABLE_TESTS ; then - echo "building "${PROJECT_NAME}-test"..." - GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go test -c -o ${BIN_DIR}/${PROJECT_NAME}-test $TEST_PATH -fi -` const goTestScript = `#!/bin/sh