@@ -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)
164163func 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