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 158 159 160 161 162 163 164 165
|
#!/bin/bash
# To run this, you need to first install cargo-lock.
#
# TODO: this script has a known bug in: if the Debian patches being applied,
# changes the set of dependencies, then "cargo vendor" is not re-run in order
# to pick up this new set of dependencies. This is manifested by an error
# message like: "perhaps a crate was updated and forgotten to be re-vendored?"
#
set -e
SCRIPTDIR="$(dirname "$(readlink -f "$0")")"
not_needed() {
diff -ur packages-before packages-after | grep "^-- " | cut -d' ' -f2-3
}
ghetto_parse_cargo() {
cat "$1" \
| tr '\n' '\t' \
| sed -e 's/\t\[/\n[/g' \
| perl -ne 'print if s/^\[(?:package|project)\].*\tname\s*=\s*"(.*?)".*\tversion\s*=\s*"(.*?)".*/\1 \2/g'
}
pruned_paths() {
for i in vendor/*/Cargo.toml; do
pkgnamever=
pkgnamever=$(ghetto_parse_cargo "$i")
if [ -z "$pkgnamever" ]; then
echo >&2 "failed to parse: $i"
exit 1
fi
echo "$pkgnamever $i"
done | grep -F -f <(not_needed) | cut '-d ' -f3 | while read x; do
echo " $(dirname $x)"
done
}
crate_to_debcargo_conf() {
echo "$1" | sed -e 's/_/-/g'
}
rm -rf vendor/
if [ -e "$CARGO_PRE_VENDOR" ]; then
"$CARGO_PRE_VENDOR"
fi
cargo vendor --verbose vendor/
mkdir -p .cargo
cat >.cargo/config <<eof
[source.crates-io]
replace-with = "vendored-sources"
[source.vendored-sources]
directory = "$PWD/vendor"
eof
cargo lock list > packages-before
cp Cargo.lock Cargo.lock.orig
if [ -d debcargo-conf ]; then ( cd debcargo-conf && git pull );
else git clone "${DEBCARGO_CONF:-https://salsa.debian.org/rust-team/debcargo-conf}"; fi
# keep applying patches, and drop to a subshell for manual fixing, until it succeeds
while ! ( cd vendor
x=true
for i in *; do
debname=$(crate_to_debcargo_conf "$i")
cd $i
# if there is a d/rules then don't mess with it, it's too custom for this
# script to deal with - just use the upstream version. example: backtrace-sys
# TODO: deal with those better, especially backtrace-sys
if [ -e ../../debcargo-conf/src/$debname/debian/rules ]; then
echo >&2 "$0: the debcargo-conf for crate $i has a custom rules file, but applying patches anyway"
echo >&2 "$0: you may want to examine this situation more closely"
fi
if [ -d ../../debcargo-conf/src/$debname/debian/patches ]; then
echo >&2 "$0: patching $i"
mkdir -p debian
if [ ! -d debian/patches ]; then
cp -a -n "../../debcargo-conf/src/$debname/debian/patches" debian/
fi
# first unapply any patches applied in the previous iteration
QUILT_PATCHES=debian/patches quilt pop -af
QUILT_PATCHES=debian/patches quilt push -a
case $? in
0|2) true;;
*) echo >&2 "$0: patching $i failed <<<<<<<<<<<<<<<<<<<<<<<<"
QUILT_PATCHES=debian/patches quilt pop -af
x=false;;
esac
fi
if [ -f ../../debcargo-conf/src/$debname/debian/build.rs ]; then
echo >&2 "$0: overwriting build.rs with our custom one"
if [ ! -f build.rs.orig ]; then
cp -f build.rs build.rs.orig
fi
cp -f ../../debcargo-conf/src/$i/debian/build.rs build.rs
fi
cd ..
done; $x ); do
echo >&2 "================================================================================"
echo >&2 "$0: You are now in a sub-shell!"
echo >&2 "$0: Fix the failed patches in debcargo-conf/, then exit the sub-shell by pressing ctrl-D ONCE."
echo >&2 "$0: If you need to abort this process, press ctrl-D then quickly ctrl-C."
if [ -f "${SRCDIR:-$PWD}/debian/debcargo-conf.patch" ]; then
echo >&2 "$0: Previous patch changes exist, to apply them run:"
echo >&2 " $ patch -d vendor -p2 < '${SRCDIR:-$PWD}/debian/debcargo-conf.patch'"
fi
echo >&2 "================================================================================"
bash || true
echo >&2 "$0: trying patches again..."
done
rm -rf vendor/*/.pc
find vendor/*/debian/patches -name '*~' -delete || true
cargo update
cargo lock list > packages-after
pruned_paths | while read x; do echo >&2 "$0: removing, because debcargo-conf patches makes it obsolete: $x"; rm -rf "$x"; done
# remove excluded files
( cd vendor
for i in *; do (
debname=$(crate_to_debcargo_conf "$i")
shopt -s globstar # needed for double-glob to work in excludes
cd $i
if [ -e ../../debcargo-conf/src/$debname/debian/rules ]; then
echo >&2 "$0: the debcargo-conf for crate $i has a custom rules file, but applying excludes anyway"
echo >&2 "$0: you may want to examine this situation more closely"
fi
if grep -q excludes ../../debcargo-conf/src/$debname/debian/debcargo.toml 2>/dev/null; then
sed -nre 's/.*excludes\s*=\s*(\[[^]]*\]).*/\1/p' \
../../debcargo-conf/src/$i/debian/debcargo.toml \
| python3 -c "import ast, sys; x=ast.literal_eval(sys.stdin.read()); print('\n'.join((i[:-3] if i.endswith('/**') else i) for i in x));" \
| while read x; do echo >&2 "$0: removing, since it's excluded by debcargo-conf: vendor/$i/$x"; rm -rf $x; done
fi
); done; )
# TODO: rm special logic from debcargo and put into debcargo-conf instead
echo >&2 "$0: removing winapi archives"
rm -rf vendor/winapi-*-pc-windows-gnu/lib/*.a
echo >&2 "$0: pruning all checksums.."
for i in vendor/*; do ${SCRIPTDIR}/prune-checksums "$i"; done
( cd vendor
for i in *; do (
cd $i
debname=$(crate_to_debcargo_conf "$i")
if [ -d debian/patches ]; then
rm -rf "../../debcargo-conf/src/$debname/debian/patches"
cp -a debian/patches "../../debcargo-conf/src/$debname/debian/"
fi
); done; )
( cd debcargo-conf
git add .
if ! git diff --cached --quiet; then
git commit -m "Manual changes from debian-cargo-vendor"
git diff @~ > ../../debcargo-conf.patch || true
(cd ../.. ; echo >&2 "$0: backed up patch changes to $PWD/debcargo-conf.patch")
echo >&2 "$0: you should backport/merge them back into debcargo-conf.git"
fi
)
echo >&2 "$0: cleaning up..."
rm -rf .cargo Cargo.lock debcargo-conf packages-before packages-after
echo >&2 "$0: restoring original Cargo.lock"
mv Cargo.lock.orig Cargo.lock
|