package build import ( "path/filepath" "slices" "github.com/host-uk/core/pkg/io" ) // Marker files for project type detection. const ( markerGoMod = "go.mod" markerWails = "wails.json" markerNodePackage = "package.json" markerComposer = "composer.json" markerCMake = "CMakeLists.txt" ) // projectMarker maps a marker file to its project type. type projectMarker struct { file string projectType ProjectType } // markers defines the detection order. More specific types come first. // Wails projects have both wails.json and go.mod, so wails is checked first. var markers = []projectMarker{ {markerWails, ProjectTypeWails}, {markerGoMod, ProjectTypeGo}, {markerNodePackage, ProjectTypeNode}, {markerComposer, ProjectTypePHP}, {markerCMake, ProjectTypeCPP}, } // Discover detects project types in the given directory by checking for marker files. // Returns a slice of detected project types, ordered by priority (most specific first). // For example, a Wails project returns [wails, go] since it has both wails.json and go.mod. func Discover(fs io.Medium, dir string) ([]ProjectType, error) { var detected []ProjectType for _, m := range markers { path := filepath.Join(dir, m.file) if fileExists(fs, path) { // Avoid duplicates (shouldn't happen with current markers, but defensive) if !slices.Contains(detected, m.projectType) { detected = append(detected, m.projectType) } } } return detected, nil } // PrimaryType returns the most specific project type detected in the directory. // Returns empty string if no project type is detected. func PrimaryType(fs io.Medium, dir string) (ProjectType, error) { types, err := Discover(fs, dir) if err != nil { return "", err } if len(types) == 0 { return "", nil } return types[0], nil } // IsGoProject checks if the directory contains a Go project (go.mod or wails.json). func IsGoProject(fs io.Medium, dir string) bool { return fileExists(fs, filepath.Join(dir, markerGoMod)) || fileExists(fs, filepath.Join(dir, markerWails)) } // IsWailsProject checks if the directory contains a Wails project. func IsWailsProject(fs io.Medium, dir string) bool { return fileExists(fs, filepath.Join(dir, markerWails)) } // IsNodeProject checks if the directory contains a Node.js project. func IsNodeProject(fs io.Medium, dir string) bool { return fileExists(fs, filepath.Join(dir, markerNodePackage)) } // IsPHPProject checks if the directory contains a PHP project. func IsPHPProject(fs io.Medium, dir string) bool { return fileExists(fs, filepath.Join(dir, markerComposer)) } // IsCPPProject checks if the directory contains a C++ project. func IsCPPProject(fs io.Medium, dir string) bool { return fileExists(fs, filepath.Join(dir, markerCMake)) } // fileExists checks if a file exists and is not a directory. func fileExists(fs io.Medium, path string) bool { return fs.IsFile(path) }