Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package nfpm for openSUSE:Factory checked in at 2025-06-10 09:05:33 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/nfpm (Old) and /work/SRC/openSUSE:Factory/.nfpm.new.19631 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "nfpm" Tue Jun 10 09:05:33 2025 rev:10 rq:1283910 version:2.43.0 Changes: -------- --- /work/SRC/openSUSE:Factory/nfpm/nfpm.changes 2025-05-22 16:57:01.994331180 +0200 +++ /work/SRC/openSUSE:Factory/.nfpm.new.19631/nfpm.changes 2025-06-10 09:08:58.936604346 +0200 @@ -1,0 +2,13 @@ +Sun Jun 08 06:10:22 UTC 2025 - Johannes Kastl <opensuse_buildserv...@ojkastl.de> + +- Update to version 2.43.0: + * New Features + - 2e47af6: feat: srpm (#935) (@caarlos0) + * Other work + - fdc6b11: docs: update cmd docs (@caarlos0) + * Dependencies + - chore(deps): bump github.com/google/rpmpack (#934) + - chore(deps): bump github.com/ProtonMail/go-crypto from 1.2.0 + to 1.3.0 (#931) + +------------------------------------------------------------------- Old: ---- nfpm-2.42.1.obscpio New: ---- nfpm-2.43.0.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ nfpm.spec ++++++ --- /var/tmp/diff_new_pack.Xc14Wg/_old 2025-06-10 09:08:59.784639401 +0200 +++ /var/tmp/diff_new_pack.Xc14Wg/_new 2025-06-10 09:08:59.784639401 +0200 @@ -17,7 +17,7 @@ Name: nfpm -Version: 2.42.1 +Version: 2.43.0 Release: 0 Summary: Simple deb, rpm, apk and arch linux packager written in Go License: MIT ++++++ _service ++++++ --- /var/tmp/diff_new_pack.Xc14Wg/_old 2025-06-10 09:08:59.820640890 +0200 +++ /var/tmp/diff_new_pack.Xc14Wg/_new 2025-06-10 09:08:59.824641054 +0200 @@ -3,7 +3,7 @@ <param name="url">https://github.com/goreleaser/nfpm</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v2.42.1</param> + <param name="revision">v2.43.0</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> <param name="changesgenerate">enable</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.Xc14Wg/_old 2025-06-10 09:08:59.848642047 +0200 +++ /var/tmp/diff_new_pack.Xc14Wg/_new 2025-06-10 09:08:59.852642212 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/goreleaser/nfpm</param> - <param name="changesrevision">9f029a49563c197ac1f83795a816afaae977b068</param></service></servicedata> + <param name="changesrevision">2e47af64a3f33d32ec1395dbd56165c4feb2bc21</param></service></servicedata> (No newline at EOF) ++++++ nfpm-2.42.1.obscpio -> nfpm-2.43.0.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nfpm-2.42.1/go.mod new/nfpm-2.43.0/go.mod --- old/nfpm-2.42.1/go.mod 2025-05-20 04:44:15.000000000 +0200 +++ new/nfpm-2.43.0/go.mod 2025-06-07 18:32:08.000000000 +0200 @@ -6,11 +6,11 @@ dario.cat/mergo v1.0.2 github.com/AlekSi/pointer v1.2.0 github.com/Masterminds/semver/v3 v3.3.1 - github.com/ProtonMail/go-crypto v1.2.0 + github.com/ProtonMail/go-crypto v1.3.0 github.com/ProtonMail/gopenpgp/v2 v2.7.1 github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb github.com/caarlos0/go-version v0.2.0 - github.com/google/rpmpack v0.6.1-0.20250405124433-758cc6896cbc + github.com/google/rpmpack v0.7.0 github.com/goreleaser/chglog v0.7.0 github.com/goreleaser/fileglob v1.3.0 github.com/invopop/jsonschema v0.13.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nfpm-2.42.1/go.sum new/nfpm-2.43.0/go.sum --- old/nfpm-2.42.1/go.sum 2025-05-20 04:44:15.000000000 +0200 +++ new/nfpm-2.43.0/go.sum 2025-06-07 18:32:08.000000000 +0200 @@ -14,8 +14,8 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/ProtonMail/go-crypto v0.0.0-20230321155629-9a39f2531310/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE= -github.com/ProtonMail/go-crypto v1.2.0 h1:+PhXXn4SPGd+qk76TlEePBfOfivE0zkWFenhGhFLzWs= -github.com/ProtonMail/go-crypto v1.2.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= +github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= +github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f h1:tCbYj7/299ekTTXpdwKYF8eBlsYsDVoggDAuAjoK66k= github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw= github.com/ProtonMail/gopenpgp/v2 v2.7.1 h1:Awsg7MPc2gD3I7IFac2qE3Gdls0lZW8SzrFZ3k1oz0s= @@ -69,8 +69,8 @@ github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/rpmpack v0.6.1-0.20250405124433-758cc6896cbc h1:qES+d3PvR9CN+zARQQH/bNXH0ybzmdjNMHICrBwXD28= -github.com/google/rpmpack v0.6.1-0.20250405124433-758cc6896cbc/go.mod h1:uqVAUVQLq8UY2hCDfmJ/+rtO3aw7qyhc90rCVEabEfI= +github.com/google/rpmpack v0.7.0 h1:mA2Yd3/dOmao1ype0DJA8DFquEpslaleywOuglVCrUs= +github.com/google/rpmpack v0.7.0/go.mod h1:uqVAUVQLq8UY2hCDfmJ/+rtO3aw7qyhc90rCVEabEfI= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nfpm-2.42.1/rpm/rpm.go new/nfpm-2.43.0/rpm/rpm.go --- old/nfpm-2.42.1/rpm/rpm.go 2025-05-20 04:44:15.000000000 +0200 +++ new/nfpm-2.43.0/rpm/rpm.go 2025-06-07 18:32:08.000000000 +0200 @@ -26,6 +26,8 @@ tagChangelogName = 1081 // https://github.com/rpm-software-management/rpm/blob/master/lib/rpmtag.h#L154 tagChangelogText = 1082 + // https://github.com/rpm-software-management/rpm/blob/master/include/rpm/rpmtag.h#L183 + tagSourcePackage = 1106 // Symbolic link tagLink = 0o120000 @@ -40,19 +42,34 @@ {{- end}}{{- end}}` ) -const packagerName = "rpm" - // nolint: gochecknoinits func init() { - nfpm.RegisterPackager(packagerName, Default) + nfpm.RegisterPackager(formatRPM.String(), DefaultRPM) + nfpm.RegisterPackager(formatSRPM.String(), DefaultSRPM) } -// Default RPM packager. +// DefaultRPM RPM packager. +// nolint: gochecknoglobals +var DefaultRPM = &RPM{formatRPM} + +// DefaultRPM RPM packager. // nolint: gochecknoglobals -var Default = &RPM{} +var DefaultSRPM = &RPM{formatSRPM} + +type format uint + +const ( + formatRPM format = iota + formatSRPM +) + +// String implements fmt.Stringer. +func (f format) String() string { return [2]string{"rpm", "srpm"}[f] } // RPM is a RPM packager implementation. -type RPM struct{} +type RPM struct { + format format +} // https://docs.fedoraproject.org/ro/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch01s03.html // nolint: gochecknoglobals @@ -85,33 +102,37 @@ // ConventionalFileName returns a file name according // to the conventions for RPM packages. See: // http://ftp.rpm.org/max-rpm/ch-rpm-file-format.html -func (*RPM) ConventionalFileName(info *nfpm.Info) string { +func (r *RPM) ConventionalFileName(info *nfpm.Info) string { info = setDefaults(info) // name-version-release.architecture.rpm return fmt.Sprintf( - "%s-%s-%s.%s.rpm", + "%s-%s-%s.%s%s", info.Name, formatVersion(info), defaultTo(info.Release, "1"), info.Arch, + r.ConventionalExtension(), ) } // ConventionalExtension returns the file name conventionally used for RPM packages -func (*RPM) ConventionalExtension() string { +func (r *RPM) ConventionalExtension() string { + if r.format == formatSRPM { + return ".src.rpm" + } return ".rpm" } // Package writes a new RPM package to the given writer using the given info. -func (*RPM) Package(info *nfpm.Info, w io.Writer) (err error) { +func (r *RPM) Package(info *nfpm.Info, w io.Writer) (err error) { var ( meta *rpmpack.RPMMetaData rpm *rpmpack.RPM ) info = setDefaults(info) - err = nfpm.PrepareForPackager(info, packagerName) + err = nfpm.PrepareForPackager(info, "rpm") if err != nil { return err } @@ -123,6 +144,10 @@ return err } + if r.format == formatSRPM { + rpm.AddCustomTag(tagSourcePackage, rpmpack.EntryUint32([]uint32{1})) + } + if info.RPM.Signature.KeyFile != "" { rpm.SetPGPSigner(sign.PGPSignerWithKeyID( info.RPM.Signature.KeyFile, @@ -365,7 +390,7 @@ func createFilesInsideRPM(info *nfpm.Info, rpm *rpmpack.RPM) (err error) { mtime := modtime.Get(info.MTime) for _, content := range info.Contents { - if content.Packager != "" && content.Packager != packagerName { + if content.Packager != "" && content.Packager != "rpm" { continue } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nfpm-2.42.1/rpm/rpm_test.go new/nfpm-2.43.0/rpm/rpm_test.go --- old/nfpm-2.42.1/rpm/rpm_test.go 2025-05-20 04:44:15.000000000 +0200 +++ new/nfpm-2.43.0/rpm/rpm_test.go 2025-06-07 18:32:08.000000000 +0200 @@ -94,13 +94,13 @@ } func TestConventionalExtension(t *testing.T) { - require.Equal(t, ".rpm", Default.ConventionalExtension()) + require.Equal(t, ".rpm", DefaultRPM.ConventionalExtension()) } func TestRPM(t *testing.T) { f, err := os.CreateTemp(t.TempDir(), "test.rpm") require.NoError(t, err) - require.NoError(t, Default.Package(exampleInfo(), f)) + require.NoError(t, DefaultRPM.Package(exampleInfo(), f)) file, err := os.OpenFile(f.Name(), os.O_RDONLY, 0o600) //nolint:gosec require.NoError(t, err) @@ -153,10 +153,70 @@ require.Equal(t, "Foo does things", description) } +func TestSRPM(t *testing.T) { + f, err := os.CreateTemp(t.TempDir(), "test.rpm") + require.NoError(t, err) + require.NoError(t, DefaultSRPM.Package(exampleInfo(), f)) + + file, err := os.OpenFile(f.Name(), os.O_RDONLY, 0o600) //nolint:gosec + require.NoError(t, err) + defer func() { + f.Close() + file.Close() + err = os.Remove(file.Name()) + require.NoError(t, err) + }() + rpm, err := rpmutils.ReadRpm(file) + require.NoError(t, err) + + os, err := rpm.Header.GetString(rpmutils.OS) + require.NoError(t, err) + require.Equal(t, "linux", os) + + arch, err := rpm.Header.GetString(rpmutils.ARCH) + require.NoError(t, err) + require.Equal(t, archToRPM["amd64"], arch) + + version, err := rpm.Header.GetString(rpmutils.VERSION) + require.NoError(t, err) + require.Equal(t, "1.0.0", version) + + release, err := rpm.Header.GetString(rpmutils.RELEASE) + require.NoError(t, err) + require.Equal(t, "1", release) + + epoch, err := rpm.Header.Get(rpmutils.EPOCH) + require.NoError(t, err) + epochUint32, ok := epoch.([]uint32) + require.True(t, ok) + require.Len(t, epochUint32, 1) + require.Equal(t, uint32(0), epochUint32[0]) + + group, err := rpm.Header.GetString(rpmutils.GROUP) + require.NoError(t, err) + require.Equal(t, "foo", group) + + buildhost, err := rpm.Header.GetString(rpmutils.BUILDHOST) + require.NoError(t, err) + require.Equal(t, "barhost", buildhost) + + summary, err := rpm.Header.GetString(rpmutils.SUMMARY) + require.NoError(t, err) + require.Equal(t, "Foo does things", summary) + + description, err := rpm.Header.GetString(rpmutils.DESCRIPTION) + require.NoError(t, err) + require.Equal(t, "Foo does things", description) + + bts, err := rpm.Header.GetUint32s(tagSourcePackage) + require.NoError(t, err) + require.Equal(t, []uint32{1}, bts) +} + func TestRPMMandatoryFieldsOnly(t *testing.T) { f, err := os.CreateTemp(t.TempDir(), "test.rpm") require.NoError(t, err) - require.NoError(t, Default.Package(&nfpm.Info{ + require.NoError(t, DefaultRPM.Package(&nfpm.Info{ Name: "foo", Arch: "amd64", Version: "1.2", @@ -213,7 +273,7 @@ t.Cleanup(func() { require.NoError(t, f.Close()) }) info := exampleInfo() info.Platform = "darwin" - require.NoError(t, Default.Package(info, f)) + require.NoError(t, DefaultRPM.Package(info, f)) } func TestRPMGroup(t *testing.T) { @@ -221,7 +281,7 @@ require.NoError(t, err) info := exampleInfo() info.RPM.Group = "Unspecified" - require.NoError(t, Default.Package(info, f)) + require.NoError(t, DefaultRPM.Package(info, f)) file, err := os.OpenFile(f.Name(), os.O_RDONLY, 0o600) //nolint:gosec require.NoError(t, err) @@ -257,7 +317,7 @@ info := exampleInfo() info.RPM.Compression = compLevel - require.NoError(t, Default.Package(info, f)) + require.NoError(t, DefaultRPM.Package(info, f)) file, err := os.OpenFile(f.Name(), os.O_RDONLY, 0o600) //nolint:gosec require.NoError(t, err) defer func() { @@ -289,7 +349,7 @@ info.RPM.Group = "Unspecified" info.RPM.Summary = customSummary - require.NoError(t, Default.Package(info, f)) + require.NoError(t, DefaultRPM.Package(info, f)) file, err := os.OpenFile(f.Name(), os.O_RDONLY, 0o600) //nolint:gosec require.NoError(t, err) @@ -316,7 +376,7 @@ info.RPM.Group = "Unspecified" info.RPM.Packager = customPackager - require.NoError(t, Default.Package(info, f)) + require.NoError(t, DefaultRPM.Package(info, f)) file, err := os.OpenFile(f.Name(), os.O_RDONLY, 0o600) //nolint:gosec require.NoError(t, err) @@ -345,7 +405,7 @@ Group: "default", } info.Description = "first line\nsecond line\nthird line" - require.NoError(t, Default.Package(info, f)) + require.NoError(t, DefaultRPM.Package(info, f)) file, err := os.OpenFile(f.Name(), os.O_RDONLY, 0o600) //nolint:gosec require.NoError(t, err) @@ -491,14 +551,14 @@ Group: "default", } info.Description = "first line\nsecond line\nthird line" - require.Error(t, Default.Package(info, f)) + require.Error(t, DefaultRPM.Package(info, f)) } func TestRPMScripts(t *testing.T) { info := exampleInfo() f, err := os.CreateTemp(t.TempDir(), fmt.Sprintf("%s-%s-*.rpm", info.Name, info.Version)) require.NoError(t, err) - err = Default.Package(info, f) + err = DefaultRPM.Package(info, f) require.NoError(t, err) file, err := os.OpenFile(f.Name(), os.O_RDONLY, 0o600) //nolint:gosec require.NoError(t, err) @@ -578,7 +638,7 @@ } abs, err := filepath.Abs("../testdata/whatever.confzzz") require.NoError(t, err) - err = Default.Package(info, io.Discard) + err = DefaultRPM.Package(info, io.Discard) require.EqualError(t, err, fmt.Sprintf("matching \"%s\": file does not exist", filepath.ToSlash(abs))) } @@ -624,7 +684,7 @@ } var rpmFileBuffer bytes.Buffer - err := Default.Package(info, &rpmFileBuffer) + err := DefaultRPM.Package(info, &rpmFileBuffer) require.NoError(t, err) expectedConfigContent, err := os.ReadFile(buildConfigFile) @@ -660,7 +720,7 @@ } var rpmFileBuffer bytes.Buffer - err := Default.Package(info, &rpmFileBuffer) + err := DefaultRPM.Package(info, &rpmFileBuffer) require.NoError(t, err) expectedConfigContent, err := os.ReadFile(buildConfigFile) @@ -714,7 +774,7 @@ info.Prerelease = testCase.Prerelease info.VersionMetadata = testCase.Metadata - require.Equal(t, testCase.Expected, Default.ConventionalFileName(info)) + require.Equal(t, testCase.Expected, DefaultRPM.ConventionalFileName(info)) } } @@ -723,7 +783,7 @@ info.Changelog = "../testdata/changelog.yaml" var rpmFileBuffer bytes.Buffer - err := Default.Package(info, &rpmFileBuffer) + err := DefaultRPM.Package(info, &rpmFileBuffer) require.NoError(t, err) rpm, err := rpmutils.ReadRpm(bytes.NewReader(rpmFileBuffer.Bytes())) @@ -770,7 +830,7 @@ info := exampleInfo() var rpmFileBuffer bytes.Buffer - err := Default.Package(info, &rpmFileBuffer) + err := DefaultRPM.Package(info, &rpmFileBuffer) require.NoError(t, err) rpm, err := rpmutils.ReadRpm(bytes.NewReader(rpmFileBuffer.Bytes())) @@ -815,7 +875,7 @@ } var rpmFileBuffer bytes.Buffer - err := Default.Package(info, &rpmFileBuffer) + err := DefaultRPM.Package(info, &rpmFileBuffer) require.NoError(t, err) packagedSymlinkHeader, err := extractFileHeaderFromRpm(rpmFileBuffer.Bytes(), symlink) @@ -842,7 +902,7 @@ require.NotNil(t, keyring, "cannot verify sigs with an empty keyring") var rpmBuffer bytes.Buffer - err = Default.Package(info, &rpmBuffer) + err = DefaultRPM.Package(info, &rpmBuffer) require.NoError(t, err) _, sigs, err := rpmutils.Verify(bytes.NewReader(rpmBuffer.Bytes()), keyring) @@ -856,7 +916,7 @@ info.RPM.Signature.KeyPassphrase = "wrongpass" var rpmBuffer bytes.Buffer - err := Default.Package(info, &rpmBuffer) + err := DefaultRPM.Package(info, &rpmBuffer) require.Error(t, err) var expectedError *nfpm.ErrSigningFailure @@ -881,7 +941,7 @@ require.NotNil(t, keyring, "cannot verify sigs with an empty keyring") var rpmBuffer bytes.Buffer - err = Default.Package(info, &rpmBuffer) + err = DefaultRPM.Package(info, &rpmBuffer) require.NoError(t, err) _, sigs, err := rpmutils.Verify(bytes.NewReader(rpmBuffer.Bytes()), keyring) @@ -909,7 +969,7 @@ } var rpmFileBuffer bytes.Buffer - err := Default.Package(info, &rpmFileBuffer) + err := DefaultRPM.Package(info, &rpmFileBuffer) require.NoError(t, err) headerFiles, err := extraFileInfoSliceFromRpm(rpmFileBuffer.Bytes()) @@ -947,7 +1007,7 @@ } var rpmFileBuffer bytes.Buffer - err := Default.Package(info, &rpmFileBuffer) + err := DefaultRPM.Package(info, &rpmFileBuffer) require.NoError(t, err) expectedContent, err := os.ReadFile("../testdata/{file}[") @@ -989,7 +1049,7 @@ } var rpmFileBuffer bytes.Buffer - err := Default.Package(info, &rpmFileBuffer) + err := DefaultRPM.Package(info, &rpmFileBuffer) require.NoError(t, err) require.Equal(t, []string{ @@ -1017,7 +1077,7 @@ } func TestGlob(t *testing.T) { - require.NoError(t, Default.Package(nfpm.WithDefaults(&nfpm.Info{ + require.NoError(t, DefaultRPM.Package(nfpm.WithDefaults(&nfpm.Info{ Name: "nfpm-repro", Version: "1.0.0", Maintainer: "asdfasdf", @@ -1044,7 +1104,7 @@ } var rpmFileBuffer bytes.Buffer - err := Default.Package(info, &rpmFileBuffer) + err := DefaultRPM.Package(info, &rpmFileBuffer) require.NoError(t, err) require.Empty(t, getTree(t, rpmFileBuffer.Bytes())) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nfpm-2.42.1/testdata/acceptance/deb.dockerfile new/nfpm-2.43.0/testdata/acceptance/deb.dockerfile --- old/nfpm-2.42.1/testdata/acceptance/deb.dockerfile 2025-05-20 04:44:15.000000000 +0200 +++ new/nfpm-2.43.0/testdata/acceptance/deb.dockerfile 2025-06-07 18:32:08.000000000 +0200 @@ -161,7 +161,7 @@ RUN dpkg -r foo # ---- triggers test ---- -FROM min as triggers +FROM min AS triggers # simulate another package that activates the trigger RUN dpkg-trigger --by-package foo manual-trigger RUN dpkg --triggers-only foo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nfpm-2.42.1/testdata/acceptance/rpm.dockerfile new/nfpm-2.43.0/testdata/acceptance/rpm.dockerfile --- old/nfpm-2.42.1/testdata/acceptance/rpm.dockerfile 2025-05-20 04:44:15.000000000 +0200 +++ new/nfpm-2.43.0/testdata/acceptance/rpm.dockerfile 2025-06-07 18:32:08.000000000 +0200 @@ -124,15 +124,15 @@ # ---- env-var-version test ---- FROM min AS env-var-version ENV EXPECTVER="Version : 1.0.0~0.1.b1+git.abcdefgh" \ - EXPECTREL="Release : 1" + EXPECTREL="Release : 1" RUN rpm -qpi /tmp/foo.rpm | sed -e 's/ \+/ /g' | grep "Version" > found.ver RUN rpm -qpi /tmp/foo.rpm | sed -e 's/ \+/ /g' | grep "Release" > found.rel RUN export FOUND_VER="$(cat found.ver)" && \ - echo "Expected: ${EXPECTVER}' :: Found: '${FOUND_VER}'" && \ - test "${FOUND_VER}" = "${EXPECTVER}" + echo "Expected: ${EXPECTVER}' :: Found: '${FOUND_VER}'" && \ + test "${FOUND_VER}" = "${EXPECTVER}" RUN export FOUND_REL="$(cat found.rel)" && \ - echo "Expected: '${EXPECTREL}' :: Found: '${FOUND_REL}'" && \ - test "${FOUND_REL}" = "${EXPECTREL}" + echo "Expected: '${EXPECTREL}' :: Found: '${FOUND_REL}'" && \ + test "${FOUND_REL}" = "${EXPECTREL}" # ---- changelog test ---- @@ -222,7 +222,7 @@ RUN test ! -d /etc/baz # ---- verify test ---- -FROM min as verify +FROM min AS verify RUN rpm -V foo RUN rm /tmp/postinstall-proof RUN ! rpm -V foo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nfpm-2.42.1/www/docs/static/latest new/nfpm-2.43.0/www/docs/static/latest --- old/nfpm-2.42.1/www/docs/static/latest 2025-05-20 04:44:15.000000000 +0200 +++ new/nfpm-2.43.0/www/docs/static/latest 2025-06-07 18:32:08.000000000 +0200 @@ -1 +1 @@ -v2.42.0 +v2.42.1 ++++++ nfpm.obsinfo ++++++ --- /var/tmp/diff_new_pack.Xc14Wg/_old 2025-06-10 09:09:00.116653126 +0200 +++ /var/tmp/diff_new_pack.Xc14Wg/_new 2025-06-10 09:09:00.120653291 +0200 @@ -1,5 +1,5 @@ name: nfpm -version: 2.42.1 -mtime: 1747709055 -commit: 9f029a49563c197ac1f83795a816afaae977b068 +version: 2.43.0 +mtime: 1749313928 +commit: 2e47af64a3f33d32ec1395dbd56165c4feb2bc21 ++++++ vendor.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/github.com/ProtonMail/go-crypto/openpgp/clearsign/clearsign.go new/vendor/github.com/ProtonMail/go-crypto/openpgp/clearsign/clearsign.go --- old/vendor/github.com/ProtonMail/go-crypto/openpgp/clearsign/clearsign.go 2025-05-21 15:50:24.000000000 +0200 +++ new/vendor/github.com/ProtonMail/go-crypto/openpgp/clearsign/clearsign.go 2025-06-07 18:32:08.000000000 +0200 @@ -206,7 +206,7 @@ type dashEscaper struct { buffered *bufio.Writer hashers []hash.Hash // one per key in privateKeys - hashType crypto.Hash + hashTypes []crypto.Hash toHash io.Writer // writes to all the hashes in hashers salts [][]byte // salts for the signatures if v6 armorHeader map[string]string // Armor headers @@ -328,7 +328,7 @@ sig.Version = k.Version sig.SigType = packet.SigTypeText sig.PubKeyAlgo = k.PubKeyAlgo - sig.Hash = d.hashType + sig.Hash = d.hashTypes[i] sig.CreationTime = t sig.IssuerKeyId = &k.KeyId sig.IssuerFingerprint = k.Fingerprint @@ -390,19 +390,22 @@ } hashType := config.Hash() - name := nameOfHash(hashType) - if len(name) == 0 { - return nil, errors.UnsupportedError("unknown hash type: " + strconv.Itoa(int(hashType))) - } - if !hashType.Available() { - return nil, errors.UnsupportedError("unsupported hash type: " + strconv.Itoa(int(hashType))) - } var hashers []hash.Hash + var hashTypes []crypto.Hash var ws []io.Writer var salts [][]byte for _, sk := range privateKeys { - h := hashType.New() + acceptedHashes := acceptableHashesToWrite(&sk.PublicKey) + // acceptedHashes contains at least one hash + selectedHashType := acceptedHashes[0] + for _, acceptedHash := range acceptedHashes { + if hashType == acceptedHash { + selectedHashType = hashType + break + } + } + h := selectedHashType.New() if sk.Version == 6 { // generate salt var salt []byte @@ -416,6 +419,7 @@ salts = append(salts, salt) } hashers = append(hashers, h) + hashTypes = append(hashTypes, selectedHashType) ws = append(ws, h) } toHash := io.MultiWriter(ws...) @@ -432,11 +436,8 @@ nonV6 := len(salts) < len(hashers) // Crypto refresh: Headers SHOULD NOT be emitted if nonV6 { // Emit header if non v6 signatures are present for compatibility - if _, err = buffered.WriteString(fmt.Sprintf("%s: %s", hashHeader, name)); err != nil { - return - } - if err = buffered.WriteByte(lf); err != nil { - return + if err := writeHashHeader(buffered, hashTypes); err != nil { + return nil, err } } if err = buffered.WriteByte(lf); err != nil { @@ -446,7 +447,7 @@ plaintext = &dashEscaper{ buffered: buffered, hashers: hashers, - hashType: hashType, + hashTypes: hashTypes, toHash: toHash, salts: salts, armorHeader: headers, @@ -470,6 +471,40 @@ return } +// writeHashHeader writes the legacy cleartext hash header to buffered. +func writeHashHeader(buffered *bufio.Writer, hashTypes []crypto.Hash) error { + seen := make(map[string]bool, len(hashTypes)) + if _, err := buffered.WriteString(fmt.Sprintf("%s: ", hashHeader)); err != nil { + return err + } + + for index, sigHashType := range hashTypes { + first := index == 0 + name := nameOfHash(sigHashType) + if len(name) == 0 { + return errors.UnsupportedError("unknown hash type: " + strconv.Itoa(int(sigHashType))) + } + + switch { + case !seen[name] && first: + if _, err := buffered.WriteString(name); err != nil { + return err + } + case !seen[name]: + if _, err := buffered.WriteString(fmt.Sprintf(",%s", name)); err != nil { + return err + } + } + seen[name] = true + } + + if err := buffered.WriteByte(lf); err != nil { + return err + } + + return nil +} + // nameOfHash returns the OpenPGP name for the given hash, or the empty string // if the name isn't known. See RFC 4880, section 9.4. func nameOfHash(h crypto.Hash) string { @@ -489,3 +524,38 @@ } return "" } + +func acceptableHashesToWrite(singingKey *packet.PublicKey) []crypto.Hash { + switch singingKey.PubKeyAlgo { + case packet.PubKeyAlgoEd448: + return []crypto.Hash{ + crypto.SHA512, + crypto.SHA3_512, + } + case packet.PubKeyAlgoECDSA, packet.PubKeyAlgoEdDSA: + if curve, err := singingKey.Curve(); err == nil { + if curve == packet.Curve448 || + curve == packet.CurveNistP521 || + curve == packet.CurveBrainpoolP512 { + return []crypto.Hash{ + crypto.SHA512, + crypto.SHA3_512, + } + } else if curve == packet.CurveBrainpoolP384 || + curve == packet.CurveNistP384 { + return []crypto.Hash{ + crypto.SHA384, + crypto.SHA512, + crypto.SHA3_512, + } + } + } + } + return []crypto.Hash{ + crypto.SHA256, + crypto.SHA384, + crypto.SHA512, + crypto.SHA3_256, + crypto.SHA3_512, + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go new/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go --- old/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go 2025-05-21 15:50:24.000000000 +0200 +++ new/vendor/github.com/ProtonMail/go-crypto/openpgp/errors/errors.go 2025-06-07 18:32:08.000000000 +0200 @@ -180,6 +180,16 @@ return "openpgp: malformed message " + string(dke) } +type messageTooLargeError int + +func (e messageTooLargeError) Error() string { + return "openpgp: decompressed message size exceeds provided limit" +} + +// ErrMessageTooLarge is returned if the read data from +// a compressed packet exceeds the provided limit. +var ErrMessageTooLarge error = messageTooLargeError(0) + // ErrEncryptionKeySelection is returned if encryption key selection fails (v2 API). type ErrEncryptionKeySelection struct { PrimaryKeyId string diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go new/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go --- old/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go 2025-05-21 15:50:24.000000000 +0200 +++ new/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/compressed.go 2025-06-07 18:32:08.000000000 +0200 @@ -98,6 +98,16 @@ return err } +// LimitedBodyReader wraps the provided body reader with a limiter that restricts +// the number of bytes read to the specified limit. +// If limit is nil, the reader is unbounded. +func (c *Compressed) LimitedBodyReader(limit *int64) io.Reader { + if limit == nil { + return c.Body + } + return &LimitReader{R: c.Body, N: *limit} +} + // compressedWriterCloser represents the serialized compression stream // header and the compressor. Its Close() method ensures that both the // compressor and serialized stream header are closed. Its Write() @@ -159,3 +169,24 @@ return } + +// LimitReader is an io.Reader that fails with MessageToLarge if read bytes exceed N. +type LimitReader struct { + R io.Reader // underlying reader + N int64 // max bytes allowed +} + +func (l *LimitReader) Read(p []byte) (int, error) { + if l.N <= 0 { + return 0, errors.ErrMessageTooLarge + } + + n, err := l.R.Read(p) + l.N -= int64(n) + + if err == nil && l.N <= 0 { + err = errors.ErrMessageTooLarge + } + + return n, err +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go new/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go --- old/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go 2025-05-21 15:50:24.000000000 +0200 +++ new/vendor/github.com/ProtonMail/go-crypto/openpgp/packet/config.go 2025-06-07 18:32:08.000000000 +0200 @@ -178,6 +178,11 @@ // When set to true, a key without flags is treated as if all flags are enabled. // This behavior is consistent with GPG. InsecureAllowAllKeyFlagsWhenMissing bool + + // MaxDecompressedMessageSize specifies the maximum number of bytes that can be + // read from a compressed packet. This serves as an upper limit to prevent + // excessively large decompressed messages. + MaxDecompressedMessageSize *int64 } func (c *Config) Random() io.Reader { @@ -415,6 +420,13 @@ return c.InsecureAllowAllKeyFlagsWhenMissing } +func (c *Config) DecompressedMessageSizeLimit() *int64 { + if c == nil { + return nil + } + return c.MaxDecompressedMessageSize +} + // BoolPointer is a helper function to set a boolean pointer in the Config. // e.g., config.CheckPacketSequence = BoolPointer(true) func BoolPointer(value bool) *bool { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go new/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go --- old/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go 2025-05-21 15:50:24.000000000 +0200 +++ new/vendor/github.com/ProtonMail/go-crypto/openpgp/read.go 2025-06-07 18:32:08.000000000 +0200 @@ -259,7 +259,7 @@ } switch p := p.(type) { case *packet.Compressed: - if err := packets.Push(p.Body); err != nil { + if err := packets.Push(p.LimitedBodyReader(config.DecompressedMessageSizeLimit())); err != nil { return nil, err } case *packet.OnePassSignature: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go new/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go --- old/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go 2025-05-21 15:50:24.000000000 +0200 +++ new/vendor/github.com/ProtonMail/go-crypto/openpgp/write.go 2025-06-07 18:32:08.000000000 +0200 @@ -253,34 +253,12 @@ } var hash crypto.Hash - for _, hashId := range candidateHashes { - if h, ok := algorithm.HashIdToHash(hashId); ok && h.Available() { - hash = h - break - } - } - - // If the hash specified by config is a candidate, we'll use that. - if configuredHash := config.Hash(); configuredHash.Available() { - for _, hashId := range candidateHashes { - if h, ok := algorithm.HashIdToHash(hashId); ok && h == configuredHash { - hash = h - break - } - } - } - - if hash == 0 { - hashId := candidateHashes[0] - name, ok := algorithm.HashIdToString(hashId) - if !ok { - name = "#" + strconv.Itoa(int(hashId)) - } - return nil, errors.InvalidArgumentError("cannot encrypt because no candidate hash functions are compiled in. (Wanted " + name + " in this case.)") - } - var salt []byte if signer != nil { + if hash, err = selectHash(candidateHashes, config.Hash(), signer); err != nil { + return nil, err + } + var opsVersion = 3 if signer.Version == 6 { opsVersion = signer.Version @@ -558,13 +536,34 @@ return s.encryptedData.Close() } +func selectHashForSigningKey(config *packet.Config, signer *packet.PublicKey) crypto.Hash { + acceptableHashes := acceptableHashesToWrite(signer) + hash, ok := algorithm.HashToHashId(config.Hash()) + if !ok { + return config.Hash() + } + for _, acceptableHashes := range acceptableHashes { + if acceptableHashes == hash { + return config.Hash() + } + } + if len(acceptableHashes) > 0 { + defaultAcceptedHash, ok := algorithm.HashIdToHash(acceptableHashes[0]) + if ok { + return defaultAcceptedHash + } + } + return config.Hash() +} + func createSignaturePacket(signer *packet.PublicKey, sigType packet.SignatureType, config *packet.Config) *packet.Signature { sigLifetimeSecs := config.SigLifetime() + hash := selectHashForSigningKey(config, signer) return &packet.Signature{ Version: signer.Version, SigType: sigType, PubKeyAlgo: signer.PubKeyAlgo, - Hash: config.Hash(), + Hash: hash, CreationTime: config.Now(), IssuerKeyId: &signer.KeyId, IssuerFingerprint: signer.Fingerprint, @@ -618,3 +617,74 @@ } return data, nil } + +// selectHash selects the preferred hash given the candidateHashes and the configuredHash +func selectHash(candidateHashes []byte, configuredHash crypto.Hash, signer *packet.PrivateKey) (hash crypto.Hash, err error) { + acceptableHashes := acceptableHashesToWrite(&signer.PublicKey) + candidateHashes = intersectPreferences(acceptableHashes, candidateHashes) + + for _, hashId := range candidateHashes { + if h, ok := algorithm.HashIdToHash(hashId); ok && h.Available() { + hash = h + break + } + } + + // If the hash specified by config is a candidate, we'll use that. + if configuredHash.Available() { + for _, hashId := range candidateHashes { + if h, ok := algorithm.HashIdToHash(hashId); ok && h == configuredHash { + hash = h + break + } + } + } + + if hash == 0 { + if len(acceptableHashes) > 0 { + if h, ok := algorithm.HashIdToHash(acceptableHashes[0]); ok { + hash = h + } else { + return 0, errors.UnsupportedError("no candidate hash functions are compiled in.") + } + } else { + return 0, errors.UnsupportedError("no candidate hash functions are compiled in.") + } + } + return +} + +func acceptableHashesToWrite(singingKey *packet.PublicKey) []uint8 { + switch singingKey.PubKeyAlgo { + case packet.PubKeyAlgoEd448: + return []uint8{ + hashToHashId(crypto.SHA512), + hashToHashId(crypto.SHA3_512), + } + case packet.PubKeyAlgoECDSA, packet.PubKeyAlgoEdDSA: + if curve, err := singingKey.Curve(); err == nil { + if curve == packet.Curve448 || + curve == packet.CurveNistP521 || + curve == packet.CurveBrainpoolP512 { + return []uint8{ + hashToHashId(crypto.SHA512), + hashToHashId(crypto.SHA3_512), + } + } else if curve == packet.CurveBrainpoolP384 || + curve == packet.CurveNistP384 { + return []uint8{ + hashToHashId(crypto.SHA384), + hashToHashId(crypto.SHA512), + hashToHashId(crypto.SHA3_512), + } + } + } + } + return []uint8{ + hashToHashId(crypto.SHA256), + hashToHashId(crypto.SHA384), + hashToHashId(crypto.SHA512), + hashToHashId(crypto.SHA3_256), + hashToHashId(crypto.SHA3_512), + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/modules.txt new/vendor/modules.txt --- old/vendor/modules.txt 2025-05-21 15:50:24.000000000 +0200 +++ new/vendor/modules.txt 2025-06-07 18:32:08.000000000 +0200 @@ -23,7 +23,7 @@ github.com/Microsoft/go-winio/internal/socket github.com/Microsoft/go-winio/internal/stringbuffer github.com/Microsoft/go-winio/pkg/guid -# github.com/ProtonMail/go-crypto v1.2.0 +# github.com/ProtonMail/go-crypto v1.3.0 ## explicit; go 1.22.0 github.com/ProtonMail/go-crypto/bitcurves github.com/ProtonMail/go-crypto/brainpool @@ -178,7 +178,7 @@ # github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 ## explicit; go 1.20 github.com/golang/groupcache/lru -# github.com/google/rpmpack v0.6.1-0.20250405124433-758cc6896cbc +# github.com/google/rpmpack v0.7.0 ## explicit; go 1.18 github.com/google/rpmpack # github.com/google/uuid v1.6.0