• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubernetes-sigs / kubebuilder / 17187150698

24 Aug 2025 09:45AM UTC coverage: 70.639%. First build
17187150698

Pull #5044

github

camilamacedo86
(fix): log format using slog
Pull Request #5044: WIP (fix): log format using slog

23 of 27 new or added lines in 3 files covered. (85.19%)

3118 of 4414 relevant lines covered (70.64%)

13.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.29
/pkg/cli/alpha/update.go
1
/*
2
Copyright 2025 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 alpha
18

19
import (
20
        "fmt"
21
        "log/slog"
22
        "os"
23

24
        "github.com/spf13/cobra"
25

26
        "sigs.k8s.io/kubebuilder/v4/pkg/cli/alpha/internal/update"
27
        "sigs.k8s.io/kubebuilder/v4/pkg/logging"
28
)
29

30
func init() {
2✔
31
        // Initialize consistent logging for alpha commands
2✔
32
        opts := logging.HandlerOptions{
2✔
33
                SlogOpts: slog.HandlerOptions{
2✔
34
                        Level: slog.LevelInfo,
2✔
35
                },
2✔
36
        }
2✔
37
        handler := logging.NewHandler(os.Stdout, opts)
2✔
38
        logger := slog.New(handler)
2✔
39
        slog.SetDefault(logger)
2✔
40
}
2✔
41

42
// NewUpdateCommand creates and returns a new Cobra command for updating Kubebuilder projects.
43
func NewUpdateCommand() *cobra.Command {
2✔
44
        opts := update.Update{}
2✔
45
        var gitCfg []string
2✔
46
        updateCmd := &cobra.Command{
2✔
47
                Use:   "update",
2✔
48
                Short: "Update your project to a newer version (3-way merge; squash by default)",
2✔
49
                Long: `Upgrade your project scaffold using a 3-way merge while preserving your code.
2✔
50

2✔
51
The updater uses four temporary branches during the run:
2✔
52
  • ancestor : clean scaffold from the starting version (--from-version)
2✔
53
  • original : snapshot of your current project (--from-branch)
2✔
54
  • upgrade  : scaffold generated with the target version (--to-version)
2✔
55
  • merge    : result of merging original into upgrade (conflicts possible)
2✔
56

2✔
57
Output branch & history:
2✔
58
  • Default: SQUASH the merge result into ONE commit on:
2✔
59
        kubebuilder-update-from-<from-version>-to-<to-version>
2✔
60
  • --show-commits: keep full history (not compatible with --restore-path).
2✔
61

2✔
62
Conflicts:
2✔
63
  • Default: stop on conflicts and leave the merge branch for manual resolution.
2✔
64
  • --force: commit with conflict markers so automation can proceed.
2✔
65

2✔
66
Other options:
2✔
67
  • --restore-path: restore paths from base when squashing (e.g., CI configs).
2✔
68
  • --output-branch: override the output branch name.
2✔
69
  • --push: push the output branch to 'origin' after the update.
2✔
70
  • --git-config: pass per-invocation Git config as -c key=value (repeatable). When not set,
2✔
71
      defaults to -c merge.renameLimit=999999 to improve rename detection during merges.
2✔
72

2✔
73
Defaults:
2✔
74
  • --from-version / --to-version: resolved from PROJECT and the latest release if unset.
2✔
75
  • --from-branch: defaults to 'main' if not specified.`,
2✔
76
                Example: `
2✔
77
  # Update from the version in PROJECT to the latest, stop on conflicts
2✔
78
  kubebuilder alpha update
2✔
79

2✔
80
  # Update from a specific version to latest
2✔
81
  kubebuilder alpha update --from-version v4.6.0
2✔
82

2✔
83
  # Update from v4.5.0 to v4.7.0 and keep conflict markers (automation-friendly)
2✔
84
  kubebuilder alpha update --from-version v4.5.0 --to-version v4.7.0 --force
2✔
85

2✔
86
  # Keep full commit history instead of squashing
2✔
87
  kubebuilder alpha update --from-version v4.5.0 --to-version v4.7.0 --force --show-commits
2✔
88

2✔
89
  # Squash while preserving CI workflows from base (e.g., main)
2✔
90
  kubebuilder alpha update --force --restore-path .github/workflows
2✔
91

2✔
92
  # Show commits into a custom output branch name
2✔
93
  kubebuilder alpha update --force --show-commits --output-branch my-update-branch
2✔
94

2✔
95
  # Run update and push the output branch to origin (works with or without --show-commits)
2✔
96
  kubebuilder alpha update --from-version v4.6.0 --to-version v4.7.0 --force --push
2✔
97

2✔
98
  # Add extra Git configs (no need to re-specify defaults)
2✔
99
  kubebuilder alpha update --git-config merge.conflictStyle=diff3 --git-config rerere.enabled=true
2✔
100
                                          
2✔
101
  # Disable Git config defaults completely, use only custom configs
2✔
102
  kubebuilder alpha update --git-config disable --git-config rerere.enabled=true`,
2✔
103
                PreRunE: func(_ *cobra.Command, _ []string) error {
2✔
104
                        if opts.ShowCommits && len(opts.RestorePath) > 0 {
×
105
                                return fmt.Errorf("the --restore-path flag is not supported with --show-commits")
×
106
                        }
×
107

108
                        // Defaults always on unless "disable" is present anywhere
109
                        defaults := []string{"merge.renameLimit=999999", "diff.renameLimit=999999"}
×
110

×
111
                        hasDisable := false
×
112
                        filtered := make([]string, 0, len(gitCfg))
×
113
                        for _, v := range gitCfg {
×
114
                                if v == "disable" {
×
115
                                        hasDisable = true
×
116
                                        continue
×
117
                                }
118
                                filtered = append(filtered, v)
×
119
                        }
120

121
                        if hasDisable {
×
122
                                // no defaults; only user-provided configs (excluding "disable")
×
123
                                opts.GitConfig = filtered
×
124
                        } else {
×
125
                                // defaults + user configs (user can override by repeating keys)
×
126
                                opts.GitConfig = append(defaults, filtered...)
×
127
                        }
×
128

129
                        if err := opts.Prepare(); err != nil {
×
130
                                return fmt.Errorf("failed to prepare update: %w", err)
×
131
                        }
×
132
                        return opts.Validate()
×
133
                },
134
                Run: func(_ *cobra.Command, _ []string) {
×
135
                        if err := opts.Update(); err != nil {
×
NEW
136
                                slog.Error("Update failed", "error", err)
×
NEW
137
                                os.Exit(1)
×
138
                        }
×
139
                },
140
        }
141

142
        updateCmd.Flags().StringVar(&opts.FromVersion, "from-version", "",
2✔
143
                "binary release version to upgrade from. Should match the version used to init the project and be "+
2✔
144
                        "a valid release version, e.g., v4.6.0. If not set, it defaults to the version specified in the PROJECT file.")
2✔
145
        updateCmd.Flags().StringVar(&opts.ToVersion, "to-version", "",
2✔
146
                "binary release version to upgrade to. Should be a valid release version, e.g., v4.7.0. "+
2✔
147
                        "If not set, it defaults to the latest release version available in the project repository.")
2✔
148
        updateCmd.Flags().StringVar(&opts.FromBranch, "from-branch", "",
2✔
149
                "Git branch to use as current state of the project for the update.")
2✔
150
        updateCmd.Flags().BoolVar(&opts.Force, "force", false,
2✔
151
                "Force the update even if conflicts occur. Conflicted files will include conflict markers, and a "+
2✔
152
                        "commit will be created automatically. Ideal for automation (e.g., cronjobs, CI).")
2✔
153
        updateCmd.Flags().BoolVar(&opts.ShowCommits, "show-commits", false,
2✔
154
                "If set, the update will keep the full history instead of squashing into a single commit.")
2✔
155
        updateCmd.Flags().StringArrayVar(&opts.RestorePath, "restore-path", nil,
2✔
156
                "Paths to preserve from the base branch (repeatable). Not supported with --show-commits.")
2✔
157
        updateCmd.Flags().StringVar(&opts.OutputBranch, "output-branch", "",
2✔
158
                "Override the default output branch name (default: kubebuilder-update-from-<from-version>-to-<to-version>).")
2✔
159
        updateCmd.Flags().BoolVar(&opts.Push, "push", false,
2✔
160
                "Push the output branch to the remote repository after the update.")
2✔
161
        updateCmd.Flags().BoolVar(&opts.OpenGhIssue, "open-gh-issue", false,
2✔
162
                "Create a GitHub issue with a pre-filled checklist and compare link after the update completes (requires `gh`).")
2✔
163
        updateCmd.Flags().StringArrayVar(
2✔
164
                &gitCfg,
2✔
165
                "git-config",
2✔
166
                nil,
2✔
167
                "Per-invocation Git config (repeatable). "+
2✔
168
                        "Defaults: -c merge.renameLimit=999999 -c diff.renameLimit=999999. "+
2✔
169
                        "Your configs are applied on top. To disable defaults, include `--git-config disable`")
2✔
170
        return updateCmd
2✔
171
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc