Change:
say in no uncertain terms "The version attribute must start with a digit". however, a very large number of packages do not follow this naming guideline. almost all of these have a version starting with . on one occasion i was even instructed to change a version starting with a digit to a version starting with either common practice is wrong, or the documentation is wrong. my suggested fix would be to tweak the documentation to match common practice: versions must begin with a number, or the string followed by a YYYY-MM-DD date. Add a :+1: [reaction] to [issues you find important]. [reaction]: [issues you find important]:
Should be fixed by

Discussion:
{ lib <del> , writeShellScript </del> <ins> , writeShellApplication </ins> , coreutils , git , nix

# commit. { url ? null # The git url, if empty it will be set to src.gitRepoUrl , branch ? null <del> , stableVersion ? false # Use version format according to RFC 107 (i.e. LAST_TAG+date=YYYY-MM-DD) , tagPrefix ? "" # strip this prefix from a tag name when using stable version </del> <ins> , hardcodeZeroVersion ? false # Use a made-up version "0" instead of latest tag. Use when there is no previous release, or the project's tagging system is incompatible with what we expect from versions , tagFormat ? "*" # A `git describe --tags --match '<format>'` pattern that tags must match to be considered , tagPrefix ? null # strip this prefix from a tag name , tagConverter ? null # A command to convert more complex tag formats. It receives the git tag via stdin and should convert it into x.y.z format to stdout </ins> , shallowClone ? true }: <ins> assert lib.asserts.assertMsg (tagPrefix == null || tagConverter == null) "Can only use either tagPrefix or tagConverter!"; </ins> let <del> updateScript = writeShellScript "unstable-update-script.sh" '' set -ex </del> <ins> updateScript = writeShellApplication { name = "unstable-update-script"; runtimeInputs = [ common-updater-scripts coreutils git nix ]; text = '' set -ex url="" branch="" hardcode_zero_version="" tag_format="" tag_prefix="" tag_converter="" shallow_clone="" : "''${systemArg:=}" </ins> <del> url="" branch="" use_stable_version="" tag_prefix="" shallow_clone="" </del> <ins> while (( $# > 0 )); do flag="$1" shift 1 case "$flag" in --url=*) url="''${flag#*=}" ;; --branch=*) branch="''${flag#*=}" ;; --hardcode-zero-version) hardcode_zero_version=1 ;; --tag-format=*) tag_format="''${flag#*=}" ;; --tag-prefix=*) tag_prefix="''${flag#*=}" ;; --tag-converter=*) tag_converter="''${flag#*=}" ;; --shallow-clone) shallow_clone=1 ;; *) echo "$0: unknown option ‘''${flag}’" exit 1 ;; esac done </ins> <del> while (( $# > 0 )); do flag="$1" shift 1 case "$flag" in --url=*) url="''${flag#*=}" ;; --branch=*) branch="''${flag#*=}" ;; --use-stable-version) use_stable_version=1 ;; --tag-prefix=*) tag_prefix="''${flag#*=}" ;; --shallow-clone) shallow_clone=1 ;; *) echo "$0: unknown option ‘''${flag}’" exit 1 ;; esac done </del> <ins> # By default we set url to src.gitRepoUrl if [[ -z "$url" ]]; then # system argument cannot be passed as 1 argument # shellcheck disable=SC2086 url="$(nix-instantiate $systemArg --eval -E  "with import ./. {}; $UPDATE_NIX_ATTR_PATH.src.gitRepoUrl"  | tr -d '"')" fi </ins> <del> # By default we set url to src.gitRepoUrl if [[ -z "$url" ]]; then url="$(${nix}/bin/nix-instantiate $systemArg --eval -E  "with import ./. {}; $UPDATE_NIX_ATTR_PATH.src.gitRepoUrl"  | tr -d '"')" fi </del> <ins> # Get info about HEAD from a shallow git clone tmpdir="$(mktemp -d)" </ins> <del> # Get info about HEAD from a shallow git clone tmpdir="$(${coreutils}/bin/mktemp -d)" </del> <ins> cloneArgs=() </ins> <del> cloneArgs=( --bare ) </del> <ins> if [[ "$shallow_clone" == "1" ]]; then cloneArgs+=(--depth=1) fi </ins> <del> if [[ "$shallow_clone" == "1" ]]; then cloneArgs+=(--depth=1) fi </del> <ins> if [[ -n "$branch" ]]; then cloneArgs+=(--branch="$branch") fi </ins> <del> if [[ -n "$branch" ]]; then cloneArgs+=(--branch="$branch") fi </del> <ins> git clone "''${cloneArgs[@]}" "$url" "$tmpdir" getLatestVersion() { git describe --tags --abbrev=0 --match "''${tag_format}" 2> /dev/null || true } </ins> <del> ${git}/bin/git clone "''${cloneArgs[@]}" "$url" "$tmpdir" </del> <ins> pushd "$tmpdir" commit_date="$(git show -s --pretty='format:%cs')" commit_sha="$(git show -s --pretty='format:%H')" last_tag="" if [[ -z "$hardcode_zero_version" ]]; then if [[ "$shallow_clone" == "1" ]]; then depth=100 while (( depth < 10000 )); do last_tag="$(getLatestVersion)" if [[ -n "$last_tag" ]]; then break fi git fetch --depth="$depth" --tags depth=$(( depth * 2 )) done </ins> <del> pushd "$tmpdir" commit_date="$(${git}/bin/git show -s --pretty='format:%cs')" commit_sha="$(${git}/bin/git show -s --pretty='format:%H')" if [[ -z "$use_stable_version" ]]; then new_version="unstable-$commit_date" else depth=100 while (( $depth < 10000 )); do last_tag="$(${git}/bin/git describe --tags --abbrev=0 2> /dev/null || true)" if [[ -n "$last_tag" ]]; then break fi ${git}/bin/git fetch --depth="$depth" --tags depth=$(( $depth * 2 )) done if [[ -z "$last_tag" ]]; then echo "Cound not found a tag within last 10000 commits" > /dev/stderr exit 1 fi if [[ -n "$tag_prefix" ]]; then last_tag="''${last_tag#$tag_prefix}" fi new_version="$last_tag+date=$commit_date" fi popd # ${coreutils}/bin/rm -rf "$tmpdir" </del> <ins> if [[ -z "$last_tag" ]]; then # To be extra sure, check if full history helps with finding a tag git fetch --tags last_tag="$(getLatestVersion)" fi else last_tag="$(getLatestVersion)" fi if [[ -z "$last_tag" ]]; then last_tag="0" fi if [[ -n "$tag_prefix" ]]; then echo "Stripping prefix '$tag_prefix' from tag '$last_tag'" last_tag="''${last_tag#"''${tag_prefix}"}" fi if [[ -n "$tag_converter" ]]; then echo "Running '$last_tag' through: $tag_converter" last_tag="$(echo "''${last_tag}" | ''${tag_converter})" fi else last_tag="0" fi if [[ ! "$last_tag" =~ ^[[:digit:]] ]]; then echo "Last tag '$last_tag' does not start with a digit" > /dev/stderr exit 1 fi new_version="$last_tag-unstable-$commit_date" popd # rm -rf "$tmpdir" </ins> <del> # update the nix expression ${common-updater-scripts}/bin/update-source-version  "$UPDATE_NIX_ATTR_PATH"  "$new_version"  --rev="$commit_sha" ''; </del> <ins> # update the nix expression update-source-version  "$UPDATE_NIX_ATTR_PATH"  "$new_version"  --rev="$commit_sha" ''; }; </ins> in [ <del> updateScript </del> <ins> (lib.getExe updateScript) </ins> "--url=${builtins.toString url}" <ins> "--tag-format=${tagFormat}" </ins> ] ++ lib.optionals (branch != null) [ "--branch=${branch}" <del> ] ++ lib.optionals stableVersion [ "--use-stable-version" </del> <ins> ] ++ lib.optionals (tagPrefix != null) [ </ins> "--tag-prefix=${tagPrefix}" <ins> ] ++ lib.optionals (tagConverter != null) [ "--tag-converter=${tagConverter}" ] ++ lib.optionals hardcodeZeroVersion [ "--hardcode-zero-version" </ins> ] ++ lib.optionals shallowClone [ "--shallow-clone" ]