added automatic mozilla-release download

This commit is contained in:
partisan 2025-04-13 19:21:04 +02:00
parent e5c95924d5
commit a13f43086f
6 changed files with 477 additions and 194 deletions

237
main.go
View file

@ -46,33 +46,75 @@ var (
var errors []error // This is also in build.go. Great! This code is a mess.
func init() {
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.StringVar(&version, "v", "", "Specify version for the package. For nightly, use current date if not specified.")
flag.StringVar(&component, "component", "browser", "Component name (default: browser)")
flag.StringVar(&arch, "arch", runtime.GOARCH, "Architecture (default: system architecture)")
flag.StringVar(&release, "release", "nightly", "Release type (default: nightly)")
flag.StringVar(&platform, "platform", runtime.GOOS, "Platform (default: system platform)")
flag.BoolVar(&all, "a", false, "Perform all steps (build, clean, update)")
flag.BoolVar(&buildFlag, "b", false, "Build Spitfire")
flag.BoolVar(&clean, "clean", false, "Revert uncommitted changes without removing build artifacts")
flag.BoolVar(&fullClean, "full-clean", false, "Perform a full clean by removing all build artifacts (clobber)")
flag.BoolVar(&update, "u", false, "Update Mozilla repository")
flag.BoolVar(&prePatch, "pre-patch", false, "Apply pre-build patches")
flag.BoolVar(&postPatch, "post-patch", false, "Apply post-build patches")
flag.BoolVar(&skipPatchUpdate, "skip-patch-update", false, "Skip updating the patches repository")
flag.BoolVar(&run, "r", false, "Run the project after build")
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.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.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.StringVar(&version, "v", "", "🏷️ Specify version for the package. For nightly, use current date if not specified.")
flag.StringVar(&component, "component", "browser", "🌐 Component name (default: browser)")
flag.StringVar(&arch, "arch", runtime.GOARCH, "💻 Architecture (default: system architecture)")
flag.StringVar(&release, "release", "nightly", "🌙 Release type (default: nightly)")
flag.StringVar(&platform, "platform", runtime.GOOS, "🖥️ Platform (default: system platform)")
flag.BoolVar(&all, "a", false, "🔄 Perform all steps (build, clean, update)")
flag.BoolVar(&buildFlag, "b", false, "🔨 Build Spitfire")
flag.BoolVar(&clean, "clean", false, "🧹 Revert uncommitted changes without removing build artifacts")
flag.BoolVar(&fullClean, "full-clean", false, "🧼 Perform a full clean by removing all build artifacts (clobber)")
flag.BoolVar(&update, "u", false, "🔄 Update Mozilla repository")
flag.BoolVar(&prePatch, "pre-patch", false, "🔧 Apply pre-build patches")
flag.BoolVar(&postPatch, "post-patch", false, "🔧 Apply post-build patches")
flag.BoolVar(&skipPatchUpdate, "skip-patch-update", false, "⏭️ Skip updating the patches repository")
flag.BoolVar(&run, "r", false, "🚀 Run the project after build")
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.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")
}
func printHelp() {
fmt.Println("Usage: go run . -p=<path-to-build> -t=<target> [-c|--compress] [-v|--version=<version>] [-component=<component>] [-arch=<architecture>] [-release=<release>] [-platform=<platform>]")
flag.PrintDefaults()
fmt.Println("Example: go run . --upload -c -a")
fmt.Println("📖 Spitfire Build System Help")
fmt.Println("Usage: go run . [options]")
fmt.Println("")
fmt.Println("🚀 Main Operations:")
fmt.Println("")
fmt.Println("🔧 Build Options:")
fmt.Println(" -a, -all Perform all steps (build, clean, update)")
fmt.Println(" -b, -build Build Spitfire")
fmt.Println(" -r, -run Run the project after build")
fmt.Println("")
fmt.Println("🧹 Clean Options:")
fmt.Println(" -clean Revert uncommitted changes")
fmt.Println(" -full-clean Remove all build artifacts (clobber)")
fmt.Println("")
fmt.Println("🔄 Update Options:")
fmt.Println(" -u, -update Update Mozilla repository")
fmt.Println(" -pre-patch Apply pre-build patches")
fmt.Println(" -post-patch Apply post-build patches")
fmt.Println(" -skip-patch-update Skip updating patches repository")
fmt.Println("")
fmt.Println("📦 Package Options:")
fmt.Println(" -c, -compress Compress build directory to tar.gz")
fmt.Println(" -upload Upload compressed file to SourceForge")
fmt.Println(" -upload-path Path to file for upload")
fmt.Println("")
fmt.Println("⚙️ Configuration Options:")
fmt.Println(" -t, -target Target format: component-arch-release-platform")
fmt.Println(" -v, -version Package version (default: date for nightly)")
fmt.Println(" -component Component name (default: browser)")
fmt.Println(" -arch Architecture (default: system arch)")
fmt.Println(" -release Release type (default: nightly)")
fmt.Println(" -platform Platform (default: system OS)")
fmt.Println("")
fmt.Println("🔍 Other Options:")
fmt.Println(" -skip-deps Skip system dependency checks")
fmt.Println(" -ignore-errors Continue despite errors")
fmt.Println(" -h, -help Show this help message")
fmt.Println("")
fmt.Println("💡 Examples:")
fmt.Println(" Full build and upload: go run . -a -c -upload")
fmt.Println(" Just build: go run . -b")
fmt.Println(" Clean build: go run . -clean")
fmt.Println(" Upload existing: go run . -upload -upload-path=./build.tar.gz")
fmt.Println("")
fmt.Println("🌐 Project: https://weforge.xyz/Spitfire")
os.Exit(0)
}
@ -92,162 +134,178 @@ func main() {
printHelp()
}
fmt.Println("🚀 Starting Spitfire build process...")
if !skipDeps {
fmt.Println("🔍 Checking system dependencies...")
if err := spitfire.CheckDependencies(); err != nil {
handleError(fmt.Errorf("system check failed: %w", err))
handleError(fmt.Errorf("system check failed: %w", err))
}
fmt.Println("✅ All dependencies verified")
}
if version == "" && release == "nightly" {
version = time.Now().Format("2006.01.02")
fmt.Printf("📅 Using nightly version: %s\n", version)
}
// Save the initial directory
var err error
initialDir, err = os.Getwd()
if err != nil {
handleError(fmt.Errorf("failed to get current directory: %w", err))
handleError(fmt.Errorf("failed to get current directory: %w", err))
}
var buildDir string
if all || buildFlag || prePatch || postPatch || clean || update || run {
fmt.Println("🏗️ Starting build process...")
buildDir, err = BuildProcess()
if err != nil {
handleError(fmt.Errorf("build process failed: %w", err))
handleError(fmt.Errorf("build process failed: %w", err))
} else if buildDir == "" && (buildFlag || all || run) {
handleError(fmt.Errorf("build directory not found after build process"))
handleError(fmt.Errorf("build directory not found after build process"))
}
}
if compress || upload {
fmt.Println("📦 Packaging and uploading build...")
if err := PackageAndUploadProcess(buildDir); err != nil {
handleError(fmt.Errorf("package/upload failed: %w", err))
handleError(fmt.Errorf("package/upload failed: %w", err))
}
}
spitfire.PrintErrors()
if len(errors) > 0 {
fmt.Fprintf(os.Stderr, "Exiting with %d error(s):\n", len(errors))
fmt.Fprintf(os.Stderr, "Exiting with %d error(s):\n", len(errors))
for _, e := range errors {
fmt.Fprintf(os.Stderr, "- %v\n", e)
fmt.Fprintf(os.Stderr, " - %v\n", e)
}
os.Exit(1)
} else {
fmt.Println("🎉 All operations completed successfully!")
os.Exit(0)
}
}
func BuildProcess() (string, error) {
fmt.Println("📂 Resolving source path...")
sourcePath, err := spitfire.ResolvePath("./mozilla-release")
if err != nil {
return "", fmt.Errorf("resolve source path: %w", err)
return "", fmt.Errorf("resolve source path: %w", err)
}
var buildDir string
if all {
fmt.Println("🔄 Running full build process...")
if err := spitfire.DownloadSource(sourcePath, sourceRepo); err != nil {
return "", fmt.Errorf("download source: %w", err)
return "", fmt.Errorf("download source: %w", err)
}
if err := spitfire.DiscardChanges(sourcePath); err != nil {
return "", fmt.Errorf("discard changes: %w", err)
return "", fmt.Errorf("discard changes: %w", err)
}
if err := spitfire.CleanBuild(sourcePath, fullClean); err != nil {
return "", fmt.Errorf("clean build: %w", err)
return "", fmt.Errorf("clean build: %w", err)
}
if err := spitfire.UpdateRepo(sourcePath); err != nil {
return "", fmt.Errorf("update repo: %w", err)
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)
return "", fmt.Errorf("pre-patch: %w", err)
}
if err := spitfire.Configure(sourcePath); err != nil {
return "", fmt.Errorf("configure: %w", err)
return "", fmt.Errorf("configure: %w", err)
}
if err := spitfire.Build(sourcePath); err != nil {
return "", fmt.Errorf("build: %w", err)
return "", fmt.Errorf("build: %w", err)
}
buildDir, err = spitfire.ResolveBuildDir(sourcePath)
if err != nil {
return "", fmt.Errorf("resolve build dir: %w", 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 {
return "", fmt.Errorf("post-patch: %w", err)
return "", fmt.Errorf("post-patch: %w", err)
}
if run {
if err := spitfire.RunProject(sourcePath); err != nil {
return "", fmt.Errorf("run project: %w", err)
return "", fmt.Errorf("run project: %w", err)
}
}
fmt.Println("Spitfire build completed successfully.")
fmt.Println("Spitfire build completed successfully")
} else if buildFlag {
fmt.Println("🔨 Running build process...")
if prePatch {
if err := spitfire.ApplyPatches(sourcePath, patchesRepo, "pre-compile-patches", filepath.Join(sourcePath, "patcher"), skipPatchUpdate); err != nil {
return "", fmt.Errorf("pre-patch: %w", err)
return "", fmt.Errorf("pre-patch: %w", err)
}
}
if err := spitfire.Configure(sourcePath); err != nil {
return "", fmt.Errorf("configure: %w", err)
return "", fmt.Errorf("configure: %w", err)
}
if err := spitfire.Build(sourcePath); err != nil {
return "", fmt.Errorf("build: %w", err)
return "", fmt.Errorf("build: %w", err)
}
buildDir, err = spitfire.ResolveBuildDir(sourcePath)
if err != nil {
return "", fmt.Errorf("resolve build dir: %w", err)
return "", fmt.Errorf("resolve build dir: %w", err)
}
if postPatch {
if err := spitfire.ApplyPatches(buildDir, patchesRepo, "post-compile-patches", filepath.Join(sourcePath, "patcher"), skipPatchUpdate); err != nil {
return "", fmt.Errorf("post-patch: %w", err)
return "", fmt.Errorf("post-patch: %w", err)
}
}
if run {
if err := spitfire.RunProject(sourcePath); err != nil {
return "", fmt.Errorf("run project: %w", err)
return "", fmt.Errorf("run project: %w", err)
}
}
fmt.Println("Spitfire build completed successfully.")
fmt.Println("Spitfire build completed successfully")
} else if clean {
fmt.Println("🧹 Cleaning build...")
if err := spitfire.CleanBuild(sourcePath, fullClean); err != nil {
return "", fmt.Errorf("clean build: %w", err)
return "", fmt.Errorf("clean build: %w", err)
}
fmt.Println("Cleaned Firefox build.")
fmt.Println("✅ Firefox build cleaned")
} else if update {
fmt.Println("🔄 Updating repository...")
if err := spitfire.DownloadSource(sourcePath, sourceRepo); err != nil {
return "", fmt.Errorf("download source: %w", err)
return "", fmt.Errorf("download source: %w", err)
}
if err := spitfire.UpdateRepo(sourcePath); err != nil {
return "", fmt.Errorf("update repo: %w", err)
return "", fmt.Errorf("update repo: %w", err)
}
fmt.Println("Mozilla repository updated.")
fmt.Println("Mozilla repository updated")
} else if prePatch {
fmt.Println("🔧 Applying pre-compile patches...")
if err := spitfire.DownloadSource(sourcePath, sourceRepo); err != nil {
return "", fmt.Errorf("download source: %w", err)
return "", fmt.Errorf("download source: %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)
return "", fmt.Errorf("pre-patch: %w", err)
}
fmt.Println("Patches updated.")
fmt.Println("✅ Pre-compile patches applied")
} else if postPatch {
fmt.Println("🔧 Applying post-compile patches...")
buildDir, err = spitfire.ResolveBuildDir(sourcePath)
if err != nil {
return "", fmt.Errorf("resolve build dir: %w", err)
return "", fmt.Errorf("resolve build dir: %w", err)
}
if _, err := os.Stat(buildDir); err == nil {
if err := spitfire.ApplyPatches(buildDir, patchesRepo, "post-compile-patches", filepath.Join(sourcePath, "patcher"), skipPatchUpdate); err != nil {
return "", fmt.Errorf("post-patch: %w", err)
return "", fmt.Errorf("post-patch: %w", err)
}
}
if run {
if err := spitfire.RunProject(sourcePath); err != nil {
return "", fmt.Errorf("run project: %w", err)
return "", fmt.Errorf("run project: %w", err)
}
}
} else if run {
fmt.Println("🚀 Running project...")
if err := spitfire.RunProject(sourcePath); err != nil {
return "", fmt.Errorf("run project: %w", err)
return "", fmt.Errorf("run project: %w", err)
}
}
@ -255,69 +313,79 @@ func BuildProcess() (string, error) {
}
func PackageAndUploadProcess(buildDir string) error {
fmt.Println("📦 Starting package and upload process...")
restoreWorkingDirectory()
pathToUse := buildDir
if upload && uploadPath != "" {
pathToUse = uploadPath
fmt.Printf(" ├─ Using custom upload path: %s\n", pathToUse)
}
if pathToUse == "" {
return fmt.Errorf("no valid build or upload path provided")
return fmt.Errorf("no valid build or upload path provided")
}
fmt.Println("📏 Calculating directory size...")
uncompressedSize, err := spitfire.GetDirectorySize(pathToUse)
if err != nil {
return fmt.Errorf("get directory size: %w", err)
return fmt.Errorf("get directory size: %w", err)
}
fmt.Printf("Uncompressed directory size: %s\n", spitfire.BytesToHumanReadable(uncompressedSize))
fmt.Printf(" ├─ Uncompressed size: %s\n", spitfire.BytesToHumanReadable(uncompressedSize))
outputCompressedFile := filepath.Join(".", fmt.Sprintf(
"%s-%s-%s-%s.tar.gz",
component, arch, release, platform,
))
fmt.Printf(" ├─ Output filename: %s\n", outputCompressedFile)
if compress {
fmt.Println("🗜️ Compressing directory...")
if err := spitfire.CompressDirectory(pathToUse, outputCompressedFile); err != nil {
return fmt.Errorf("compress directory: %w", err)
return fmt.Errorf("compress directory: %w", err)
}
fmt.Printf("Build directory compressed to: %s\n", outputCompressedFile)
fmt.Printf("Build directory compressed to: %s\n", outputCompressedFile)
}
compressedSize, err := spitfire.GetFileSize(outputCompressedFile)
if err != nil {
return fmt.Errorf("get compressed file size: %w", err)
return fmt.Errorf("get compressed file size: %w", err)
}
fmt.Printf("Compressed file size: %s\n", spitfire.BytesToHumanReadable(compressedSize))
fmt.Printf(" ├─ Compressed size: %s\n", spitfire.BytesToHumanReadable(compressedSize))
compressionRatio, efficiency := spitfire.CalculateCompressionEfficiency(uncompressedSize, compressedSize)
fmt.Printf("Compression ratio: %.2f:1\n", compressionRatio)
fmt.Printf("Compression efficiency: %.2f%%\n", efficiency)
fmt.Printf("Compressed dir: %s\n", pathToUse)
fmt.Printf(" ├─ Compression ratio: %.2f:1\n", compressionRatio)
fmt.Printf(" ├─ Compression efficiency: %.2f%%\n", efficiency)
fmt.Printf(" └─ Source directory: %s\n", pathToUse)
if !upload {
fmt.Println("⏩ Upload skipped (not requested)")
return nil
}
fmt.Println("🔑 Loading configuration...")
config, err := spitfire.LoadConfig()
if err != nil {
return fmt.Errorf("load config: %w", err)
return fmt.Errorf("load config: %w", err)
}
if _, err := os.Stat(outputCompressedFile); err != nil {
return fmt.Errorf("compressed file not found: %w", err)
return fmt.Errorf("compressed file not found: %w", err)
}
uploadDir := fmt.Sprintf("%s/%s/%s/%s", component, arch, release, version)
fmt.Printf("📤 Uploading to: %s\n", uploadDir)
if err := spitfire.Upload(config, outputCompressedFile, "/home/frs/project/spitfire-browser/"+uploadDir+"/"); err != nil {
return fmt.Errorf("upload compressed file: %w", err)
return fmt.Errorf("upload compressed file: %w", err)
}
fmt.Println("Compressed file uploaded successfully.")
fmt.Println("Compressed file uploaded successfully")
fmt.Println("📥 Downloading APPINDEX...")
if err := spitfire.DownloadAPPINDEX(config, "/home/frs/project/spitfire-browser/"); err != nil {
fmt.Println("Failed to download APPINDEX. A new one will be created and uploaded.")
fmt.Println("⚠️ Failed to download APPINDEX - creating new one")
}
fmt.Println("📝 Updating APPINDEX...")
if err := spitfire.PackageAPPINDEX(
packageName,
release,
@ -334,24 +402,27 @@ func PackageAndUploadProcess(buildDir string) error {
platform,
uploadDir,
); err != nil {
return fmt.Errorf("package APPINDEX: %w", err)
return fmt.Errorf("package APPINDEX: %w", err)
}
fmt.Println("APPINDEX updated successfully.")
fmt.Println("APPINDEX updated successfully")
fmt.Println("🧹 Cleaning APPINDEX...")
if err := spitfire.CleanAppIndex(); err != nil {
return fmt.Errorf("clean APPINDEX: %w", err)
return fmt.Errorf("clean APPINDEX: %w", err)
}
fmt.Println("📤 Uploading APPINDEX...")
if err := spitfire.UploadAPPINDEX(config, "/home/frs/project/spitfire-browser/"); err != nil {
return fmt.Errorf("upload APPINDEX: %w", err)
return fmt.Errorf("upload APPINDEX: %w", err)
}
fmt.Println("APPINDEX uploaded successfully.")
fmt.Println("APPINDEX uploaded successfully")
return nil
}
func restoreWorkingDirectory() {
fmt.Println("↩️ Restoring working directory...")
if err := os.Chdir(initialDir); err != nil {
log.Printf("Failed to restore working directory: %v", err)
log.Printf("⚠️ Failed to restore working directory: %v", err)
}
}