From e8857d62d91538e0760c50c5e1a68eaa16caf309 Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Sun, 5 Oct 2025 07:35:57 -0500 Subject: a binary to replace aptly --- Makefile | 2 - argv.go | 50 +++++++++++++++++++++ build | 10 +++++ control | 2 +- doDistro.go | 94 +++++++++++++++++++++++++++++++++++++++ main.go | 119 ++++++++------------------------------------------ resources/wit-sid.asc | 41 +++++++++++++++++ resources/wit.list | 4 ++ structs.go | 38 ++++++++++++++++ wit-sid.asc | 41 ----------------- wit.list | 4 -- 11 files changed, 255 insertions(+), 150 deletions(-) create mode 100644 argv.go create mode 100644 doDistro.go create mode 100644 resources/wit-sid.asc create mode 100644 resources/wit.list create mode 100644 structs.go delete mode 100644 wit-sid.asc delete mode 100644 wit.list diff --git a/Makefile b/Makefile index 0e253ca..ac6bb13 100644 --- a/Makefile +++ b/Makefile @@ -28,8 +28,6 @@ go-deb: goimports: goimports -w *.go - # // to globally reset paths: - # // gofmt -w -r '"go.wit.com/gui/gadgets" -> "go.wit.com/lib/gadgets"' *.go clean: rm -f go.* diff --git a/argv.go b/argv.go new file mode 100644 index 0000000..346dc5d --- /dev/null +++ b/argv.go @@ -0,0 +1,50 @@ +// Copyright 2017-2025 WIT.COM Inc. All rights reserved. +// Use of this source code is governed by the GPL 3.0 + +package main + +/* + this parses the command line arguements + this enables command line options from other packages like 'gui' and 'log' +*/ + +import ( + "os" + + "go.wit.com/lib/gui/prep" +) + +var argv args + +type args struct { + Update *EmptyCmd `arg:"subcommand:update" help:"update the apt repo"` + DryRun bool `arg:"--dry-run" help:"only show what would be packaged"` + Verbose bool `arg:"--verbose" help:"be loud about it"` + Force bool `arg:"--force" help:"rebuild everything"` +} + +type EmptyCmd struct { +} + +func (args) Buildtime() (string, string) { + return BUILDTIME, VERSION +} + +func (args) Version() string { + return ARGNAME + " " + VERSION + " Built on " + BUILDTIME +} + +func (args) Appname() string { + return ARGNAME +} + +func (a args) DoAutoComplete(pb *prep.Auto) { + base := []string{"--version", "update", "--dry-run", "--force"} + + if pb.Cmd == "" { + pb.Autocomplete3(base) + } else { + pb.SubCommand(pb.Goargs...) + } + os.Exit(0) +} diff --git a/build b/build index eba7c70..4dfcd69 100755 --- a/build +++ b/build @@ -1,4 +1,14 @@ #!/bin/bash -x +# these are the keys and files you need +# +# to be able to apt install packages from mirrors.wit.com + +mkdir -p files/etc/apt/trusted.gpg.d/ +cp resources/wit-sid.asc files/etc/apt/trusted.gpg.d/ + +mkdir -p files/etc/apt/sources.list.d/ +cp resources/wit.list files/etc/apt/sources.list.d/ + mkdir -p files/usr/share/bash-completion/completions/ mirrors --bash > files/usr/share/bash-completion/completions/mirrors diff --git a/control b/control index 9974c56..ea80ad8 100644 --- a/control +++ b/control @@ -7,6 +7,6 @@ Architecture: all Depends: URL: https://mirrors.wit.com/ Recommends: -Version: 0.0.7 +Version: 0.0.8 Description: apt keys and source file This was packaged with go-deb from go.wit.com diff --git a/doDistro.go b/doDistro.go new file mode 100644 index 0000000..f63b20e --- /dev/null +++ b/doDistro.go @@ -0,0 +1,94 @@ +package main + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "go.wit.com/log" +) + +func doDistro() error { + log.Println("--- Starting Debian repository generation in Go ---") + + // 1. Clean and create directory structure + distPath := filepath.Join(distsDir, dist) + log.Printf("Cleaning up old dists directory: %s\n", distPath) + if err := os.RemoveAll(distPath); err != nil { + return 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.Printf("Failed to create directory %s: %v\n", binPath, err) + return err + } + } + + // 2. Scan pool directory for .deb files and gather info + log.Printf("Scanning for .deb files in %s/ જુ\n", poolDir) + debInfos, err := scanDebs(poolDir) + if err != nil { + log.Printf("Failed to scan .deb files: %v\n", err) + return 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 { + return err + } + + // Compress the Packages file + if err := compressFile(packagesFile, "gz"); err != nil { + return err + } + if err := compressFile(packagesFile, "bz2"); err != nil { + return err + } + } + + // 5. Generate and sign the Release file + log.Println("Generating and signing Release file...") + if err := generateAndSignReleaseFile(distPath); err != nil { + log.Printf("Failed to generate or sign Release file: %v\n", err) + return err + } + + log.Println("--- Repository generation complete! ---") + return nil +} diff --git a/main.go b/main.go index 5c6846b..3e0f080 100644 --- a/main.go +++ b/main.go @@ -1,115 +1,30 @@ package main import ( - "fmt" - "log" - "os" - "path/filepath" - "strings" -) + "embed" -// --- Configuration --- -// !!! IMPORTANT: Set your GPG Key ID here! -// Find it with: gpg --list-secret-keys --keyid-format=long -const gpgKeyID = "5D7C9BE47836D2FA48F83C2B4A854AEAF7E0E16D" + "go.wit.com/lib/gui/prep" +) -const dist = "sid" -const component = "main" -const poolDir = "pool" -const distsDir = "dists" +// sent via -ldflags +var VERSION string +var BUILDTIME string -var architectures = []string{"amd64", "riscv64", "arm64", "all"} +// used for shell auto completion +var ARGNAME string = "mirrors" // todo: get this from $0 ? -// 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 -} +//go:embed resources/* +var resources embed.FS func main() { - 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) - } + me = new(mainType) + me.sh = prep.Bash3(&argv) // add support for bash autocomplete with go-arg - 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"]...) + if argv.Update != nil { + if err := doDistro(); err != nil { + me.sh.BadExit("boo", err) } + me.sh.GoodExit("") } - - // 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! ---") + me.sh.GoodExit("nothing to do") } diff --git a/resources/wit-sid.asc b/resources/wit-sid.asc new file mode 100644 index 0000000..8648d6c --- /dev/null +++ b/resources/wit-sid.asc @@ -0,0 +1,41 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +yGA= +=tw/F +-----END PGP PUBLIC KEY BLOCK----- diff --git a/resources/wit.list b/resources/wit.list new file mode 100644 index 0000000..f1b6db6 --- /dev/null +++ b/resources/wit.list @@ -0,0 +1,4 @@ +deb http://mirrors.wit.com/wit/ sid main +# deb-src http://mirrors.wit.com/wit/ sid main + +# cp apt-wit.list /etc/apt/sources.list.d/ diff --git a/structs.go b/structs.go new file mode 100644 index 0000000..c0d5cb1 --- /dev/null +++ b/structs.go @@ -0,0 +1,38 @@ +package main + +import ( + "sync" + + "go.wit.com/lib/gui/prep" +) + +// --- Configuration --- +// !!! IMPORTANT: Set your GPG Key ID here! +// Find it with: gpg --list-secret-keys --keyid-format=long +const gpgKeyID = "5D7C9BE47836D2FA48F83C2B4A854AEAF7E0E16D" + +const dist = "sid" +const component = "main" +const poolDir = "pool" +const distsDir = "dists" + +var architectures = []string{"amd64", "riscv64", "arm64", "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 +} + +var me *mainType + +// this app's variables +type mainType struct { + once sync.Once // one-time initialized data + sh *prep.Auto // more experiments for bash handling + // forge *forgepb.Forge // your customized repo preferences and settings +} diff --git a/wit-sid.asc b/wit-sid.asc deleted file mode 100644 index 8648d6c..0000000 --- a/wit-sid.asc +++ /dev/null @@ -1,41 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- - -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 -yGA= -=tw/F ------END PGP PUBLIC KEY BLOCK----- diff --git a/wit.list b/wit.list deleted file mode 100644 index f1b6db6..0000000 --- a/wit.list +++ /dev/null @@ -1,4 +0,0 @@ -deb http://mirrors.wit.com/wit/ sid main -# deb-src http://mirrors.wit.com/wit/ sid main - -# cp apt-wit.list /etc/apt/sources.list.d/ -- cgit v1.2.3