improving windows compatability
This commit is contained in:
parent
921540d5a4
commit
8de4db960a
6 changed files with 73 additions and 107 deletions
|
@ -66,8 +66,6 @@ Below is a detailed description of all the flags supported by the Spitfire Build
|
||||||
|
|
||||||
### **Customization Flags**
|
### **Customization Flags**
|
||||||
|
|
||||||
- **`-p=<path>`**:
|
|
||||||
Specifies the build directory path for uploads. If not provided, the script dynamically detects the build directory.
|
|
||||||
- **`-t=<target>`**:
|
- **`-t=<target>`**:
|
||||||
Sets the target format for the build output. The format follows `component-arch-release-platform`.
|
Sets the target format for the build output. The format follows `component-arch-release-platform`.
|
||||||
- **`-v=<version>`**:
|
- **`-v=<version>`**:
|
||||||
|
|
91
main.go
91
main.go
|
@ -5,7 +5,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime" // for detecting system architecture and platform
|
"runtime" // for detecting system architecture and platform
|
||||||
"spitfire-builder/spitfire"
|
"spitfire-builder/spitfire"
|
||||||
|
@ -25,7 +24,6 @@ var (
|
||||||
skipPatchUpdate bool
|
skipPatchUpdate bool
|
||||||
run bool
|
run bool
|
||||||
compress bool
|
compress bool
|
||||||
buildPath string
|
|
||||||
target string
|
target string
|
||||||
version string
|
version string
|
||||||
component string
|
component string
|
||||||
|
@ -46,7 +44,6 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
flag.StringVar(&buildPath, "p", "", "Path to the build directory")
|
|
||||||
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")
|
||||||
flag.StringVar(&version, "v", "", "Specify version for the package. For nightly, use current date if not specified.")
|
flag.StringVar(&version, "v", "", "Specify version for the package. For nightly, use current date if not specified.")
|
||||||
|
@ -76,37 +73,6 @@ func printHelp() {
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkDependencies verifies if required dependencies are installed
|
|
||||||
func checkDependencies() error {
|
|
||||||
dependencies := map[string]string{
|
|
||||||
"mercurial": "hg",
|
|
||||||
"python3": "python3",
|
|
||||||
"rsync": "rsync",
|
|
||||||
"git": "git",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log the PATH for debugging
|
|
||||||
fmt.Printf("Current PATH: %s\n", os.Getenv("PATH"))
|
|
||||||
|
|
||||||
for dep, cmd := range dependencies {
|
|
||||||
// Use LookPath to check availability
|
|
||||||
if _, err := exec.LookPath(cmd); err != nil {
|
|
||||||
return fmt.Errorf("dependency %s is not installed or not found in PATH. Please run: sudo apt install %s", dep, dep)
|
|
||||||
}
|
|
||||||
|
|
||||||
// For python3, run a specific version check to confirm
|
|
||||||
if dep == "python3" {
|
|
||||||
out, err := exec.Command(cmd, "--version").Output()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("dependency %s is installed but not functional. Ensure 'python3 --version' works correctly: %v", dep, err)
|
|
||||||
}
|
|
||||||
fmt.Printf("Detected %s: %s", dep, string(out))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
@ -117,7 +83,7 @@ func main() {
|
||||||
|
|
||||||
// Only check dependencies if NOT skipping them
|
// Only check dependencies if NOT skipping them
|
||||||
if !skipDeps {
|
if !skipDeps {
|
||||||
if err := checkDependencies(); err != nil {
|
if err := spitfire.CheckDependencies(); err != nil {
|
||||||
log.Fatalf("System check failed: %v", err)
|
log.Fatalf("System check failed: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,28 +101,6 @@ func main() {
|
||||||
}
|
}
|
||||||
fmt.Printf("Initial working directory: %s\n", initialDir)
|
fmt.Printf("Initial working directory: %s\n", initialDir)
|
||||||
|
|
||||||
// Determine buildPath dynamically if not provided
|
|
||||||
if buildPath == "" {
|
|
||||||
sourcePath, err := spitfire.ResolvePath("./mozilla-central")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Error resolving source path: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
resolvedBuildPath, err := spitfire.ResolveBuildDir(sourcePath)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to detect build directory dynamically: %v", err)
|
|
||||||
}
|
|
||||||
buildPath = resolvedBuildPath
|
|
||||||
fmt.Printf("Automatically detected buildPath: %s\n", buildPath)
|
|
||||||
} else {
|
|
||||||
// Convert buildPath to absolute path
|
|
||||||
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 != "" {
|
if uploadPath != "" {
|
||||||
uploadPath, err2 = spitfire.ResolvePath(uploadPath)
|
uploadPath, err2 = spitfire.ResolvePath(uploadPath)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
|
@ -170,7 +114,31 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if compress || upload {
|
if compress || upload {
|
||||||
PackageAndUploadProcess()
|
// Resolve the build directory dynamically
|
||||||
|
fmt.Println("Resolving build directory dynamically...")
|
||||||
|
sourcePath, err := spitfire.ResolvePath("./mozilla-central")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error resolving source path: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
buildDir, err := spitfire.ResolveBuildDir(sourcePath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error resolving build directory dynamically: %v", err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Resolved build directory: %s\n", buildDir)
|
||||||
|
|
||||||
|
// Validate that the build directory exists
|
||||||
|
stat, err := os.Stat(buildDir)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
log.Fatalf("Error: build directory does not exist at %s\n", buildDir)
|
||||||
|
} else if err != nil {
|
||||||
|
log.Fatalf("Error accessing build directory: %v\n", err)
|
||||||
|
} else if !stat.IsDir() {
|
||||||
|
log.Fatalf("Error: path exists but is not a directory: %s\n", buildDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proceed with packaging and uploading
|
||||||
|
PackageAndUploadProcess(buildDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
spitfire.PrintErrors()
|
spitfire.PrintErrors()
|
||||||
|
@ -260,12 +228,12 @@ func BuildProcess() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PackageAndUploadProcess handles compressing, packaging, and uploading the build to SourceForge.
|
// PackageAndUploadProcess handles compressing, packaging, and uploading the build to SourceForge.
|
||||||
func PackageAndUploadProcess() {
|
func PackageAndUploadProcess(buildDir string) {
|
||||||
|
|
||||||
// Restore working directory before performing SourceForge operations
|
// Restore working directory before performing SourceForge operations
|
||||||
restoreWorkingDirectory()
|
restoreWorkingDirectory()
|
||||||
|
|
||||||
pathToUse := buildPath
|
pathToUse := buildDir
|
||||||
if upload && uploadPath != "" {
|
if upload && uploadPath != "" {
|
||||||
pathToUse = uploadPath
|
pathToUse = uploadPath
|
||||||
}
|
}
|
||||||
|
@ -308,6 +276,9 @@ func PackageAndUploadProcess() {
|
||||||
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", pathToUse)
|
||||||
|
|
||||||
// If not uploading, we're done
|
// If not uploading, we're done
|
||||||
if !upload {
|
if !upload {
|
||||||
return
|
return
|
||||||
|
|
|
@ -82,33 +82,12 @@ func DiscardChanges(sourcePath string) {
|
||||||
func CleanBuild(sourcePath string, fullClean bool) {
|
func CleanBuild(sourcePath string, fullClean bool) {
|
||||||
fmt.Println("Cleaning build...")
|
fmt.Println("Cleaning build...")
|
||||||
|
|
||||||
// Resolve the build directory dynamically
|
|
||||||
buildDir, err := ResolveBuildDir(sourcePath)
|
|
||||||
if err != nil {
|
|
||||||
errors = append(errors, fmt.Sprintf("Failed to resolve build directory: %v", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Revert uncommitted changes
|
// Revert uncommitted changes
|
||||||
if err := runCommand("hg", "revert", "--all", "--no-backup"); err != nil {
|
if err := runCommand("hg", "revert", "--all", "--no-backup"); err != nil {
|
||||||
errors = append(errors, "Failed to revert changes in Mozilla repository.")
|
errors = append(errors, "Failed to revert changes in Mozilla repository.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Paths for CLOBBER file and last build timestamp
|
if fullClean {
|
||||||
clobberFile := filepath.Join(buildDir, "CLOBBER")
|
|
||||||
buildTimestampFile := filepath.Join(buildDir, ".last_build_timestamp")
|
|
||||||
|
|
||||||
// Check if a clobber is required
|
|
||||||
clobberRequired := false
|
|
||||||
if _, err := os.Stat(clobberFile); err == nil {
|
|
||||||
clobberFileInfo, _ := os.Stat(clobberFile)
|
|
||||||
if buildInfo, err := os.Stat(buildTimestampFile); err != nil || clobberFileInfo.ModTime().After(buildInfo.ModTime()) {
|
|
||||||
clobberRequired = true
|
|
||||||
fmt.Println("CLOBBER file has been updated. Clobber is required.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if fullClean || clobberRequired {
|
|
||||||
// Perform full clean or clobber if necessary
|
// Perform full clean or clobber if necessary
|
||||||
var machCmd string
|
var machCmd string
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
|
@ -181,7 +160,7 @@ func UpdatePatches(patchesDir, patchesRepo, sourcePath string) {
|
||||||
|
|
||||||
// Handle platform-specific rsync command
|
// Handle platform-specific rsync command
|
||||||
fmt.Println("Copying files from patches directory to Firefox source directory...")
|
fmt.Println("Copying files from patches directory to Firefox source directory...")
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" || !isMsys2() {
|
||||||
// Use robocopy for Windows
|
// Use robocopy for Windows
|
||||||
if err := runCommand("robocopy", patchesDir, sourcePath, "*", "/S", "/XF", ".git", "/XD", ".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).")
|
errors = append(errors, "Failed to copy files (Windows robocopy).")
|
||||||
|
|
|
@ -6,44 +6,47 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CheckSystemDependencies ensures that required tools for building are installed.
|
// CheckDependencies ensures that all required tools and dependencies for the build are installed.
|
||||||
func CheckSystemDependencies() error {
|
func CheckDependencies() error {
|
||||||
requiredTools := map[string]string{
|
// Common dependencies
|
||||||
|
dependencies := map[string]string{
|
||||||
"git": "https://git-scm.com/download/win", // Git
|
"git": "https://git-scm.com/download/win", // Git
|
||||||
"python": "https://www.python.org/downloads/", // Python
|
"python": "https://www.python.org/downloads/", // Python
|
||||||
"pip3": "https://pip.pypa.io/en/stable/installing/", // Pip3
|
"pip3": "https://pip.pypa.io/en/stable/installing/", // Pip3
|
||||||
|
"mercurial": "https://www.mercurial-scm.org/", // Mercurial (hg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if runtime.GOOS == "windows" {
|
// Add platform-specific dependencies
|
||||||
// Check for MozillaBuild installation
|
if runtime.GOOS == "windows" || !isMsys2() {
|
||||||
mozBuildPath := os.Getenv("MOZILLABUILD")
|
mozBuildPath := os.Getenv("MOZILLABUILD")
|
||||||
if mozBuildPath == "" {
|
if mozBuildPath == "" {
|
||||||
mozBuildPath = "C:\\mozilla-build" // Default to standard MozillaBuild path
|
mozBuildPath = "C:\\mozilla-build" // Default path for MozillaBuild
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if MozillaBuild exists at the specified location
|
|
||||||
if !dirExists(mozBuildPath) {
|
if !dirExists(mozBuildPath) {
|
||||||
requiredTools["mozbuild"] = "https://ftp.mozilla.org/pub/mozilla/libraries/win32/MozillaBuildSetup-Latest.exe"
|
dependencies["mozbuild"] = "https://ftp.mozilla.org/pub/mozilla/libraries/win32/MozillaBuildSetup-Latest.exe"
|
||||||
}
|
}
|
||||||
|
} else if runtime.GOOS != "windows" || !isMsys2() {
|
||||||
|
dependencies["rsync"] = "https://rsync.samba.org/download.html" // rsync for non-Windows platforms
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for missing tools
|
||||||
missingTools := []string{}
|
missingTools := []string{}
|
||||||
|
for tool, downloadLink := range dependencies {
|
||||||
// Check for each required tool
|
|
||||||
for tool, downloadLink := range requiredTools {
|
|
||||||
if !isCommandAvailable(tool) {
|
if !isCommandAvailable(tool) {
|
||||||
missingTools = append(missingTools, fmt.Sprintf("%s (Download: %s)", tool, downloadLink))
|
missingTools = append(missingTools, fmt.Sprintf("%s (Download: %s)", tool, downloadLink))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special check for mach in the local source directory (mozilla-central)
|
// Special check for `mach` in the local source directory
|
||||||
machPath := filepath.Join("mozilla-central", "mach")
|
machPath := filepath.Join("mozilla-central", "mach")
|
||||||
if !fileExists(machPath) {
|
if !fileExists(machPath) {
|
||||||
missingTools = append(missingTools, fmt.Sprintf("mach (run from mozilla-central directory)"))
|
missingTools = append(missingTools, "mach (ensure you are in the mozilla-central directory)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Report missing tools if any
|
||||||
if len(missingTools) > 0 {
|
if len(missingTools) > 0 {
|
||||||
fmt.Println("The following tools are missing and are required for the build:")
|
fmt.Println("The following tools are missing and are required for the build:")
|
||||||
for _, tool := range missingTools {
|
for _, tool := range missingTools {
|
||||||
|
@ -76,3 +79,8 @@ func dirExists(path string) bool {
|
||||||
}
|
}
|
||||||
return info.IsDir()
|
return info.IsDir()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isMsys2 detects if the environment is MSYS2 by checking the MSYSTEM environment variable.
|
||||||
|
func isMsys2() bool {
|
||||||
|
return strings.Contains(strings.ToLower(os.Getenv("MSYSTEM")), "msys")
|
||||||
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ func ApplyPatches(sourcePath string, patchesRepo string, patchesPath string, pat
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the patches using `run.sh`
|
// Apply the patches using `run.sh`
|
||||||
applyCmd := exec.Command("go", "run", ".", "--path", sourcePath, "--patches", fullPatchesPath) applyCmd.Dir = patchesCloneDir // Run from the patches directory
|
applyCmd := exec.Command("go", "run", ".", "--path", sourcePath, "--patches", fullPatchesPath)
|
||||||
applyCmd.Dir = patchesCloneDir // Run from the patches directory
|
applyCmd.Dir = patchesCloneDir // Run from the patches directory
|
||||||
applyCmd.Stdout = os.Stdout
|
applyCmd.Stdout = os.Stdout
|
||||||
applyCmd.Stderr = os.Stderr
|
applyCmd.Stderr = os.Stderr
|
||||||
|
|
|
@ -26,16 +26,24 @@ type Config struct {
|
||||||
func LoadConfig() (*Config, error) {
|
func LoadConfig() (*Config, error) {
|
||||||
file, err := os.Open("sourceforge_config.json") // Assuming a JSON config file
|
file, err := os.Open("sourceforge_config.json") // Assuming a JSON config file
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("failed to open config file: %v", err)
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
config := &Config{}
|
config := &Config{}
|
||||||
if err := json.NewDecoder(file).Decode(config); err != nil {
|
if err := json.NewDecoder(file).Decode(config); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("failed to decode config file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
config.SFKeyPath = filepath.FromSlash(config.SFKeyPath)
|
// Normalize the SSH key path for the current OS
|
||||||
|
config.SFKeyPath = filepath.Clean(config.SFKeyPath)
|
||||||
|
|
||||||
|
// Validate that the key file exists
|
||||||
|
if _, err := os.Stat(config.SFKeyPath); os.IsNotExist(err) {
|
||||||
|
return nil, fmt.Errorf("SSH key file not found at path: %s", config.SFKeyPath)
|
||||||
|
} else if err != nil {
|
||||||
|
return nil, fmt.Errorf("error accessing SSH key file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
@ -74,7 +82,9 @@ func CompressDirectory(srcDir, dstFile string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
header.Name = relPath
|
|
||||||
|
// Normalize paths to UNIX-style for tar compatibility
|
||||||
|
header.Name = filepath.ToSlash(relPath)
|
||||||
|
|
||||||
// Explicitly set the type flag for directories
|
// Explicitly set the type flag for directories
|
||||||
if fi.IsDir() {
|
if fi.IsDir() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue