summary refs log tree commit diff
path: root/pkgs/common-updater
diff options
context:
space:
mode:
authorJosé Romildo Malaquias <malaquias@gmail.com>2020-04-13 17:57:30 -0300
committerJosé Romildo Malaquias <malaquias@gmail.com>2020-04-15 09:45:25 -0300
commit827a6619eb7732b9b9e823fd8f120d2c78394f33 (patch)
treeb07fd730115da18c1d32089e66f7c205ecda11d1 /pkgs/common-updater
parenta772bc6eaefbcf2fa387105703c3c6b763c3695c (diff)
downloadnixpkgs-827a6619eb7732b9b9e823fd8f120d2c78394f33.tar
nixpkgs-827a6619eb7732b9b9e823fd8f120d2c78394f33.tar.gz
nixpkgs-827a6619eb7732b9b9e823fd8f120d2c78394f33.tar.bz2
nixpkgs-827a6619eb7732b9b9e823fd8f120d2c78394f33.tar.lz
nixpkgs-827a6619eb7732b9b9e823fd8f120d2c78394f33.tar.xz
nixpkgs-827a6619eb7732b9b9e823fd8f120d2c78394f33.tar.zst
nixpkgs-827a6619eb7732b9b9e823fd8f120d2c78394f33.zip
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
Diffstat (limited to 'pkgs/common-updater')
-rw-r--r--pkgs/common-updater/scripts.nix4
-rwxr-xr-xpkgs/common-updater/scripts/list-archive-two-level-versions35
-rwxr-xr-xpkgs/common-updater/scripts/list-git-tags32
-rw-r--r--pkgs/common-updater/update-script.nix98
4 files changed, 167 insertions, 2 deletions
diff --git a/pkgs/common-updater/scripts.nix b/pkgs/common-updater/scripts.nix
index ec897914b6b..655924e5f28 100644
--- a/pkgs/common-updater/scripts.nix
+++ b/pkgs/common-updater/scripts.nix
@@ -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
   '';
 }
diff --git a/pkgs/common-updater/scripts/list-archive-two-level-versions b/pkgs/common-updater/scripts/list-archive-two-level-versions
new file mode 100755
index 00000000000..e46652820ad
--- /dev/null
+++ b/pkgs/common-updater/scripts/list-archive-two-level-versions
@@ -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
diff --git a/pkgs/common-updater/scripts/list-git-tags b/pkgs/common-updater/scripts/list-git-tags
new file mode 100755
index 00000000000..ff09671c7cb
--- /dev/null
+++ b/pkgs/common-updater/scripts/list-git-tags
@@ -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"
diff --git a/pkgs/common-updater/update-script.nix b/pkgs/common-updater/update-script.nix
new file mode 100644
index 00000000000..8e8153d9a33
--- /dev/null
+++ b/pkgs/common-updater/update-script.nix
@@ -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 ]