Skip to content

Commit b8eff8f

Browse files
author
Phillip Wittrock
authored
Merge pull request #140 from droot/dep-manifest-upgrade
preserve user dependencies during 'update vendor'
2 parents 2f9c87f + 79c7537 commit b8eff8f

File tree

5 files changed

+212
-32
lines changed

5 files changed

+212
-32
lines changed

cmd/kubebuilder/initproject/dep_manifest.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,23 @@ limitations under the License.
1616

1717
package initproject
1818

19+
const depManifestHeader = `
20+
# Users add deps lines here
21+
22+
[prune]
23+
go-tests = true
24+
#unused-packages = true
25+
26+
# Note: Stanzas below are generated by Kubebuilder and may be rewritten when
27+
# upgrading kubebuilder versions.
28+
`
29+
30+
// depManifestKBMarker acts as a separater between the user managed dependencies
31+
// and KB generated dependencies. Content above this marker is user managed and
32+
// needs to be preserved across 'vendor update' operations. Content below this
33+
// marker is generated by KB and will be updated by KB during 'vendor update'.
34+
const depManifestKBMarker = `# DO NOT MODIFY BELOW THIS LINE.`
35+
1936
// template for dep's manifest file (Gopkg.toml). This is generated using
2037
// scripts/generate_dep_manifest.sh scripts.
2138
const depManifestOverride = `

cmd/kubebuilder/initproject/vendor.go

Lines changed: 98 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,16 @@ limitations under the License.
1717
package initproject
1818

1919
import (
20+
"bufio"
21+
"bytes"
2022
"fmt"
23+
"html/template"
24+
"io"
25+
"io/ioutil"
2126
"log"
2227
"os"
2328
"os/exec"
29+
"strings"
2430

2531
"github.com/spf13/cobra"
2632

@@ -49,30 +55,17 @@ func RunVendorInstall(cmd *cobra.Command, args []string) {
4955
if !depExists() {
5056
log.Fatalf("Dep is not installed. Follow steps at: https://golang.github.io/dep/docs/installation.html")
5157
}
52-
var backupFilename string
5358
if Update {
54-
backupFilename = fmt.Sprintf("%s.bkp", depManifestFile)
55-
if err := os.Rename(depManifestFile, backupFilename); err != nil {
56-
fmt.Printf("Error renaming existing Gopkg.toml file: %v \n", err)
57-
return
59+
if err := updateDepManifest(); err != nil {
60+
log.Fatalf("error upgrading the dep manifest (Gopkg.toml): %v", err)
5861
}
62+
} else {
63+
createNewDepManifest()
5964
}
60-
depTmplArgs := map[string]string{
61-
"Version": version.GetVersion().KubeBuilderVersion,
62-
}
63-
util.Write(depManifestFile, "dep-manifest-file", depManifestTmpl, depTmplArgs)
6465
if err := runDepEnsure(); err != nil {
6566
fmt.Printf("Error running 'dep ensure': %v\n", err)
66-
fmt.Printf("Previous Gopkg.toml file has been saved at '%s'\n", backupFilename)
6767
return
6868
}
69-
if Update && backupFilename != "" {
70-
err := os.Remove(backupFilename)
71-
if err != nil {
72-
fmt.Printf("Warning: failed to remove backup file: %s", backupFilename)
73-
}
74-
}
75-
return
7669
}
7770

7871
func runDepEnsure() error {
@@ -92,16 +85,94 @@ func depExists() bool {
9285
return err == nil
9386
}
9487

95-
var depManifestTmpl = fmt.Sprintf("%s\n%s", depManifestHeader, depManifestOverride)
88+
func createNewDepManifest() {
89+
depTmplArgs := map[string]string{
90+
"Version": version.GetVersion().KubeBuilderVersion,
91+
}
92+
depManifestTmpl := fmt.Sprintf("%s\n%s\n%s", depManifestHeader, depManifestKBMarker, depManifestOverride)
93+
util.Write(depManifestFile, "dep-manifest-file", depManifestTmpl, depTmplArgs)
94+
}
95+
96+
// updateDepManifest updates the existing dep manifest with newer dependencies.
97+
// dep manifest update workflow:
98+
// Try to read user managed dep manifest section. If success, then append the
99+
// user managed dep with KB managed section and update the dep Manifest.
100+
func updateDepManifest() error {
101+
// open the existing dep manifest.
102+
f, err := os.Open(depManifestFile)
103+
if err != nil {
104+
return err
105+
}
106+
defer f.Close()
107+
108+
// try to read content till the dep marker
109+
userDeps, foundKBMarker, err := tryReadingUserDeps(f)
110+
if err != nil {
111+
return err
112+
}
113+
114+
if !foundKBMarker {
115+
// depManifest file or abort the operation here.
116+
// for now, aborting.
117+
log.Fatalf(`
118+
Failed to upgrade the dep manifest (Gopkg.toml) file. It seems that the dep manifest
119+
is not being managed by Kubebuilder. You can run the command with --overwrite-dep-manifest
120+
flag if you want to re-initialize the dep manifest file.
121+
`)
122+
}
123+
124+
b := bytes.NewBufferString(userDeps)
125+
err = addKubeBuilderDeps(b)
126+
if err != nil {
127+
return err
128+
}
129+
130+
tmpfile, err := ioutil.TempFile(".", "dep")
131+
if err != nil {
132+
return err
133+
}
96134

97-
const depManifestHeader = `
98-
# Users add deps lines here
135+
defer os.Remove(tmpfile.Name()) // clean up
99136

