common-updater-scripts: add scripts to help update packages

- updateScript:
  A nix expression that can be used in passThrough to update a package

- list-git-tags:
  A shell script to list available tags in a git repository

- list-archive-two-level-versions:

  A shell script to list available versions in a web site in two
  levels: there is a page listing the available major.minor versions,
  and for each of them there is another page listings the patch level
  versions major.minor.patch.

  It is suitable for Xfce packages for instance.

How the updater works:

1. collect the available versions from the source repository (using a
script given as argument)

2. print the collected versions (for debugging)

3. (optionally) apply some transformation to the collected versions to
make them compatible with the versions used in nixpkgs (for instance,
tags in the Xfce git repository may be prefixed with the package name,
and the prefix need to be removed)

4. sort the available versions in decreasing order

5. choose the first version that pass validation:
   - check if the version may be a development version

   - if the version IS unstable, skip it and give a warning about
   skipping a development version (for debugging)

   - if the version COULD BE unstable, take it and give a warning
   about taking a potential development version (for debugging)

   - if the version IS stable, take it

6. update the package version and checksum in its nix expression

7. print the git commands for adding the modified files and for
committing the changes
This commit is contained in:
José Romildo Malaquias 2020-04-13 17:57:30 -03:00
parent a772bc6eae
commit 827a6619eb
4 changed files with 167 additions and 2 deletions

View file

@ -1,4 +1,4 @@
{ stdenv, makeWrapper, coreutils, gnused, gnugrep, diffutils, nix }:
{ stdenv, makeWrapper, coreutils, gnused, gnugrep, diffutils, nix, git }:
stdenv.mkDerivation {
name = "common-updater-scripts";
@ -12,7 +12,7 @@ stdenv.mkDerivation {
cp ${./scripts}/* $out/bin
for f in $out/bin/*; do
wrapProgram $f --prefix PATH : ${stdenv.lib.makeBinPath [ coreutils gnused gnugrep nix diffutils ]}
wrapProgram $f --prefix PATH : ${stdenv.lib.makeBinPath [ coreutils gnused gnugrep nix diffutils git ]}
done
'';
}

View file

@ -0,0 +1,35 @@
#! /bin/sh
# lists all available versions listed for a package in a site (http)
scriptName=list-archive-two-level-versions # do not use the .wrapped name
usage() {
echo "Usage: $scriptName <archive url> [<package name> [<debug file path>]]"
}
archive="$1" # archive url
pname="$2" # package name
file="$3" # file for writing debugging information
if [ -z "$archive" ]; then
echo "$scriptName: Missing archive url"
usage
exit 1
fi
# print a debugging message
if [ -n "$file" ]; then
echo "# Listing versions for $pname at $archive" >> $file
fi
# list all major-minor versions from archive
tags1=$(curl -sS "$archive/")
tags1=$(echo "$tags1" | sed -rne 's,^<a href="([0-9]+\.[0-9]+)/">.*,\1,p')
# print available versions
for tag in $tags1; do
tags2=$(curl -sS "$archive/$tag/")
tags2=$(echo "$tags2" | sed -rne "s,^<a href=\"$pname-([0-9.]+)\\.[^0-9].*\">.*,\\1,p")
echo "$tags2"
done

View file

@ -0,0 +1,32 @@
#! /bin/sh -x
# lists all available tags from a git repository
scriptName=list-git-tags # do not use the .wrapped name
usage() {
echo "Usage: $scriptName <repository url> [<package name> [<debug file path>]]"
}
repo="$1" # git repository url
pname="$2" # package name
file="$3" # file for writing debugging information
if [ -z "$repo" ]; then
echo "$scriptName: Missing git repository url"
usage
exit 1
fi
# print a debugging message
if [ -n "$file" ]; then
echo "# Listing tags for $pname at $repo" >> $file
fi
# list all tags from the remote repository
tags=$(git ls-remote --tags --refs "$repo")
# keep only the version part of the tag
tags=$(echo "$tags" | cut --delimiter=/ --field=3)
echo "$tags"

View file

@ -0,0 +1,98 @@
{ stdenv, writeScript, coreutils, gnugrep, gnused, common-updater-scripts, nix }:
{ pname
, version
, attrPath ? pname
, versionLister
, rev-prefix ? ""
, odd-unstable ? true
, patchlevel-unstable ? true
}:
let
# where to print git commands and debugging messages
fileForGitCommands = "update-git-commits.txt";
# shell script to update package
updateScript = writeScript "update-script.sh" ''
#! ${stdenv.shell}
set -o errexit
set -x
pname="$1"
version="$2"
attr_path="$3"
version_lister="$4"
rev_prefix="$5"
odd_unstable="$6"
patchlevel_unstable="$7"
# print header
echo "# $pname-$version" >> ${fileForGitCommands}
function version_is_unstable() {
local tag="$1"
local enforce="$2"
if [ -n "$odd_unstable" -o -n "$enforce" ]; then
local minor=$(echo "$tag" | ${gnused}/bin/sed -rne 's,^[0-9]+\.([0-9]+).*,\1,p')
if [ $((minor % 2)) -eq 1 ]; then
return 0
fi
fi
if [ -n "$patchlevel_unstable" -o -n "$enforce" ]; then
local patchlevel=$(echo "$tag" | ${gnused}/bin/sed -rne 's,^[0-9]+\.[0-9]+\.([0-9]+).*$,\1,p')
if ((patchlevel >= 90)); then
return 0
fi
fi
return 1
}
tags=$($version_lister $pname ${fileForGitCommands}) || exit 1
# print available tags
for tag in $tags; do
echo "# found $pname version: $tag" >> ${fileForGitCommands}
done
# cut any revision prefix not used in the NixOS package version
if [ -n "$rev_prefix" ]; then
tags=$(echo "$tags" | ${gnugrep}/bin/grep "^$rev_prefix")
tags=$(echo "$tags" | ${gnused}/bin/sed -e "s,^$rev_prefix,,")
fi
tags=$(echo "$tags" | ${gnugrep}/bin/grep "^[0-9]")
# sort the tags in decreasing order
tags=$(echo "$tags" | ${coreutils}/bin/sort --reverse --version-sort)
# find the newest tag
# do not consider development versions
for latest_tag in $tags; do
if version_is_unstable "$latest_tag"; then
echo "# skip development version: $pname-$latest_tag" >> ${fileForGitCommands}
latest_tag=
else
if version_is_unstable "$latest_tag" "enforce"; then
echo "# use potential development version: $pname-$latest_tag" >> ${fileForGitCommands}
fi
break
fi
done
if [ -n "$latest_tag" ]; then
# print commands to commit the changes
if [ "$version" != "$latest_tag" ]; then
pfile=$(EDITOR=echo ${nix}/bin/nix edit -f. "$attr_path")
echo " git add $pfile " >> ${fileForGitCommands}
echo " git commit -m '$attr_path: $version -> $latest_tag'" >> ${fileForGitCommands}
fi
# update the nix expression
${common-updater-scripts}/bin/update-source-version "$attr_path" "$latest_tag"
fi
echo "" >> ${fileForGitCommands}
'';
in
[ updateScript pname version attrPath versionLister rev-prefix odd-unstable patchlevel-unstable ]