Compare commits
10 commits
89687eecd6
...
430357108c
Author | SHA1 | Date | |
---|---|---|---|
|
430357108c | ||
|
917e9a1547 | ||
|
358cd7147b | ||
|
048bbc1e3e | ||
|
39a3e90c42 | ||
|
6d2a7669a2 | ||
|
3a36e4dda5 | ||
|
8d6f46c4ca | ||
|
dfbecf7f98 | ||
|
f497557264 |
6 changed files with 528 additions and 208 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -4,4 +4,5 @@
|
||||||
/packages_temp.json
|
/packages_temp.json
|
||||||
/APKINDEX
|
/APKINDEX
|
||||||
/APPINDEX
|
/APPINDEX
|
||||||
/browser-amd64-nightly-linux.tar.gz
|
/browser-amd64-nightly-linux.tar.gz
|
||||||
|
/browser-amd64-nightly-windows.tar.gz
|
145
README.md
Normal file
145
README.md
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
<p align="center">
|
||||||
|
<img src="https://weforge.xyz/Spitfire/Branding/raw/branch/main/active/browser/icon.svg" alt="Logo" width="64" height="64">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center" style="font-size: 32px;">
|
||||||
|
<strong>Spitfire Builder</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
This is a "simple" script for building the Spitfire Browser based on Mozilla Firefox source code.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- Mercurial (hg)
|
||||||
|
- Git
|
||||||
|
- Golang (tested with v1.21)
|
||||||
|
- Python 3.11 and pip3
|
||||||
|
|
||||||
|
# Example usage:
|
||||||
|
|
||||||
|
## Build:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go run . -a
|
||||||
|
```
|
||||||
|
|
||||||
|
## Upload:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go run . --upload -c --upload-path=./mozilla-central/obj-x86_64-pc-linux-gnu/dist/bin
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build and upload:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go run . --upload -c --upload-path=./mozilla-central/obj-x86_64-pc-linux-gnu/dist/bin -a
|
||||||
|
```
|
||||||
|
|
||||||
|
## Display all flags:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go run . -h
|
||||||
|
```
|
||||||
|
|
||||||
|
### Config file for uploading example:
|
||||||
|
|
||||||
|
*sourceforge_config.json*
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"SFKeyPath": "~/.ssh/id_rsa.pub",
|
||||||
|
"SFUser": "internet-addict",
|
||||||
|
"SFHost": "web.sourceforge.net",
|
||||||
|
"SFProject": "spitfire-browser"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## APPINDEX example:
|
||||||
|
|
||||||
|
```
|
||||||
|
C:905cd0cc2dea9e400e1ecd099462b6b19188a9f1
|
||||||
|
P:Spitfire
|
||||||
|
R:nightly
|
||||||
|
V:2024.09.08
|
||||||
|
A:amd64
|
||||||
|
S:788506622
|
||||||
|
I:3324483350
|
||||||
|
T:Spitfire build
|
||||||
|
U:https://spitfirebrowser.com/
|
||||||
|
L:AGPL-3.0
|
||||||
|
o:browser
|
||||||
|
m:Internet Addict
|
||||||
|
t:1725830641
|
||||||
|
c:905cd0cc2dea9e400e1ecd099462b6b19188a9f1
|
||||||
|
D:
|
||||||
|
p:linux
|
||||||
|
q:
|
||||||
|
Z:905cd0cc2dea9e400e1ecd099462b6b19188a9f1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Repositary structure
|
||||||
|
|
||||||
|
```
|
||||||
|
spitfire-browser/
|
||||||
|
├── browser/
|
||||||
|
│ ├── amd64/
|
||||||
|
│ │ ├── stable/
|
||||||
|
│ │ │ ├── latest/deb.tar.gz
|
||||||
|
│ │ │ ├── x.x.x/deb.tar.gz
|
||||||
|
│ │ ├── nightly/
|
||||||
|
│ │ ├── latest/deb.tar.gz
|
||||||
|
│ │ ├── yyyy-mm-dd/deb.tar.gz
|
||||||
|
│ ├── arm/
|
||||||
|
│ │ ├── stable/
|
||||||
|
│ │ │ ├── latest/
|
||||||
|
│ │ │ ├── x.x.x/
|
||||||
|
│ │ ├── nightly/
|
||||||
|
│ │ ├── latest/
|
||||||
|
│ │ ├── yyyy-mm-dd/
|
||||||
|
├── cli-package-manager/
|
||||||
|
│ ├── stable/
|
||||||
|
│ │ ├── latest/
|
||||||
|
│ │ ├── x.x.x/
|
||||||
|
│ ├── nightly/
|
||||||
|
│ ├── latest/
|
||||||
|
│ ├── yyyy-mm-dd/
|
||||||
|
├── gui-installer/
|
||||||
|
│ ├── stable/
|
||||||
|
│ │ ├── latest/
|
||||||
|
│ │ ├── x.x.x/
|
||||||
|
│ ├── nightly/
|
||||||
|
│ ├── latest/
|
||||||
|
│ ├── yyyy-mm-dd/
|
||||||
|
├── gui-package-manager/
|
||||||
|
│ ├── stable/
|
||||||
|
│ │ ├── latest/
|
||||||
|
│ │ ├── x.x.x/
|
||||||
|
│ ├── nightly/
|
||||||
|
│ ├── latest/
|
||||||
|
│ ├── yyyy-mm-dd/
|
||||||
|
├── addons/
|
||||||
|
│ ├── themes/
|
||||||
|
│ │ ├── stable/
|
||||||
|
│ │ │ ├── latest/
|
||||||
|
│ │ │ ├── x.x.x/
|
||||||
|
│ │ ├── nightly/
|
||||||
|
│ │ ├── latest/
|
||||||
|
│ │ ├── yyyy-mm-dd/
|
||||||
|
│ ├── custom-configs/
|
||||||
|
│ │ ├── stable/
|
||||||
|
│ │ │ ├── latest/
|
||||||
|
│ │ │ ├── x.x.x/
|
||||||
|
│ │ ├── nightly/
|
||||||
|
│ │ ├── latest/
|
||||||
|
│ │ ├── yyyy-mm-dd/
|
||||||
|
│ ├── search-engines/
|
||||||
|
│ ├── stable/
|
||||||
|
│ │ ├── latest/
|
||||||
|
│ │ ├── x.x.x/
|
||||||
|
│ ├── nightly/
|
||||||
|
│ ├── latest/
|
||||||
|
│ ├── yyyy-mm-dd/
|
||||||
|
├── APPINDEX
|
||||||
|
```
|
405
main.go
405
main.go
|
@ -1,231 +1,254 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime" // for detecting system architecture and platform
|
"runtime" // for detecting system architecture and platform
|
||||||
"time"
|
"spitfire/spitfire"
|
||||||
"spitfire/spitfire"
|
"time"
|
||||||
//"errors"
|
//"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Define all flags as package-level variables
|
// Define all flags as package-level variables
|
||||||
all bool
|
all bool
|
||||||
buildFlag bool
|
buildFlag bool
|
||||||
clean bool
|
clean bool
|
||||||
update bool
|
update bool
|
||||||
patches bool
|
patches bool
|
||||||
run bool
|
run bool
|
||||||
compress bool
|
compress bool
|
||||||
buildPath string
|
buildPath string
|
||||||
target string
|
target string
|
||||||
version string
|
version string
|
||||||
component string
|
component string
|
||||||
arch string
|
arch string
|
||||||
release string
|
release string
|
||||||
platform string
|
platform string
|
||||||
upload bool
|
upload bool
|
||||||
uploadPath string
|
uploadPath string
|
||||||
sourceRepo = "https://hg.mozilla.org/mozilla-central"
|
sourceRepo = "https://hg.mozilla.org/mozilla-central"
|
||||||
patchesRepo = "https://weforgecode.xyz/Spitfire/Browser.git"
|
patchesRepo = "https://weforgecode.xyz/Spitfire/Browser.git"
|
||||||
url = "https://spitfirebrowser.com/"
|
url = "https://spitfirebrowser.com/"
|
||||||
licence = "AGPL-3.0"
|
licence = "AGPL-3.0"
|
||||||
name = "Spitfire"
|
name = "Spitfire"
|
||||||
maintainer = "Internet Addict"
|
maintainer = "Internet Addict"
|
||||||
initialDir string
|
initialDir string
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
flag.StringVar(&buildPath, "p", "", "Path to the build directory")
|
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.")
|
||||||
flag.StringVar(&component, "component", "browser", "Component name (default: browser)")
|
flag.StringVar(&component, "component", "browser", "Component name (default: browser)")
|
||||||
flag.StringVar(&arch, "arch", runtime.GOARCH, "Architecture (default: system architecture)")
|
flag.StringVar(&arch, "arch", runtime.GOARCH, "Architecture (default: system architecture)")
|
||||||
flag.StringVar(&release, "release", "nightly", "Release type (default: nightly)")
|
flag.StringVar(&release, "release", "nightly", "Release type (default: nightly)")
|
||||||
flag.StringVar(&platform, "platform", runtime.GOOS, "Platform (default: system platform)")
|
flag.StringVar(&platform, "platform", runtime.GOOS, "Platform (default: system platform)")
|
||||||
flag.BoolVar(&all, "a", false, "Perform all steps (build, clean, update)")
|
flag.BoolVar(&all, "a", false, "Perform all steps (build, clean, update)")
|
||||||
flag.BoolVar(&buildFlag, "b", false, "Build Spitfire")
|
flag.BoolVar(&buildFlag, "b", false, "Build Spitfire")
|
||||||
flag.BoolVar(&clean, "clean", false, "Clean build")
|
flag.BoolVar(&clean, "clean", false, "Clean build")
|
||||||
flag.BoolVar(&update, "u", false, "Update Mozilla repository")
|
flag.BoolVar(&update, "u", false, "Update Mozilla repository")
|
||||||
flag.BoolVar(&patches, "patches", false, "Update patches")
|
flag.BoolVar(&patches, "patches", false, "Update patches")
|
||||||
flag.BoolVar(&run, "r", false, "Run the project after build")
|
flag.BoolVar(&run, "r", false, "Run the project after build")
|
||||||
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.Bool("h", false, "Display help message")
|
flag.Bool("h", false, "Display help message")
|
||||||
}
|
}
|
||||||
|
|
||||||
func printHelp() {
|
func printHelp() {
|
||||||
fmt.Println("Usage: ./main -p=<path-to-build> -t=<target> [-c|--compress] [-v|--version=<version>] [-component=<component>] [-arch=<architecture>] [-release=<release>] [-platform=<platform>]")
|
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()
|
flag.PrintDefaults()
|
||||||
fmt.Println("Example: go run . --upload -c --upload-path=./mozilla-central/obj-x86_64-pc-linux-gnu/dist/bin -a")
|
fmt.Println("Example: go run . --upload -c --upload-path=./mozilla-central/obj-x86_64-pc-linux-gnu/dist/bin -a")
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
// // Check system dependencies
|
||||||
|
// err := spitfire.CheckSystemDependencies()
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatalf("System check failed: %v", err)
|
||||||
|
// }
|
||||||
|
|
||||||
if flag.Lookup("h").Value.(flag.Getter).Get().(bool) {
|
flag.Parse()
|
||||||
printHelp()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set version to current date if it's empty and release is nightly
|
if flag.Lookup("h").Value.(flag.Getter).Get().(bool) {
|
||||||
if version == "" && release == "nightly" {
|
printHelp()
|
||||||
version = time.Now().Format("2006.01.02") // Set version to current date if nightly
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Save the initial directory
|
// Set version to current date if it's empty and release is nightly
|
||||||
var err error
|
if version == "" && release == "nightly" {
|
||||||
initialDir, err = os.Getwd()
|
version = time.Now().Format("2006.01.02") // Set version to current date if nightly
|
||||||
if err != nil {
|
}
|
||||||
log.Fatalf("Failed to get current working directory: %v", err)
|
|
||||||
}
|
|
||||||
fmt.Printf("Initial working directory: %s\n", initialDir)
|
|
||||||
|
|
||||||
if all || buildFlag {
|
// Save the initial directory
|
||||||
BuildProcess()
|
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)
|
||||||
|
|
||||||
if compress || upload {
|
// Convert buildPath and uploadPath to absolute paths
|
||||||
PackageAndUploadProcess()
|
if buildPath != "" {
|
||||||
}
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
spitfire.PrintErrors()
|
if uploadPath != "" {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
if all || buildFlag {
|
||||||
|
BuildProcess()
|
||||||
|
}
|
||||||
|
|
||||||
|
if compress || upload {
|
||||||
|
PackageAndUploadProcess()
|
||||||
|
}
|
||||||
|
|
||||||
|
spitfire.PrintErrors()
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildProcess handles the build process: downloading, cleaning, configuring, and building the project.
|
// BuildProcess handles the build process: downloading, cleaning, configuring, and building the project.
|
||||||
func BuildProcess() {
|
func BuildProcess() {
|
||||||
sourcePath, err := spitfire.ResolvePath("./mozilla-central")
|
sourcePath, err := spitfire.ResolvePath("./mozilla-central")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error resolving source path: %v", err)
|
log.Fatalf("Error resolving source path: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
patchesDir, err := spitfire.ResolvePath(filepath.Join(sourcePath, "Spitfire"))
|
patchesDir, err := spitfire.ResolvePath(filepath.Join(sourcePath, "Spitfire"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error resolving patches directory: %v", err)
|
log.Fatalf("Error resolving patches directory: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if all {
|
if all {
|
||||||
spitfire.DownloadSource(sourcePath, sourceRepo)
|
spitfire.DownloadSource(sourcePath, sourceRepo)
|
||||||
spitfire.DiscardChanges(sourcePath)
|
spitfire.DiscardChanges(sourcePath)
|
||||||
spitfire.CleanBuild(sourcePath)
|
spitfire.CleanBuild(sourcePath)
|
||||||
spitfire.UpdateRepo(sourcePath)
|
spitfire.UpdateRepo(sourcePath)
|
||||||
spitfire.UpdatePatches(patchesDir, patchesRepo, sourcePath)
|
spitfire.UpdatePatches(patchesDir, patchesRepo, sourcePath)
|
||||||
spitfire.Configure(sourcePath)
|
spitfire.Configure(sourcePath)
|
||||||
spitfire.Build(sourcePath)
|
spitfire.Build(sourcePath)
|
||||||
if run {
|
if run {
|
||||||
spitfire.RunProject(sourcePath)
|
spitfire.RunProject(sourcePath)
|
||||||
}
|
}
|
||||||
fmt.Println("Spitfire build completed successfully.")
|
fmt.Println("Spitfire build completed successfully.")
|
||||||
} else if clean {
|
} else if clean {
|
||||||
spitfire.CleanBuild(sourcePath)
|
spitfire.CleanBuild(sourcePath)
|
||||||
fmt.Println("Cleaned Firefox build.")
|
fmt.Println("Cleaned Firefox build.")
|
||||||
} else if update {
|
} else if update {
|
||||||
spitfire.DownloadSource(sourcePath, sourceRepo)
|
spitfire.DownloadSource(sourcePath, sourceRepo)
|
||||||
spitfire.UpdateRepo(sourcePath)
|
spitfire.UpdateRepo(sourcePath)
|
||||||
fmt.Println("Mozilla repository updated.")
|
fmt.Println("Mozilla repository updated.")
|
||||||
} else if patches {
|
} else if patches {
|
||||||
spitfire.DownloadSource(sourcePath, sourceRepo)
|
spitfire.DownloadSource(sourcePath, sourceRepo)
|
||||||
spitfire.UpdatePatches(patchesDir, patchesRepo, sourcePath)
|
spitfire.UpdatePatches(patchesDir, patchesRepo, sourcePath)
|
||||||
fmt.Println("Patches updated.")
|
fmt.Println("Patches updated.")
|
||||||
} else if buildFlag {
|
} else if buildFlag {
|
||||||
spitfire.Configure(sourcePath)
|
spitfire.Configure(sourcePath)
|
||||||
spitfire.Build(sourcePath)
|
spitfire.Build(sourcePath)
|
||||||
if run {
|
if run {
|
||||||
spitfire.RunProject(sourcePath)
|
spitfire.RunProject(sourcePath)
|
||||||
}
|
}
|
||||||
fmt.Println("Spitfire build completed successfully.")
|
fmt.Println("Spitfire build completed successfully.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PackageAndUploadProcess handles compressing, packaging, and uploading the build to SourceForge.
|
// PackageAndUploadProcess handles compressing, packaging, and uploading the build to SourceForge.
|
||||||
func PackageAndUploadProcess() {
|
func PackageAndUploadProcess() {
|
||||||
|
|
||||||
// Restore working directory before performing SourceForge operations
|
|
||||||
restoreWorkingDirectory()
|
|
||||||
|
|
||||||
pathToUse := buildPath
|
// Restore working directory before performing SourceForge operations
|
||||||
if upload && uploadPath != "" {
|
restoreWorkingDirectory()
|
||||||
pathToUse = uploadPath
|
|
||||||
}
|
|
||||||
|
|
||||||
if pathToUse == "" {
|
pathToUse := buildPath
|
||||||
log.Fatalf("Error: no valid build or upload path provided.")
|
if upload && uploadPath != "" {
|
||||||
}
|
pathToUse = uploadPath
|
||||||
|
}
|
||||||
|
|
||||||
// // This is stupid, it wait for the path to exist (up to a maximum wait time)
|
if pathToUse == "" {
|
||||||
// err := waitForPath(pathToUse, 60, 5) // Max 60 seconds, checking every 5 seconds
|
log.Fatalf("Error: no valid build or upload path provided.")
|
||||||
// if err != nil {
|
}
|
||||||
// log.Fatalf("Error: Build path or upload path not found: %v", err)
|
|
||||||
// }
|
|
||||||
|
|
||||||
uncompressedSize, err := spitfire.GetDirectorySize(pathToUse)
|
// // This is stupid, it wait for the path to exist (up to a maximum wait time)
|
||||||
if err != nil {
|
// err := waitForPath(pathToUse, 60, 5) // Max 60 seconds, checking every 5 seconds
|
||||||
log.Fatalf("Failed to calculate uncompressed size: %v", err)
|
// if err != nil {
|
||||||
}
|
// log.Fatalf("Error: Build path or upload path not found: %v", err)
|
||||||
fmt.Printf("Uncompressed directory size: %d bytes\n", uncompressedSize)
|
// }
|
||||||
|
|
||||||
outputCompressedFile := filepath.Join(".", fmt.Sprintf("%s-%s-%s-%s.tar.gz", component, arch, release, platform))
|
uncompressedSize, err := spitfire.GetDirectorySize(pathToUse)
|
||||||
if compress {
|
if err != nil {
|
||||||
err := spitfire.CompressDirectory(pathToUse, outputCompressedFile)
|
log.Fatalf("Failed to calculate uncompressed size: %v", err)
|
||||||
if err != nil {
|
}
|
||||||
log.Fatalf("Failed to compress build directory: %v", err)
|
fmt.Printf("Uncompressed directory size: %d bytes\n", uncompressedSize)
|
||||||
}
|
|
||||||
fmt.Printf("Build directory compressed to: %s\n", outputCompressedFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
compressedSize, err := spitfire.GetFileSize(outputCompressedFile)
|
outputCompressedFile := filepath.Join(".", fmt.Sprintf("%s-%s-%s-%s.tar.gz", component, arch, release, platform))
|
||||||
if err != nil {
|
if compress {
|
||||||
log.Fatalf("Failed to get compressed file size: %v", err)
|
err := spitfire.CompressDirectory(pathToUse, outputCompressedFile)
|
||||||
}
|
if err != nil {
|
||||||
fmt.Printf("Compressed file size: %d bytes\n", compressedSize)
|
log.Fatalf("Failed to compress build directory: %v", err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Build directory compressed to: %s\n", outputCompressedFile)
|
||||||
|
}
|
||||||
|
|
||||||
if upload {
|
compressedSize, err := spitfire.GetFileSize(outputCompressedFile)
|
||||||
config, err := spitfire.LoadConfig()
|
if err != nil {
|
||||||
if err != nil {
|
log.Fatalf("Failed to get compressed file size: %v", err)
|
||||||
log.Fatalf("Failed to load SourceForge config: %v", err)
|
}
|
||||||
}
|
fmt.Printf("Compressed file size: %d bytes\n", compressedSize)
|
||||||
|
|
||||||
if _, err := os.Stat(outputCompressedFile); err == nil {
|
if upload {
|
||||||
err = spitfire.Upload(config, outputCompressedFile, "/home/frs/project/spitfire-browser/"+component+"/"+arch+"/"+release+"/"+version+"/")
|
config, err := spitfire.LoadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to upload compressed file: %v", err)
|
log.Fatalf("Failed to load SourceForge config: %v", err)
|
||||||
}
|
}
|
||||||
fmt.Println("Compressed file uploaded successfully.")
|
|
||||||
} else {
|
|
||||||
log.Fatalf("No compressed file found to upload.")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = spitfire.DownloadAPPINDEX(config, "/home/frs/project/spitfire-browser/")
|
if _, err := os.Stat(outputCompressedFile); err == nil {
|
||||||
if err != nil {
|
err = spitfire.Upload(config, outputCompressedFile, "/home/frs/project/spitfire-browser/"+component+"/"+arch+"/"+release+"/"+version+"/")
|
||||||
fmt.Println("Failed to download APPINDEX. A new APPINDEX will be created and uploaded.")
|
if err != nil {
|
||||||
}
|
log.Fatalf("Failed to upload compressed file: %v", err)
|
||||||
|
}
|
||||||
|
fmt.Println("Compressed file uploaded successfully.")
|
||||||
|
} else {
|
||||||
|
log.Fatalf("No compressed file found to upload.")
|
||||||
|
}
|
||||||
|
|
||||||
err = spitfire.PackageAPPINDEX(
|
err = spitfire.DownloadAPPINDEX(config, "/home/frs/project/spitfire-browser/")
|
||||||
name, release, version, arch,
|
if err != nil {
|
||||||
fmt.Sprintf("%d", compressedSize),
|
fmt.Println("Failed to download APPINDEX. A new APPINDEX will be created and uploaded.")
|
||||||
fmt.Sprintf("%d", uncompressedSize),
|
}
|
||||||
"Spitfire build", url, licence, component, maintainer, "", platform,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Failed to update APPINDEX: %v", err)
|
|
||||||
}
|
|
||||||
fmt.Println("APPINDEX updated successfully.")
|
|
||||||
|
|
||||||
if err := spitfire.CleanAppIndex(); err != nil {
|
err = spitfire.PackageAPPINDEX(
|
||||||
log.Fatalf("Failed to clean APPINDEX: %v", err)
|
name, release, version, arch,
|
||||||
}
|
fmt.Sprintf("%d", compressedSize),
|
||||||
|
fmt.Sprintf("%d", uncompressedSize),
|
||||||
|
"Spitfire build", url, licence, component, maintainer, "", platform,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to update APPINDEX: %v", err)
|
||||||
|
}
|
||||||
|
fmt.Println("APPINDEX updated successfully.")
|
||||||
|
|
||||||
err = spitfire.UploadAPPINDEX(config, "/home/frs/project/spitfire-browser/")
|
if err := spitfire.CleanAppIndex(); err != nil {
|
||||||
if err != nil {
|
log.Fatalf("Failed to clean APPINDEX: %v", err)
|
||||||
log.Fatalf("Failed to upload updated APPINDEX: %v", err)
|
}
|
||||||
}
|
|
||||||
fmt.Println("APPINDEX uploaded successfully.")
|
err = spitfire.UploadAPPINDEX(config, "/home/frs/project/spitfire-browser/")
|
||||||
}
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to upload updated APPINDEX: %v", err)
|
||||||
|
}
|
||||||
|
fmt.Println("APPINDEX uploaded successfully.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// // waitForPath checks if a path exists, waiting for up to maxWait seconds and retrying every interval seconds.
|
// // waitForPath checks if a path exists, waiting for up to maxWait seconds and retrying every interval seconds.
|
||||||
|
@ -252,9 +275,9 @@ func PackageAndUploadProcess() {
|
||||||
|
|
||||||
// restoreWorkingDirectory restores the initial working directory after any operation that might change it.
|
// restoreWorkingDirectory restores the initial working directory after any operation that might change it.
|
||||||
func restoreWorkingDirectory() {
|
func restoreWorkingDirectory() {
|
||||||
err := os.Chdir(initialDir)
|
err := os.Chdir(initialDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to restore the working directory: %v", err)
|
log.Fatalf("Failed to restore the working directory: %v", err)
|
||||||
}
|
}
|
||||||
fmt.Printf("Restored working directory to: %s\n", initialDir)
|
fmt.Printf("Restored working directory to: %s\n", initialDir)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
"SFKeyPath": "~/.ssh/id_rsa.pub",
|
"SFKeyPath": "~/.ssh/id_rsa.pub",
|
||||||
"SFUser": "internet-addict",
|
"SFUser": "internet-addict",
|
||||||
"SFHost": "web.sourceforge.net",
|
"SFHost": "web.sourceforge.net",
|
||||||
"SFProject": "spitfire-browser"
|
"SFProject": "spitfire-browser"
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,39 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Array to store errors
|
// Array to store errors
|
||||||
var errors []string
|
var errors []string
|
||||||
|
|
||||||
|
// SetGlobalEnv sets the MOZILLABUILD environment variable globally for the user (or system)
|
||||||
|
func SetGlobalEnv(variable, value string, scope string) error {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
var cmd *exec.Cmd
|
||||||
|
if scope == "user" {
|
||||||
|
cmd = exec.Command("setx", variable, value) // Set for current user
|
||||||
|
} else if scope == "system" {
|
||||||
|
cmd = exec.Command("setx", variable, value, "/M") // Set for system (requires admin privileges)
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("unknown scope: %s", scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the command
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to set environment variable %s=%s: %v\nOutput: %s", variable, value, err, string(out))
|
||||||
|
}
|
||||||
|
fmt.Printf("Successfully set %s=%s\n", variable, value)
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("global environment variable setting is not supported on non-Windows systems")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Run an external command like scp or rsync
|
// Run an external command like scp or rsync
|
||||||
func runCommand(command string, args ...string) error {
|
func runCommand(command string, args ...string) error {
|
||||||
|
fmt.Printf("Running command: %s %v\n", command, args)
|
||||||
cmd := exec.Command(command, args...)
|
cmd := exec.Command(command, args...)
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
|
@ -20,9 +46,13 @@ func runCommand(command string, args ...string) error {
|
||||||
|
|
||||||
// Function to resolve paths using absolute path
|
// Function to resolve paths using absolute path
|
||||||
func ResolvePath(path string) (string, error) {
|
func ResolvePath(path string) (string, error) {
|
||||||
|
// Convert Unix-style slashes to the platform's native slashes
|
||||||
|
path = filepath.FromSlash(path)
|
||||||
|
|
||||||
|
// Get the absolute path
|
||||||
absPath, err := filepath.Abs(path)
|
absPath, err := filepath.Abs(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to resolve path: %s", path)
|
return "", fmt.Errorf("failed to resolve path: %s, error: %v", path, err)
|
||||||
}
|
}
|
||||||
return absPath, nil
|
return absPath, nil
|
||||||
}
|
}
|
||||||
|
@ -54,10 +84,21 @@ func CleanBuild(sourcePath string) {
|
||||||
errors = append(errors, "Failed to navigate to source directory.")
|
errors = append(errors, "Failed to navigate to source directory.")
|
||||||
return
|
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 {
|
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.")
|
||||||
}
|
}
|
||||||
if err := runCommand("./mach", "clobber"); err != nil {
|
// Clean the build
|
||||||
|
if err := runCommand(machCmd, "clobber"); err != nil {
|
||||||
errors = append(errors, "Failed to clean build.")
|
errors = append(errors, "Failed to clean build.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,9 +154,19 @@ func UpdatePatches(patchesDir, patchesRepo, sourcePath string) {
|
||||||
errors = append(errors, "Failed to clone patches repository.")
|
errors = append(errors, "Failed to clone patches repository.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 err := runCommand("rsync", "-av", "--exclude=.git", patchesDir+"/", sourcePath+"/"); err != nil {
|
if runtime.GOOS == "windows" {
|
||||||
errors = append(errors, "Failed to copy files.")
|
// Use robocopy for Windows
|
||||||
|
if err := runCommand("robocopy", patchesDir, sourcePath, "*", "/S", "/XF", ".git", "/XD", ".git"); err != nil {
|
||||||
|
errors = append(errors, "Failed to copy files (Windows robocopy).")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Use rsync for Unix-like systems
|
||||||
|
if err := runCommand("rsync", "-av", "--exclude=.git", patchesDir+"/", sourcePath+"/"); err != nil {
|
||||||
|
errors = append(errors, "Failed to copy files (rsync).")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +177,16 @@ func Configure(sourcePath string) {
|
||||||
errors = append(errors, "Failed to navigate to source directory.")
|
errors = append(errors, "Failed to navigate to source directory.")
|
||||||
return
|
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.")
|
errors = append(errors, "Configuration failed.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +198,16 @@ func Build(sourcePath string) {
|
||||||
errors = append(errors, "Failed to navigate to source directory.")
|
errors = append(errors, "Failed to navigate to source directory.")
|
||||||
return
|
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.")
|
errors = append(errors, "Build failed.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,11 +215,16 @@ func Build(sourcePath string) {
|
||||||
// Function to run the project after build
|
// Function to run the project after build
|
||||||
func RunProject(sourcePath string) {
|
func RunProject(sourcePath string) {
|
||||||
fmt.Println("Running the project...")
|
fmt.Println("Running the project...")
|
||||||
if err := os.Chdir(sourcePath); err != nil {
|
|
||||||
errors = append(errors, "Failed to navigate to source directory.")
|
// Use the appropriate mach command for Windows or Unix-like systems
|
||||||
return
|
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.")
|
errors = append(errors, "Failed to run the project.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
78
spitfire/checks.go
Normal file
78
spitfire/checks.go
Normal file
|
@ -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()
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue