Skip to content

Commit 74151d3

Browse files
Apply suggestions from code review
Co-authored-by: Camila Macedo <[email protected]>
1 parent 1340dc8 commit 74151d3

File tree

2 files changed

+72
-53
lines changed

2 files changed

+72
-53
lines changed

pkg/cli/alpha/internal/update.go

Lines changed: 56 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
log "github.com/sirupsen/logrus"
1313
"github.com/spf13/afero"
14+
"sigs.k8s.io/kubebuilder/v4/pkg/config/store"
1415
"sigs.k8s.io/kubebuilder/v4/pkg/config/store/yaml"
1516
"sigs.k8s.io/kubebuilder/v4/pkg/machinery"
1617
)
@@ -20,6 +21,8 @@ type Update struct {
2021
// FromVersion specifies which version of Kubebuilder to use for the update.
2122
// If empty, the version from the PROJECT file will be used.
2223
FromVersion string
24+
// CliVersion holds the version to be used during the upgrade process
25+
CliVersion string
2326
}
2427

2528
// Update performs a complete project update by creating a three-way merge to help users
@@ -29,31 +32,21 @@ type Update struct {
2932
// - upgrade: New Kubebuilder version scaffolding
3033
// - merge: Attempts to merge upgrade changes into current state
3134
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()
3737

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()
4040

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)
5144
}
5245

5346
// Download the specific Kubebuilder binary version for generating clean scaffolding
54-
tempDir, err := opts.downloadKubebuilderBinary(cliVersion)
47+
tempDir, err := opts.downloadKubebuilderBinary()
5548
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)
5750
}
5851
log.Infof("Downloaded binary kept at %s for debugging purposes", tempDir)
5952

@@ -68,7 +61,7 @@ func (opts *Update) Update() error {
6861
}
6962

7063
// 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 {
7265
return fmt.Errorf("failed to run alpha generate on ancestor branch: %w", err)
7366
}
7467

@@ -95,21 +88,42 @@ func (opts *Update) Update() error {
9588
return nil
9689
}
9790

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+
98114
// downloadKubebuilderBinary downloads the specified version of Kubebuilder binary
99115
// from GitHub releases and saves it to a temporary directory with executable permissions.
100116
// 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) {
104118
// Construct GitHub release URL based on current OS and architecture
105119
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)
107121

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)
109123

110124
// Create temporary directory for storing the downloaded binary
111125
fs := afero.NewOsFs()
112-
tempDir, err := afero.TempDir(fs, "", "kubebuilder"+cliVersion+"-")
126+
tempDir, err := afero.TempDir(fs, "", "kubebuilder"+opts.CliVersion+"-")
113127
if err != nil {
114128
return "", fmt.Errorf("failed to create temporary directory: %w", err)
115129
}
@@ -145,7 +159,7 @@ func (opts *Update) downloadKubebuilderBinary(version string) (string, error) {
145159
return "", fmt.Errorf("failed to make binary executable: %w", err)
146160
}
147161

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)
149163

150164
return tempDir, nil
151165
}
@@ -195,19 +209,27 @@ func (opts *Update) cleanUpAncestorBranch() error {
195209
// to create clean scaffolding in the ancestor branch. This uses the downloaded
196210
// binary with the original PROJECT file to recreate the project's initial state.
197211
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")
199219

200220
// Temporarily modify PATH to use the downloaded Kubebuilder binary
221+
tempBinaryPath := tempDir + "/kubebuilder"
201222
originalPath := os.Getenv("PATH")
202223
tempEnvPath := tempDir + ":" + originalPath
203224

204225
if err := os.Setenv("PATH", tempEnvPath); err != nil {
205226
return fmt.Errorf("failed to set temporary PATH: %w", err)
206227
}
228+
207229
// Restore original PATH when function completes
208230
defer func() {
209231
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)
211233
}
212234
}()
213235

