added '--ignore-errors' flag instead of ignoring errors during build by default

This commit is contained in:
partisan 2025-04-12 09:49:58 +02:00
parent df3e8e3a83
commit e5c95924d5
3 changed files with 167 additions and 179 deletions

View file

@ -56,6 +56,8 @@ Below is a detailed description of all the flags supported by the Spitfire Build
Runs the built project after the build process completes successfully. Runs the built project after the build process completes successfully.
- **`--skip-deps`**: - **`--skip-deps`**:
Skip checking for required system dependencies. Skip checking for required system dependencies.
- **`ignoreErrors`**:
Processes all steps even if errors occur.
### **Compression and Upload Flags** ### **Compression and Upload Flags**

240
main.go
View file

@ -6,14 +6,13 @@ import (
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"runtime" // for detecting system architecture and platform "runtime"
"spitfire-builder/spitfire" "spitfire-builder/spitfire"
"time" "time"
//"errors" //"errors"
) )
var ( var (
// Define all flags as package-level variables
all bool all bool
buildFlag bool buildFlag bool
clean bool clean bool
@ -41,8 +40,11 @@ var (
maintainer = "Internet Addict" maintainer = "Internet Addict"
initialDir string initialDir string
skipDeps bool skipDeps bool
ignoreErrors bool
) )
var errors []error // This is also in build.go. Great! This code is a mess.
func init() { func init() {
flag.StringVar(&target, "t", "", "Target location format: component-arch-release-platform") flag.StringVar(&target, "t", "", "Target location format: component-arch-release-platform")
flag.BoolVar(&compress, "c", false, "Compress the build directory into a tar.gz file before uploading") flag.BoolVar(&compress, "c", false, "Compress the build directory into a tar.gz file before uploading")
@ -63,6 +65,7 @@ func init() {
flag.BoolVar(&upload, "upload", false, "Upload the compressed build file to SourceForge") flag.BoolVar(&upload, "upload", false, "Upload the compressed build file to SourceForge")
flag.StringVar(&uploadPath, "upload-path", "", "Path to the file to upload if no build present") flag.StringVar(&uploadPath, "upload-path", "", "Path to the file to upload if no build present")
flag.BoolVar(&skipDeps, "skip-deps", false, "Skip checking for required system dependencies") flag.BoolVar(&skipDeps, "skip-deps", false, "Skip checking for required system dependencies")
flag.BoolVar(&ignoreErrors, "ignore-errors", false, "Processes all steps even if errors occur")
flag.Bool("h", false, "Display help message") flag.Bool("h", false, "Display help message")
} }
@ -73,6 +76,15 @@ func printHelp() {
os.Exit(0) os.Exit(0)
} }
func handleError(err error) {
if err != nil {
errors = append(errors, err)
if !ignoreErrors {
log.Fatal(err)
}
}
}
func main() { func main() {
flag.Parse() flag.Parse()
@ -82,7 +94,7 @@ func main() {
if !skipDeps { if !skipDeps {
if err := spitfire.CheckDependencies(); err != nil { if err := spitfire.CheckDependencies(); err != nil {
log.Fatalf("System check failed: %v", err) handleError(fmt.Errorf("system check failed: %w", err))
} }
} }
@ -94,138 +106,155 @@ func main() {
var err error var err error
initialDir, err = os.Getwd() initialDir, err = os.Getwd()
if err != nil { if err != nil {
log.Fatalf("Failed to get current working directory: %v", err) handleError(fmt.Errorf("failed to get current directory: %w", err))
} }
var buildDir string // Store the resolved build directory here var buildDir string
// Perform build if necessary
if all || buildFlag || prePatch || postPatch || clean || update || run { if all || buildFlag || prePatch || postPatch || clean || update || run {
buildDir = BuildProcess() buildDir, err = BuildProcess()
if buildDir == "" { if err != nil {
log.Fatalf("Build process completed, but no build directory was found.") handleError(fmt.Errorf("build process failed: %w", err))
} else if buildDir == "" && (buildFlag || all || run) {
handleError(fmt.Errorf("build directory not found after build process"))
} }
fmt.Printf("Build directory from process: %s\n", buildDir)
} }
// Resolve build directory for compression/upload
if compress || upload { if compress || upload {
if buildDir == "" { // Resolve dynamically if no build was performed if err := PackageAndUploadProcess(buildDir); err != nil {
fmt.Println("No build directory detected during build process. Resolving dynamically...") handleError(fmt.Errorf("package/upload failed: %w", err))
sourcePath, err := spitfire.ResolvePath("./mozilla-release")
if err != nil {
log.Fatalf("Error resolving source path: %v", err)
} }
fmt.Printf("Resolved source path: %s\n", sourcePath)
buildDir, err = spitfire.ResolveBuildDir(sourcePath)
if err != nil {
log.Fatalf("Error resolving build directory dynamically: %v", err)
}
}
if buildDir == "" {
log.Fatalf("No build directory found for compression or upload.")
}
fmt.Printf("Resolved build directory for compress/upload: %s\n", buildDir)
PackageAndUploadProcess(buildDir)
} }
spitfire.PrintErrors() spitfire.PrintErrors()
if len(errors) > 0 {
fmt.Fprintf(os.Stderr, "Exiting with %d error(s):\n", len(errors))
for _, e := range errors {
fmt.Fprintf(os.Stderr, "- %v\n", e)
}
os.Exit(1)
} else {
os.Exit(0)
}
} }
// Update the BuildProcess function to pass patchesRepo func BuildProcess() (string, error) {
func BuildProcess() string {
sourcePath, err := spitfire.ResolvePath("./mozilla-release") sourcePath, err := spitfire.ResolvePath("./mozilla-release")
if err != nil { if err != nil {
log.Fatalf("Error resolving source path: %v", err) return "", fmt.Errorf("resolve source path: %w", err)
} }
var buildDir string var buildDir string
if all { if all {
spitfire.DownloadSource(sourcePath, sourceRepo) if err := spitfire.DownloadSource(sourcePath, sourceRepo); err != nil {
spitfire.DiscardChanges(sourcePath) return "", fmt.Errorf("download source: %w", err)
spitfire.CleanBuild(sourcePath, fullClean) }
spitfire.UpdateRepo(sourcePath) if err := spitfire.DiscardChanges(sourcePath); err != nil {
if err := spitfire.ApplyPatches(sourcePath, patchesRepo, "pre-compile-patches", filepath.Join(sourcePath, "patcher"), skipPatchUpdate); err != nil { return "", fmt.Errorf("discard changes: %w", err)
log.Fatalf("Error during patch application: %v", err) }
if err := spitfire.CleanBuild(sourcePath, fullClean); err != nil {
return "", fmt.Errorf("clean build: %w", err)
}
if err := spitfire.UpdateRepo(sourcePath); err != nil {
return "", fmt.Errorf("update repo: %w", err)
}
if err := spitfire.ApplyPatches(sourcePath, patchesRepo, "pre-compile-patches", filepath.Join(sourcePath, "patcher"), skipPatchUpdate); err != nil {
return "", fmt.Errorf("pre-patch: %w", err)
}
if err := spitfire.Configure(sourcePath); err != nil {
return "", fmt.Errorf("configure: %w", err)
}
if err := spitfire.Build(sourcePath); err != nil {
return "", fmt.Errorf("build: %w", err)
} }
spitfire.Configure(sourcePath)
spitfire.Build(sourcePath)
// Detect the build directory dynamically
buildDir, err = spitfire.ResolveBuildDir(sourcePath) buildDir, err = spitfire.ResolveBuildDir(sourcePath)
if err != nil { if err != nil {
log.Fatalf("Error resolving build directory: %v", err) return "", fmt.Errorf("resolve build dir: %w", err)
} }
if err := spitfire.ApplyPatches(buildDir, patchesRepo, "post-compile-patches", filepath.Join(sourcePath, "patcher"), skipPatchUpdate); err != nil { if err := spitfire.ApplyPatches(buildDir, patchesRepo, "post-compile-patches", filepath.Join(sourcePath, "patcher"), skipPatchUpdate); err != nil {
log.Fatalf("Error during patch application: %v", err) return "", fmt.Errorf("post-patch: %w", err)
} }
if run { if run {
spitfire.RunProject(sourcePath) if err := spitfire.RunProject(sourcePath); err != nil {
return "", fmt.Errorf("run project: %w", err)
}
} }
fmt.Println("Spitfire build completed successfully.") fmt.Println("Spitfire build completed successfully.")
} else if buildFlag { } else if buildFlag {
if prePatch { if prePatch {
if err := spitfire.ApplyPatches(sourcePath, patchesRepo, "pre-compile-patches", filepath.Join(sourcePath, "patcher"), skipPatchUpdate); err != nil { if err := spitfire.ApplyPatches(sourcePath, patchesRepo, "pre-compile-patches", filepath.Join(sourcePath, "patcher"), skipPatchUpdate); err != nil {
log.Fatalf("Error during patch application: %v", err) return "", fmt.Errorf("pre-patch: %w", err)
} }
} }
spitfire.Configure(sourcePath) if err := spitfire.Configure(sourcePath); err != nil {
spitfire.Build(sourcePath) return "", fmt.Errorf("configure: %w", err)
// Detect the build directory dynamically }
if err := spitfire.Build(sourcePath); err != nil {
return "", fmt.Errorf("build: %w", err)
}
buildDir, err = spitfire.ResolveBuildDir(sourcePath) buildDir, err = spitfire.ResolveBuildDir(sourcePath)
if err != nil { if err != nil {
log.Fatalf("Error resolving build directory: %v", err) return "", fmt.Errorf("resolve build dir: %w", err)
} }
if postPatch { if postPatch {
if err := spitfire.ApplyPatches(buildDir, patchesRepo, "post-compile-patches", filepath.Join(sourcePath, "patcher"), skipPatchUpdate); err != nil { if err := spitfire.ApplyPatches(buildDir, patchesRepo, "post-compile-patches", filepath.Join(sourcePath, "patcher"), skipPatchUpdate); err != nil {
log.Fatalf("Error during patch application: %v", err) return "", fmt.Errorf("post-patch: %w", err)
} }
} }
if run { if run {
spitfire.RunProject(sourcePath) if err := spitfire.RunProject(sourcePath); err != nil {
return "", fmt.Errorf("run project: %w", err)
}
} }
fmt.Println("Spitfire build completed successfully.") fmt.Println("Spitfire build completed successfully.")
} else if clean { } else if clean {
spitfire.CleanBuild(sourcePath, fullClean) if err := spitfire.CleanBuild(sourcePath, fullClean); err != nil {
return "", fmt.Errorf("clean build: %w", err)
}
fmt.Println("Cleaned Firefox build.") fmt.Println("Cleaned Firefox build.")
} else if update { } else if update {
spitfire.DownloadSource(sourcePath, sourceRepo) if err := spitfire.DownloadSource(sourcePath, sourceRepo); err != nil {
spitfire.UpdateRepo(sourcePath) return "", fmt.Errorf("download source: %w", err)
}
if err := spitfire.UpdateRepo(sourcePath); err != nil {
return "", fmt.Errorf("update repo: %w", err)
}
fmt.Println("Mozilla repository updated.") fmt.Println("Mozilla repository updated.")
} else if prePatch { } else if prePatch {
spitfire.DownloadSource(sourcePath, sourceRepo) if err := spitfire.DownloadSource(sourcePath, sourceRepo); err != nil {
return "", fmt.Errorf("download source: %w", err)
}
if err := spitfire.ApplyPatches(sourcePath, patchesRepo, "pre-compile-patches", filepath.Join(sourcePath, "patcher"), skipPatchUpdate); err != nil { if err := spitfire.ApplyPatches(sourcePath, patchesRepo, "pre-compile-patches", filepath.Join(sourcePath, "patcher"), skipPatchUpdate); err != nil {
log.Fatalf("Error during patch application: %v", err) return "", fmt.Errorf("pre-patch: %w", err)
} }
fmt.Println("Patches updated.") fmt.Println("Patches updated.")
} else if postPatch { } else if postPatch {
// Detect the build directory dynamically
buildDir, err = spitfire.ResolveBuildDir(sourcePath) buildDir, err = spitfire.ResolveBuildDir(sourcePath)
if err != nil { if err != nil {
log.Fatalf("Error resolving build directory: %v", err) return "", fmt.Errorf("resolve build dir: %w", err)
} }
if _, err := os.Stat(buildDir); err == nil { if _, err := os.Stat(buildDir); err == nil {
if err := spitfire.ApplyPatches(buildDir, patchesRepo, "post-compile-patches", filepath.Join(sourcePath, "patcher"), skipPatchUpdate); err != nil { if err := spitfire.ApplyPatches(buildDir, patchesRepo, "post-compile-patches", filepath.Join(sourcePath, "patcher"), skipPatchUpdate); err != nil {
log.Fatalf("Error during patch application: %v", err) return "", fmt.Errorf("post-patch: %w", err)
} }
} }
if run { if run {
spitfire.RunProject(sourcePath) if err := spitfire.RunProject(sourcePath); err != nil {
return "", fmt.Errorf("run project: %w", err)
}
} }
} else if run { } else if run {
spitfire.RunProject(sourcePath) if err := spitfire.RunProject(sourcePath); err != nil {
return "", fmt.Errorf("run project: %w", err)
}
} }
return buildDir return buildDir, nil
} }
// PackageAndUploadProcess handles compressing, packaging, and uploading the build to SourceForge. func PackageAndUploadProcess(buildDir string) error {
func PackageAndUploadProcess(buildDir string) {
// Restore working directory before performing SourceForge operations
restoreWorkingDirectory() restoreWorkingDirectory()
pathToUse := buildDir pathToUse := buildDir
@ -234,120 +263,95 @@ func PackageAndUploadProcess(buildDir string) {
} }
if pathToUse == "" { if pathToUse == "" {
log.Fatalf("Error: no valid build or upload path provided.") return fmt.Errorf("no valid build or upload path provided")
} }
// Calculate & display uncompressed size
uncompressedSize, err := spitfire.GetDirectorySize(pathToUse) uncompressedSize, err := spitfire.GetDirectorySize(pathToUse)
if err != nil { if err != nil {
log.Fatalf("Failed to calculate uncompressed size: %v", err) return fmt.Errorf("get directory size: %w", err)
} }
fmt.Printf("Uncompressed directory size: %s\n", spitfire.BytesToHumanReadable(uncompressedSize)) fmt.Printf("Uncompressed directory size: %s\n", spitfire.BytesToHumanReadable(uncompressedSize))
// Create the tar.gz name, e.g. "browser-amd64-nightly-linux.tar.gz"
outputCompressedFile := filepath.Join(".", fmt.Sprintf( outputCompressedFile := filepath.Join(".", fmt.Sprintf(
"%s-%s-%s-%s.tar.gz", "%s-%s-%s-%s.tar.gz",
component, arch, release, platform, component, arch, release, platform,
)) ))
// Compress if requested
if compress { if compress {
err := spitfire.CompressDirectory(pathToUse, outputCompressedFile) if err := spitfire.CompressDirectory(pathToUse, outputCompressedFile); err != nil {
if err != nil { return fmt.Errorf("compress directory: %w", err)
log.Fatalf("Failed to compress build directory: %v", err)
} }
fmt.Printf("Build directory compressed to: %s\n", outputCompressedFile) fmt.Printf("Build directory compressed to: %s\n", outputCompressedFile)
} }
// Compressed size
compressedSize, err := spitfire.GetFileSize(outputCompressedFile) compressedSize, err := spitfire.GetFileSize(outputCompressedFile)
if err != nil { if err != nil {
log.Fatalf("Failed to get compressed file size: %v", err) return fmt.Errorf("get compressed file size: %w", err)
} }
fmt.Printf("Compressed file size: %s\n", spitfire.BytesToHumanReadable(compressedSize)) fmt.Printf("Compressed file size: %s\n", spitfire.BytesToHumanReadable(compressedSize))
// Show compression ratio & efficiency
compressionRatio, efficiency := spitfire.CalculateCompressionEfficiency(uncompressedSize, compressedSize) compressionRatio, efficiency := spitfire.CalculateCompressionEfficiency(uncompressedSize, compressedSize)
fmt.Printf("Compression ratio: %.2f:1\n", compressionRatio) fmt.Printf("Compression ratio: %.2f:1\n", compressionRatio)
fmt.Printf("Compression efficiency: %.2f%%\n", efficiency) fmt.Printf("Compression efficiency: %.2f%%\n", efficiency)
// Display compressed directory path
fmt.Printf("Compressed dir: %s\n", pathToUse) fmt.Printf("Compressed dir: %s\n", pathToUse)
// If not uploading, we're done
if !upload { if !upload {
return return nil
} }
// Load SourceForge config
config, err := spitfire.LoadConfig() config, err := spitfire.LoadConfig()
if err != nil { if err != nil {
log.Fatalf("Failed to load SourceForge config: %v", err) return fmt.Errorf("load config: %w", err)
} }
// Check tarball existence
if _, err := os.Stat(outputCompressedFile); err != nil { if _, err := os.Stat(outputCompressedFile); err != nil {
log.Fatalf("No compressed file found to upload: %v", err) return fmt.Errorf("compressed file not found: %w", err)
} }
// The subdirectory path in the SF project
// e.g. "browser/amd64/nightly/2024.12.23"
uploadDir := fmt.Sprintf("%s/%s/%s/%s", component, arch, release, version) uploadDir := fmt.Sprintf("%s/%s/%s/%s", component, arch, release, version)
if err := spitfire.Upload(config, outputCompressedFile, "/home/frs/project/spitfire-browser/"+uploadDir+"/"); err != nil {
// 1) Upload the file to SourceForge once return fmt.Errorf("upload compressed file: %w", err)
err = spitfire.Upload(config, outputCompressedFile,
"/home/frs/project/spitfire-browser/"+uploadDir+"/")
if err != nil {
log.Fatalf("Failed to upload compressed file: %v", err)
} }
fmt.Println("Compressed file uploaded successfully.") fmt.Println("Compressed file uploaded successfully.")
// 2) Download existing APPINDEX or create new if err := spitfire.DownloadAPPINDEX(config, "/home/frs/project/spitfire-browser/"); err != nil {
err = spitfire.DownloadAPPINDEX(config, "/home/frs/project/spitfire-browser/")
if err != nil {
fmt.Println("Failed to download APPINDEX. A new one will be created and uploaded.") fmt.Println("Failed to download APPINDEX. A new one will be created and uploaded.")
} }
// 3) Update the APPINDEX if err := spitfire.PackageAPPINDEX(
err = spitfire.PackageAPPINDEX( packageName,
packageName, // e.g. "spitfire-browser" release,
release, // e.g. "nightly" version,
version, // e.g. "2024.12.23"
arch, arch,
fmt.Sprintf("%d", compressedSize), fmt.Sprintf("%d", compressedSize),
fmt.Sprintf("%d", uncompressedSize), fmt.Sprintf("%d", uncompressedSize),
name, // e.g. "Spitfire" name,
url, url,
licence, licence,
component, component,
maintainer, maintainer,
"", // dependencies "",
platform, platform,
uploadDir, uploadDir,
) ); err != nil {
if err != nil { return fmt.Errorf("package APPINDEX: %w", err)
log.Fatalf("Failed to update APPINDEX: %v", err)
} }
fmt.Println("APPINDEX updated successfully.") fmt.Println("APPINDEX updated successfully.")
// 4) Clean
if err := spitfire.CleanAppIndex(); err != nil { if err := spitfire.CleanAppIndex(); err != nil {
log.Fatalf("Failed to clean APPINDEX: %v", err) return fmt.Errorf("clean APPINDEX: %w", err)
} }
// 5) Upload the updated APPINDEX if err := spitfire.UploadAPPINDEX(config, "/home/frs/project/spitfire-browser/"); err != nil {
err = spitfire.UploadAPPINDEX(config, "/home/frs/project/spitfire-browser/") return fmt.Errorf("upload APPINDEX: %w", err)
if err != nil {
log.Fatalf("Failed to upload updated APPINDEX: %v", err)
} }
fmt.Println("APPINDEX uploaded successfully.") fmt.Println("APPINDEX uploaded successfully.")
return nil
} }
// restoreWorkingDirectory restores the initial working directory after any operation that might change it.
func restoreWorkingDirectory() { func restoreWorkingDirectory() {
err := os.Chdir(initialDir) if err := os.Chdir(initialDir); err != nil {
if err != nil { log.Printf("Failed to restore working directory: %v", err)
log.Fatalf("Failed to restore the working directory: %v", err)
} }
fmt.Printf("Restored working directory to: %s\n", initialDir)
} }

