Skip to content

Commit 4b7f1df

Browse files
authored
Convert shell scripts to Rust (#891)
`cargo.sh` is now a thin wrapper around a new `cargo-zerocopy` tool located in the `tools` directory. README generation is now done by a similar `generate-readme` tool. A wrapper script for running `cargo-zerocopy` on Windows has been added as `win-cargo.bat`, effectively allowing the test suites to be run on Windows.
1 parent 65c080c commit 4b7f1df

File tree

13 files changed

+404
-196
lines changed

13 files changed

+404
-196
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- Copyright 2022 The Fuchsia Authors
1+
<!-- Copyright 2024 The Fuchsia Authors
22
33
Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
44
<LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
@@ -7,7 +7,7 @@ This file may not be copied, modified, or distributed except according to
77
those terms.
88
99
WARNING: DO NOT EDIT THIS FILE. It is generated automatically. Edits should be
10-
made in the doc comment on `src/lib.rs` or in `generate-readme.sh`.
10+
made in the doc comment on `src/lib.rs` or in `tools/generate-readme`.
1111
-->
1212

1313
# zerocopy

cargo.sh

Lines changed: 5 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,135 +1,12 @@
1-
#!/bin/bash
2-
#
3-
# Copyright 2023 The Fuchsia Authors
1+
# Copyright 2024 The Fuchsia Authors
42
#
53
# Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
64
# <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
75
# license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
86
# This file may not be copied, modified, or distributed except according to
97
# those terms.
108

11-
# This script is a thin wrapper around Cargo that provides human-friendly
12-
# toolchain names which are automatically translated to the toolchain versions
13-
# we have pinned in CI.
14-
#
15-
# cargo.sh --version <toolchain-name> # looks up the version for the named toolchain
16-
# cargo.sh +<toolchain-name> [...] # runs cargo commands with the named toolchain
17-
# cargo.sh +all [...] # runs cargo commands with each toolchain
18-
#
19-
# The meta-toolchain "all" instructs this script to run the provided command
20-
# once for each "major" toolchain (msrv, stable, nightly). This does not include
21-
# any toolchain which is listed in the `package.metadata.build-rs` Cargo.toml
22-
# section.
23-
#
24-
# A common task that is especially annoying to perform by hand is to update
25-
# trybuild's stderr files. Using this script:
26-
#
27-
# TRYBUILD=overwrite ./cargo.sh +all test --workspace
28-
29-
set -eo pipefail
30-
31-
function print-usage-and-exit {
32-
echo "Usage:" >&2
33-
echo " $0 --version <toolchain-name>" >&2
34-
echo " $0 +<toolchain-name> [...]" >&2
35-
echo " $0 +all [...]" >&2
36-
exit 1
37-
}
38-
39-
[[ $# -gt 0 ]] || print-usage-and-exit
40-
41-
function pkg-meta {
42-
# NOTE(#547): We set `CARGO_TARGET_DIR` here because `cargo metadata`
43-
# sometimes causes the `cargo-metadata` crate to be rebuilt from source using
44-
# the default toolchain. This has the effect of clobbering any existing build
45-
# artifacts from whatever toolchain the user has specified (e.g., `+nightly`),
46-
# causing the subsequent `cargo` invocation to rebuild unnecessarily. By
47-
# specifying a separate build directory here, we ensure that this never
48-
# clobbers the build artifacts used by the later `cargo` invocation.
49-
#
50-
# In CI, make sure to use the default stable toolchain. If we're testing on
51-
# our MSRV, then we also have our MSRV toolchain installed. As of this
52-
# writing, our MSRV is low enough that the correspoding Rust toolchain's Cargo
53-
# doesn't know about the `rust-version` field, and so if we were to use Cargo
54-
# with that toolchain, `pkg-meta` would return `null` when asked to retrieve
55-
# the `rust-version` field. This also requires `RUSTFLAGS=''` to override any
56-
# unstable `RUSTFLAGS` set by the caller.
57-
RUSTFLAGS='' CARGO_TARGET_DIR=target/cargo-sh cargo +stable metadata --format-version 1 | jq -r ".packages[] | select(.name == \"zerocopy\").$1"
58-
}
59-
60-
function lookup-version {
61-
VERSION="$1"
62-
case "$VERSION" in
63-
msrv)
64-
pkg-meta rust_version
65-
;;
66-
stable)
67-
pkg-meta 'metadata.ci."pinned-stable"'
68-
;;
69-
nightly)
70-
pkg-meta 'metadata.ci."pinned-nightly"'
71-
;;
72-
*)
73-
TOOLCHAIN=$(pkg-meta "metadata.\"build-rs\".\"${VERSION}\"")
74-
if [ "$TOOLCHAIN" != "null" ]; then
75-
echo "$TOOLCHAIN"
76-
else
77-
echo "Unrecognized toolchain name: '$VERSION' (options are 'msrv', 'stable', 'nightly', and any value in Cargo.toml's 'metadata.build-rs' table)" >&2
78-
return 1
79-
fi
80-
;;
81-
esac
82-
}
83-
84-
function get-rustflags {
85-
[ "$1" == nightly ] && echo "--cfg __INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS"
86-
}
87-
88-
function prompt {
89-
PROMPT="$1"
90-
YES="$2"
91-
while true; do
92-
read -p "$PROMPT " yn
93-
case "$yn" in
94-
[Yy]) $YES; return $?; ;;
95-
[Nn]) return 1; ;;
96-
*) break; ;;
97-
esac
98-
done
99-
}
100-
101-
case "$1" in
102-
# cargo.sh --version <toolchain-name>
103-
--version)
104-
[[ $# -eq 2 ]] || print-usage-and-exit
105-
lookup-version "$2"
106-
;;
107-
# cargo.sh +all [...]
108-
+all)
109-
echo "[cargo.sh] warning: running the same command for each toolchain (msrv, stable, nightly)" >&2
110-
for toolchain in msrv stable nightly; do
111-
echo "[cargo.sh] running with toolchain: $toolchain" >&2
112-
$0 "+$toolchain" ${@:2}
113-
done
114-
exit 0
115-
;;
116-
# cargo.sh +<toolchain-name> [...]
117-
+*)
118-
TOOLCHAIN="$(lookup-version ${1:1})"
119-
120-
cargo "+$TOOLCHAIN" version &>/dev/null && \
121-
rustup "+$TOOLCHAIN" component list | grep '^rust-src (installed)$' >/dev/null || {
122-
echo "[cargo.sh] missing either toolchain '$TOOLCHAIN' or component 'rust-src'" >&2
123-
# If we're running in a GitHub action, then it's better to bail than to
124-
# hang waiting for input we're never going to get.
125-
[ -z ${GITHUB_RUN_ID+x} ] || exit 1
126-
prompt "[cargo.sh] would you like to install toolchain '$TOOLCHAIN' and component 'rust-src' via 'rustup'?" \
127-
"rustup toolchain install $TOOLCHAIN -c rust-src"
128-
} || exit 1
129-
130-
RUSTFLAGS="$(get-rustflags ${1:1}) $RUSTFLAGS" cargo "+$TOOLCHAIN" ${@:2}
131-
;;
132-
*)
133-
print-usage-and-exit
134-
;;
135-
esac
9+
# Build `cargo-zerocopy` without any RUSTFLAGS set in the environment
10+
env -u RUSTFLAGS cargo +stable build --manifest-path tools/Cargo.toml -p cargo-zerocopy -q
11+
# Thin wrapper around the `cargo-zerocopy` binary in `tools/cargo-zerocopy`
12+
./tools/target/debug/cargo-zerocopy $@

