summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--apt.makedistro.go332
2 files changed, 1 insertions, 332 deletions
diff --git a/Makefile b/Makefile
index b6d7794..ab8cb2b 100644
--- a/Makefile
+++ b/Makefile
@@ -31,6 +31,7 @@ goimports:
clean:
rm -f go.*
+ go-mod-clean purge
gpl:
wit-test --witcom
diff --git a/apt.makedistro.go b/apt.makedistro.go
deleted file mode 100644
index 510bbd0..0000000
--- a/apt.makedistro.go
+++ /dev/null
@@ -1,332 +0,0 @@
-package main
-
-import (
- "bufio"
- "bytes"
- "compress/gzip"
- "crypto/md5"
- "crypto/sha1"
- "crypto/sha256"
- "fmt"
- "io"
- "log"
- "os"
- "os/exec"
- "path/filepath"
- "strings"
- "time"
-)
-
-// --- Configuration ---
-// !!! IMPORTANT: Set your GPG Key ID here!
-// Find it with: gpg --list-secret-keys --keyid-format=long
-const gpgKeyID = "YOUR_GPG_KEY_ID"
-
-const dist = "sid"
-const component = "main"
-const poolDir = "pool"
-const distsDir = "dists"
-
-var architectures = []string{"amd64", "riscv64", "all"}
-
-// DebInfo holds the control information for a single .deb package.
-type DebInfo struct {
- ControlData map[string]string
- Filename string
- Size int64
- MD5Sum string
- SHA1Sum string
- SHA256Sum string
-}
-
-func makeDistroFiles() {
- log.Println("--- Starting Debian repository generation in Go ---")
-
- if gpgKeyID == "YOUR_GPG_KEY_ID" || gpgKeyID == "" {
- log.Fatal("ERROR: Please set the 'gpgKeyID' constant at the top of the script.")
- }
-
- // 1. Clean and create directory structure
- distPath := filepath.Join(distsDir, dist)
- log.Printf("Cleaning up old dists directory: %s", distPath)
- if err := os.RemoveAll(distPath); err != nil {
- log.Fatalf("Failed to remove old dists directory: %v", err)
- }
-
- log.Println("Creating new directory structure...")
- for _, arch := range architectures {
- binPath := filepath.Join(distPath, component, "binary-"+arch)
- if err := os.MkdirAll(binPath, 0755); err != nil {
- log.Fatalf("Failed to create directory %s: %v", binPath, err)
- }
- }
-
- // 2. Scan pool directory for .deb files and gather info
- log.Printf("Scanning for .deb files in %s/ જુ", poolDir)
- debInfos, err := scanDebs(poolDir)
- if err != nil {
- log.Fatalf("Failed to scan .deb files: %v", err)
- }
- log.Printf("Found %d total .deb packages.", len(debInfos))
-
- // 3. Group packages by architecture
- debsByArch := make(map[string][]DebInfo)
- for _, deb := range debInfos {
- arch := deb.ControlData["Architecture"]
- debsByArch[arch] = append(debsByArch[arch], deb)
- }
- // Add the 'all' packages to each specific architecture list as well, as is standard.
- for _, arch := range architectures {
- if arch != "all" {
- debsByArch[arch] = append(debsByArch[arch], debsByArch["all"]...)
- }
- }
-
- // 4. Generate Packages files
- log.Println("Generating Packages files...")
- for _, arch := range architectures {
- binPath := filepath.Join(distPath, component, "binary-"+arch)
- packagesFile := filepath.Join(binPath, "Packages")
-
- var content strings.Builder
- for _, deb := range debsByArch[arch] {
- for key, val := range deb.ControlData {
- fmt.Fprintf(&content, "%s: %s\n", key, val)
- }
- fmt.Fprintf(&content, "Filename: %s\n", deb.Filename)
- fmt.Fprintf(&content, "Size: %d\n", deb.Size)
- fmt.Fprintf(&content, "MD5sum: %s\n", deb.MD5Sum)
- fmt.Fprintf(&content, "SHA1: %s\n", deb.SHA1Sum)
- fmt.Fprintf(&content, "SHA256: %s\n", deb.SHA256Sum)
- fmt.Fprintln(&content)
- }
-
- if err := os.WriteFile(packagesFile, []byte(content.String()), 0644); err != nil {
- log.Fatalf("Failed to write Packages file for %s: %v", arch, err)
- }
-
- // Compress the Packages file
- if err := compressFile(packagesFile, "gz"); err != nil {
- log.Fatalf("Failed to gzip Packages file for %s: %v", arch, err)
- }
- if err := compressFile(packagesFile, "bz2"); err != nil {
- log.Fatalf("Failed to bzip2 Packages file for %s: %v", arch, err)
- }
- }
-
- // 5. Generate and sign the Release file
- log.Println("Generating and signing Release file...")
- if err := generateAndSignReleaseFile(distPath); err != nil {
- log.Fatalf("Failed to generate or sign Release file: %v", err)
- }
-
- log.Println("--- Repository generation complete! ---")
-}
-
-// scanDebs finds all .deb files and extracts their metadata.
-func scanDebs(root string) ([]DebInfo, error) {
- var debs []DebInfo
- err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
- if err != nil {
- return err
- }
- if !info.IsDir() && strings.HasSuffix(info.Name(), ".deb") {
- log.Printf(" -> Processing %s", path)
-
- // Get control info
- cmd := exec.Command("dpkg-deb", "-I", path)
- var out bytes.Buffer
- cmd.Stdout = &out
- if err := cmd.Run(); err != nil {
- return fmt.Errorf("failed to run dpkg-deb on %s: %v", path, err)
- }
-
- controlData := parseControlData(out.String())
-
- // Get checksums
- md5sum, sha1sum, sha256sum, err := getChecksums(path)
- if err != nil {
- return err
- }
-
- relativePath, err := filepath.Rel(".", path)
- if err != nil {
- return err
- }
-
- debs = append(debs, DebInfo{
- ControlData: controlData,
- Filename: relativePath,
- Size: info.Size(),
- MD5Sum: md5sum,
- SHA1Sum: sha1sum,
- SHA256Sum: sha256sum,
- })
- }
- return nil
- })
- return debs, err
-}
-
-// parseControlData converts the text output of dpkg-deb into a map.
-func parseControlData(data string) map[string]string {
- control := make(map[string]string)
- scanner := bufio.NewScanner(strings.NewReader(data))
- for scanner.Scan() {
- line := strings.TrimSpace(scanner.Text())
- parts := strings.SplitN(line, ":", 2)
- if len(parts) == 2 {
- control[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
- }
- }
- return control
-}
-
-// getChecksums calculates all required hashes for a file.
-// FIX 1: Renamed return variables to avoid shadowing package names.
-func getChecksums(filePath string) (md5sum, sha1sum, sha256sum string, err error) {
- file, err := os.Open(filePath)
- if err != nil {
- return "", "", "", err
- }
- defer file.Close()
-
- hMD5 := md5.New()
- hSHA1 := sha1.New()
- hSHA256 := sha256.New()
-
- // TeeReader allows writing to multiple hashers at once
- multiWriter := io.MultiWriter(hMD5, hSHA1, hSHA256)
- if _, err := io.Copy(multiWriter, file); err != nil {
- return "", "", "", err
- }
-
- return fmt.Sprintf("%x", hMD5.Sum(nil)),
- fmt.Sprintf("%x", hSHA1.Sum(nil)),
- fmt.Sprintf("%x", hSHA256.Sum(nil)),
- nil
-}
-
-// compressFile creates a compressed version of a file (gz or bz2).
-func compressFile(sourcePath, format string) error {
- if format == "gz" {
- sourceFile, err := os.Open(sourcePath)
- if err != nil {
- return err
- }
- defer sourceFile.Close()
-
- destPath := sourcePath + ".gz"
- destFile, err := os.Create(destPath)
- if err != nil {
- return err
- }
- defer destFile.Close()
-
- writer := gzip.NewWriter(destFile)
- defer writer.Close()
-
- _, err = io.Copy(writer, sourceFile)
- return err
- } else if format == "bz2" {
- // FIX 2: Shell out to the bzip2 command for compression.
- destPath := sourcePath + ".bz2"
- cmd := exec.Command("bzip2", "-c", sourcePath)
-
- outfile, err := os.Create(destPath)
- if err != nil {
- return fmt.Errorf("failed to create destination file for bzip2: %v", err)
- }
- defer outfile.Close()
- cmd.Stdout = outfile
-
- return runCommand(cmd)
- }
-
- return fmt.Errorf("unsupported compression format: %s", format)
-}
-
-// generateAndSignReleaseFile creates the main Release file and signs it.
-func generateAndSignReleaseFile(distPath string) error {
- releasePath := filepath.Join(distPath, "Release")
- var content strings.Builder
-
- // Add headers
- fmt.Fprintf(&content, "Origin: Your Repository\n")
- fmt.Fprintf(&content, "Label: Your Repository\n")
- fmt.Fprintf(&content, "Suite: %s\n", dist)
- fmt.Fprintf(&content, "Codename: %s\n", dist)
- fmt.Fprintf(&content, "Date: %s\n", time.Now().UTC().Format(time.RFC1123Z))
- fmt.Fprintf(&content, "Architectures: %s\n", strings.Join(architectures, " "))
- fmt.Fprintf(&content, "Components: %s\n", component)
- fmt.Fprintf(&content, "Description: A cool repository\n")
-
- // Add checksums
- addChecksums := func(name string) {
- fmt.Fprintf(&content, "%s:\n", name)
- err := filepath.Walk(distPath, func(path string, info os.FileInfo, err error) error {
- if err != nil {
- return err
- }
- if !info.IsDir() && info.Name() != "Release" && info.Name() != "InRelease" && info.Name() != "Release.gpg" {
- relativePath, _ := filepath.Rel(distPath, path)
-
- fileBytes, err := os.ReadFile(path)
- if err != nil {
- return err
- }
-
- var sum string
- switch name {
- case "MD5Sum":
- sum = fmt.Sprintf("%x", md5.Sum(fileBytes))
- case "SHA1":
- sum = fmt.Sprintf("%x", sha1.Sum(fileBytes))
- case "SHA256":
- // FIX 3: Use the correct sha256.Sum256 function.
- sum = fmt.Sprintf("%x", sha256.Sum256(fileBytes))
- }
- fmt.Fprintf(&content, " %s %d %s\n", sum, info.Size(), relativePath)
- }
- return nil
- })
- if err != nil {
- log.Printf("Warning: could not walk path for checksums: %v", err)
- }
- }
-
- addChecksums("MD5Sum")
- addChecksums("SHA1")
- addChecksums("SHA256")
-
- if err := os.WriteFile(releasePath, []byte(content.String()), 0644); err != nil {
- return fmt.Errorf("failed to write Release file: %v", err)
- }
-
- // Sign the file
- log.Println("Signing with GPG key:", gpgKeyID)
-
- // Create InRelease
- cmdClearSign := exec.Command("gpg", "--default-key", gpgKeyID, "--clearsign", "-o", filepath.Join(distPath, "InRelease"), releasePath)
- if err := runCommand(cmdClearSign); err != nil {
- return fmt.Errorf("failed to create InRelease: %v", err)
- }
-
- // Create Release.gpg
- cmdDetachedSign := exec.Command("gpg", "--default-key", gpgKeyID, "-abs", "-o", filepath.Join(distPath, "Release.gpg"), releasePath)
- if err := runCommand(cmdDetachedSign); err != nil {
- return fmt.Errorf("failed to create Release.gpg: %v", err)
- }
-
- return nil
-}
-
-func runCommand(cmd *exec.Cmd) error {
- var stderr bytes.Buffer
- cmd.Stderr = &stderr
- err := cmd.Run()
- if err != nil {
- return fmt.Errorf("command '%s' failed: %v\nStderr: %s", cmd.String(), err, stderr.String())
- }
- return nil
-}