#1295 [DRAFT] Document %forgeversion and new repository location
Opened 10 months ago by gotmax23. Modified 10 months ago
gotmax23/packaging-committee forgeversion  into  master

@@ -5,7 +5,7 @@ 

  # https://github.com/GoogleCloudPlatform/google-cloud-go

  %global goipath         cloud.google.com/go

  %global forgeurl        https://github.com/GoogleCloudPlatform/google-cloud-go

- Version:                0.37.4

+ %global version0        0.37.4

  

  %gometa

  
@@ -23,6 +23,7 @@ 

  %global godocs          AUTHORS CODE_OF_CONDUCT.md CONTRIBUTING.md CONTRIBUTORS RELEASING.md old-news.md CHANGES.md README.md

  

  Name:           %{goname}

+ Version:        %{forgeversion}

  Release:        1%{?dist}

  Summary:        Google Cloud client libraries for Go

  

@@ -1,6 +1,6 @@ 

  # https://github.com/sirupsen/logrus

  %global goipath         github.com/sirupsen/logrus

- Version:                1.4.0

+ %global version0        1.4.0

  

  %gometa

  
@@ -14,6 +14,7 @@ 

  %global godocs        *.md

  

  Name:           %{goname}

+ Version:        %{forgeversion}

  Release:        1%{?dist}

  Summary:        Structured logger for Go

  License:        MIT

@@ -1,6 +1,6 @@ 

  # https://github.com/stretchr/testify

  %global goipath         github.com/stretchr/testify

- Version:                1.2.2

+ %global version0        1.2.2

  

  %gometa

  
@@ -17,6 +17,7 @@ 

  %global golicenses    LICENSE

  

  Name:           %{goname}

+ Version:        %{forgeversion}

  Release:        1%{?dist}

  Summary:        Tools for testifying that your code will behave as you intend

  License:        MIT

@@ -1,7 +1,7 @@ 

  # https://github.com/square/go-jose

  %global goipath         gopkg.in/square/go-jose.v2

  %global forgeurl        https://github.com/square/go-jose

- Version:                2.1.9

+ %global version0        2.1.9

  

  %gometa

  
@@ -19,6 +19,7 @@ 

  }

  

  Name:           %{goname}

+ Version:        %{forgeversion}

  Release:        1%{?dist}

  Summary:        An implementation of JOSE standards (JWE, JWS, JWT) in Go

  # Detected licences

@@ -25,9 +25,10 @@ 

  #  – define “forgeurl”, including “https://” prefixing, if the import path

  #    does not match the repository URL; otherwise it is not necessary,

  %global forgeurl 

- #  – move the Version: line before the “gometa” call if you are packaging a

- #    release.

- Version:         

+ # The version to use for %%forgeversion.

+ # Set to 0 if packaging a git snapshot for a project with no releases.

+ # Set to an actual version if packaging a release or a pre/post release snapshot

+ %global version0

  %global tag      

  %global commit   

  #
@@ -55,8 +56,7 @@ 

  # and you understand the consequences. Otherwise you will just add

  # maintenance-intensive discrepancies in the distribution.

  Name:    %{goname}

- # If not set before

- Version: 

+ Version: %{forgeversion}

  Release: 1%{?dist}

  Summary: 

  URL:     %{gourl}

@@ -7,7 +7,7 @@ 

  # overlaps. Try to read them all.

  #

  %global goipath  

- Version:         

+ %global version0

  %global tag      

  %global commit   

  #
@@ -75,8 +75,7 @@ 

  }

  

  Name:    %{goname}

- # If not set before

- Version: 

+ Version: %{forgeversion}

  Release: 1%{?dist}

  Summary: 

  URL:     %{gourl}

@@ -18,7 +18,7 @@ 

  # fixed to use the new name as soon as possible.

  #

  %global goipath  

- Version:         

+ %global version0

  %global tag      

  %global commit   

  %gometa
@@ -34,8 +34,7 @@ 

  }

  

  Name:    %{goname}

- # If not set before

- Version: 

+ Version: %{forgeversion}

  Release: 1%{?dist}

  Summary: 

  URL:     %{gourl}

@@ -8,7 +8,7 @@ 

  #

  %global goipath  

  %global forgeurl 

- Version:         

+ %global version0

  %global tag      

  %global commit   

  %global gocid    
@@ -60,8 +60,7 @@ 

  }

  

  Name:    %{goname}

- # If not set before

- Version: 

+ Version: %{forgeversion}

  Release: 1%{?dist}

  Summary: 

  URL:     %{gourl}

@@ -12,7 +12,7 @@ 

  # requires more manual work.

  #

  %global goipath  

- Version:         

+ %global version0

  %global tag      

  %global commit   

  %gometa
@@ -34,7 +34,7 @@ 

  # package instead of “goname”. Separate built binaries in different subpackages

  # if needed.

  Name:    %{goname}

- Version: 

+ Version: %{forgeversion}

  Release: 1%{?dist}

  Summary: 

  URL:     %{gourl}

@@ -8,7 +8,7 @@ 

  #

  %global goipath  

  %global forgeurl 

- Version:         

+ %global version0

  %global tag      

  %global commit   

  %global gocid    
@@ -50,8 +50,7 @@ 

  

  

  Name:    %{goname}

- # If not set before

- Version: 

+ Version: %{forgeversion}

  Release: 1%{?dist}

  Summary: 

  URL:     %{gourl}

@@ -18,7 +18,7 @@ 

  # Main archive

  %global goipath0  

  %global forgeurl0 

- Version:          

+ %global version0

  %global tag0      

  %global commit0   

  %global gocid0    
@@ -120,8 +120,7 @@ 

  

  # Use usual naming rules when generating binaries.

  Name:    %{goname}

- # If not set before

- Version: 

+ Version: %{forgeversion -a}

  Release: 1%{?dist}

  Summary: 

  URL:	 %{gourl}

@@ -10,7 +10,7 @@ 

  #

  %global goipath  

  %global forgeurl 

- Version:         

+ %global version0

  %global tag      

  %global commit   

  %gometa
@@ -23,8 +23,7 @@ 

  }

  

  Name:    %{goname}

- # If not set before

- Version: 

+ Version: %{forgeversion}

  Release: 1%{?dist}

  Summary: 

  URL:     %{gourl}

@@ -9,6 +9,10 @@ 

  #

  # The branch being packaged

  %global branch   

+ 

+ # The base version to use for %%forgeversion

+ %global version0

+ 

  #

  #  – use the “-i” flag to display the variables forgemeta reads and sets

  #  – use the “-v” flag if you want verbose processing
@@ -20,7 +24,7 @@ 

  # forgemeta will prepend branch information to dist. Release ordering is

  # controlled by the packager with x%{?dist}/0.x%{?dist} number chains.

  Name:    

- Version: 

+ Version: %{forgeversion}

  Release: 1%{?dist}

  Summary: 

  URL:	 %{forgeurl}

@@ -6,6 +6,12 @@ 

  #

  # The commit being packaged (when using git, a full hash)

  %global commit   

+ 

+ # The version to use for %%forgeversion.

+ # Set to 0 if packaging a git snapshot for a project with no releases.

+ # Set to an actual version if packaging a pre or post release snapshot

+ %global version0

+ 

  #

  #  – use the “-i” flag to display the variables forgemeta reads and sets

  #  – use the “-v” flag if you want verbose processing
@@ -14,10 +20,11 @@ 

  

  # The following lines use variables computed by forgemeta as default values.

  # You can replace them with manual definitions.

- # forgemeta will prepend commit information to dist. Release ordering is

- # controlled by the packager with x%{?dist}/0.x%{?dist} numbers chains.

  Name:    

- Version: 

+ # This macro appends commit version to %%{version}.

+ # Use the -p flag when packaging a pre-release or project with no releases

+ # to use `~` instead of `^`.

