@@ -11,6 +11,7 @@ import (
11
11
12
12
log "github.com/sirupsen/logrus"
13
13
"github.com/spf13/afero"
14
+ "sigs.k8s.io/kubebuilder/v4/pkg/config/store"
14
15
"sigs.k8s.io/kubebuilder/v4/pkg/config/store/yaml"
15
16
"sigs.k8s.io/kubebuilder/v4/pkg/machinery"
16
17
)
@@ -20,6 +21,8 @@ type Update struct {
20
21
// FromVersion specifies which version of Kubebuilder to use for the update.
21
22
// If empty, the version from the PROJECT file will be used.
22
23
FromVersion string
24
+ // CliVersion holds the version to be used during the upgrade process
25
+ CliVersion string
23
26
}
24
27
25
28
// Update performs a complete project update by creating a three-way merge to help users
@@ -29,31 +32,21 @@ type Update struct {
29
32
// - upgrade: New Kubebuilder version scaffolding
30
33
// - merge: Attempts to merge upgrade changes into current state
31
34
func (opts * Update ) Update () error {
32
- // Load the PROJECT configuration file to get the current CLI version
33
- projectConfigFile := yaml .New (machinery.Filesystem {FS : afero .NewOsFs ()})
34
- if err := projectConfigFile .LoadFrom (yaml .DefaultPath ); err != nil { // TODO: assess if DefaultPath could be renamed to a more self-descriptive name
35
- return fmt .Errorf ("fail to run command: %w" , err )
36
- }
35
+ // Load the PROJECT configuration file
36
+ projectConfigFile , _ := opts .loadConfigFile ()
37
37
38
- // Determine which Kubebuilder version to use for the update
39
- cliVersion : = projectConfigFile .Config ().GetCliVersion ()
38
+ // Extract the cliVersion field from the PROJECT file
39
+ opts . CliVersion = projectConfigFile .Config ().GetCliVersion ()
40
40
41
- // Allow override of the version from PROJECT file via command line flag
42
- if opts .FromVersion != "" {
43
- // Ensure version has 'v' prefix for consistency with GitHub releases
44
- if ! strings .HasPrefix (opts .FromVersion , "v" ) {
45
- opts .FromVersion = "v" + opts .FromVersion
46
- }
47
- log .Infof ("Overriding cliVersion field %s from PROJECT file with --from-version %s" , cliVersion , opts .FromVersion )
48
- cliVersion = opts .FromVersion
49
- } else {
50
- log .Infof ("Using CLI version from PROJECT file: %s" , cliVersion )
41
+ // Determine which Kubebuilder version to use for the update
42
+ if err := opts .defineFromVersion (); err != nil {
43
+ return fmt .Errorf ("failed to define version: %w" , err )
51
44
}
52
45
53
46
// Download the specific Kubebuilder binary version for generating clean scaffolding
54
- tempDir , err := opts .downloadKubebuilderBinary (cliVersion )
47
+ tempDir , err := opts .downloadKubebuilderBinary ()
55
48
if err != nil {
56
- return fmt .Errorf ("failed to download Kubebuilder %s binary: %w" , cliVersion , err )
49
+ return fmt .Errorf ("failed to download Kubebuilder %s binary: %w" , opts . CliVersion , err )
57
50
}
58
51
log .Infof ("Downloaded binary kept at %s for debugging purposes" , tempDir )
59
52
@@ -68,7 +61,7 @@ func (opts *Update) Update() error {
68
61
}
69
62
70
63
// Generate clean scaffolding using the old Kubebuilder version
71
- if err := opts .runAlphaGenerate (tempDir , cliVersion ); err != nil {
64
+ if err := opts .runAlphaGenerate (tempDir , opts . CliVersion ); err != nil {
72
65
return fmt .Errorf ("failed to run alpha generate on ancestor branch: %w" , err )
73
66
}
74
67
@@ -95,21 +88,42 @@ func (opts *Update) Update() error {
95
88
return nil
96
89
}
97
90
91
+ // Load the PROJECT configuration file to get the current CLI version
92
+ func (opts * Update ) loadConfigFile () (store.Store , error ) {
93
+ projectConfigFile := yaml .New (machinery.Filesystem {FS : afero .NewOsFs ()})
94
+ // TODO: assess if DefaultPath could be renamed to a more self-descriptive name
95
+ if err := projectConfigFile .LoadFrom (yaml .DefaultPath ); err != nil {
96
+ return projectConfigFile , fmt .Errorf ("fail to run command: %w" , err )
97
+ }
98
+ return projectConfigFile , nil
99
+ }
100
+
101
+ // Define the version of the binary to be downloaded
102
+ func (opts * Update ) defineFromVersion () error {
103
+ // Allow override of the version from PROJECT file via command line flag
104
+ if opts .FromVersion != "" {
105
+ // Ensure version has 'v' prefix for consistency with GitHub releases
106
+ if ! strings .HasPrefix (opts .FromVersion , "v" ) {
107
+ opts .FromVersion = "v" + opts .FromVersion
108
+ }
109
+ opts .CliVersion = opts .FromVersion
110
+ }
111
+ return nil
112
+ }
113
+
98
114
// downloadKubebuilderBinary downloads the specified version of Kubebuilder binary
99
115
// from GitHub releases and saves it to a temporary directory with executable permissions.
100
116
// Returns the temporary directory path containing the binary.
101
- func (opts * Update ) downloadKubebuilderBinary (version string ) (string , error ) {
102
- cliVersion := version
103
-
117
+ func (opts * Update ) downloadKubebuilderBinary () (string , error ) {
104
118
// Construct GitHub release URL based on current OS and architecture
105
119
url := fmt .Sprintf ("https://github.com/kubernetes-sigs/kubebuilder/releases/download/%s/kubebuilder_%s_%s" ,
106
- cliVersion , runtime .GOOS , runtime .GOARCH )
120
+ opts . CliVersion , runtime .GOOS , runtime .GOARCH )
107
121
108
- log .Infof ("Downloading the Kubebuilder %s binary from: %s" , cliVersion , url )
122
+ log .Infof ("Downloading the Kubebuilder %s binary from: %s" , opts . CliVersion , url )
109
123
110
124
// Create temporary directory for storing the downloaded binary
111
125
fs := afero .NewOsFs ()
112
- tempDir , err := afero .TempDir (fs , "" , "kubebuilder" + cliVersion + "-" )
126
+ tempDir , err := afero .TempDir (fs , "" , "kubebuilder" + opts . CliVersion + "-" )
113
127
if err != nil {
114
128
return "" , fmt .Errorf ("failed to create temporary directory: %w" , err )
115
129
}
@@ -145,7 +159,7 @@ func (opts *Update) downloadKubebuilderBinary(version string) (string, error) {
145
159
return "" , fmt .Errorf ("failed to make binary executable: %w" , err )
146
160
}
147
161
148
- log .Infof ("Kubebuilder version %s succesfully downloaded to %s" , cliVersion , binaryPath )
162
+ log .Infof ("Kubebuilder version %s successfully downloaded to %s" , opts . CliVersion , binaryPath )
149
163
150
164
return tempDir , nil
151
165
}
@@ -195,19 +209,27 @@ func (opts *Update) cleanUpAncestorBranch() error {
195
209
// to create clean scaffolding in the ancestor branch. This uses the downloaded
196
210
// binary with the original PROJECT file to recreate the project's initial state.
197
211
func (opts * Update ) runAlphaGenerate (tempDir , version string ) error {
198
- tempBinaryPath := tempDir + "/kubebuilder"
212
+ // Restore the original PROJECT file from master branch to ensure
213
+ // we're using the correct project configuration for scaffolding
214
+ gitCmd := exec .Command ("git" , "checkout" , "master" , "--" , "PROJECT" )
215
+ if err := gitCmd .Run (); err != nil {
216
+ return fmt .Errorf ("failed to checkout PROJECT from master" )
217
+ }
218
+ log .Info ("Successfully checked out the PROJECT file from master branch" )
199
219
200
220
// Temporarily modify PATH to use the downloaded Kubebuilder binary
221
+ tempBinaryPath := tempDir + "/kubebuilder"
201
222
originalPath := os .Getenv ("PATH" )
202
223
tempEnvPath := tempDir + ":" + originalPath
203
224
204
225
if err := os .Setenv ("PATH" , tempEnvPath ); err != nil {
205
226
return fmt .Errorf ("failed to set temporary PATH: %w" , err )
206
227
}
228
+
207
229
// Restore original PATH when function completes
208
230
defer func () {
209
231
if err := os .Setenv ("PATH" , originalPath ); err != nil {
210
- log .Errorf ("failed to restore original PATH: %w " , err )
232
+ log .Errorf ("failed to restore original PATH: %v " , err )
211
233
}
212
234
}()
213
235
@@ -219,11 +241,11 @@ func (opts *Update) runAlphaGenerate(tempDir, version string) error {
219
241
220
242
// Restore the original PROJECT file from master branch to ensure
221
243
// we're using the correct project configuration for scaffolding
222
- gitCmd : = exec .Command ("git" , "checkout" , "master" , "--" , "PROJECT" )
244
+ gitCmd = exec .Command ("git" , "checkout" , "master" , "--" , "PROJECT" )
223
245
if err := gitCmd .Run (); err != nil {
224
246
return fmt .Errorf ("failed to checkout PROJECT from master" )
225
247
}
226
- log .Info ("Succesfully checked out the PROJECT file from master branch" )
248
+ log .Info ("Successfully checked out the PROJECT file from master branch" )
227
249
228
250
// Execute the alpha generate command to create clean scaffolding
229
251
if err := cmd .Run (); err != nil {
@@ -243,7 +265,7 @@ func (opts *Update) runAlphaGenerate(tempDir, version string) error {
243
265
if err := gitCmd .Run (); err != nil {
244
266
return fmt .Errorf ("failed to commit changes in ancestor: %w" , err )
245
267
}
246
- log .Info ("Successfully commited changes in ancestor" )
268
+ log .Info ("Successfully committed changes in ancestor" )
247
269
248
270
return nil
249
271
}
@@ -278,7 +300,7 @@ func (opts *Update) checkoutCurrentOffAncestor() error {
278
300
if err := gitCmd .Run (); err != nil {
279
301
return fmt .Errorf ("failed to commit changes: %w" , err )
280
302
}
281
- log .Info ("Successfully commited changes in current" )
303
+ log .Info ("Successfully committed changes in current" )
282
304
283
305
return nil
284
306
}
@@ -317,7 +339,7 @@ func (opts *Update) checkoutUpgradeOffAncestor() error {
317
339
if err := gitCmd .Run (); err != nil {
318
340
return fmt .Errorf ("failed to commit changes in upgrade branch: %w" , err )
319
341
}
320
- log .Info ("Successfully commited changes in upgrade branch" )
342
+ log .Info ("Successfully committed changes in upgrade branch" )
321
343
322
344
return nil
323
345
}
0 commit comments