updated APPINDEX
This commit is contained in:
parent
3545a5f73b
commit
2bb34d2f5c
3 changed files with 214 additions and 111 deletions
22
README.md
22
README.md
|
@ -124,24 +124,28 @@ go run . -h
|
||||||
## APPINDEX example:
|
## APPINDEX example:
|
||||||
|
|
||||||
```
|
```
|
||||||
C:905cd0cc2dea9e400e1ecd099462b6b19188a9f1
|
C:a6af7ebb5c1382084704be0b5714ab026c819d63
|
||||||
P:Spitfire
|
P:spitfire-browser
|
||||||
R:nightly
|
R:nightly
|
||||||
V:2024.09.08
|
V:2024.12.23
|
||||||
A:amd64
|
A:amd64
|
||||||
S:788506622
|
S:838594187
|
||||||
I:3324483350
|
I:3595780372
|
||||||
T:Spitfire build
|
T:Spitfire
|
||||||
U:https://spitfirebrowser.xyz/
|
U:https://spitfirebrowser.xyz/
|
||||||
L:AGPL-3.0
|
L:AGPL-3.0
|
||||||
o:browser
|
o:browser
|
||||||
m:Internet Addict
|
m:Internet Addict
|
||||||
t:1725830641
|
t:1734949294
|
||||||
c:905cd0cc2dea9e400e1ecd099462b6b19188a9f1
|
|
||||||
D:
|
D:
|
||||||
p:linux
|
p:linux
|
||||||
q:
|
q:
|
||||||
Z:905cd0cc2dea9e400e1ecd099462b6b19188a9f1
|
d:https://downloads.sourceforge.net/project/spitfire-browser/browser/amd64/nightly/2024.12.23/browser-amd64-nightly-linux.tar.gz
|
||||||
|
I:https://weforge.xyz/Spitfire/Branding/raw/branch/main/active/browser/icon.svg
|
||||||
|
S:https://spitfirebrowser.xyz/static/images/screenshots/1.png
|
||||||
|
T:browser,experimental,testing
|
||||||
|
r: Automated Nightly build of Spitfire
|
||||||
|
c:a6af7ebb5c1382084704be0b5714ab026c819d63
|
||||||
```
|
```
|
||||||
|
|
||||||
## Repository structure
|
## Repository structure
|
||||||
|
|
62
main.go
62
main.go
|
@ -39,6 +39,7 @@ var (
|
||||||
url = "https://spitfirebrowser.xyz/"
|
url = "https://spitfirebrowser.xyz/"
|
||||||
licence = "AGPL-3.0"
|
licence = "AGPL-3.0"
|
||||||
name = "Spitfire"
|
name = "Spitfire"
|
||||||
|
packageName = "spitfire-browser"
|
||||||
maintainer = "Internet Addict"
|
maintainer = "Internet Addict"
|
||||||
initialDir string
|
initialDir string
|
||||||
)
|
)
|
||||||
|
@ -260,15 +261,20 @@ func PackageAndUploadProcess() {
|
||||||
log.Fatalf("Error: no valid build or upload path provided.")
|
log.Fatalf("Error: no valid build or upload path provided.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate and display uncompressed size
|
// 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)
|
log.Fatalf("Failed to calculate uncompressed size: %v", err)
|
||||||
}
|
}
|
||||||
fmt.Printf("Uncompressed directory size: %s\n", spitfire.BytesToHumanReadable(uncompressedSize))
|
fmt.Printf("Uncompressed directory size: %s\n", spitfire.BytesToHumanReadable(uncompressedSize))
|
||||||
|
|
||||||
// Compress the build directory
|
// Create the tar.gz name, e.g. "browser-amd64-nightly-linux.tar.gz"
|
||||||
outputCompressedFile := filepath.Join(".", fmt.Sprintf("%s-%s-%s-%s.tar.gz", component, arch, release, platform))
|
outputCompressedFile := filepath.Join(".", fmt.Sprintf(
|
||||||
|
"%s-%s-%s-%s.tar.gz",
|
||||||
|
component, arch, release, platform,
|
||||||
|
))
|
||||||
|
|
||||||
|
// Compress if requested
|
||||||
if compress {
|
if compress {
|
||||||
err := spitfire.CompressDirectory(pathToUse, outputCompressedFile)
|
err := spitfire.CompressDirectory(pathToUse, outputCompressedFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -277,62 +283,86 @@ func PackageAndUploadProcess() {
|
||||||
fmt.Printf("Build directory compressed to: %s\n", outputCompressedFile)
|
fmt.Printf("Build directory compressed to: %s\n", outputCompressedFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate and display compressed size
|
// 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)
|
log.Fatalf("Failed to get compressed file size: %v", err)
|
||||||
}
|
}
|
||||||
fmt.Printf("Compressed file size: %s\n", spitfire.BytesToHumanReadable(compressedSize))
|
fmt.Printf("Compressed file size: %s\n", spitfire.BytesToHumanReadable(compressedSize))
|
||||||
|
|
||||||
// Calculate and display compression efficiency
|
// 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)
|
||||||
|
|
||||||
// Handle uploading
|
// If not uploading, we're done
|
||||||
if upload {
|
if !upload {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
log.Fatalf("Failed to load SourceForge config: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := os.Stat(outputCompressedFile); err == nil {
|
// Check tarball existence
|
||||||
err = spitfire.Upload(config, outputCompressedFile, "/home/frs/project/spitfire-browser/"+component+"/"+arch+"/"+release+"/"+version+"/")
|
if _, err := os.Stat(outputCompressedFile); err != nil {
|
||||||
|
log.Fatalf("No compressed file found to upload: %v", 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)
|
||||||
|
|
||||||
|
// 1) Upload the file to SourceForge once
|
||||||
|
err = spitfire.Upload(config, outputCompressedFile,
|
||||||
|
"/home/frs/project/spitfire-browser/"+uploadDir+"/")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to upload compressed file: %v", err)
|
log.Fatalf("Failed to upload compressed file: %v", err)
|
||||||
}
|
}
|
||||||
fmt.Println("Compressed file uploaded successfully.")
|
fmt.Println("Compressed file uploaded successfully.")
|
||||||
} else {
|
|
||||||
log.Fatalf("No compressed file found to upload.")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 2) Download existing APPINDEX or create new
|
||||||
err = spitfire.DownloadAPPINDEX(config, "/home/frs/project/spitfire-browser/")
|
err = spitfire.DownloadAPPINDEX(config, "/home/frs/project/spitfire-browser/")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Failed to download APPINDEX. A new APPINDEX will be created and uploaded.")
|
fmt.Println("Failed to download APPINDEX. A new one will be created and uploaded.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3) Update the APPINDEX
|
||||||
err = spitfire.PackageAPPINDEX(
|
err = spitfire.PackageAPPINDEX(
|
||||||
name, release, version, arch,
|
packageName, // e.g. "spitfire-browser"
|
||||||
|
release, // e.g. "nightly"
|
||||||
|
version, // e.g. "2024.12.23"
|
||||||
|
arch,
|
||||||
fmt.Sprintf("%d", compressedSize),
|
fmt.Sprintf("%d", compressedSize),
|
||||||
fmt.Sprintf("%d", uncompressedSize),
|
fmt.Sprintf("%d", uncompressedSize),
|
||||||
"Spitfire build", url, licence, component, maintainer, "", platform,
|
name, // e.g. "Spitfire"
|
||||||
|
url,
|
||||||
|
licence,
|
||||||
|
component,
|
||||||
|
maintainer,
|
||||||
|
"", // dependencies
|
||||||
|
platform,
|
||||||
|
uploadDir,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to update APPINDEX: %v", 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)
|
log.Fatalf("Failed to clean APPINDEX: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 5) Upload the updated APPINDEX
|
||||||
err = spitfire.UploadAPPINDEX(config, "/home/frs/project/spitfire-browser/")
|
err = spitfire.UploadAPPINDEX(config, "/home/frs/project/spitfire-browser/")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to upload updated APPINDEX: %v", err)
|
log.Fatalf("Failed to upload updated APPINDEX: %v", err)
|
||||||
}
|
}
|
||||||
fmt.Println("APPINDEX uploaded successfully.")
|
fmt.Println("APPINDEX uploaded successfully.")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 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() {
|
||||||
|
|
|
@ -11,20 +11,38 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Package the APPINDEX update process
|
// Package the APPINDEX update process
|
||||||
func PackageAPPINDEX(name, release, version, arch, size, installedSize, description, url, license, origin, maintainer, dependencies, platform string) error {
|
func PackageAPPINDEX(
|
||||||
// Mock package file name
|
name, // e.g. "spitfire-browser"
|
||||||
pkgFile := fmt.Sprintf("%s-%s", name, version)
|
release, // e.g. "nightly"
|
||||||
|
version, // e.g. "2024.12.21"
|
||||||
|
arch, // e.g. "amd64"
|
||||||
|
size, // e.g. "838205457" (compressed size)
|
||||||
|
installedSize, // e.g. "3595495684" (uncompressed size)
|
||||||
|
description, // e.g. "Spitfire build"
|
||||||
|
url, // e.g. "https://spitfirebrowser.xyz/"
|
||||||
|
license, // e.g. "AGPL-3.0"
|
||||||
|
origin, // e.g. "browser"
|
||||||
|
maintainer, // e.g. "Internet Addict"
|
||||||
|
dependencies, // usually blank ..."
|
||||||
|
platform, // e.g. "linux"
|
||||||
|
remoteDir string, // e.g. "nightly/linux/amd64"
|
||||||
|
) error {
|
||||||
|
|
||||||
// Calculate checksums
|
// Construct a filename that matches what you compress & upload
|
||||||
checksum := calcChecksum(pkgFile)
|
// Adjust this naming convention to match your compress step exactly!
|
||||||
contentChecksum := calcChecksum(pkgFile)
|
// Example: "spitfire-browser-nightly-amd64-linux.tar.gz"
|
||||||
|
fileName := fmt.Sprintf("%s-%s-%s-%s.tar.gz", origin, arch, release, platform)
|
||||||
|
|
||||||
// Timestamp
|
// If you have a real file on disk, you might call `calcChecksum(fileName)`.
|
||||||
timestamp := time.Now().Unix()
|
// For demo, we call `calcChecksum` with a mock package name.
|
||||||
|
checksum := calcChecksum(fileName)
|
||||||
|
|
||||||
// Remove existing entry based on P, R, A, and o fields
|
// Remove existing entry based on P, R, A, o (if you want to deduplicate).
|
||||||
removeExistingEntry(name, release, arch, origin)
|
removeExistingEntry(name, release, arch, origin)
|
||||||
|
|
||||||
|
// Use current Unix timestamp
|
||||||
|
timestamp := time.Now().Unix()
|
||||||
|
|
||||||
// Open or create the APPINDEX file for appending
|
// Open or create the APPINDEX file for appending
|
||||||
file, err := os.OpenFile("./APPINDEX", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
file, err := os.OpenFile("./APPINDEX", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -32,7 +50,11 @@ func PackageAPPINDEX(name, release, version, arch, size, installedSize, descript
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
// Write the new entry
|
// Build the SourceForge-based download URL:
|
||||||
|
// https://downloads.sourceforge.net/project/spitfire-browser/<remoteDir>/<fileName>
|
||||||
|
downloadURL := fmt.Sprintf("https://downloads.sourceforge.net/project/spitfire-browser/%s/%s", remoteDir, fileName)
|
||||||
|
|
||||||
|
// Format the entry.
|
||||||
entry := fmt.Sprintf(`
|
entry := fmt.Sprintf(`
|
||||||
C:%s
|
C:%s
|
||||||
P:%s
|
P:%s
|
||||||
|
@ -47,15 +69,23 @@ L:%s
|
||||||
o:%s
|
o:%s
|
||||||
m:%s
|
m:%s
|
||||||
t:%d
|
t:%d
|
||||||
c:%s
|
|
||||||
D:%s
|
D:%s
|
||||||
p:%s
|
p:%s
|
||||||
q:
|
q:
|
||||||
Z:%s
|
d:%s
|
||||||
|
I:https://weforge.xyz/Spitfire/Branding/raw/branch/main/active/browser/icon.svg
|
||||||
|
S:https://spitfirebrowser.xyz/static/images/screenshots/1.png
|
||||||
|
T:browser,experimental,testing
|
||||||
|
r: Automated Nightly build of Spitfire
|
||||||
|
c:%s
|
||||||
|
`, checksum, name, release, version, arch, size, installedSize,
|
||||||
|
description, url, license, origin, maintainer, timestamp, dependencies,
|
||||||
|
platform, downloadURL, checksum)
|
||||||
|
|
||||||
`, checksum, name, release, version, arch, size, installedSize, description, url, license, origin, maintainer, timestamp, contentChecksum, dependencies, platform, checksum)
|
// Trim leading newline to keep it clean
|
||||||
|
entry = strings.TrimPrefix(entry, "\n")
|
||||||
|
|
||||||
if _, err := file.WriteString(entry); err != nil {
|
if _, err := file.WriteString(entry + "\n"); err != nil {
|
||||||
log.Fatalf("Failed to write to APPINDEX file: %v", err)
|
log.Fatalf("Failed to write to APPINDEX file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +100,7 @@ func calcChecksum(input string) string {
|
||||||
return fmt.Sprintf("%x", h.Sum(nil))
|
return fmt.Sprintf("%x", h.Sum(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
// removeExistingEntry removes an existing entry from APPINDEX based on P, R, A, and o fields
|
// removeExistingEntry removes an existing entry from APPINDEX if it matches P, R, A, and o fields.
|
||||||
func removeExistingEntry(name, release, arch, origin string) {
|
func removeExistingEntry(name, release, arch, origin string) {
|
||||||
// Read file contents
|
// Read file contents
|
||||||
content, err := os.ReadFile("./APPINDEX")
|
content, err := os.ReadFile("./APPINDEX")
|
||||||
|
@ -81,39 +111,78 @@ func removeExistingEntry(name, release, arch, origin string) {
|
||||||
log.Fatalf("Failed to read APPINDEX: %v", err)
|
log.Fatalf("Failed to read APPINDEX: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove lines matching the package with the same P, R, A, and o fields
|
|
||||||
lines := strings.Split(string(content), "\n")
|
lines := strings.Split(string(content), "\n")
|
||||||
|
|
||||||
var newLines []string
|
var newLines []string
|
||||||
remove := false
|
var currentEntry []string
|
||||||
|
|
||||||
|
inEntry := false // true when we're reading lines for a single entry
|
||||||
|
|
||||||
|
// Use these to store the P, R, A, o values within the current entry
|
||||||
|
var pVal, rVal, aVal, oVal string
|
||||||
|
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
// Detect start of an entry by matching on P, R, A, and o
|
trimmed := strings.TrimSpace(line)
|
||||||
if strings.HasPrefix(line, "P:"+name) {
|
|
||||||
remove = true
|
|
||||||
}
|
|
||||||
if remove && strings.HasPrefix(line, "R:"+release) {
|
|
||||||
remove = true
|
|
||||||
}
|
|
||||||
if remove && strings.HasPrefix(line, "A:"+arch) {
|
|
||||||
remove = true
|
|
||||||
}
|
|
||||||
if remove && strings.HasPrefix(line, "o:"+origin) {
|
|
||||||
remove = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop removal at the end of an entry
|
// Detect the start of an entry (a line that starts with "C:")
|
||||||
if remove && line == "" {
|
if strings.HasPrefix(trimmed, "C:") {
|
||||||
remove = false
|
// If we were in an entry previously, check if it should be removed or kept
|
||||||
continue // Skip the line
|
if inEntry && len(currentEntry) > 0 {
|
||||||
}
|
// Decide whether to keep the previous entry
|
||||||
|
if !(pVal == name && rVal == release && aVal == arch && oVal == origin) {
|
||||||
// Append lines that are not part of the matching entry
|
newLines = append(newLines, currentEntry...)
|
||||||
if !remove {
|
newLines = append(newLines, "") // Blank line to separate entries
|
||||||
newLines = append(newLines, line)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the updated contents back to the file
|
// Start a new entry
|
||||||
err = os.WriteFile("./APPINDEX", []byte(strings.Join(newLines, "\n")), 0644)
|
currentEntry = []string{trimmed}
|
||||||
|
inEntry = true
|
||||||
|
|
||||||
|
// Reset these values for the new entry
|
||||||
|
pVal, rVal, aVal, oVal = "", "", "", ""
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if inEntry {
|
||||||
|
// Collect lines for this entry
|
||||||
|
currentEntry = append(currentEntry, trimmed)
|
||||||
|
|
||||||
|
// Extract P, R, A, o for matching later
|
||||||
|
switch {
|
||||||
|
case strings.HasPrefix(trimmed, "P:"):
|
||||||
|
pVal = strings.TrimPrefix(trimmed, "P:")
|
||||||
|
case strings.HasPrefix(trimmed, "R:"):
|
||||||
|
rVal = strings.TrimPrefix(trimmed, "R:")
|
||||||
|
case strings.HasPrefix(trimmed, "A:"):
|
||||||
|
aVal = strings.TrimPrefix(trimmed, "A:")
|
||||||
|
case strings.HasPrefix(trimmed, "o:"):
|
||||||
|
oVal = strings.TrimPrefix(trimmed, "o:")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Lines outside of entries just get appended directly
|
||||||
|
// (e.g. if there's extraneous text before the first "C:" or after the last)
|
||||||
|
if trimmed != "" {
|
||||||
|
newLines = append(newLines, trimmed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the last entry if we ended inEntry
|
||||||
|
if inEntry && len(currentEntry) > 0 {
|
||||||
|
// Decide whether to keep the final entry
|
||||||
|
if !(pVal == name && rVal == release && aVal == arch && oVal == origin) {
|
||||||
|
newLines = append(newLines, currentEntry...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Join everything back and ensure at least one trailing newline
|
||||||
|
finalContent := strings.Join(newLines, "\n")
|
||||||
|
if !strings.HasSuffix(finalContent, "\n") {
|
||||||
|
finalContent += "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile("./APPINDEX", []byte(finalContent), 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to update APPINDEX: %v", err)
|
log.Fatalf("Failed to update APPINDEX: %v", err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue