-
Notifications
You must be signed in to change notification settings - Fork 18
Description
We have several projects where we build the .spec file from some template via a script (usually called rpm/precheckin.sh, but I'm sure there are others) to account for slight differences (e.g. two packages for different device adaptations that differ only in package name and build flags, or multiple variations of the same package, etc..). This is good, but has several problems:
- We store generated files in the Git repository in addition to the template and the script
- People forget to run
precheckin.shand patch the generated (=output) files in Git, leading to problems down the line the next time the template is updated andprecheckin.shrun (I've had this at least two times, and was on the "receiving end" of this issue, meaning I had to merge back changes to generated files somebody else did into the template file) - Patches and pull/merge requests are hard to read, as the same changes appear multiple times (once in the template, and then once for every output file)
- If the list of generated files changes, either
precheckin.shhas to take care of removing the old file, or the developer has to figure out that the file isn't generated, and has to manuallygit rmthe outdated generated file (e.g. an outdated device variant is removed from being generated, then the associated output file also needs to be manually removed) - Sometimes variants are generated from a base
.specfile, making it harder to figure out which.specfile is the "template" one (e.g.precheckin.shgeneratesbar.specfromfoo.specviased -e "s/FooFoo/BarBar/g" <foo.spec >bar.spec-- one has to read and understandprecheckin.shto figure out thatbar.specis read fromfoo.spec, and thatfoo.specis used as "template" as well as "output")
I hereby propose a feature enhancement for tar_git, whereas:
- If the
.specfile is not generated, it is stored in Git like now (rpm/<packagename>.spec), nothing changes - If the
.specfile(s) is/are (to be) generated:- The generated
.specfiles SHOULD NOT be stored in Git - The template file MUST NOT end in
.spec(suggested:.spec.in, but not required, as it could theoretically be fully generated byrpm/precheckin.shwithout any template file) - There MUST be a script
rpm/precheckin.shthat is run bytar_gitusing a Bourne shell with the working directory beingrpm/(think:cd rpm && rm -f *.spec && sh precheckin.sh) after the Git checkout and that generates one or more.specfiles - The
rpm/precheckin.shscript MUST NOT assume that any.specfile exists, meaning that one cannot generate.specfile variants out of a base.specfile - the base.specfile must always be a template (e.g..spec.in) -- this is to allowrm -f rpm/*.specto remove leftover files, and to avoid situations like withbar.specgenerated fromfoo.specas described above - The
rpm/precheckin.shscript SHOULD NOT have the executable bit (+x) set and the shebang line SHOULD BE#!/bin/sh(but is ignored, as it's run withsh precheckin.shas above) - The
rpm/precheckin.shscript MUST NOT use any bash-isms, only a normal Bourne shell should be assumed - Transitional feature: If the generated
.specfile is stored in Git (as for all projects using generated.specfiles up to now), it WILL BE overwritten byrpm/precheckin.sh - If
rpm/precheckin.shexists, it is always safe to runcd rpm && rm -f *.spec && sh precheckin.sh, this way, the script doesn't have to take care of removing outdated files (e.g. when a variant for an outdated device is removed, thereby causing less.specfiles to be generated) - It is RECOMMENDED that projects that use
rpm/precheckin.shhaverpm/*.spec(like this, with the glob) in their.gitignorefiles, to avoid accidentally adding/checking in generated.specfiles during development
- The generated
This specification allows local build tools such as mb2 to be eventually extended to generate and update .spec files on demand, and also provides a consistent way for developers to generate/update the .spec files manually (cd rpm && sh precheckin.sh).
In short:
- If
rpm/precheckin.shexists, any tooling or developer should assume that it/he/she needs to firstrm rpm/*.specand then runsh precheckin.sh(inside therpm/directory as working directory) before the list of.specfiles is up to date and before any package building can take place. Any change in the source directory - even outside ofrpm/- should cause a re-run ofrpm/precheckin.sh, as theprecheckin.shscript might parse source code files to obtain values used in the.specfile --tar_gitwill run this script after checkout
Or in code (assume fail is a function that prints the error message and then exits with non-zero exit status):
# Right after checkout (tar_git) OR just before build (mb2 / manual build)
if [ -f rpm/precheckin.sh ]; then
cd rpm
rm -f *.spec
sh precheckin.sh || fail "Could not generate .spec files with precheckin.sh"
cd ..
fi
Advantages that this gives us:
- We don't store redundant/generated files in Git
- Generated files will always be up to date
- We avoid users editing generated files and forgetting to update the templates
- There is a single, documented and simple way of generating
.specfiles - Less frustration, more automation, consistency and fun(!)
Possible transitional disadvantages (= yes, we can't have nice things, there's a transitional cost):
- Some existing
precheckin.shscripts might assume that they are run from the project root - Some existing
precheckin.shmight require parameters, these need to be fixed - We need to educate developers how to use the new feature, and fix existing packaging