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="$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,^.*,\1,p') + +# print available versions +for tag in $tags1; do + tags2=$(curl -sS "$archive/$tag/") + tags2=$(echo "$tags2" | sed -rne "s,^.*,\\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 [ []]" +} + +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 ]