100-
[prune]
101-
go-tests = true
102-
#unused-packages = true
137+
_, err = tmpfile.Write(b.Bytes())
138+
if err != nil {
139+
return err
140+
}
141+
err = tmpfile.Close()
142+
if err != nil {
143+
return err
144+
}
103145

104-
# Note: Stanzas below are generated by Kubebuilder and may be rewritten when
105-
# upgrading kubebuilder versions.
106-
# DO NOT MODIFY BELOW THIS LINE.
107-
`
146+
err = os.Rename(tmpfile.Name(), depManifestFile)
147+
if err != nil {
148+
return err
149+
}
150+
return nil
151+
}
152+
153+
func tryReadingUserDeps(r io.Reader) (userDeps string, foundMarker bool, err error) {
154+
b := &bytes.Buffer{}
155+
scanner := bufio.NewScanner(r)
156+
157+
for scanner.Scan() {
158+
line := scanner.Text()
159+
b.WriteString(line)
160+
b.WriteString("\n")
161+
if strings.HasPrefix(line, depManifestKBMarker) {
162+
foundMarker = true
163+
userDeps = b.String()
164+
return
165+
}
166+
}
167+
168+
err = scanner.Err()
169+
return
170+
}
171+
172+
func addKubeBuilderDeps(w io.Writer) error {
173+
depTmplArgs := map[string]string{
174+
"Version": version.GetVersion().KubeBuilderVersion,
175+
}
176+
t := template.Must(template.New("dep-manifest-template").Parse(depManifestOverride))
177+
return t.Execute(w, depTmplArgs)
178+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
Copyright 2017 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package initproject
18+
19+
import (
20+
"bytes"
21+
"testing"
22+
)
23+
24+
func TestTryReadingUserDeps(t *testing.T) {
25+
tests := []struct {
26+
in string
27+
expKBMarker bool
28+
expUserDeps string
29+
}{
30+
{
31+
in: `
32+
ABC
33+
ABC
34+
jslsls
35+
sjsslsls
36+
`,
37+
expKBMarker: false,
38+
expUserDeps: "",
39+
},
40+
{
41+
in: `
42+
ABC
43+
ABC
44+
# DO NOT MODIFY BELOW THIS LINE.
45+
jslsls
46+
sjsslsls
47+
`,
48+
expKBMarker: true,
49+
expUserDeps: `
50+
ABC
51+
ABC
52+
# DO NOT MODIFY BELOW THIS LINE.
53+
`,
54+
},
55+
{
56+
in: `
57+
ABC
58+
ABC
59+
# DO NOT MODIFY BELOW THIS LINE.
60+
`,
61+
expKBMarker: true,
62+
expUserDeps: `
63+
ABC
64+
ABC
65+
# DO NOT MODIFY BELOW THIS LINE.
66+
`,
67+
},
68+
}
69+
70+
for _, test := range tests {
71+
r := bytes.NewReader([]byte(test.in))
72+
userDeps, kbMarker, err := tryReadingUserDeps(r)
73+
if err != nil {
74+
t.Errorf("Reading UserDeps should succeed, but got an error: %v", err)
75+
}
76+
if test.expKBMarker != kbMarker {
77+
t.Errorf("KB marker mismatch: exp: '%v' got: '%v'", test.expKBMarker, kbMarker)
78+
}
79+
if test.expUserDeps != userDeps {
80+
t.Errorf("UserDeps don't match: exp: '%v' got: '%v'", test.expUserDeps, userDeps)
81+
}
82+
83+
}
84+
}

cmd/kubebuilder/update/vendor.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ package update
1919
import (
2020
"github.com/spf13/cobra"
2121

22-
"github.com/emicklei/go-restful/log"
2322
"github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/initproject"
2423
)
2524

25+
var overwriteDepManifest bool
26+
2627
var vendorCmd = &cobra.Command{
2728
Use: "vendor",
2829
Short: "Update the vendor packages managed by kubebuilder.",
@@ -35,10 +36,14 @@ kubebuilder update vendor
3536

3637
func AddUpdateVendorCmd(cmd *cobra.Command) {
3738
cmd.AddCommand(vendorCmd)
39+
vendorCmd.Flags().BoolVar(&overwriteDepManifest, "overwrite-dep-manifest", false, "if true, overwrites the dep manifest file (Gopkg.toml)")
3840
}
3941

4042
func RunUpdateVendor(cmd *cobra.Command, args []string) {
4143
initproject.Update = true
42-
log.Printf("Replacing vendored libraries managed by kubebuilder with the current version.")
44+
if overwriteDepManifest {
45+
// suppress the update behavior
46+
initproject.Update = false
47+
}
4348
initproject.RunVendorInstall(cmd, args)
4449
}

test.sh

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -489,9 +489,9 @@ function test_generated_controller {
489489
go test -v ./pkg/...
490490
}
491491

492-
function run_dep_ensure {
493-
header_text "running dep ensure"
494-
dep ensure
492+
function test_vendor_update {
493+
header_text "performing vendor update"
494+
kubebuilder update vendor
495495
}
496496

497497
function test_docs {
@@ -510,4 +510,7 @@ prepare_testdir_under_gopath
510510
generate_crd_resources
511511
test_docs
512512
test_generated_controller
513+
test_vendor_update
514+
# re-running controller tests post vendor update
515+
test_generated_controller
513516
exit $rc

0 commit comments

Comments
 (0)