Multi-package Debian/RPM: schema + scaffolders + user-template rendering #56
No reviewers
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
nagonag
nagonag/ignore
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
heiko/gogogo!56
Loading…
Reference in a new issue
No description provided.
Delete branch "worktree-multi-deb"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds full multi-package Debian/RPM support to gogogo. Three layers land in this PR:
artifacts.packages:field (absent /'*'/ list) with per-package merge and validation.debian/controland multi-%package -n<name>.specfiles. Both honor user-edited templates indebian/*andrpm/<name>.specviatext/templaterendering against a stableDebContext/RPMContext.gogogo config packages— scaffold theartifacts.packages:YAML block fromcmd/*discovery (replaces the misnamed first version ofpack populate).gogogo pack populate— scaffold editable starter files intodebian/andrpm/for users who want to customise the source-package shape beyond what the YAML schema covers.Behavior change
Existing multi-binary projects without an
artifacts.packages:declaration now produce one combined.debnamed after the module, instead of one.debpercmd/*binary. Setpackages: '*'(or usegogogo config packages --shorthand --in-place) to preserve the prior per-binary split.CLI surface
User-template contract
User-edited
debian/control,debian/rules,debian/changelog,debian/source/format, andrpm/<name>.specfiles are rendered throughtext/templateat build time against:DebContext—Source,Maintainer,Tag,DebVersion,Packages[],Synopsis,LongDescIndented,ChangelogDate, etc.RPMContext—Name,RPMVersion,RPMRelease,TarName,Packages[],Group,Changelog, etc.Field names form a public stability contract.
missingkey=errormakes typos like{{ .Versoin }}fail loud with the offending file path in the error.Test plan
go test ./...— all packages passgo vet ./...cleangolangci-lint run— no new issues in any added file (intentional misspellings +fmt.Fprintfprogress lines marked with//nolint)gogogo --version,gogogo config packages --help,gogogo pack populateend-to-end on a fixture project.dscrebuild produces the same multi-package set as direct.debbuild (multi-stanzadebian/control+ per-packagego build)rpmbuild -bson the generated<name>.specworks for both single-package (no-n) and multi-package (%package -nper entry) projectsCommits
Known limitations (CHANGELOG-worthy)
.debby default. Usepackages: '*'to preserve the prior per-binary split.depends_remove:escape hatch can land separately.DebContext/RPMContextfield names are committed — renames are breaking changes for users with customdebian/*orrpm/<name>.spectemplates.ius:ai:claude-opus-4-7
Introduce artifacts.packages: as a polymorphic YAML field with three modes: absent (new default — all binaries combined into one package named after the module), '*' (one package per cmd/* binary — the prior implicit behavior, now explicit), and an explicit list of {name, binaries, deb, rpm, files} entries with per-package overrides under union-merge semantics for list fields. This is a deliberate behavior change for existing multi-binary projects: without a config edit, two cmd/* binaries that previously produced two identically-configured .debs now produce one combined .deb. Set packages: '*' to preserve the prior split, or use an explicit list for differentiation (per-package depends, scripts, files, etc.). Source-package generation (.dsc) follows the same mode and produces a matching multi-stanza debian/control with one go build per entry when applicable, so .dsc rebuilds match the direct .deb build output. Validation enforces unique names, Debian package-name shape, binary existence in build.commands or as the module basename, no double-claim across packages, and well-formed file entries — but only in Explicit mode; Combined and PerBinary need no per-entry rules. Add gogogo pack populate subcommand to scaffold the packages: block from cmd/* discovery: stdout by default (safe path), with --shorthand for the packages: '*' one-liner, --in-place to splice into .gogogo.conf (refuses if the key is already present), and --force to overwrite an existing block. auto.detectCommands is exported as auto.DetectCommands so populate can reuse the same discovery logic. ius:ai:claude-opus-4-7Previously the migrator only read legacy v1 Formats.* and Packages fields, so running `gogogo config migrate` against a current v2 .gogogo.conf silently dropped user-set artifacts.deb.depends, artifacts.rpm.group, artifacts.common.maintainer, and similar v2 fields — they were re-rendered as commented defaults. Introduce migrator.effective() that returns an Artifacts struct combining v1 Formats.* (the original migration source) with v2 Artifacts.* overlaid where set. Precedence is "v2 wins where set" because these are explicit user values, not per-package overrides that need union semantics. artifacts() now reads from this effective struct, so user-set v2 fields round-trip through Migrated() while legacy v1 configs still migrate correctly. Includes the v1→v2 derivations: - Packages []string ("deb", "rpm") → per-format Enabled bools - Formats.Source → Deb.Source / RPM.Source / SourceVendor - Formats.Deb.* / Formats.RPM.* / Formats.Common.* → Artifacts.* Per-format source toggles now emit independently — deb.source and rpm.source are no longer linked to a single v1 Source switch when v2 sets them separately. ius:ai:claude-opus-4-7Replace the module-path-based version line ("go.schlittermann.de/heiko/gogogo v1.0.0") with a more human-readable form: the command's basename, the version, and the full path to the executable on disk. The basename + path lets users disambiguate when multiple gogogo binaries are installed (e.g. one from `go install`, one from a .deb package, one from a worktree build) — `which gogogo` answers the "which one" question, --version now does it inline. Falls back to os.Args[0] when os.Executable() fails, so the version line stays useful even in pathological environments. ius:ai:claude-opus-4-7writeDebianDir now honors user-edited debian/source/format, control, rules, copyright, and changelog files when they're present in the source tree (already copied into pkgDir by copyTree). The contents are rendered through text/template against a new DebContext exposing Source, Maintainer, Tag, DebVersion, Packages, etc. When the file is absent the existing generator runs as before — so projects without any debian/ directory in their source produce byte-identical output (existing tests verify this). Template parsing uses missingkey=error so user typos like {{ .Versoin }} fail loud with a clear file-locating error. The DebContext field names form a public stability contract — once shipped, renaming them breaks user templates. This is groundwork for the new `pack populate` subcommand (next commit) which scaffolds editable stub files containing these placeholders. ius:ai:claude-opus-4-7`gogogo pack populate` now does what the original design intended: it writes editable starter files into the project's debian/ and rpm/ directories. Each file is a text/template that the build renders against a DebContext / RPMContext at package-creation time. Scaffolded files: - debian/source/format (literal "3.0 (native)") - debian/control (Source/Maintainer/{{ range .Packages }}) - debian/rules (per-package go build per .Packages entry, 0755) - debian/changelog (Source/DebVersion/Tag/ChangelogDate) - rpm/<module>.spec (multi-stanza-ready; full multi-package %package -n support lands in a follow-up commit) Existing files are skipped silently with a "skip <name> (exists; --force overwrites)" notice; --force overwrites them. The skip behavior keeps re-running safe — users can pull in new stubs after a gogogo upgrade without losing local edits to existing files. A new exported source.RenderDebTemplate provides the entry point that tests (and pack populate's own end-to-end render test) use to verify stub templates flow through the renderer cleanly without leftover {{ }} markers. Combined with the missingkey=error setting from the prior commit, typos like {{ .Versoin }} fail loudly at build time. ius:ai:claude-opus-4-7- internal/pack/source/template.go: //nolint:misspell on a comment that uses {{ .Versoin }} as a literal example of the typo the missingkey=error setting catches. - internal/pack/source/deb_test.go: //nolint:misspell on the same typo used as a test fixture for that error path. - internal/cmd/pack/populate.go: //nolint:errcheck on two fmt.Fprintf progress lines. These are user-facing progress notes; if the output writer fails, there's no recovery and no useful place to log. ius:ai:claude-opus-4-7Add multi-package support for Debian and RPM artifactsto Multi-package Debian/RPM: schema + scaffolders + user-template renderingMulti-package Debian/RPM: schema + scaffolders + user-template renderingto WIP: Multi-package Debian/RPM: schema + scaffolders + user-template rendering32e68a5b36tod7d1d11ba6WIP: Multi-package Debian/RPM: schema + scaffolders + user-template renderingto Multi-package Debian/RPM: schema + scaffolders + user-template rendering