File: for-every-commit

package info (click to toggle)
rust-derive-deftly 1.6.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,652 kB
  • sloc: perl: 1,032; sh: 373; python: 227; makefile: 11
file content (157 lines) | stat: -rwxr-xr-x 3,892 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/bin/bash
#
# We fail CI if the word "F I X M E" is detedcted, as a whole word,
# in any case.  The word is not matched if there are word-characters
# abutted to it.

set -e
set -o pipefail

BASE_BRANCHES='main'

repo=$(
    perl -MTOML -we '
        use strict;
        undef $/;
        my $toml = from_toml(<STDIN>);
        print $toml->{package}{repository} // die;
    ' <Cargo.toml
)
repo_host=$(
    perl -we '
        $ARGV[0] =~ m{^https://[-.0-9a-z]+/}
            or die "bad repository url";
        print "$&\n";
    ' "$repo"
)

echo "Cargo.toml package.repository: $repo"
echo "Upstream repository instance: $repo_host"

# Ideally we would somehow find which repo and branch this was going
# to be an MR for.  But, in fact, we can't even find out which
# repo this repo it was forked from, in a principled way, with env vars.
# This approach to finding the upstream will have to do for now.
case "$CI_PROJECT_URL" in
    "$repo_host"*)
	# `package.repository` in `Cargo.toml` is
	# on same instance as this CI job.
	#
	# Use $BASE_BRANCHES on `package.repository` as the baseline.
	git remote rm upstream.tmp >/dev/null 2>&1 ||:
	git remote rename upstream upstream.tmp >/dev/null 2>&1 ||:
	git remote add upstream "$repo"
	ORIGIN=upstream
	;;
    '')
	# Not running in CI, use a guess at the baseline:
	# $BASE_BRANCHES at whatever `origin` points to.
	ORIGIN=origin
	;;
    *)
	# We are apparently running in a different instance to upstream.
	# It's not clear what this testing would mean.
	# Should it use our repo URL?  That would be quite exciting.
	echo >&2 "CI_PROJECT_URL $CI_PROJECT_URL not recognised!"
	exit 4
	;;
esac

echo "Baseline repo remote $ORIGIN, at:"
git remote get-url "$ORIGIN"

tlref () {
    echo "refs/remotes/$ORIGIN/$tbranch"
}

x () {
    echo "+ $*"
    "$@"
}

git_checkout_maybe_clean () {
    x=$1; shift
    if
	$x git checkout -q "$1"
    then :
    else 
	echo "Checkout failed, trying with git clean and git reset"
	x git clean -xdff
	x git reset --hard
	x git checkout -q "$1"
    fi
}

old_branch=$(git symbolic-ref -q HEAD || test $? = 1)

restore_old_branch () {
    case "$old_branch" in
	refs/heads/*)
	    git_checkout_maybe_clean '' "${old_branch#refs/heads/}" ||
		echo '*** Failed to return to original branch ***'
	    ;;
	*)
	    echo "*** Was not originally on a branch, HEAD changed! ***"
	    ;;
    esac
}

trap 'restore_old_branch' 0

refspecs=()
for tbranch in $BASE_BRANCHES; do
    refspecs+=(+"refs/heads/$tbranch:$(tlref)")
done

# If you try to unshallow a repo that's already complete, you get
# an error!  Hence this.  Not all versions of git-rev-parse
# understand this option; we err on the side of trying the unshallow.
if [ "x$(git rev-parse --is-shallow-repository)" != xfalse ]; then
    # TODO really we want something like the converse of
    #  git fetch --shallow-exclude
    # but it doesn't seem to exist.
    git fetch --unshallow "$ORIGIN" "${refspecs[@]}"
fi

for tbranch in $BASE_BRANCHES; do
    trevlist="$(tlref)..HEAD"
    tcount=$(git rev-list --count "$trevlist")
    printf "HEAD is %3d commits ahead of %s\n" "$tcount" "$tbranch"
    if [ "$count" ] && [ $count -le $tcount ]; then continue; fi
    count=$tcount
    branch=$tbranch
    revlist=$trevlist
done

echo "Testing every commit not already on $branch"

commits=$(git rev-list --reverse "$revlist")

i=0
for commit in $commits; do
    banner='##############################'
    printf "|\n%s %d/%d %s\n|\n" "$banner" "$i" "$count" "$banner"
    git log -n1 "$commit" | sed 's/^/| /'
    echo '|'

    git_checkout_maybe_clean x "$commit"

    if x "$@"; then :; else
	rc="$?"
	printf "
|
========================= Failed after $i/$count =========================
|
Earliest broken commit is
  "
	git --no-pager log -n1 --pretty=oneline "$commit"
	exit "$rc"
    fi
    i=$(( $i + 1 ))
done

echo "|
$banner ok $banner
|"

rc=0