+ Version: %{forgeversion}

  Release: 1%{?dist}

  Summary: 

  URL:	 %{forgeurl}

@@ -21,7 +21,7 @@ 

  #

  # Main archive. In this example we package a full release

  %global forgeurl0 

- Version:          

+ %global version0

  

  # Second archive.

  %global forgeurl1 
@@ -45,6 +45,9 @@ 

  # Release ordering is controlled by the packager with x%{?dist}/0.x%{?dist}

  # numbers chains.

  Name:    

+ # Use the -a flag to append snapshot versions for the secondary projects

+ # (%%forgeurl1 and %%forgeurl2).

+ Version: %{forgeversion -a}

  Release: 1%{?dist}

  Summary: 

  URL:	 %{forgeurl0}

@@ -11,7 +11,7 @@ 

  # release objects, forgemeta will try to guess the customary way to write

  # release tags on the selected forge.

  # If it guesses wrong use the forge-tag template instead of this one.

- Version:         

+ %global version0

  #

  # forgemeta converts the suppplied rpm variables to variables that can be used

  # in the spec file. Most of those can be overriden before or after the
@@ -25,9 +25,9 @@ 

  # You can replace them with manual definitions. For example, replace forgeurl

  # with the project homepage if it exists separately from the repository URL.

  # Only replace the variables when it adds value to the spec file and you

- # understand the consequences. Release ordering is controlled by the packager

- # with x%{?dist}/0.x%{?dist} number chains.

+ # understand the consequences.

  Name:    

+ Version: %{forgeversion}

  Release: 1%{?dist}

  Summary: 

  URL:	 %{forgeurl}

@@ -6,6 +6,9 @@ 

  #

  # The tag being packaged

  %global tag      

+ 

+ # The base version to use for %%forgeversion

+ %global version0

  #

  #  – use the “-i” flag to display the variables forgemeta reads and sets

  #  – use the “-v” flag if you want verbose processing
@@ -17,7 +20,7 @@ 

  # forgemeta will prepend tag information to dist. Release ordering is

  # controlled by the packager with x%{?dist}/0.x%{?dist} numbers chains.

  Name:    

- Version: 

+ Version: %{forgeversion}

  Release: 1%{?dist}

  Summary: 

  URL:	 %{forgeurl}

@@ -28,7 +28,8 @@ 

  

  Any software publishing website, permitting the download of source archives via normalized URLs,

  that can be deduced from a project root URL and version, commit, tag, scm, extension… values is a _“forge”_

- that can be supported by the `redhat-rpm-config` `+%{forgemeta}+` macro.

+ that can be supported by the

+ https://sr.ht/~gotmax23/forge-srpm-macros[forge-srpm-macros] `+%{forgemeta}+` macro.

  Common Forge examples are _GitLab_ and _GitHub_.

  `+%{forgemeta}+` centralizes and abstracts our knowledge about those forges,

  so packagers do not have to handle download quirks manually.

This change is part of https://fedoraproject.org/wiki/Changes/Revitalize_Forge_Macros. forge-srpm-macros has not yet been imported into Fedora.

Thank you for working on this!

One thing that strikes me as slightly odd (or potentially problematic) is that you define %{version} twice (once by setting %global version, once by setting the Version: %{forgeversion} tag). It might work, but only due to a quirk of how RPM parses spec files. It might be better to use a different name for the macro rather than relying on the order in which %global version foo and Version: bar are evaluated.

Agreed with @decathorpe. I haven't looked at the macro definition for %forgeversion yet, but based on these examples i don't really understand — semantically — the purpose of how it works.

Does the %forgeversion macro depend on a global %version variable having being defined, which it will then consume? That seems like a recipe for confusion, if not disaster.

If %forgeversion is just used to append snapshot info, why not use it that way?

Version:     0.37.4%{?forgeversion}

(I'd even consider calling it something else, like %forgesnap or %forgedist.)

If the version number absolutely needs to be accessible to the macro, then why not name the variable that holds it something else?

%global pkgversion 0.37.4

Version: %forgeversion

(Either way) %version will get defined as the entire version string including the forge additions, but that's how it's supposed to work in rpm specfile code, and why other variables are often used to hold version numbers for use in things like download URLs and etc. when necessary.

Yeah, now that I've looked at both the current redhat-rpm-config-sourced macros.forge and the updated one at https://git.sr.ht/~gotmax23/forge-srpm-macros/tree/main/item/rpm/macros.d/macros.forge, I have to say that this magical (ab)use of a pre-defined global %version variable seems like a terrible idea.

The comments at the top of the file (both old and new) even say,

#   %{version<number>}   the packaged version
#                          – %{version}/%{version0} are set via:
#                              Version:
#                          – because git is lacking a built-in version
#                            reference, %{version<number>} will be translated
#                            into %{tag<number>} using unreliable heuristics;
#                            set %{tag<number>} directly if those fail

But the new code is trying to make that "set via: Version:" part no longer true, which seems like an extremely ill-advised perversion of how rpmbuild specfile processing works. This probably isn't the correct place to continue this, so I'll open an issue at https://todo.sr.ht/~gotmax23/forge-srpm-macros

I'll open an issue at https://todo.sr.ht/~gotmax23/forge-srpm-macros

Oh. Apparently I... can't do that.

Well, in addition to what I wrote above, you should also take a look at https://docs.pagure.org/fedora-infra.rpmautospec/peculiarities.html#peculiarities if you haven't already. In particular:

Package versions must be determinable from the spec file alone

Both the Koji plugin and fedpkg preprocess package spec files outside of the target build root. If the version field of a package depends on macros not defined in the spec file (directly or indirectly), this will likely result in unexpected behavior if the macros in question differ between the environment of the target and that where preprocessing happens.

...The versioning done by the forge macros may not be compatible with the new-style versioning, despite its status as the recommended approach. That's why legacy versioning is still supported for packages that have "complex version requirements", which seems to describe any forge-driven package.

There's even support in the %autorelease macro to specify additional version elements as part of the Release: field

One thing that strikes me as slightly odd (or potentially problematic) is that you define %{version} twice (once by setting %global version, once by setting the Version: %{forgeversion} tag). It might work, but only due to a quirk of how RPM parses spec files. It might be better to use a different name for the macro rather than relying on the order in which %global version foo and Version: bar are evaluated.

We could change this to suggest using %version0 instead. That's already supported by %forgemeta for reading to determine %forgesource. What do you think?

If %forgeversion is just used to append snapshot info, why not use it that way?

%forgemeta needs to know the base version of software to determine %forgesource. That's why %global version is set before the %forgemeta / %gometa invocation and then Version: %{forgeversion} is set after. %{forgeversion} contains %{version} + any snapshot information determined by %forgemeta.

If the version number absolutely needs to be accessible to the macro, then why not name the variable that holds it something else?

(Note: Some may not know this, but the forge macros support multiple %forgeurl definitions (e.g. %forgeurl1, %forgeurl2) to define multiple sources. Therefore, %version<suffix>, %commit<suffix, etc.) can be specified to correspond to each %forgeurl<suffix> block.)

We could change it to something else, but if that thing isn't defined, then the forge macros MUST fall back to reading the value from %version / %version<suffix> (whether that's set with %global version or through the Version: tag) to preserve backwards compatibility. I'm suggesting that we change %global version everywhere in this patch to %global version0, as this will require just a single code change in %forgeversion itself, but %forgemeta and %forgesource will remain the same without having to add extra fall backs and code branches. If that's undesired, I could add support for a %baseversion macro that'll behave the same as %versionand %version<suffix> currently do for the purposes of determining %forgesource.

I'll open an issue at https://todo.sr.ht/~gotmax23/forge-srpm-macros

Oh. Apparently I... can't do that.