View file

@ -59,63 +59,59 @@ func ResolvePath(path string) (string, error) {
} }
// Function to download Mozilla source if not present // Function to download Mozilla source if not present
func DownloadSource(sourcePath string, sourceRepo string) { func DownloadSource(sourcePath, sourceRepo string) error {
if _, err := os.Stat(sourcePath); os.IsNotExist(err) { if _, err := os.Stat(sourcePath); os.IsNotExist(err) {
fmt.Println("Mozilla source not found. Cloning from repository...") fmt.Println("Mozilla source not found. Cloning from repository...")
if err := runCommand("hg", "clone", sourceRepo, sourcePath); err != nil { if err := runCommand("hg", "clone", sourceRepo, sourcePath); err != nil {
errors = append(errors, "Failed to clone Mozilla repository.") return fmt.Errorf("failed to clone Mozilla repository: %w", err)
} }
} else { } else {
fmt.Println("Mozilla source already exists.") fmt.Println("Mozilla source already exists.")
} }
return nil
} }
// Function to discard uncommitted changes // Function to discard uncommitted changes
func DiscardChanges(sourcePath string) { func DiscardChanges(sourcePath string) error {
fmt.Println("Discarding uncommitted changes...") fmt.Println("Discarding uncommitted changes...")
if err := runCommand("hg", "revert", "--all", "--no-backup", "-R", sourcePath); err != nil { if err := runCommand("hg", "revert", "--all", "--no-backup", "-R", sourcePath); err != nil {
errors = append(errors, "Failed to revert changes in Mozilla repository.") return fmt.Errorf("failed to revert changes: %w", err)
} }
return nil
} }
// Function to clean build // Function to clean build
func CleanBuild(sourcePath string, fullClean bool) { func CleanBuild(sourcePath string, fullClean bool) error {
fmt.Println("Cleaning build...") fmt.Println("Cleaning build...")
if err := runCommand("hg", "revert", "--all", "--no-backup", "-R", sourcePath); err != nil {
// Revert uncommitted changes return fmt.Errorf("failed to revert changes: %w", err)
if err := runCommand("hg", "revert", "--all", "--no-backup"); err != nil {
errors = append(errors, "Failed to revert changes in Mozilla repository.")
} }
if fullClean { if fullClean {
// Perform full clean or clobber if necessary machCmd := filepath.Join(sourcePath, "mach")
var machCmd string
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
machCmd = ".\\mach" machCmd = filepath.Join(sourcePath, "mach.bat")
} else { }
machCmd = "./mach" cmd := exec.Command(machCmd, "clobber")
cmd.Dir = sourcePath // Run in the source directory
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to clean build: %w", err)
} }
if err := runCommand(machCmd, "clobber"); err != nil {
errors = append(errors, "Failed to clean build.")
} else {
fmt.Println("Build artifacts cleaned successfully.") fmt.Println("Build artifacts cleaned successfully.")
} }
} else { return nil
fmt.Println("Skipping full clean. Build artifacts remain intact.")
}
} }
// Function to update Mozilla repository // Function to update Mozilla repository
func UpdateRepo(sourcePath string) { func UpdateRepo(sourcePath string) error {
fmt.Println("Updating Mozilla repository...") fmt.Println("Updating Mozilla repository...")
if err := os.Chdir(sourcePath); err != nil { if err := os.Chdir(sourcePath); err != nil {
errors = append(errors, "Failed to navigate to source directory.") return fmt.Errorf("failed to navigate to source directory: %w", err)
return
} }
if err := runCommand("hg", "pull", "-u"); err != nil { if err := runCommand("hg", "pull", "-u"); err != nil {
errors = append(errors, "Failed to update Mozilla repository.") return fmt.Errorf("failed to update repository: %w", err)
} }
return nil
} }
// Function to update patches // Function to update patches
@ -174,56 +170,41 @@ func UpdatePatches(patchesDir, patchesRepo, sourcePath string) {
} }
// Function to configure Spitfire // Function to configure Spitfire
func Configure(sourcePath string) { func Configure(sourcePath string) error {
fmt.Println("Configuring Spitfire...") fmt.Println("Configuring Spitfire...")
if err := os.Chdir(sourcePath); err != nil { if err := os.Chdir(sourcePath); err != nil {
errors = append(errors, "Failed to navigate to source directory.") return fmt.Errorf("failed to navigate to source directory: %w", err)
return
} }
// Use the appropriate mach command for Windows or Unix-like systems machCmd := "./mach"
var machCmd string
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
machCmd = ".\\mach" machCmd = ".\\mach"
} else {
machCmd = "./mach"
}
if err := runCommand(machCmd, "configure"); err != nil {
errors = append(errors, "Configuration failed.")
} }
return runCommand(machCmd, "configure")
} }
// Function to build Spitfire // Function to build Spitfire
func Build(sourcePath string) { func Build(sourcePath string) error {
fmt.Println("Building Spitfire...") fmt.Println("Building Spitfire...")
if err := os.Chdir(sourcePath); err != nil { if err := os.Chdir(sourcePath); err != nil {
errors = append(errors, "Failed to navigate to source directory.") return fmt.Errorf("failed to navigate to source directory: %w", err)
return
} }
// Use the appropriate mach command for Windows or Unix-like systems machCmd := "./mach"
var machCmd string
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
machCmd = ".\\mach" machCmd = ".\\mach"
} else {
machCmd = "./mach"
}
if err := runCommand(machCmd, "build"); err != nil {
errors = append(errors, "Build failed.")
} }
return runCommand(machCmd, "build")
} }
// Function to run the project after build // Function to run the project after build
func RunProject(sourcePath string) { func RunProject(sourcePath string) error {
fmt.Println("Running the project...") fmt.Println("Running the project...")
// Resolve the build directory // Resolve the build directory
buildDir, err := ResolveBuildDir(sourcePath) buildDir, err := ResolveBuildDir(sourcePath)
if err != nil { if err != nil {
fmt.Printf("Error resolving build directory: %v\n", err) return fmt.Errorf("error resolving build directory: %w", err)
return
} }
// List of possible binaries // List of possible binaries
@ -242,15 +223,13 @@ func RunProject(sourcePath string) {
} }
if binaryPath == "" { if binaryPath == "" {
fmt.Println("No suitable binary found to run the project.") return fmt.Errorf("no suitable binary found to run the project")
return
} }
// Create a unique profile directory for each run // Create a unique profile directory for each run
profilePath := filepath.Join(buildDir, fmt.Sprintf("profile_%d", time.Now().UnixNano())) profilePath := filepath.Join(buildDir, fmt.Sprintf("profile_%d", time.Now().UnixNano()))
if err := os.Mkdir(profilePath, 0755); err != nil { if err := os.Mkdir(profilePath, 0755); err != nil {
fmt.Printf("Failed to create profile directory: %v\n", err) return fmt.Errorf("failed to create profile directory: %w", err)
return
} }
// Run the binary with the new profile // Run the binary with the new profile
@ -260,19 +239,22 @@ func RunProject(sourcePath string) {
cmd.Stdin = os.Stdin cmd.Stdin = os.Stdin
fmt.Printf("Running binary: %s with new profile at %s\n", binaryPath, profilePath) fmt.Printf("Running binary: %s with new profile at %s\n", binaryPath, profilePath)
if err := cmd.Run(); err != nil { runErr := cmd.Run()
fmt.Printf("Failed to run the project: %v\n", err)
} else {
fmt.Println("Binary execution finished successfully.")
}
// Delete the profile directory after execution // Delete the profile directory after execution
fmt.Printf("Deleting profile directory: %s\n", profilePath) fmt.Printf("Deleting profile directory: %s\n", profilePath)
if err := os.RemoveAll(profilePath); err != nil { if removeErr := os.RemoveAll(profilePath); removeErr != nil {
fmt.Printf("Failed to delete profile directory: %v\n", err) fmt.Printf("Warning: failed to delete profile directory: %v\n", removeErr)
} else { } else {
fmt.Println("Profile directory deleted successfully.") fmt.Println("Profile directory deleted successfully.")
} }
if runErr != nil {
return fmt.Errorf("failed to run the project: %w", runErr)
}
fmt.Println("Binary execution finished successfully.")
return nil
} }
// ResolveBuildDir detects the build directory dynamically // ResolveBuildDir detects the build directory dynamically