ci/check_readme.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ set -eo pipefail
66
# suppress all errors from it.
77
cargo install cargo-readme --version 3.2.0 -q
88

9-
diff <(./generate-readme.sh) README.md
9+
diff <(cargo -q run --manifest-path tools/Cargo.toml -p generate-readme) README.md
1010
exit $?

generate-readme.sh

Lines changed: 0 additions & 50 deletions
This file was deleted.

src/lib.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// After updating the following doc comment, make sure to run the following
1111
// command to update `README.md` based on its contents:
1212
//
13-
// ./generate-readme.sh > README.md
13+
// cargo -q run --manifest-path tools/Cargo.toml -p generate-readme > README.md
1414

1515
//! *<span style="font-size: 100%; color:grey;">Need more out of zerocopy?
1616
//! Submit a [customer request issue][customer-request-issue]!</span>*
@@ -164,7 +164,7 @@
164164
variant_size_differences
165165
)]
166166
#![cfg_attr(
167-
__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS,
167+
__INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS,
168168
deny(fuzzy_provenance_casts, lossy_provenance_casts)
169169
)]
170170
#![deny(
@@ -233,7 +233,7 @@
233233
)]
234234
#![cfg_attr(doc_cfg, feature(doc_cfg))]
235235
#![cfg_attr(
236-
__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS,
236+
__INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS,
237237
feature(layout_for_ptr, strict_provenance)
238238
)]
239239

@@ -318,9 +318,9 @@ pub use crate::pointer::{Maybe, MaybeAligned, Ptr};
318318
use crate::util::polyfills::NonNullExt as _;
319319

320320
#[rustversion::nightly]
321-
#[cfg(all(test, not(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)))]
321+
#[cfg(all(test, not(__INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS)))]
322322
const _: () = {
323-
#[deprecated = "some tests may be skipped due to missing RUSTFLAGS=\"--cfg __INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS\""]
323+
#[deprecated = "some tests may be skipped due to missing RUSTFLAGS=\"--cfg __INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS\""]
324324
const _WARNING: () = ();
325325
#[warn(deprecated)]
326326
_WARNING
@@ -6243,7 +6243,7 @@ mod tests {
62436243
}
62446244

62456245
#[test]
6246-
#[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
6246+
#[cfg(__INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS)]
62476247
fn test_validate_rust_layout() {
62486248
use core::ptr::NonNull;
62496249

src/macro_util.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use core::{marker::PhantomData, mem::ManuallyDrop};
2121

2222
// TODO(#29), TODO(https://github.com/rust-lang/rust/issues/69835): Remove this
2323
// `cfg` when `size_of_val_raw` is stabilized.
24-
#[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
24+
#[cfg(__INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS)]
2525
use core::ptr::{self, NonNull};
2626

2727
/// A compile-time check that should be one particular value.
@@ -70,7 +70,7 @@ const _64K: usize = 1 << 16;
7070

7171
// TODO(#29), TODO(https://github.com/rust-lang/rust/issues/69835): Remove this
7272
// `cfg` when `size_of_val_raw` is stabilized.
73-
#[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
73+
#[cfg(__INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS)]
7474
#[repr(C, align(65536))]
7575
struct Aligned64kAllocation([u8; _64K]);
7676

@@ -82,7 +82,7 @@ struct Aligned64kAllocation([u8; _64K]);
8282
/// allocation with size and alignment 2^16, and to have valid provenance.
8383
// TODO(#29), TODO(https://github.com/rust-lang/rust/issues/69835): Remove this
8484
// `cfg` when `size_of_val_raw` is stabilized.
85-
#[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
85+
#[cfg(__INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS)]
8686
pub const ALIGNED_64K_ALLOCATION: NonNull<[u8]> = {
8787
const REF: &Aligned64kAllocation = &Aligned64kAllocation([0; _64K]);
8888
let ptr: *const Aligned64kAllocation = REF;
@@ -111,7 +111,7 @@ pub const ALIGNED_64K_ALLOCATION: NonNull<[u8]> = {
111111
/// `trailing_field_offset!` produces code which is valid in a `const` context.
112112
// TODO(#29), TODO(https://github.com/rust-lang/rust/issues/69835): Remove this
113113
// `cfg` when `size_of_val_raw` is stabilized.
114-
#[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
114+
#[cfg(__INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS)]
115115
#[doc(hidden)] // `#[macro_export]` bypasses this module's `#[doc(hidden)]`.
116116
#[macro_export]
117117
macro_rules! trailing_field_offset {
@@ -211,7 +211,7 @@ macro_rules! trailing_field_offset {
211211
/// `align_of!` produces code which is valid in a `const` context.
212212
// TODO(#29), TODO(https://github.com/rust-lang/rust/issues/69835): Remove this
213213
// `cfg` when `size_of_val_raw` is stabilized.
214-
#[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
214+
#[cfg(__INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS)]
215215
#[doc(hidden)] // `#[macro_export]` bypasses this module's `#[doc(hidden)]`.
216216
#[macro_export]
217217
macro_rules! align_of {
@@ -477,7 +477,7 @@ mod tests {
477477
// TODO(#29), TODO(https://github.com/rust-lang/rust/issues/69835): Remove
478478
// this `cfg` when `size_of_val_raw` is stabilized.
479479
#[allow(clippy::decimal_literal_representation)]
480-
#[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
480+
#[cfg(__INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS)]
481481
#[test]
482482
fn test_trailing_field_offset() {
483483
assert_eq!(mem::align_of::<Aligned64kAllocation>(), _64K);
@@ -579,7 +579,7 @@ mod tests {
579579
// TODO(#29), TODO(https://github.com/rust-lang/rust/issues/69835): Remove
580580
// this `cfg` when `size_of_val_raw` is stabilized.
581581
#[allow(clippy::decimal_literal_representation)]
582-
#[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
582+
#[cfg(__INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS)]
583583
#[test]
584584
fn test_align_of_dst() {
585585
// Test that `align_of!` correctly computes the alignment of DSTs.

src/util.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl<T: ?Sized> AsAddress for *const T {
3535
// `.addr()` instead of `as usize` once it's stable, and get rid of this
3636
// `allow`. Currently, `as usize` is the only way to accomplish this.
3737
#[allow(clippy::as_conversions)]
38-
#[cfg_attr(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS, allow(lossy_provenance_casts))]
38+
#[cfg_attr(__INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS, allow(lossy_provenance_casts))]
3939
return self.cast::<()>() as usize;
4040
}
4141
}
@@ -311,7 +311,7 @@ mod proofs {
311311

312312
// Restricted to nightly since we use the unstable `usize::next_multiple_of`
313313
// in our model implementation.
314-
#[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
314+
#[cfg(__INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS)]
315315
#[kani::proof]
316316
fn prove_padding_needed_for() {
317317
fn model_impl(len: usize, align: NonZeroUsize) -> usize {

tools/Cargo.toml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright 2018 The Fuchsia Authors
2+
#
3+
# Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4+
# <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5+
# license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6+
# This file may not be copied, modified, or distributed except according to
7+
# those terms.
8+
9+
[workspace]
10+
members = [
11+
"cargo-zerocopy",
12+
"generate-readme",
13+
]
14+
resolver = "2"
15+
16+
[workspace.package]
17+
edition = "2021"
18+
version = "0.0.0"
19+
authors = ["Joshua Liebow-Feeser <[email protected]>"]
20+
license = "BSD-2-Clause OR Apache-2.0 OR MIT"
21+
publish = false
22+
23+
[workspace.dependencies]
24+
regex = "1"
25+
serde_json = "1"

tools/cargo-zerocopy/Cargo.toml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright 2024 The Fuchsia Authors
2+
#
3+
# Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4+
# <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5+
# license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6+
# This file may not be copied, modified, or distributed except according to
7+
# those terms.
8+
9+
[package]
10+
edition.workspace = true
11+
name = "cargo-zerocopy"
12+
version.workspace = true
13+
authors.workspace = true
14+
license.workspace = true
15+
publish.workspace = true
16+
17+
[dependencies]
18+
serde_json.workspace = true

0 commit comments

Comments
 (0)