diff --git a/.github/.cspell/project-dictionary.txt b/.github/.cspell/project-dictionary.txt index 9c64a958..1dbd6a3a 100644 --- a/.github/.cspell/project-dictionary.txt +++ b/.github/.cspell/project-dictionary.txt @@ -1,4 +1,5 @@ almalinux +bindgen binstall coreutils distro diff --git a/README.md b/README.md index d352372b..d61980ab 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ https://spdx.org/licenses | [**shfmt**](https://github.com/mvdan/sh) | `/usr/local/bin` | [GitHub Releases](https://github.com/mvdan/sh/releases) | Linux, macOS, Windows | [BSD-3-Clause](https://github.com/mvdan/sh/blob/HEAD/LICENSE) | | [**syft**](https://github.com/anchore/syft) | `/usr/local/bin` | [Github Releases](https://github.com/anchore/syft/releases) | Linux, macOS, Windows | [Apache-2.0](https://github.com/anchore/syft/blob/HEAD/LICENSE) | | [**valgrind**](https://valgrind.org) | `/snap/bin` | [snap](https://snapcraft.io/install/valgrind/ubuntu) | Linux | [GPL-2.0-or-later](https://valgrind.org/docs/manual/license.gpl.html) | +| [**wasm-bindgen**](https://github.com/rustwasm/wasm-bindgen) | `$CARGO_HOME/bin` | [GitHub Releases](https://github.com/rustwasm/wasm-bindgen/releases) | Linux, macOS, Windows | [Apache-2.0](https://github.com/rustwasm/wasm-bindgen/blob/HEAD/LICENSE-APACHE) OR [MIT](https://github.com/rustwasm/wasm-bindgen/blob/HEAD/LICENSE-MIT) | | [**wasm-pack**](https://github.com/rustwasm/wasm-pack) | `$CARGO_HOME/bin` | [GitHub Releases](https://github.com/rustwasm/wasm-pack/releases) | Linux, macOS, Windows | [Apache-2.0](https://github.com/rustwasm/wasm-pack/blob/HEAD/LICENSE-APACHE) OR [MIT](https://github.com/rustwasm/wasm-pack/blob/HEAD/LICENSE-MIT) | | [**wasmtime**](https://github.com/bytecodealliance/wasmtime) | `$CARGO_HOME/bin` | [GitHub Releases](https://github.com/bytecodealliance/wasmtime/releases) | Linux, macOS, Windows | [Apache-2.0 WITH LLVM-exception](https://github.com/bytecodealliance/wasmtime/blob/HEAD/LICENSE) | | [**xbuild**](https://github.com/rust-mobile/xbuild) | `$CARGO_HOME/bin` | [GitHub Releases](https://github.com/rust-mobile/xbuild/releases) | Linux, macOS, Windows | Apache-2.0 OR MIT | diff --git a/main.sh b/main.sh index 98b554f8..8b7404fb 100755 --- a/main.sh +++ b/main.sh @@ -54,18 +54,26 @@ download_and_checksum() { } download_and_extract() { local url="$1" - local checksum="$2" - local bin_dir="$3" - local bin_in_archive="$4" # path to bin in archive + shift + local checksum="$1" + shift + local bin_dir="$1" + shift + local bin_in_archive=("$@") # path to bin in archive if [[ "${bin_dir}" == "${install_action_dir}/bin" ]]; then init_install_action_bin_dir fi - local installed_bin - # xbuild's binary name is "x", as opposed to the usual crate name + installed_bin=() + local tmp case "${tool}" in - xbuild) installed_bin="${bin_dir}/x" ;; - *) installed_bin="${bin_dir}/$(basename "${bin_in_archive}")" ;; + # xbuild's binary name is "x", as opposed to the usual crate name + xbuild) installed_bin=("${bin_dir}/x") ;; + *) + for tmp in "${bin_in_archive[@]}"; do + installed_bin+=("${bin_dir}/$(basename "${tmp}")") + done + ;; esac local tar_args=() @@ -119,19 +127,23 @@ download_and_extract() { download_and_checksum "${url}" "${checksum}" if [[ ${#tar_args[@]} -gt 0 ]]; then tar_args+=("tmp") - local components - components=$(tr <<<"${bin_in_archive}" -cd '/' | wc -c) - if [[ "${components}" != "0" ]]; then - tar_args+=(--strip-components "${components}") - fi - tar "${tar_args[@]}" -C "${bin_dir}" "${bin_in_archive}" + tar "${tar_args[@]}" + for tmp in "${bin_in_archive[@]}"; do + mv "${tmp}" "${bin_dir}/" + done else case "${url}" in *.zip) unzip -q tmp "${bin_in_archive#\./}" - mv "${bin_in_archive}" "${bin_dir}/" + for tmp in "${bin_in_archive[@]}"; do + mv "${tmp}" "${bin_dir}/" + done + ;; + *) + for tmp in "${installed_bin[@]}"; do + mv tmp "${tmp}" + done ;; - *) mv tmp "${installed_bin}" ;; esac fi ) @@ -139,9 +151,11 @@ download_and_extract() { case "${host_os}" in linux | macos) - if [[ ! -x "${installed_bin}" ]]; then - chmod +x "${installed_bin}" - fi + for tmp in "${installed_bin[@]}"; do + if [[ ! -x "${tmp}" ]]; then + chmod +x "${tmp}" + fi + done ;; esac } @@ -198,15 +212,31 @@ read_download_info() { fi checksum=$(call_jq <<<"${download_info}" -r '.checksum') url=$(call_jq <<<"${download_info}" -r '.url') + local tmp + bin_in_archive=() if [[ "${url}" == "null" ]]; then local template template=$(call_jq -r ".template.${host_platform}" "${manifest_dir}/${tool}.json") url=$(call_jq <<<"${template}" -r '.url') url="${url//\$\{version\}/${exact_version}}" - bin_in_archive=$(call_jq <<<"${template}" -r '.bin') - bin_in_archive="${bin_in_archive//\$\{version\}/${exact_version}}" + tmp=$(call_jq <<<"${template}" -r '.bin' | sed -E "s/\\$\\{version\\}/${exact_version}/g") + if [[ "${tmp}" == *"["* ]]; then + # shellcheck disable=SC2207 + bin_in_archive=($(call_jq <<<"${template}" -r '.bin[]' | sed -E "s/\\$\\{version\\}/${exact_version}/g")) + fi else - bin_in_archive=$(call_jq <<<"${download_info}" -r '.bin') + tmp=$(call_jq <<<"${download_info}" -r '.bin') + if [[ "${tmp}" == *"["* ]]; then + # shellcheck disable=SC2207 + bin_in_archive=($(call_jq <<<"${download_info}" -r '.bin[]')) + fi + fi + if [[ ${#bin_in_archive[@]} -eq 0 ]]; then + if [[ "${tmp}" == "null" ]]; then + bin_in_archive=("${tool}${exe}") + else + bin_in_archive=("${tmp}") + fi fi if [[ "${rust_crate}" == "null" ]]; then if [[ "${host_os}" == "windows" ]] || [[ ! -e /usr/local/bin ]]; then @@ -217,9 +247,6 @@ read_download_info() { else bin_dir="${cargo_bin}" fi - if [[ "${bin_in_archive}" == "null" ]]; then - bin_in_archive="${tool}${exe}" - fi } download_from_manifest() { read_manifest "$@" @@ -227,7 +254,7 @@ download_from_manifest() { } download_from_download_info() { read_download_info "$@" - download_and_extract "${url}" "${checksum}" "${bin_dir}" "${bin_in_archive}" + download_and_extract "${url}" "${checksum}" "${bin_dir}" "${bin_in_archive[@]}" } install_cargo_binstall() { local binstall_version @@ -540,6 +567,7 @@ for tool in "${tools[@]}"; do else version="latest" fi + installed_bin=() case "${tool}" in protoc) info "installing ${tool}@${version}" @@ -576,6 +604,7 @@ for tool in "${tools[@]}"; do fi ) rm -rf "${tmp_dir}" + installed_bin=("${tool}${exe}") ;; valgrind) info "installing ${tool}@${version}" @@ -593,6 +622,7 @@ for tool in "${tools[@]}"; do # Use snap to install the latest Valgrind # https://snapcraft.io/install/valgrind/ubuntu snap_install valgrind --classic + installed_bin=("${tool}${exe}") ;; cargo-binstall) case "${version}" in @@ -651,41 +681,50 @@ for tool in "${tools[@]}"; do ;; esac - case "${tool}" in - xbuild) tool_bin="x" ;; - *) tool_bin="${tool}" ;; - esac - installed_at=$(type -P "${tool_bin}${exe}" || echo "") - if [[ -n "${installed_at}" ]]; then - tool_bin="${tool_bin}${exe}" - else + tool_bin_stems=() + for tool_bin in "${installed_bin[@]}"; do + tool_bin=$(basename "${tool_bin}") + tool_bin_stem="${tool_bin%.exe}" installed_at=$(type -P "${tool_bin}" || echo "") - fi - if [[ -n "${installed_at}" ]]; then - info "${tool} installed at ${installed_at}" - else - warn "${tool} should be installed at ${bin_dir:+"${bin_dir}/"}${tool_bin}${exe}; but ${tool_bin}${exe} not found in path" - fi - # cargo-udeps 0.1.30 and wasm-pack 0.12.0 do not support --version option. - case "${tool}" in - biome) rx "${tool_bin}" --version || true ;; # biome up to 1.2.2 exits with 1 on --version and --help - cargo-careful | cargo-machete) ;; # cargo-careful 0.3.4 and cargo-machete 0.5.0 do not support neither --version nor --help option. - cargo-*) - case "${tool}" in - cargo-valgrind) rx "${tool_bin}" "${tool#cargo-}" --help ;; # cargo-valgrind 2.1.0's --version option just calls cargo's --version option - *) - if ! rx "${tool_bin}" "${tool#cargo-}" --version; then - rx "${tool_bin}" "${tool#cargo-}" --help - fi - ;; - esac - ;; - *) - if ! rx "${tool_bin}" --version; then - rx "${tool_bin}" --help - fi - ;; - esac + if [[ -z "${installed_at}" ]]; then + tool_bin="${tool_bin_stem}" + installed_at=$(type -P "${tool_bin}" || echo "") + fi + if [[ -n "${installed_at}" ]]; then + info "${tool_bin_stem} installed at ${installed_at}" + else + warn "${tool_bin_stem} should be installed at ${bin_dir:+"${bin_dir}/"}${tool_bin}${exe}; but ${tool_bin}${exe} not found in path" + fi + tool_bin_stems+=("${tool_bin_stem}") + done + for tool_bin_stem in "${tool_bin_stems[@]}"; do + # cargo-udeps 0.1.30 and wasm-pack 0.12.0 do not support --version flag. + case "${tool_bin_stem}" in + # biome up to 1.2.2 exits with 1 on both --version and --help flags. + # cargo-machete up to 0.6.0 does not support --version flag. + biome | cargo-machete) rx "${tool_bin_stem}" --version || true ;; + # these packages support neither --version nor --help flag. + cargo-careful | wasm-bindgen-test-runner) ;; + # wasm2es6js does not support --version flag and --help flag doesn't contains version info. + wasm2es6js) ;; + cargo-*) + case "${tool_bin_stem}" in + # cargo-valgrind 2.1.0's --version flag just calls cargo's --version flag + cargo-valgrind) rx "${tool_bin_stem}" "${tool_bin_stem#cargo-}" --help ;; + *) + if ! rx "${tool_bin_stem}" "${tool_bin_stem#cargo-}" --version; then + rx "${tool_bin_stem}" "${tool_bin_stem#cargo-}" --help + fi + ;; + esac + ;; + *) + if ! rx "${tool_bin_stem}" --version; then + rx "${tool_bin_stem}" --help + fi + ;; + esac + done echo done diff --git a/manifests/wasm-bindgen.json b/manifests/wasm-bindgen.json new file mode 100644 index 00000000..8cda7bfc --- /dev/null +++ b/manifests/wasm-bindgen.json @@ -0,0 +1,119 @@ +{ + "rust_crate": "wasm-bindgen-cli", + "template": { + "x86_64_linux_musl": { + "url": "https://github.com/rustwasm/wasm-bindgen/releases/download/${version}/wasm-bindgen-${version}-x86_64-unknown-linux-musl.tar.gz", + "bin": [ + "wasm-bindgen-${version}-x86_64-unknown-linux-musl/wasm-bindgen-test-runner", + "wasm-bindgen-${version}-x86_64-unknown-linux-musl/wasm-bindgen", + "wasm-bindgen-${version}-x86_64-unknown-linux-musl/wasm2es6js" + ] + }, + "x86_64_macos": { + "url": "https://github.com/rustwasm/wasm-bindgen/releases/download/${version}/wasm-bindgen-${version}-x86_64-apple-darwin.tar.gz", + "bin": [ + "wasm-bindgen-${version}-x86_64-apple-darwin/wasm-bindgen-test-runner", + "wasm-bindgen-${version}-x86_64-apple-darwin/wasm-bindgen", + "wasm-bindgen-${version}-x86_64-apple-darwin/wasm2es6js" + ] + }, + "x86_64_windows": { + "url": "https://github.com/rustwasm/wasm-bindgen/releases/download/${version}/wasm-bindgen-${version}-x86_64-pc-windows-msvc.tar.gz", + "bin": [ + "wasm-bindgen-${version}-x86_64-pc-windows-msvc/wasm-bindgen-test-runner.exe", + "wasm-bindgen-${version}-x86_64-pc-windows-msvc/wasm-bindgen.exe", + "wasm-bindgen-${version}-x86_64-pc-windows-msvc/wasm2es6js.exe" + ] + }, + "aarch64_linux_gnu": { + "url": "https://github.com/rustwasm/wasm-bindgen/releases/download/${version}/wasm-bindgen-${version}-aarch64-unknown-linux-gnu.tar.gz", + "bin": [ + "wasm-bindgen-${version}-aarch64-unknown-linux-gnu/wasm-bindgen-test-runner", + "wasm-bindgen-${version}-aarch64-unknown-linux-gnu/wasm-bindgen", + "wasm-bindgen-${version}-aarch64-unknown-linux-gnu/wasm2es6js" + ] + }, + "aarch64_macos": { + "url": "https://github.com/rustwasm/wasm-bindgen/releases/download/${version}/wasm-bindgen-${version}-aarch64-apple-darwin.tar.gz", + "bin": [ + "wasm-bindgen-${version}-aarch64-apple-darwin/wasm-bindgen-test-runner", + "wasm-bindgen-${version}-aarch64-apple-darwin/wasm-bindgen", + "wasm-bindgen-${version}-aarch64-apple-darwin/wasm2es6js" + ] + } + }, + "latest": { + "version": "0.2.91" + }, + "0.2": { + "version": "0.2.91" + }, + "0.2.91": { + "x86_64_linux_musl": { + "checksum": "48123760cd139036125dbc07aaf09c73237d2bf910810b00a2dabbbac7a92e4e" + }, + "x86_64_macos": { + "checksum": "8c9378515f5162d77c8bbec8925e2444e4509fc5fd4e42c218b70bd7e7b5c34d" + }, + "x86_64_windows": { + "checksum": "9077f846f8e29dbc246688294b02474c4247e176739b43b0ce5df093e3c23ccf" + }, + "aarch64_linux_gnu": { + "checksum": "06a93a6c4ca7166082e8c6179e9f1dc6ca1df822894669b5257cdff08692bf00" + }, + "aarch64_macos": { + "checksum": "8f644617cbd12763268854cb550604f18e15a869c9b2e63ba977278fee99ff3d" + } + }, + "0.2.90": { + "x86_64_linux_musl": { + "checksum": "46131161e31617d102260b1420159fe5006f6b0fdb8a0a90fe7adc858b662132" + }, + "x86_64_macos": { + "checksum": "374a460a4c8cf097e84725082da6c909830cbc6caa16538735bcc066971e3bcd" + }, + "x86_64_windows": { + "checksum": "919b6f010164c5d2f28df505098d94c0ac3727c9aeeea2df12453008dc451c78" + }, + "aarch64_linux_gnu": { + "checksum": "29075a17870097d800e471ec2a800f915c09c5c8d4b2b1436fd43381aa7bf480" + }, + "aarch64_macos": { + "checksum": "d3724348014d028048b9539fac36858a0a1aba165814a69542d3038d65303093" + } + }, + "0.2.89": { + "x86_64_linux_musl": { + "checksum": "e6361f3069a8a94ca44f0eb6e22b1de59ee71236bba2acd0278f1387e09a90d0" + }, + "x86_64_macos": { + "checksum": "5ca6b6e9a2b971cdc5571a54a963f6f13ae6263bbf921998feeef3ff6b6b70b7" + }, + "x86_64_windows": { + "checksum": "5dd04e972fc0910122f5d9881aa49470e6734e5a1d3294030eaace738771fddc" + }, + "aarch64_linux_gnu": { + "checksum": "4ca6d7cedf6d47eec55d739bfd228270061a1c2bb4b625442e2bb716d2cc7337" + }, + "aarch64_macos": { + "checksum": "cff8b011832e0f17fc94e4673a2910b04cb11bd527736b96f94abea24ff674be" + } + }, + "0.2.88": { + "x86_64_linux_musl": { + "checksum": "d7dcb7f5ad1d0cb68df5d45ffd9119d1db3d42ee6d50a8b2d3c42a56c74bdd8e" + }, + "x86_64_macos": { + "checksum": "0d1913322e657444c942c644abb687e46807fec31e3efbafb199a7932e677dcc" + }, + "x86_64_windows": { + "checksum": "ed885be56d41c5c1d3b1495307d57a2d48b296cfe5afe92e06b6ea09c4ba4532" + }, + "aarch64_linux_gnu": { + "checksum": "f13bb83170a3d44edfbebd263c695e6fb5815d77467490af1c49e2e8ec816803" + }, + "aarch64_macos": { + "checksum": "712c787c411a765e5bf8f2f3f11db9d5ec823260b763e1017d6790e9b3c225ff" + } + } +} diff --git a/tools/codegen/base/wasm-bindgen.json b/tools/codegen/base/wasm-bindgen.json new file mode 100644 index 00000000..13e2892f --- /dev/null +++ b/tools/codegen/base/wasm-bindgen.json @@ -0,0 +1,19 @@ +{ + "repository": "https://github.com/rustwasm/wasm-bindgen", + "tag_prefix": "", + "rust_crate": "wasm-bindgen-cli", + "version_range": ">= 0.2.88", + "asset_name": "wasm-bindgen-${version}-${rust_target}.tar.gz", + "bin": [ + "wasm-bindgen-${version}-${rust_target}/wasm-bindgen-test-runner${exe}", + "wasm-bindgen-${version}-${rust_target}/wasm-bindgen${exe}", + "wasm-bindgen-${version}-${rust_target}/wasm2es6js${exe}" + ], + "platform": { + "x86_64_linux_musl": {}, + "x86_64_macos": {}, + "x86_64_windows": {}, + "aarch64_linux_gnu": {}, + "aarch64_macos": {} + } +} diff --git a/tools/codegen/src/main.rs b/tools/codegen/src/main.rs index 1f7d2f65..04564895 100644 --- a/tools/codegen/src/main.rs +++ b/tools/codegen/src/main.rs @@ -41,6 +41,7 @@ fn main() -> Result<()> { let mut base_info: BaseManifest = serde_json::from_slice(&fs::read( workspace_root.join("tools/codegen/base").join(format!("{package}.json")), )?)?; + base_info.validate(); let repo = base_info .repository .strip_prefix("https://github.com/") @@ -116,7 +117,10 @@ fn main() -> Result<()> { for (platform, d) in &mut manifest.download_info { let template = &template.download_info[platform]; d.url = Some(template.url.replace("${version}", version)); - d.bin = template.bin.as_ref().map(|s| s.replace("${version}", version)); + d.bin = template + .bin + .as_ref() + .map(|s| s.map(|s| s.replace("${version}", version))); } } } @@ -310,11 +314,8 @@ fn main() -> Result<()> { download_info.insert(platform, ManifestDownloadInfo { url: Some(url), checksum: hash, - bin: base_download_info - .bin - .as_ref() - .or(base_info.bin.as_ref()) - .map(|s| { + bin: base_download_info.bin.as_ref().or(base_info.bin.as_ref()).map(|s| { + s.map(|s| { replace_vars( s, package, @@ -322,8 +323,9 @@ fn main() -> Result<()> { Some(platform), base_info.rust_crate.as_deref(), ) + .unwrap() }) - .transpose()?, + }), }); buf.clear(); } @@ -451,7 +453,7 @@ fn main() -> Result<()> { let t = template.as_mut().unwrap(); for (platform, d) in &mut manifest.download_info { let template_url = d.url.take().unwrap().replace(version, "${version}"); - let template_bin = d.bin.take().map(|s| s.replace(version, "${version}")); + let template_bin = d.bin.take().map(|s| s.map(|s| s.replace(version, "${version}"))); if let Some(d) = t.download_info.get(platform) { if template_url != d.url || template_bin != d.bin { template = None; @@ -711,9 +713,9 @@ struct ManifestDownloadInfo { #[serde(skip_serializing_if = "Option::is_none")] url: Option, checksum: String, - /// Default to ${tool}${exe} + /// Path to binaries in archive. Default to `${tool}${exe}`. #[serde(skip_serializing_if = "Option::is_none")] - bin: Option, + bin: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -725,9 +727,9 @@ struct ManifestTemplate { #[derive(Debug, Clone, Serialize, Deserialize)] struct ManifestTemplateDownloadInfo { url: String, - /// Default to ${tool}${exe} + /// Path to binaries in archive. Default to `${tool}${exe}`. #[serde(skip_serializing_if = "Option::is_none")] - bin: Option, + bin: Option, } #[derive(Debug, Deserialize)] @@ -742,14 +744,26 @@ struct BaseManifest { default_major_version: Option, /// Asset name patterns. asset_name: Option, - /// Path to binary in archive. Default to `${tool}${exe}`. - bin: Option, + /// Path to binaries in archive. Default to `${tool}${exe}`. + bin: Option, signing: Option, #[serde(default)] broken: Vec, platform: BTreeMap, version_range: Option, } +impl BaseManifest { + fn validate(&self) { + if let Some(bin) = &self.bin { + assert!(!bin.as_slice().is_empty()); + } + for m in self.platform.values() { + if let Some(bin) = &m.bin { + assert!(!bin.as_slice().is_empty()); + } + } + } +} #[derive(Debug, Deserialize)] #[serde(deny_unknown_fields)] @@ -772,11 +786,11 @@ enum SigningKind { struct BaseManifestPlatformInfo { /// Asset name patterns. Default to the value at `BaseManifest::asset_name`. asset_name: Option, - /// Path to binary in archive. Default to the value at `BaseManifest::bin`. - bin: Option, + /// Path to binaries in archive. Default to the value at `BaseManifest::bin`. + bin: Option, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(untagged)] enum StringOrArray { String(String), @@ -786,8 +800,14 @@ enum StringOrArray { impl StringOrArray { fn as_slice(&self) -> &[String] { match self { - Self::Array(v) => v, Self::String(s) => slice::from_ref(s), + Self::Array(v) => v, + } + } + fn map(&self, mut f: impl FnMut(&String) -> String) -> Self { + match self { + Self::String(s) => Self::String(f(s)), + Self::Array(v) => Self::Array(v.iter().map(f).collect()), } } }