From Fedora Project Wiki

Line 19: Line 19:
 
=== Go code packages ===
 
=== Go code packages ===
  
==== For a dedicated source package ====
+
==== In a dedicated source package ====
 
Packages that ship Go code in ''%gopath'' should be named '''%{goname}-devel'''. If your source package is already named ''%{goname}'', that is easily achieved with:
 
Packages that ship Go code in ''%gopath'' should be named '''%{goname}-devel'''. If your source package is already named ''%{goname}'', that is easily achieved with:
 
  %package '''devel'''
 
  %package '''devel'''
Line 27: Line 27:
 
  %files '''devel'''
 
  %files '''devel'''
  
==== For a generic source package ====
+
==== In a generic source package ====
 
If your source package is named something else, you can use:
 
If your source package is named something else, you can use:
 
  %package '''-n %{goname}-devel'''
 
  %package '''-n %{goname}-devel'''
Line 35: Line 35:
 
  %files '''-n %{goname}-devel'''
 
  %files '''-n %{goname}-devel'''
  
==== When separating ====
+
==== Multiplying ====
 
And, finally, if you wish to ventilate the project Go code in multiple packages, you can compute the corresponding names with:
 
And, finally, if you wish to ventilate the project Go code in multiple packages, you can compute the corresponding names with:
 
  '''%global goname1 %gorpmname importpath1'''
 
  '''%global goname1 %gorpmname importpath1'''

Revision as of 17:00, 15 December 2017

This is an alternative proposal to PackagingDrafts/Go which does not seem to move forward anymore and does not result in the creation of quality up-to-date Go packages in Fedora.

Instead of relying on an external utility to produce verbose, difficult to understand and to update spec code, it builds the Go integration inside rpm, and factors out common tasks. It tries to limit spec content to items where the packager adds actual value, and makes it easy to adapt to upstream changes. It uses rpm facilities to auto-compute Requires and Provides. Note that Go has not standardized on a common component tool yet, therefore the auto-produced dependencies are highly granular and lacking versionning constrains.

This proposal achieves a drastic reduction of Go spec sizes, up to 90% in some cases, not counting changelog lines. It removes hundreds of high-maintenance lines per spec file. It increases quality by enabling stricter checks in the factored-out code, without relying on packagers to cut and paste the correct snippets in their spec files. It aggressively runs all the unit tests found in upstream projects. It does not try to rely on bundled Go code, to hide upstream renamings, to avoid rebasing packages when their dependencies change.

This proposal relies heavily on the Forge-hosted projects packaging automation proposal since the Go ecosystem uses almost exclusively modern software publishing services. It reuses the rpm automation of PackagingDrafts/Go when it exists, and produces compatible packages. Unlike Suse it does not try to build Go code in libraries, that may be added later.

Links

Naming

Source packages (src.rpm)

  • Packages dedicated to the furniture of Go code to other projects, with eventually some ancillary utilities, MUST use a Go-specific name derived from the upstream Go package import path. This name is automatically computed in %{goname} by %gometa.
  • Packages that provide an application such as etcd MUST be named after the application. End users do not care about the language their applications are written in.
  • Packages that provide connector code in multiple programming languages SHOULD also be named in some neutral non Go-specific way.

Go code packages

In a dedicated source package

Packages that ship Go code in %gopath should be named %{goname}-devel. If your source package is already named %{goname}, that is easily achieved with:

%package devel
…
%description devel
…
%files devel

In a generic source package

If your source package is named something else, you can use:

%package -n %{goname}-devel
…
%description -n %{goname}-devel
…
%files -n %{goname}-devel

Multiplying

And, finally, if you wish to ventilate the project Go code in multiple packages, you can compute the corresponding names with:

%global goname1 %gorpmname importpath1
…
%package -n %{goname1}-devel
…
%description -n %{goname1}-devel
…
%files -n %{goname1}-devel

%gometa uses %gorpmname to compute the main %{goname} from %{goipath}.

Do remember that for Go each directory is a package. Never separate the .go files contained in a single directory in different packages (unit tests excepted).

Note.png
%gorpmname can produce collisions
%gorpmname tries to compute human-friendly and rpm-compatible naming from Go import paths. It simplifies them, removes redundancies and common qualifiers. As a result it is possible for two different import paths to produce the same result. In that case, feel free to adjust this result manually to avoid the collision. And please report the case.

Go utilities

Ancillary Go utilities (not full applications) should be shipped in %{goname}-utils packages. The rules are the same as for %{goname}-devel packages.

Go example code

Example code is usually shipped as %doc in the corresponding %{goname}-devel package. You can also produce a separate -devel package dedicated to the example import path.

Usage

Header

A Go package is identified by its import path. A Go spec file will therefore start with the %{goipath} declaration. Don't get it wrong, it will control the behaviour of the rest of the spec file.

 %global goipath     google.golang.org/api

If you’re lucky the Internet hosting of the Go package can be automatically deduced from this variable (typically by prefixing it with https://). If that is not the case, you need to declare explicitly the hosting URL:

 %global forgeurl    https://code.googlesource.com/google-api-go-client/

If rpmbuild complains later your hosting service in unknown of %forgemeta, please extend this macro. As a workaround you can manually declare here the following variables to benefit from the rest of the automation.

  • archiveurl
  • archivename
  • forgesetupargs
  • scm (if packaging a code snapshot)

The %{forgeurl} declaration is followed by Version, %{commit} and %{tag}. Use the combination that matches your use-case. The rules are the same as in Forge-hosted packaging.

%global commit      3a1d936b7575b82197a1fea0632218dd07b1e65c
Note.png
Commits vs releases
You SHOULD package releases in priority. Please reward the projects that make an effort to identify stable code states. Only fall back to commits when the project does not release, when the release is more than six months old, or if you absolutely need one of the changes of a later commit. In the later cases please inform the project politely of the reason you needed to give up on their official releases. Promoting releases is a way to limit incompatible commit hell.

The code versioning information is followed by a clear project description that will be reused in the various rpm packages produced from this spec file.

 %global common_description %{expand:
 A human-friendly multi-line project description.}

Then you need to call the %gometa macro to put it all together

 %gometa

Its behavior is similar to %forgemeta, with some Go-specific enhancements. Like %forgemeta, it comes with an optional debugging %gometacheck helper.

Then you can declare the usual rpm headers, using the values computed by %gometa.

Name:    %{goname}     See also Go naming
Version: 0             If zero, because the project does not release. Otherwise it should have been declared before calling %gometa.
Release: 0.X%{?dist}   %gometa uses %forgemeta to compute the correct %{dist} value for snapshots.
Summary: Supplementary Google APIs Client Library for Go
License: BSD           See also Fedora licensing guidelines.
URL:     %{gourl}
Source:  %{gosource}
Note.png
“%{gourl}“ or “%{forgeurl}“ use as “URL:”
You do not have to use %{gourl} or %{forgeurl} as URL: values if the packaged project has a better customized home page. They are a convenience, nothing more.


Examples

Go packaging macros reference

Benefits and limitations