diff --git a/README.md b/README.md index a4f4b06..63a79fa 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,12 @@ This is a "simple" script for building the Spitfire Browser based on Mozilla Fir ## Dependencies -- Mercurial (hg) - Git - Golang (tested with v1.21) - Python 3.11 and pip3 +- Mercurial (hg) + +*Python 3.11, pip3, and Mercurial (hg) are dependencies needed to build Firefox, and they might change in the future or based on your operating system. For Windows, you need to install MozillaBuild. Please ensure you have all the dependencies to build Firefox by following the instructions on Mozilla Firefox's website!* # Example usage: diff --git a/main.go b/main.go index 4a96458..5eefa46 100644 --- a/main.go +++ b/main.go @@ -67,16 +67,11 @@ func printHelp() { } func main() { - - path, err3 := spitfire.ResolvePath("/mozilla-central") - // Check and set the MOZILLABUILD environment variable globally - err2 := spitfire.SetGlobalEnv("MOZILLABUILD", path, "user") // For user - if err2 != nil { - log.Fatalf("Error setting global environment variable: %v", err2) - } - if err3 != nil { - log.Fatalf("Error setting global environment variable: %v", err3) - } + // // Check system dependencies + // err := spitfire.CheckSystemDependencies() + // if err != nil { + // log.Fatalf("System check failed: %v", err) + // } flag.Parse() @@ -90,26 +85,26 @@ func main() { } // Save the initial directory - var err error - initialDir, err = os.Getwd() - if err != nil { - log.Fatalf("Failed to get current working directory: %v", err) + var err2 error + initialDir, err2 = os.Getwd() + if err2 != nil { + log.Fatalf("Failed to get current working directory: %v", err2) } fmt.Printf("Initial working directory: %s\n", initialDir) // Convert buildPath and uploadPath to absolute paths if buildPath != "" { - buildPath, err = spitfire.ResolvePath(buildPath) - if err != nil { - log.Fatalf("Failed to convert buildPath to absolute path: %v", err) + buildPath, err2 = spitfire.ResolvePath(buildPath) + if err2 != nil { + log.Fatalf("Failed to convert buildPath to absolute path: %v", err2) } fmt.Printf("Resolved buildPath: %s\n", buildPath) } if uploadPath != "" { - uploadPath, err = spitfire.ResolvePath(uploadPath) - if err != nil { - log.Fatalf("Failed to convert uploadPath to absolute path: %v", err) + uploadPath, err2 = spitfire.ResolvePath(uploadPath) + if err2 != nil { + log.Fatalf("Failed to convert uploadPath to absolute path: %v", err2) } fmt.Printf("Resolved uploadPath: %s\n", uploadPath) } diff --git a/spitfire/build.go b/spitfire/build.go index 78a9efd..3f5be5d 100644 --- a/spitfire/build.go +++ b/spitfire/build.go @@ -37,6 +37,7 @@ func SetGlobalEnv(variable, value string, scope string) error { // Run an external command like scp or rsync func runCommand(command string, args ...string) error { + fmt.Printf("Running command: %s %v\n", command, args) cmd := exec.Command(command, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr @@ -83,10 +84,21 @@ func CleanBuild(sourcePath string) { errors = append(errors, "Failed to navigate to source directory.") return } + + // Use the appropriate mach command for Windows or Unix-like systems + var machCmd string + if runtime.GOOS == "windows" { + machCmd = ".\\mach" + } else { + machCmd = "./mach" + } + + // Revert uncommitted changes if err := runCommand("hg", "revert", "--all", "--no-backup"); err != nil { errors = append(errors, "Failed to revert changes in Mozilla repository.") } - if err := runCommand("./mach", "clobber"); err != nil { + // Clean the build + if err := runCommand(machCmd, "clobber"); err != nil { errors = append(errors, "Failed to clean build.") } } @@ -147,7 +159,7 @@ func UpdatePatches(patchesDir, patchesRepo, sourcePath string) { fmt.Println("Copying files from patches directory to Firefox source directory...") if runtime.GOOS == "windows" { // Use robocopy for Windows - if err := runCommand("robocopy", patchesDir, sourcePath, "*", "/E", "/XF", ".git"); err != nil { + if err := runCommand("robocopy", patchesDir, sourcePath, "*", "/S", "/XF", ".git", "/XD", ".git"); err != nil { errors = append(errors, "Failed to copy files (Windows robocopy).") } } else { @@ -155,7 +167,7 @@ func UpdatePatches(patchesDir, patchesRepo, sourcePath string) { if err := runCommand("rsync", "-av", "--exclude=.git", patchesDir+"/", sourcePath+"/"); err != nil { errors = append(errors, "Failed to copy files (rsync).") } - } + } } // Function to configure Spitfire @@ -165,7 +177,16 @@ func Configure(sourcePath string) { errors = append(errors, "Failed to navigate to source directory.") return } - if err := runCommand("./mach", "configure"); err != nil { + + // Use the appropriate mach command for Windows or Unix-like systems + var machCmd string + if runtime.GOOS == "windows" { + machCmd = ".\\mach" + } else { + machCmd = "./mach" + } + + if err := runCommand(machCmd, "configure"); err != nil { errors = append(errors, "Configuration failed.") } } @@ -177,7 +198,16 @@ func Build(sourcePath string) { errors = append(errors, "Failed to navigate to source directory.") return } - if err := runCommand("./mach", "build"); err != nil { + + // Use the appropriate mach command for Windows or Unix-like systems + var machCmd string + if runtime.GOOS == "windows" { + machCmd = ".\\mach" + } else { + machCmd = "./mach" + } + + if err := runCommand(machCmd, "build"); err != nil { errors = append(errors, "Build failed.") } } @@ -185,11 +215,16 @@ func Build(sourcePath string) { // Function to run the project after build func RunProject(sourcePath string) { fmt.Println("Running the project...") - if err := os.Chdir(sourcePath); err != nil { - errors = append(errors, "Failed to navigate to source directory.") - return + + // Use the appropriate mach command for Windows or Unix-like systems + var machCmd string + if runtime.GOOS == "windows" { + machCmd = ".\\mach" + } else { + machCmd = "./mach" } - if err := runCommand("./mach", "run"); err != nil { + + if err := runCommand(machCmd, "run"); err != nil { errors = append(errors, "Failed to run the project.") } } diff --git a/spitfire/checks.go b/spitfire/checks.go new file mode 100644 index 0000000..c0bb232 --- /dev/null +++ b/spitfire/checks.go @@ -0,0 +1,78 @@ +package spitfire + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "runtime" +) + +// CheckSystemDependencies ensures that required tools for building are installed. +func CheckSystemDependencies() error { + requiredTools := map[string]string{ + "git": "https://git-scm.com/download/win", // Git + "python": "https://www.python.org/downloads/", // Python + "pip3": "https://pip.pypa.io/en/stable/installing/", // Pip3 + } + + if runtime.GOOS == "windows" { + // Check for MozillaBuild installation + mozBuildPath := os.Getenv("MOZILLABUILD") + if mozBuildPath == "" { + mozBuildPath = "C:\\mozilla-build" // Default to standard MozillaBuild path + } + + // Check if MozillaBuild exists at the specified location + if !dirExists(mozBuildPath) { + requiredTools["mozbuild"] = "https://ftp.mozilla.org/pub/mozilla/libraries/win32/MozillaBuildSetup-Latest.exe" + } + } + + missingTools := []string{} + + // Check for each required tool + for tool, downloadLink := range requiredTools { + if !isCommandAvailable(tool) { + missingTools = append(missingTools, fmt.Sprintf("%s (Download: %s)", tool, downloadLink)) + } + } + + // Special check for mach in the local source directory (mozilla-central) + machPath := filepath.Join("mozilla-central", "mach") + if !fileExists(machPath) { + missingTools = append(missingTools, fmt.Sprintf("mach (run from mozilla-central directory)")) + } + + if len(missingTools) > 0 { + fmt.Println("The following tools are missing and are required for the build:") + for _, tool := range missingTools { + fmt.Println(" - " + tool) + } + return fmt.Errorf("missing required tools") + } + + fmt.Println("All required system dependencies are installed.") + return nil +} + +// isCommandAvailable checks if a command/tool is available on the system. +func isCommandAvailable(command string) bool { + _, err := exec.LookPath(command) + return err == nil +} + +// fileExists checks if a file exists at the given path. +func fileExists(path string) bool { + _, err := os.Stat(path) + return err == nil +} + +// dirExists checks if a directory exists at the given path. +func dirExists(path string) bool { + info, err := os.Stat(path) + if os.IsNotExist(err) { + return false + } + return info.IsDir() +}