summaryrefslogtreecommitdiff
path: root/maint
diff options
context:
space:
mode:
Diffstat (limited to 'maint')
-rwxr-xr-xmaint/cbindgen172
-rwxr-xr-xmaint/list_crates10
2 files changed, 179 insertions, 3 deletions
diff --git a/maint/cbindgen b/maint/cbindgen
new file mode 100755
index 000000000..895a71ac2
--- /dev/null
+++ b/maint/cbindgen
@@ -0,0 +1,172 @@
+#!/usr/bin/env bash
+#
+# Run cbindgen in each appropriate crate (the ones with a ffi interface),
+# and inspect the output for changes.
+#
+# This script will, by default, replace the headers
+# if the warnings have not changed.
+# You can replace the old headers _and_ the old saved warnings
+# with the "--force" option.
+# You can use "--check" to make any changes (to headers or warnings) a failure.
+#
+# Our cbindgen configurations require nightly rust—otherwise, we can't
+# expand macros. If $RUSTC_NIGHTLY is set, or if $RUSTC is nightly,
+# or if "rustc" is nightly, we'll use that. Otherwise, we'll try to
+# ask `rustup` if there is a nightly toolchain.
+
+# TODO: Use maint/common helpers once they are merged.
+
+set -eou pipefail
+
+TOPLEVEL=$(realpath "$(dirname "$0")"/..)
+
+: "${CBINDGEN_RUSTC:=}"
+: "${RUSTC:=rustc}"
+
+replace=1
+emit_all_warnings=0
+fail_on_change=0
+overwrite_warnings=0
+
+function usage()
+{
+ cat <<EOF
+cbindgen: Run cbindgen in appropriate crates, and inspect outputs for changes.
+
+Usage:
+ cbindgen [opts]
+
+Options:
+ -h: Print this message.
+ -v: Do not suppress expected warnings.
+
+ -f: Overwrite files, even if there are new warnings.
+ -c: Give a nonzero exit status if any files have changed; do not overwrite.
+EOF
+}
+
+set +e
+options=$(getopt -ohfvc --long help,force,verbose,check -- "$@")
+status="$?"
+set -e
+if test "$status" != 0; then
+ usage
+ exit 1
+fi
+
+eval set -- "$options"
+
+while true; do
+ case "$1" in
+ -h | --help)
+ usage
+ exit 1
+ ;;
+ -f | --force)
+ overwrite_warnings=1
+ shift
+ ;;
+ -v | --verbose)
+ emit_all_warnings=1
+ shift
+ ;;
+ -c | --check)
+ fail_on_change=0
+ replace=0
+ shift
+ ;;
+ --)
+ shift
+ break
+ ;;
+ esac
+done
+
+# First, find a suitable rustc.
+if test "$CBINDGEN_RUSTC" != ""; then
+ # Supposedly we have one. Use that.
+ :
+elif $RUSTC --version |grep -q nightly; then
+ # Our rustc is apparently nightly. That'll do.
+ CBINDGEN_RUSTC="$RUSTC"
+else
+ # Maybe rustup can help us?
+ #
+ # TODO: If we start to see differences depending on the version
+ # of nightly, we may want to change this to instead look at a
+ # particular version of nightly.
+ : "${CBINDGEN_TOOLCHAIN:=nightly}"
+ CBINDGEN_RUSTC=$(rustup "+$CBINDGEN_TOOLCHAIN" which rustc)
+fi
+
+ANY_DIFFERENCES=0
+SUGGEST_FORCE=0
+
+for cratedir in $("$TOPLEVEL/maint/list_crates" --subdir); do
+ crate=$(basename "$cratedir")
+ if ! test -e "$cratedir/cbindgen.toml"; then
+ # no cbindgen.toml here; we don't run in this crate.
+ continue
+ fi
+
+ echo "$crate ..."
+ pushd "$TOPLEVEL/$cratedir">/dev/null
+
+ set +e
+ RUSTC="${CBINDGEN_RUSTC}" cbindgen --lockfile ../../Cargo.lock >"$crate.h.tmp" 2>cbindgen.warnings.tmp
+ status="$?"
+ set -e
+ if test "$emit_all_warnings" = 1 || test "$status" != 0; then
+ cat cbindgen.warnings.tmp 1>&2
+ if "$status" != 0; then
+ echo "cbindgen failed with status $status: See warnings above."
+ exit "$status"
+ fi
+ fi
+
+ changed_this_time=0
+ new_warnings_this_time=0
+ if diff -uN "$crate.h" "$crate.h.tmp"; then
+ echo " (No changes in the header)"
+ else
+ changed_this_time=1
+ ANY_DIFFERENCES=1
+ fi
+ if diff -uN "cbindgen.warnings" "cbindgen.warnings.tmp"; then
+ echo " (No changes in the warnings)"
+ else
+ new_warnings_this_time=1
+ changed_this_time=1
+ ANY_DIFFERENCES=1
+ fi
+
+ if test "$changed_this_time" = 1 && test "$replace" = 1; then
+ if test "$new_warnings_this_time" = 1 && test "$overwrite_warnings" = 0; then
+ # TODO: Possibly we should only refuse to overwrite when there
+ # are _new_ warnings; not when warnings have gone away or been
+ # re-ordered.
+ echo " CHANGED WARNINGS; not overwriting."
+ SUGGEST_FORCE=1
+ else
+ echo " Overwriting warnings and header file."
+ mv -f cbindgen.warnings.tmp cbindgen.warnings
+ mv -f "$crate.h.tmp" "$crate.h"
+ fi
+ fi
+
+ popd>/dev/null
+done
+
+if test "$ANY_DIFFERENCES" = 1; then
+ echo "------------------------------"
+ echo "At least one file changed; see above for diffs."
+ if test "$replace" = 0; then
+ echo "(Running in 'check' mode, so nothing was changed.)"
+ elif test "$SUGGEST_FORCE" = 1; then
+ echo "(Did not overwrite files in which the warnings changed.)"
+ echo "Make sure to look over the list of warnings, and then run with -f"
+ fi
+ if test "$fail_on_change" = 1; then
+ exit 2
+ fi
+fi
diff --git a/maint/list_crates b/maint/list_crates
index bcea8fcc4..71a7643a8 100755
--- a/maint/list_crates
+++ b/maint/list_crates
@@ -17,6 +17,7 @@ WORKSPACE_TOML = os.path.join(TOPDIR, "Cargo.toml")
class Crate:
'''Information about one crate'''
name: str
+ subdir: str
publish: bool
version: str
raw_metadata: Any
@@ -26,14 +27,14 @@ def list_crates() -> Iterator[Crate]:
Iterator over all the crates in the workspace.
'''
t = toml.decoder.load(WORKSPACE_TOML)
- for path in t['workspace']['members']:
- pt = toml.decoder.load(path + "/Cargo.toml")
+ for subdir in t['workspace']['members']:
+ pt = toml.decoder.load(subdir + "/Cargo.toml")
package = pt["package"]["name"]
publish = pt["package"].get("publish")
version = pt["package"]["version"]
if publish is None:
publish = True
- yield Crate(package, publish, version, pt)
+ yield Crate(package, subdir, publish, version, pt)
def print_crates(args: argparse.Namespace) -> None:
shown_any = False
@@ -44,6 +45,8 @@ def print_crates(args: argparse.Namespace) -> None:
shown_any = True
if args.version:
print("%-23s %s" % (c.name, c.version))
+ elif args.subdir:
+ print(c.subdir)
else:
print(c.name)
@@ -56,6 +59,7 @@ if __name__ == '__main__':
)
parser.add_argument('--all', action='store_true', help='list even unpublished crates')
parser.add_argument('--version', action='store_true', help='print versions')
+ parser.add_argument('--subdir', action='store_true', help="print relative directories")
parser.add_argument('-p', '--package', help='specific crate')
args = parser.parse_args()