Skip to content

Commit 757f7a0

Browse files
authored
*: remove GOPATH requirement from the SDK and operator projects (#1475)
* internal/util/projutil: generalize project util functions for GOPATH and non-GOPATH scenarios * *.go: remove `projutil.CheckAndGetProjectGoPkg()` and use `projutil.GetGoPkg()` instead *.md: remove $GOPATH references * test/e2e/main_test.go: use testArgs struct for test args; add local-repo flag to specify the local repo path if the SDK is not in $GOPATH/src/github.com/operator-framework/operator-sdk test/e2e/memcached_test.go: remove any 'replace' directives for the SDK repo in memcached-operator's go.mod file before adding one for the e2e test; cp e2e code templates without replacing repo; set --repo in "operator-sdk new" * hack/tests/e2e-{ansible,helm}.sh: remove SDK replace lines in go.mod before adding one * CHANGELOG.md: add GOPATH change and --repo addition * doc/sdk-cli-reference.md: add --repo to new and migrate, and add/remove some flags where appropriate
1 parent 78f5488 commit 757f7a0

File tree

26 files changed

+220
-97
lines changed

26 files changed

+220
-97
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@
99
- Generating and serving info metrics about each custom resource. By default these metrics are exposed on port 8686. ([#1277](https://github.com/operator-framework/operator-sdk/pull/1277))
1010
- Scaffold a `pkg/apis/<group>/group.go` package file to avoid `go/build` errors when running Kubernetes code generators. ([#1401](https://github.com/operator-framework/operator-sdk/pull/1401))
1111
- Adds a new extra variable containing the unmodified CR spec for ansible based operators. [#1563](https://github.com/operator-framework/operator-sdk/pull/1563)
12+
- New flag `--repo` for subcommands [`new`](https://github.com/operator-framework/operator-sdk/blob/master/doc/sdk-cli-reference.md#new) and [`migrate`](https://github.com/operator-framework/operator-sdk/blob/master/doc/sdk-cli-reference.md#migrate) specifies the repository path to be used in Go source files generated by the SDK. This flag can only be used with [Go modules](https://github.com/golang/go/wiki/Modules). ([#1475](https://github.com/operator-framework/operator-sdk/pull/1475))
1213

1314
### Changed
1415

1516
- Remove TypeMeta declaration from the implementation of the objects [#1462](https://github.com/operator-framework/operator-sdk/pull/1462/)
1617
- Relaxed API version format check when parsing `pkg/apis` in code generators. API dir structures can now be of the format `pkg/apis/<group>/<anything>`, where `<anything>` was previously required to be in the Kubernetes version format, ex. `v1alpha1`. ([#1525](https://github.com/operator-framework/operator-sdk/pull/1525))
18+
- The SDK and operator projects will work outside of `$GOPATH/src` when using [Go modules](https://github.com/golang/go/wiki/Modules). ([#1475](https://github.com/operator-framework/operator-sdk/pull/1475))
1719

1820
### Deprecated
1921

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ Follow the steps in the [installation guide][install_guide] to learn how to inst
5757

5858
```sh
5959
# Create an app-operator project that defines the App CR.
60-
$ mkdir -p $GOPATH/src/github.com/example-inc/
60+
$ mkdir -p $HOME/projects/example-inc/
6161
# Create a new app-operator project
62-
$ cd $GOPATH/src/github.com/example-inc/
62+
$ cd $HOME/projects/example-inc/
6363
$ export GO111MODULE=on
6464
$ operator-sdk new app-operator
6565
$ cd app-operator

cmd/operator-sdk/add/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func apiRun(cmd *cobra.Command, args []string) error {
103103
absProjectPath := projutil.MustGetwd()
104104

105105
cfg := &input.Config{
106-
Repo: projutil.CheckAndGetProjectGoPkg(),
106+
Repo: projutil.GetGoPkg(),
107107
AbsProjectPath: absProjectPath,
108108
}
109109
s := &scaffold.Scaffold{}

cmd/operator-sdk/add/controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ func controllerRun(cmd *cobra.Command, args []string) error {
8181
}
8282

8383
cfg := &input.Config{
84-
Repo: projutil.CheckAndGetProjectGoPkg(),
84+
Repo: projutil.GetGoPkg(),
8585
AbsProjectPath: projutil.MustGetwd(),
8686
}
8787
s := &scaffold.Scaffold{}

cmd/operator-sdk/add/crd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func verifyCRDFlags() error {
118118
return nil
119119
}
120120

121-
// verifyCRDDeployPath checks if the path <project-name>/deploy sub-directory is exists, and that is rooted under $GOPATH
121+
// verifyCRDDeployPath checks if the <project-name>/deploy directory exists.
122122
func verifyCRDDeployPath() error {
123123
wd, err := os.Getwd()
124124
if err != nil {

cmd/operator-sdk/build/cmd.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,17 +93,16 @@ func buildFunc(cmd *cobra.Command, args []string) error {
9393
goBuildEnv = append(goBuildEnv, "CGO_ENABLED=0")
9494
}
9595

96-
trimPath := os.ExpandEnv("all=-trimpath=${GOPATH}")
97-
goTrimFlags := []string{"-gcflags", trimPath, "-asmflags", trimPath}
9896
absProjectPath := projutil.MustGetwd()
9997
projectName := filepath.Base(absProjectPath)
10098

10199
// Don't need to build Go code if a non-Go Operator.
102100
if projutil.IsOperatorGo() {
101+
trimPath := fmt.Sprintf("all=-trimpath=%s", filepath.Dir(absProjectPath))
103102
opts := projutil.GoCmdOptions{
104103
BinName: filepath.Join(absProjectPath, scaffold.BuildBinDir, projectName),
105-
PackagePath: path.Join(projutil.CheckAndGetProjectGoPkg(), filepath.ToSlash(scaffold.ManagerDir)),
106-
Args: goTrimFlags,
104+
PackagePath: path.Join(projutil.GetGoPkg(), filepath.ToSlash(scaffold.ManagerDir)),
105+
Args: []string{"-gcflags", trimPath, "-asmflags", trimPath},
107106
Env: goBuildEnv,
108107
GoMod: projutil.IsDepManagerGoMod(),
109108
}

cmd/operator-sdk/internal/genutil/k8s.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import (
3535
func K8sCodegen() error {
3636
projutil.MustInProjectRoot()
3737

38-
repoPkg := projutil.CheckAndGetProjectGoPkg()
38+
repoPkg := projutil.GetGoPkg()
3939

4040
gvMap, err := parseGroupVersions()
4141
if err != nil {

cmd/operator-sdk/internal/genutil/openapi.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func OpenAPIGen() error {
3838
projutil.MustInProjectRoot()
3939

4040
absProjectPath := projutil.MustGetwd()
41-
repoPkg := projutil.CheckAndGetProjectGoPkg()
41+
repoPkg := projutil.GetGoPkg()
4242

4343
gvMap, err := parseGroupVersions()
4444
if err != nil {

cmd/operator-sdk/main.go

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package main
1616

1717
import (
18+
"fmt"
1819
"os"
1920

2021
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
@@ -48,14 +49,15 @@ func main() {
4849
Short: "An SDK for building operators with ease",
4950
PersistentPreRun: func(cmd *cobra.Command, args []string) {
5051
if viper.GetBool(flags.VerboseOpt) {
51-
err := projutil.SetGoVerbose()
52-
if err != nil {
53-
log.Errorf("Could not set GOFLAGS: (%v)", err)
54-
return
52+
if err := projutil.SetGoVerbose(); err != nil {
53+
log.Fatalf("Could not set GOFLAGS: (%v)", err)
5554
}
5655
log.SetLevel(log.DebugLevel)
5756
log.Debug("Debug logging is set")
5857
}
58+
if err := checkDepManagerForCmd(cmd); err != nil {
59+
log.Fatal(err)
60+
}
5961
},
6062
}
6163

@@ -82,3 +84,77 @@ func main() {
8284
os.Exit(1)
8385
}
8486
}
87+
88+
func checkDepManagerForCmd(cmd *cobra.Command) (err error) {
89+
// Certain commands are able to be run anywhere or handle this check
90+
// differently in their CLI code.
91+
if skipCheckForCmd(cmd) {
92+
return nil
93+
}
94+
// Do not perform this check if the project is non-Go, as they will not have
95+
// a (Go) dep manager.
96+
if !projutil.IsOperatorGo() {
97+
return nil
98+
}
99+
// Do not perform a dep manager check if the working directory is not in
100+
// the project root, as some sub-commands might not require project root.
101+
// Individual subcommands will perform this check as needed.
102+
if err := projutil.CheckProjectRoot(); err != nil {
103+
return nil
104+
}
105+
106+
dm, err := projutil.GetDepManagerType()
107+
if err != nil {
108+
return err
109+
}
110+
return checkDepManager(dm)
111+
}
112+
113+
var commandsToSkip = map[string]struct{}{
114+
"new": struct{}{}, // Handles this logic in cmd/operator-sdk/new
115+
"migrate": struct{}{}, // Handles this logic in cmd/operator-sdk/migrate
116+
"operator-sdk": struct{}{}, // Alias for "help"
117+
"help": struct{}{},
118+
"completion": struct{}{},
119+
"version": struct{}{},
120+
}
121+
122+
func skipCheckForCmd(cmd *cobra.Command) (skip bool) {
123+
if _, ok := commandsToSkip[cmd.Name()]; ok {
124+
return true
125+
}
126+
cmd.VisitParents(func(pc *cobra.Command) {
127+
if _, ok := commandsToSkip[pc.Name()]; ok {
128+
// The bare "operator-sdk" command will be checked above.
129+
if pc.Name() != "operator-sdk" {
130+
skip = true
131+
}
132+
}
133+
})
134+
return skip
135+
}
136+
137+
func checkDepManager(dm projutil.DepManagerType) error {
138+
switch dm {
139+
case projutil.DepManagerGoMod:
140+
goModOn, err := projutil.GoModOn()
141+
if err != nil {
142+
return err
143+
}
144+
if !goModOn {
145+
return fmt.Errorf(`dependency manager "modules" requires working directory to be in $GOPATH/src` +
146+
` and GO111MODULE=on, or outside of $GOPATH/src and GO111MODULE="on", "auto", or unset`)
147+
}
148+
case projutil.DepManagerDep:
149+
inGopathSrc, err := projutil.WdInGoPathSrc()
150+
if err != nil {
151+
return err
152+
}
153+
if !inGopathSrc {
154+
return fmt.Errorf(`dependency manager "dep" requires working directory to be in $GOPATH/src`)
155+
}
156+
default:
157+
return projutil.ErrInvalidDepManager(dm)
158+
}
159+
return nil
160+
}

cmd/operator-sdk/migrate/cmd.go

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
var (
3434
depManager string
3535
headerFile string
36+
repo string
3637
)
3738

3839
// NewCmd returns a command that will add source code to an existing non-go operator
@@ -46,6 +47,7 @@ func NewCmd() *cobra.Command {
4647

4748
newCmd.Flags().StringVar(&depManager, "dep-manager", "modules", `Dependency manager the new project will use (choices: "dep", "modules")`)
4849
newCmd.Flags().StringVar(&headerFile, "header-file", "", "Path to file containing headers for generated Go files. Copied to hack/boilerplate.go.txt")
50+
newCmd.Flags().StringVar(&repo, "repo", "", "Project repository path. Used as the project's Go import path. This must be set if outside of $GOPATH/src with Go modules, and cannot be set if --dep-manager=dep")
4951

5052
return newCmd
5153
}
@@ -55,7 +57,13 @@ func NewCmd() *cobra.Command {
5557
func migrateRun(cmd *cobra.Command, args []string) error {
5658
projutil.MustInProjectRoot()
5759

58-
_ = projutil.CheckAndGetProjectGoPkg()
60+
if err := verifyFlags(); err != nil {
61+
return err
62+
}
63+
64+
if repo == "" {
65+
repo = projutil.GetGoPkg()
66+
}
5967

6068
opType := projutil.GetOperatorType()
6169
switch opType {
@@ -67,12 +75,20 @@ func migrateRun(cmd *cobra.Command, args []string) error {
6775
return fmt.Errorf("operator of type %s cannot be migrated", opType)
6876
}
6977

78+
func verifyFlags() error {
79+
err := projutil.CheckDepManagerWithRepo(projutil.DepManagerType(depManager), repo)
80+
if err != nil {
81+
return err
82+
}
83+
return nil
84+
}
85+
7086
// migrateAnsible runs the migration process for an ansible-based operator
7187
func migrateAnsible() error {
7288
wd := projutil.MustGetwd()
7389

7490
cfg := &input.Config{
75-
Repo: projutil.CheckAndGetProjectGoPkg(),
91+
Repo: repo,
7692
AbsProjectPath: wd,
7793
ProjectName: filepath.Base(wd),
7894
}
@@ -126,7 +142,7 @@ func migrateHelm() error {
126142
wd := projutil.MustGetwd()
127143

128144
cfg := &input.Config{
129-
Repo: projutil.CheckAndGetProjectGoPkg(),
145+
Repo: repo,
130146
AbsProjectPath: wd,
131147
ProjectName: filepath.Base(wd),
132148
}
@@ -180,9 +196,6 @@ func scaffoldHelmDepManager(s *scaffold.Scaffold, cfg *input.Config) error {
180196
case projutil.DepManagerDep:
181197
files = append(files, &helm.GopkgToml{})
182198
case projutil.DepManagerGoMod:
183-
if err := goModCheck(); err != nil {
184-
return err
185-
}
186199
files = append(files, &helm.GoMod{}, &scaffold.Tools{})
187200
default:
188201
return projutil.ErrInvalidDepManager(depManager)
@@ -196,21 +209,9 @@ func scaffoldAnsibleDepManager(s *scaffold.Scaffold, cfg *input.Config) error {
196209
case projutil.DepManagerDep:
197210
files = append(files, &ansible.GopkgToml{})
198211
case projutil.DepManagerGoMod:
199-
if err := goModCheck(); err != nil {
200-
return err
201-
}
202212
files = append(files, &ansible.GoMod{}, &scaffold.Tools{})
203213
default:
204214
return projutil.ErrInvalidDepManager(depManager)
205215
}
206216
return s.Execute(cfg, files...)
207217
}
208-
209-
func goModCheck() error {
210-
goModOn, err := projutil.GoModOn()
211-
if err == nil && !goModOn {
212-
log.Fatal(`Dependency manager "modules" has been selected but go modules are not active. ` +
213-
`Activate modules then run "operator-sdk migrate".`)
214-
}
215-
return err
216-
}

0 commit comments

Comments
 (0)