cargo-matrix 0.4.6

Run feature matrices against cargo commands that support feature lists
#!/usr/bin/env fish
# Shared helpers for scripts/release/*.fish. Sourced, never executed directly.
#
# Fish has no `set -e`; every risky external command in the stage scripts is
# followed by `; or rel_die "..."` instead.

function rel_log
    echo "[release] $argv"
end

function rel_warn
    echo "[release] warning: $argv" >&2
end

function rel_die
    echo "[release] error: $argv" >&2
    exit 1
end

function rel_require_cmd
    type -q $argv[1]
    or rel_die "required command '$argv[1]' not found on PATH"
end

function rel_repo_root
    git rev-parse --show-toplevel
    or rel_die "not inside the cargo-matrix git repository"
end

# Sets RELEASE_TAG / RELEASE_PKGVER from whatever release-shaped tag points
# at HEAD. Dies if HEAD isn't tagged, or if HEAD carries more than one
# release-shaped tag (genuine ambiguity -- remove the extra one first).
function rel_resolve_tag
    if set -q RELEASE_TAG; and set -q RELEASE_PKGVER
        return 0
    end

    set -l tags (git tag --points-at HEAD | string match -r '^v[0-9].*')
    if test (count $tags) -eq 0
        rel_die "HEAD is not tagged with a vX.Y.Z or vX.Y.Z-rcN tag. Create and push one first: git tag vX.Y.Z && git push origin vX.Y.Z"
    else if test (count $tags) -gt 1
        rel_die "HEAD has multiple release-shaped tags ($tags); remove the extra one(s) before releasing"
    end

    set -g RELEASE_TAG $tags[1]
    set -g RELEASE_PKGVER (string replace -r '^v' '' -- $RELEASE_TAG)
end

function rel_is_rc
    string match -qr -- '-rc' $RELEASE_TAG
end

# Polls $argv[2..-2] (relative filenames) inside directory $argv[1] until
# every one exists, or $argv[-1] seconds elapses. Used to wait for the
# repomon build/audit jobs' scp hand-back -- repomon itself has no
# synchronous "wait for job N" API, so this is a plain poll loop instead of
# anything repomon-aware.
#
# Existence-only is safe here *because* handoff.sh/windows-handoff.ps1 scp
# to a `.partial` suffix and atomically mv it into the final name only once
# the transfer is complete -- a plain `scp foo "$dest"` would create `foo`
# and start streaming into it immediately, letting this poll observe and
# hand off a partially-written file. Don't relax the handoff scripts back to
# a direct scp without also changing this to a size-stability check.
function rel_wait_for_files
    set -l dir $argv[1]
    set -l timeout_s $argv[-1]
    set -l files $argv[2..-2]

    set -l waited 0
    set -l interval 15

    while true
        set -l missing
        for f in $files
            test -f "$dir/$f"
            or set -a missing $f
        end

        if test (count $missing) -eq 0
            return 0
        end

        if test $waited -ge $timeout_s
            rel_warn "timed out after {$timeout_s}s waiting for: $missing"
            return 1
        end

        if test (math "$waited % 60") -eq 0
            rel_log "waiting for repomon artifacts in $dir ("(math "$timeout_s - $waited")"s left): still missing $missing"
        end

        sleep $interval
        set waited (math "$waited + $interval")
    end
end