@@ -219,11 +241,11 @@ func (opts *Update) runAlphaGenerate(tempDir, version string) error {
219241

220242
// Restore the original PROJECT file from master branch to ensure
221243
// 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")
223245
if err := gitCmd.Run(); err != nil {
224246
return fmt.Errorf("failed to checkout PROJECT from master")
225247
}
226-
log.Info("Succesfully checked out the PROJECT file from master branch")
248+
log.Info("Successfully checked out the PROJECT file from master branch")
227249

228250
// Execute the alpha generate command to create clean scaffolding
229251
if err := cmd.Run(); err != nil {
@@ -243,7 +265,7 @@ func (opts *Update) runAlphaGenerate(tempDir, version string) error {
243265
if err := gitCmd.Run(); err != nil {
244266
return fmt.Errorf("failed to commit changes in ancestor: %w", err)
245267
}
246-
log.Info("Successfully commited changes in ancestor")
268+
log.Info("Successfully committed changes in ancestor")
247269

248270
return nil
249271
}
@@ -278,7 +300,7 @@ func (opts *Update) checkoutCurrentOffAncestor() error {
278300
if err := gitCmd.Run(); err != nil {
279301
return fmt.Errorf("failed to commit changes: %w", err)
280302
}
281-
log.Info("Successfully commited changes in current")
303+
log.Info("Successfully committed changes in current")
282304

283305
return nil
284306
}
@@ -317,7 +339,7 @@ func (opts *Update) checkoutUpgradeOffAncestor() error {
317339
if err := gitCmd.Run(); err != nil {
318340
return fmt.Errorf("failed to commit changes in upgrade branch: %w", err)
319341
}
320-
log.Info("Successfully commited changes in upgrade branch")
342+
log.Info("Successfully committed changes in upgrade branch")
321343

322344
return nil
323345
}

pkg/cli/alpha/update.go

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,33 +20,30 @@ func NewUpdateCommand() *cobra.Command {
2020
updateCmd := &cobra.Command{
2121
Use: "update",
2222
Short: "Update a Kubebuilder project to a newer version",
23-
Long: `Update a Kubebuilder project to a newer version using a three-way merge strategy.
23+
Long: `This command upgrades your Kubebuilder project to the latest scaffold layout using a 3-way merge strategy.
2424
25-
This command helps you upgrade your Kubebuilder project by:
26-
1. Creating a clean ancestor branch with the old version's scaffolding
27-
2. Creating a current branch with your project's current state
28-
3. Creating an upgrade branch with the new version's scaffolding
29-
4. Attempting to merge the changes automatically
25+
It performs the following steps:
26+
1. Creates an 'ancestor' branch from the version originally used to scaffold the project
27+
2. Creates a 'current' branch with your project's current state
28+
3. Creates an 'upgrade' branch using the new version's scaffolding
29+
4. Attempts a 3-way merge into a 'merge' branch
3030
31-
The process creates several Git branches to help you manage the upgrade:
32-
- ancestor: Clean scaffolding from the original version
33-
- current: Your project's current state
34-
- upgrade: Clean scaffolding from the new version
35-
- merge: Attempted automatic merge of upgrade into current
31+
The process uses Git branches:
32+
- ancestor: clean scaffold from the original version
33+
- current: your existing project state
34+
- upgrade: scaffold from the target version
35+
- merge: result of the 3-way merge
3636
37-
If conflicts occur during the merge, you'll need to resolve them manually.
37+
If conflicts occur during the merge, resolve them manually in the 'merge' branch.
38+
Once resolved, commit and push it as a pull request. This branch will contain the
39+
final upgraded project with the latest Kubebuilder layout and your custom code.
3840
3941
Examples:
4042
# Update using the version specified in PROJECT file
4143
kubebuilder alpha update
4244
4345
# Update from a specific version
44-
kubebuilder alpha update --from-version v3.0.0
45-
46-
Requirements:
47-
- Must be run from the root of a Kubebuilder project
48-
- Git repository must be clean (no uncommitted changes)
49-
- PROJECT file must exist and contain a valid layout version`,
46+
kubebuilder alpha update --from-version v3.0.0`,
5047

5148
// TODO: Add validation to ensure we're in a Kubebuilder project and Git repo is clean
5249
// PreRunE: func(_ *cobra.Command, _ []string) error {
@@ -62,7 +59,7 @@ Requirements:
6259

6360
// Flag to override the version specified in the PROJECT file
6461
updateCmd.Flags().StringVar(&opts.FromVersion, "from-version", "",
65-
"Override the CLI version from PROJECT file. Specify the Kubebuilder version to upgrade from (e.g., 'v3.0.0' or '3.0.0')")
62+
"Kubebuilder binary release version to upgrade from. Should match the version used to init the project.")
6663

6764
return updateCmd
6865
}

0 commit comments

Comments
 (0)