diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 00000000..e930561c --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[alias] +xtask = "run --manifest-path ci/xtask/Cargo.toml --" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 9408b01e..6d5d7c24 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -62,4 +62,4 @@ jobs: run: cargo +${{ env.RUST_NIGHTLY }} sort --workspace --check - name: crate order - run: ci/order-crates-for-publishing.py + run: cargo xtask publish order diff --git a/.gitignore b/.gitignore index 8c2c925b..0df643dd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ target/ **/*.rs.bk -.cargo +.cargo/* +!.cargo/config.toml /config/ diff --git a/ci/order-crates-for-publishing.py b/ci/order-crates-for-publishing.py deleted file mode 100755 index b7a16972..00000000 --- a/ci/order-crates-for-publishing.py +++ /dev/null @@ -1,155 +0,0 @@ -#!/usr/bin/env python3 -# -# This script figures the order in which workspace crates must be published to -# crates.io. Along the way it also ensures there are no circular dependencies -# that would cause a |cargo publish| to fail. -# -# On success an ordered list of Cargo.toml files is written to stdout -# - -import os -import json -import subprocess -import sys; - -real_file = os.path.realpath(__file__) -ci_path = os.path.dirname(real_file) -src_root = os.path.dirname(ci_path) - -def load_metadata(): - cmd = f'{src_root}/cargo metadata --no-deps --format-version=1' - return json.loads(subprocess.Popen( - cmd, shell=True, stdout=subprocess.PIPE).communicate()[0]) - -# Consider a situation where a crate now wants to use already existing -# developing-oriented library code for their integration tests and benchmarks, -# like creating malformed data or omitting signature verification. Ideally, -# the code should have been guarded under the special feature -# `dev-context-only-utils` to avoid accidental misuse for production code path. -# -# In this case, the feature needs to be defined then activated for the crate -# itself. To that end, the crate actually needs to depend on itself as a -# dev-dependency with `dev-context-only-utils` activated, so that the feature -# is conditionally activated only for integration tests and benchmarks. In this -# way, other crates won't see the feature activated even if they normal-depend -# on the crate. -# -# This self-referencing dev-dependency can be thought of a variant of -# dev-dependency cycles and it's well supported by cargo. The only exception is -# when publishing. In general, cyclic dev-dependency doesn't work nicely with -# publishing: https://github.com/rust-lang/cargo/issues/4242 . -# -# However, there's a work around supported by cargo. Namely, it will ignore and -# strip these cyclic dev-dependencies when publishing, if explicit version -# isn't specified: https://github.com/rust-lang/cargo/pull/7333 (Released in -# rust 1.40.0: https://releases.rs/docs/1.40.0/#cargo ) -# -# This script follows the same safe discarding logic to exclude these -# special-cased dev dependencies from its `dependency_graph` and further -# processing. -def is_self_dev_dep_with_dev_context_only_utils(package, dependency, wrong_self_dev_dependencies): - no_explicit_version = '*' - - is_special_cased = False - if (dependency['kind'] == 'dev' and - dependency['name'] == package['name'] and - 'dev-context-only-utils' in dependency['features'] and - 'path' in dependency): - is_special_cased = True - if dependency['req'] != no_explicit_version: - # it's likely `{ workspace = true, ... }` is used, which implicitly pulls the - # version in... - wrong_self_dev_dependencies.append(dependency) - - return is_special_cased - - -# `cargo publish` is fine with circular dev-dependencies if -# they are path deps. -# However, cargo still fails if deps are path deps with versions -# (this when you use `workspace = true`): https://github.com/rust-lang/cargo/issues/4242 -# Unlike in is_self_dev_dep_with_dev_context_only_utils(), -# we don't have a clean way of checking if someone used a workspace dev -# dep when they probably meant to use a path dev dep, -# so this function just checks if a dev dep is a path dep -# and provides no special warnings. -def is_path_dev_dep(dependency): - no_explicit_version = '*' - return ( - dependency['kind'] == 'dev' - and 'path' in dependency - and dependency['req'] == no_explicit_version - ) - -def should_add(package, dependency, wrong_self_dev_dependencies): - related_to_solana = dependency['name'].startswith(('solana','agave')) - self_dev_dep_with_dev_context_only_utils = is_self_dev_dep_with_dev_context_only_utils( - package, dependency, wrong_self_dev_dependencies - ) - return ( - related_to_solana - and not self_dev_dep_with_dev_context_only_utils - and not is_path_dev_dep(dependency) - ) - -def get_packages(): - metadata = load_metadata() - - manifest_path = dict() - - # Build dictionary of packages and their immediate solana-only dependencies - dependency_graph = dict() - wrong_self_dev_dependencies = list() - - for pkg in metadata['packages']: - manifest_path[pkg['name']] = pkg['manifest_path']; - dependency_graph[pkg['name']] = [ - x['name'] for x in pkg['dependencies'] if should_add(pkg, x, wrong_self_dev_dependencies) - ]; - - # Check for direct circular dependencies - circular_dependencies = set() - for package, dependencies in dependency_graph.items(): - for dependency in dependencies: - if dependency in dependency_graph and package in dependency_graph[dependency]: - circular_dependencies.add(' <--> '.join(sorted([package, dependency]))) - - for dependency in circular_dependencies: - sys.stderr.write('Error: Circular dependency: {}\n'.format(dependency)) - for dependency in wrong_self_dev_dependencies: - sys.stderr.write('Error: wrong dev-context-only-utils circular dependency. try: ' + - '{} = {{ path = ".", features = {} }}\n' - .format(dependency['name'], json.dumps(dependency['features'])) - ) - - if len(circular_dependencies) != 0 or len(wrong_self_dev_dependencies) != 0: - sys.exit(1) - - # Order dependencies - sorted_dependency_graph = [] - max_iterations = pow(len(dependency_graph),2) - while dependency_graph: - deleted_packages = [] - if max_iterations == 0: - # One day be more helpful and find the actual cycle for the user... - sys.exit('Error: Circular dependency suspected between these packages: \n {}\n'.format('\n '.join(dependency_graph.keys()))) - - max_iterations -= 1 - - for package, dependencies in dependency_graph.items(): - if package in deleted_packages: - continue - for dependency in dependencies: - if dependency in dependency_graph: - break - else: - deleted_packages.append(package) - sorted_dependency_graph.append((package, manifest_path[package])) - - dependency_graph = {p: d for p, d in dependency_graph.items() if not p in deleted_packages } - - - return sorted_dependency_graph - -for package, manifest in get_packages(): - print(os.path.relpath(manifest)) diff --git a/ci/xtask/Cargo.lock b/ci/xtask/Cargo.lock new file mode 100644 index 00000000..688f2681 --- /dev/null +++ b/ci/xtask/Cargo.lock @@ -0,0 +1,622 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "bstr" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "camino" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +dependencies = [ + "serde_core", +] + +[[package]] +name = "cargo-platform" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87a0c0e6148f11f01f32650a2ea02d532b2ad4e81d8bd41e6e565b5adc5e6082" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "cargo_metadata" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef987d17b0a113becdd19d3d0022d04d7ef41f9efe4f3fb63ac44ba61df3ade9" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "clap" +version = "4.5.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "env_filter" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a1c3cc8e57274ec99de65301228b537f1e4eedc1b8e0f9411c6caac8ae7308f" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2daee4ea451f429a58296525ddf28b45a3b64f1acf6587e2067437bb11e218d" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "globset" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "ignore" +version = "0.4.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3d782a365a015e0f5c04902246139249abf769125006fbe7649e2ee88169b4a" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata", + "same-file", + "walkdir", + "winapi-util", +] + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + +[[package]] +name = "jiff" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3e3d65f018c6ae946ab16e80944b97096ed73c35b221d1c478a6c81d8f57940" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", +] + +[[package]] +name = "jiff-static" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17c2b211d863c7fde02cbea8a3c1a439b98e109286554f2860bdded7ff83818" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "portable-atomic-util" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +dependencies = [ + "serde_core", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.24.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01f2eadbbc6b377a847be05f60791ef1058d9f696ecb51d2c07fe911d8569d8e" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.9+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] + +[[package]] +name = "xtask" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "env_logger", + "log", + "xtask 0.1.0 (git+https://github.com/anza-xyz/xtask?rev=d189441c1bc86aa1741e1a079572fea00ea9b007)", +] + +[[package]] +name = "xtask" +version = "0.1.0" +source = "git+https://github.com/anza-xyz/xtask?rev=d189441c1bc86aa1741e1a079572fea00ea9b007#d189441c1bc86aa1741e1a079572fea00ea9b007" +dependencies = [ + "anyhow", + "cargo_metadata", + "clap", + "env_logger", + "ignore", + "log", + "scopeguard", + "semver", + "serde", + "serde_json", + "toml_edit", + "walkdir", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/ci/xtask/Cargo.toml b/ci/xtask/Cargo.toml new file mode 100644 index 00000000..e71f7488 --- /dev/null +++ b/ci/xtask/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "xtask" +version = "0.1.0" +edition = "2021" +publish = false + +# Prevents auto-detection of parent workspace +[workspace] + +[dependencies] +anza-xtask = { package = "xtask", git = "https://github.com/anza-xyz/xtask", rev = "d189441c1bc86aa1741e1a079572fea00ea9b007" } +anyhow = "1.0" +clap = { version = "4.5", features = ["derive"] } +env_logger = "0.11" +log = "0.4" diff --git a/ci/xtask/README.md b/ci/xtask/README.md new file mode 100644 index 00000000..dea2d496 --- /dev/null +++ b/ci/xtask/README.md @@ -0,0 +1,62 @@ +# XTask - SVM Build and Release Automation + +Build and release automation tasks for the SVM (Solana Virtual Machine) workspace. + +## Installation + +From the SVM repository root: + +```bash +cargo build --manifest-path ci/xtask/Cargo.toml +``` + +## Usage + +### Publish Order + +Compute the dependency-ordered list of crates for publishing to crates.io. + +**JSON format** (for CI/scripting): +```bash +cargo xtask publish order --format json +``` + +Output example: +```json +[ + [ + {"name":"solana-svm-callback","path":"callback","dependencies":[]}, + {"name":"solana-svm-feature-set","path":"feature-set","dependencies":[]} + ], + [ + {"name":"solana-program-runtime","path":"program-runtime","dependencies":["..."]} + ] +] +``` + +**Tree format** (for humans): +```bash +cargo xtask publish order --format tree +``` + +Output example: +``` +📦 Total packages: 15 +🌳 Total levels: 5 + +L1: (8 package(s)) + solana-svm-callback + solana-svm-feature-set + ... + +L2: (1 package(s)) + solana-program-runtime + L1: ["solana-svm-timings", "solana-svm-callback", ...] +``` + +## Features + +- **Dependency Analysis**: Computes topological ordering of workspace crates +- **Circular Dependency Detection**: Validates no circular dependencies exist +- **Publish Filter**: Automatically excludes crates with `publish = false` +- **Multiple Output Formats**: JSON for automation, tree for visualization diff --git a/ci/xtask/src/commands.rs b/ci/xtask/src/commands.rs new file mode 100644 index 00000000..0d7eb0f4 --- /dev/null +++ b/ci/xtask/src/commands.rs @@ -0,0 +1 @@ +pub mod publish; diff --git a/ci/xtask/src/commands/publish.rs b/ci/xtask/src/commands/publish.rs new file mode 100644 index 00000000..4bb36ce3 --- /dev/null +++ b/ci/xtask/src/commands/publish.rs @@ -0,0 +1 @@ +pub use anza_xtask::commands::publish::{run, CommandArgs}; diff --git a/ci/xtask/src/main.rs b/ci/xtask/src/main.rs new file mode 100644 index 00000000..d2b029ae --- /dev/null +++ b/ci/xtask/src/main.rs @@ -0,0 +1,58 @@ +use { + anyhow::Result, + clap::{Args, Parser, Subcommand}, + log::error, +}; + +mod commands; + +#[derive(Parser)] +#[command(name = "xtask", about = "SVM build and release tasks", version)] +struct Xtask { + #[command(flatten)] + pub global: GlobalOptions, + + #[command(subcommand)] + command: Commands, +} + +#[derive(Subcommand)] +enum Commands { + #[command(about = "Publish crates")] + Publish(commands::publish::CommandArgs), +} + +#[derive(Args, Debug)] +pub struct GlobalOptions { + #[arg(short, long, global = true)] + pub verbose: bool, +} + +fn main() { + if let Err(err) = try_main() { + error!("Error: {err}"); + for (i, cause) in err.chain().skip(1).enumerate() { + error!(" {}: {}", i.saturating_add(1), cause); + } + std::process::exit(1); + } +} + +fn try_main() -> Result<()> { + let xtask = Xtask::parse(); + + if xtask.global.verbose { + std::env::set_var("RUST_LOG", "debug"); + } else { + std::env::set_var("RUST_LOG", "info"); + } + env_logger::init(); + + match xtask.command { + Commands::Publish(args) => { + commands::publish::run(args)?; + } + } + + Ok(()) +} diff --git a/scripts/cargo-for-all-lock-files.sh b/scripts/cargo-for-all-lock-files.sh index b5ea56e2..aeb6e1b9 100755 --- a/scripts/cargo-for-all-lock-files.sh +++ b/scripts/cargo-for-all-lock-files.sh @@ -40,7 +40,7 @@ else fi for lock_file in $files; do - if [[ $lock_file = *ci/xtask/tests/dummy-workspace* ]]; then + if [[ $lock_file = *ci/xtask* ]]; then continue fi if [[ $lock_file = *programs/sbf* ]]; then diff --git a/svm/Cargo.toml b/svm/Cargo.toml index 1cae8d45..0e8ef0d8 100644 --- a/svm/Cargo.toml +++ b/svm/Cargo.toml @@ -109,7 +109,8 @@ solana-secp256k1-program = { workspace = true, features = ["bincode"] } solana-secp256r1-program = { workspace = true, features = ["openssl-vendored"] } solana-signature = { workspace = true, features = ["rand"] } solana-signer = { workspace = true } -# See order-crates-for-publishing.py for using this unusual `path = "."` +# Self-referencing dev-dependency to enable dev-context-only-utils in tests +# Cargo allows this circular dev-dependency when publishing (no explicit version) solana-svm = { path = ".", features = ["agave-unstable-api", "dev-context-only-utils", "svm-internal"] } solana-system-program = { workspace = true } solana-system-transaction = { workspace = true }