Skip to content

Commit 3682ddd

Browse files
authored
Merge pull request #5154 from camilamacedo86/fix-init
🐛 (go/v4): Simplify init directory validation to only block kubebuilder files
2 parents e77755e + eaf95e3 commit 3682ddd

File tree

1 file changed

+52
-36
lines changed

1 file changed

+52
-36
lines changed

pkg/plugins/golang/v4/init.go

Lines changed: 52 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"os"
2323
"path/filepath"
2424
"strings"
25-
"unicode"
2625

2726
"github.com/spf13/pflag"
2827

@@ -158,57 +157,74 @@ func (p *initSubcommand) PostScaffold() error {
158157
return nil
159158
}
160159

161-
// checkDir will return error if the current directory has files which are not allowed.
162-
// Note that, it is expected that the directory to scaffold the project is cleaned.
163-
// Otherwise, it might face issues to do the scaffold.
160+
// checkDir checks the target directory before scaffolding:
161+
// 1. Returns error if key kubebuilder files already exist (prevents re-initialization)
162+
// 2. Warns if directory is not empty (but allows scaffolding to continue)
164163
func checkDir() error {
164+
// Files scaffolded by 'kubebuilder init' that indicate the directory is already initialized.
165+
// Blocking these prevents accidental re-initialization and file conflicts.
166+
// Note: go.mod and go.sum are NOT blocked because:
167+
// - They may exist in pre-existing Go projects
168+
// - Kubebuilder will overwrite them (machinery.OverwriteFile)
169+
// - Testdata generation creates go.mod before running init
170+
scaffoldedFiles := []string{
171+
"PROJECT", // Kubebuilder project config (key indicator)
172+
"Makefile", // Build automation
173+
filepath.Join("cmd", "main.go"), // Controller manager entry point
174+
}
175+
176+
// Check for existing scaffolded files
177+
for _, file := range scaffoldedFiles {
178+
if _, err := os.Stat(file); err == nil {
179+
return fmt.Errorf("target directory is already initialized. "+
180+
"Found existing kubebuilder file %q. "+
181+
"Please run this command in a new directory or remove existing scaffolded files", file)
182+
}
183+
}
184+
185+
// Check if directory has any other files (warn only)
186+
// Note: We ignore certain files that are expected or safely overwritten:
187+
// - go.mod and go.sum: Users may run `go mod init` before `kubebuilder init`
188+
// - .gitignore and .dockerignore: Safely overwritten by kubebuilder
189+
// - Other dot directories (.git, .vscode, .idea): Not scaffolded by kubebuilder
190+
// However, we DO check .github directory since kubebuilder scaffolds workflows there
191+
var hasFiles bool
165192
err := filepath.Walk(".",
166193
func(path string, info os.FileInfo, err error) error {
167194
if err != nil {
168195
return fmt.Errorf("error walking path %q: %w", path, err)
169196
}
170-
// Allow directory trees starting with '.'
171-
if info.IsDir() && strings.HasPrefix(info.Name(), ".") && info.Name() != "." {
172-
return filepath.SkipDir
173-
}
174-
// Allow files starting with '.'
175-
if strings.HasPrefix(info.Name(), ".") {
176-
return nil
177-
}
178-
// Allow files ending with '.md' extension
179-
if strings.HasSuffix(info.Name(), ".md") && !info.IsDir() {
197+
// Skip the current directory itself
198+
if path == "." {
180199
return nil
181200
}
182-
// Allow capitalized files except PROJECT
183-
isCapitalized := true
184-
for _, l := range info.Name() {
185-
if !unicode.IsUpper(l) {
186-
isCapitalized = false
187-
break
201+
// Skip dot directories EXCEPT .github (which contains scaffolded workflows)
202+
if info.IsDir() && strings.HasPrefix(info.Name(), ".") {
203+
if info.Name() != ".github" {
204+
return filepath.SkipDir
188205
}
189206
}
190-
if isCapitalized && info.Name() != "PROJECT" {
191-
return nil
192-
}
193-
disallowedExtensions := []string{
194-
".go",
195-
".yaml",
196-
".mod",
197-
".sum",
198-
}
199-
// Deny files with .go or .yaml or .mod or .sum extensions
200-
for _, ext := range disallowedExtensions {
201-
if strings.HasSuffix(info.Name(), ext) {
207+
// Skip files that are expected or safely overwritten
208+
ignoredFiles := []string{"go.mod", "go.sum"}
209+
for _, ignored := range ignoredFiles {
210+
if info.Name() == ignored {
202211
return nil
203212
}
204213
}
205-
// Do not allow any other file
206-
return fmt.Errorf("target directory is not empty and contains a disallowed file %q. "+
207-
"files with the following extensions [%s] are not allowed to avoid conflicts with the tooling",
208-
path, strings.Join(disallowedExtensions, ", "))
214+
// Track if any other files/directories exist
215+
hasFiles = true
216+
return nil
209217
})
210218
if err != nil {
211219
return fmt.Errorf("error walking directory: %w", err)
212220
}
221+
222+
// Warn if directory is not empty (but don't block)
223+
if hasFiles {
224+
log.Warn("The target directory is not empty. " +
225+
"Scaffolding may overwrite existing files or cause conflicts. " +
226+
"It is recommended to initialize in an empty directory.")
227+
}
228+
213229
return nil
214230
}

0 commit comments

Comments
 (0)