See https://git.sr.ht/~gotmax23/forge-srpm-macros/tree/main/item/CONTRIBUTING.md#issue-reporting-and-feature-requests. We might as well continue the discussion here, though.

Both the Koji plugin and fedpkg preprocess package spec files outside of the target build root. If the version field of a package depends on macros not defined in the spec file (directly or indirectly), this will likely result in unexpected behavior if the macros in question differ between the environment of the target and that where preprocessing happens.

It really should not do that. Independent of this feature, this assumption will break if packagers start adopting any RPM features that depend on a newer version than what's available in the environment running the Koji plugin. In any case, we should wait to start recommending %{forgeversion} in the guidelines until we've backported it to stable Fedoras, as users running fedpkg srpm in rpmautospec-less packages won't be able to use this either.

The versioning done by the forge macros may not be compatible with the new-style versioning, despite its status as the recommended approach.

What makes it incompatible with new-style versioning? We're allowing packagers to opt-in to storing the same information that it'd otherwise store in %distprefix. I think this approach is better, as it makes the whole thing more explicit and removes the possibility for bugs like https://pagure.io/releng/issue/10852 that come about when %dist is redefined.

Yeah, using %{version0} for the version of the "main" package / first source URL / etc. would be better, I think. It's already supported by the forge macros and is less likely to cause confusion.

What makes it incompatible with new-style versioning?

This is likely referring to the current implementation of the forge macros without %{forgeversion}?

1 new commit added

  • Set %version0 instead of %version in forge macro examples
10 months ago

Yeah, using %{version0} for the version of the "main" package / first source URL / etc. would be better, I think. It's already supported by the forge macros and is less likely to cause confusion.

Done.

See https://git.sr.ht/~gotmax23/forge-srpm-macros/commit/f06ccd7dffe849a28f1859c4cc79d4764031339b and the latest commit in this PR.

This is likely referring to the current implementation of the forge macros without %{forgeversion}?

Yeah, that would make more sense :).

Metadata
Changes Summary 18
+2 -1
file changed
guidelines/modules/ROOT/examples/golang/golang-cloud-google-go.spec
+2 -1
file changed
guidelines/modules/ROOT/examples/golang/golang-github-sirupsen-logrus.spec
+2 -1
file changed
guidelines/modules/ROOT/examples/golang/golang-github-stretchr-testify.spec
+2 -1
file changed
guidelines/modules/ROOT/examples/golang/golang-gopkg-square-jose-2.spec
+5 -5
file changed
guidelines/modules/ROOT/examples/golang/spectemplate-go-0-source-minimal.spec
+2 -3
file changed
guidelines/modules/ROOT/examples/golang/spectemplate-go-1-source-full.spec
+2 -3
file changed
guidelines/modules/ROOT/examples/golang/spectemplate-go-2-alternative-import-path-minimal.spec
+2 -3
file changed
guidelines/modules/ROOT/examples/golang/spectemplate-go-3-alternative-import-path-full.spec
+2 -2
file changed
guidelines/modules/ROOT/examples/golang/spectemplate-go-4-binary-minimal.spec
+2 -3
file changed
guidelines/modules/ROOT/examples/golang/spectemplate-go-5-binary-full.spec
+2 -3
file changed
guidelines/modules/ROOT/examples/golang/spectemplate-go-6-multi.spec
+2 -3
file changed
guidelines/modules/ROOT/examples/golang/spectemplate-go-7-manual.spec
+5 -1
file changed
guidelines/modules/ROOT/examples/spectemplate-forge-branch.spec
+10 -3
file changed
guidelines/modules/ROOT/examples/spectemplate-forge-commit.spec
+4 -1
file changed
guidelines/modules/ROOT/examples/spectemplate-forge-multi.spec
+3 -3
file changed
guidelines/modules/ROOT/examples/spectemplate-forge-release.spec
+4 -1
file changed
guidelines/modules/ROOT/examples/spectemplate-forge-tag.spec
+2 -1
file changed
guidelines/modules/ROOT/pages/SourceURL.adoc