diff --git a/.bazelrc b/.bazelrc index e6b2385..e515f02 100644 --- a/.bazelrc +++ b/.bazelrc @@ -6,3 +6,9 @@ test:ci --keep_going # Only show failing test targets to avoid scrolling past a long list of # successful tests in order to see error logs. test:ci --test_summary=terse + +build --aspects=@rules_rust//rust:defs.bzl%rust_clippy_aspect +build --output_groups=+clippy_checks + +build --aspects=@rules_rust//rust:defs.bzl%rustfmt_aspect +build --output_groups=+rustfmt_checks diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index be090b6..fba650a 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -11,3 +11,4 @@ jobs: - uses: actions/checkout@v2 - uses: bazelbuild/setup-bazelisk@v1 - run: bazel test --config=ci //... + - run: bazel run //:gazelle -- -mode diff || exit 1 diff --git a/.gitignore b/.gitignore index c4ddd4b..b3aa306 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ bazel-testlogs bin/ocitool-* node_modules + +target diff --git a/BUILD.bazel b/BUILD.bazel index 3fbba4a..4005e01 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -1,5 +1,6 @@ load("@gazelle//:def.bzl", "DEFAULT_LANGUAGES", "gazelle", "gazelle_binary") load("@npm//:defs.bzl", "npm_link_all_packages") +load("@rules_pkg//pkg:pkg.bzl", "pkg_tar") # gazelle:prefix github.com/DataDog/rules_oci # gazelle:go_naming_convention go_default_library @@ -31,6 +32,17 @@ alias( actual = "@io_bazel_rules_go//go", ) +pkg_tar( + name = "release", + srcs = [ + "//oci:files", + "//oci/private:files", + "//oci/private/repositories:files", + ], + empty_files = ["BUILD.bazel"], + extension = "tar.gz", +) + exports_files( ["WORKSPACE"], visibility = ["//visibility:public"], diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..f47f2d8 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,980 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "cc" +version = "1.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "windows-targets", +] + +[[package]] +name = "clap" +version = "4.5.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "colored" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" +dependencies = [ + "lazy_static", + "windows-sys", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "derive_builder" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" +dependencies = [ + "derive_builder_core", + "syn", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "fs-err" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb60e7409f34ef959985bc9d9c5ee8f5db24ee46ed9775850548021710f807f" +dependencies = [ + "autocfg", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getset" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f636605b743120a8d32ed92fc27b6cde1a769f8f936c065151eb66f88ded513c" +dependencies = [ + "proc-macro-error2", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "js-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "oci-spec" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da406e58efe2eb5986a6139626d611ce426e5324a824133d76367c765cf0b882" +dependencies = [ + "derive_builder", + "getset", + "regex", + "serde", + "serde_json", + "strum", + "strum_macros", + "thiserror", +] + +[[package]] +name = "ocitool" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "colored", + "fs-err", + "hex", + "oci-spec", + "serde", + "serde_json", + "sha2", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustversion" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "serde" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.134" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + +[[package]] +name = "syn" +version = "2.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "987bc0be1cdea8b10216bd06e2ca407d40b9543468fafd3ddfb02f36e77f71f3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "chrono", + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasm-bindgen" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..e935d87 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,19 @@ +[workspace] +resolver = "2" + +members = [ + "ocitool", +] + +[workspace.dependencies] +anyhow = "1.0.95" +clap = { version = "4.5.23", features = ["derive"] } +colored = "2.2.0" +fs-err = "3.0.0" +hex = "0.4.3" +oci-spec = "0.7.1" +serde = { version = "1.0.217", features = ["derive"] } +serde_json = "1.0.134" +sha2 = "0.10.8" +tracing = { version = "0.1.41", features = ["log"] } +tracing-subscriber = { version = "0.3.19", features = ["chrono", "env-filter", "json"] } diff --git a/MODULE.bazel b/MODULE.bazel index 0883ffc..fb6f0f8 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -3,8 +3,8 @@ module( repo_name = "com_github_datadog_rules_oci", ) -bazel_dep(name = "aspect_rules_js", version = "2.1.2") bazel_dep(name = "aspect_bazel_lib", version = "2.7.3") +bazel_dep(name = "aspect_rules_js", version = "2.1.2") bazel_dep(name = "aspect_rules_lint", version = "1.0.8") bazel_dep(name = "bazel_skylib", version = "1.6.1") bazel_dep(name = "gazelle", version = "0.38.0") diff --git a/README.md b/README.md index 76ae584..547db75 100644 --- a/README.md +++ b/README.md @@ -94,14 +94,12 @@ base images. ### Developing -#### Run the tests - -Run `bazel test //...` - -#### Update the docs - -Run `bzl run //docs:update` - -#### Update go dependencies - -Run `bzl run //:go -- get DEPENDENCY` +| action | command | +| ------------------------ | ------------------------------------- | +| Run the tests | `just test` | +| Run the formatter | `just format` | +| Run gazelle | `just gazelle` | +| Update the docs | `just update-docs` | +| Update go dependencies | `bazel run //:go -- get ` | +| Update rust dependencies | `just update-crates` | +| Publish a new release | `just release` | diff --git a/WORKSPACE b/WORKSPACE index 205e32c..09ce670 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1 +1,44 @@ workspace(name = "com_github_datadog_rules_oci") + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +# If this is updated, make sure you also update rust-toolchain.toml +_RUSTC_VERSION = "1.81.0" + +http_archive( + name = "rules_rust", + integrity = "sha256-r09Wyq5QqZpov845sUG1Cd1oVIyCBLmKt6HK/JTVuwI=", + urls = ["https://github.com/bazelbuild/rules_rust/releases/download/0.54.1/rules_rust-v0.54.1.tar.gz"], +) + +load("@rules_rust//rust:repositories.bzl", "rules_rust_dependencies", "rust_register_toolchains") + +rules_rust_dependencies() + +rust_register_toolchains( + edition = "2021", + extra_target_triples = [ + "aarch64-unknown-linux-gnu", + "aarch64-apple-darwin", + "x86_64-apple-darwin", + "x86_64-unknown-linux-gnu", + ], + versions = [_RUSTC_VERSION], +) + +load("@rules_rust//crate_universe:defs.bzl", "crates_repository") + +crates_repository( + name = "crate_index", + cargo_lockfile = "//:Cargo.lock", + lockfile = "//:cargo-bazel-lock.json", + manifests = [ + "//:Cargo.toml", + "//ocitool:Cargo.toml", + ], + rust_version = _RUSTC_VERSION, +) + +load("@crate_index//:defs.bzl", "crate_repositories") + +crate_repositories() diff --git a/cargo-bazel-lock.json b/cargo-bazel-lock.json new file mode 100644 index 0000000..59524c0 --- /dev/null +++ b/cargo-bazel-lock.json @@ -0,0 +1,7016 @@ +{ + "checksum": "030e153464f00aa0a15a3162aa3e206b5e42faf52412bf783ec58f62406c22bc", + "crates": { + "aho-corasick 1.1.3": { + "name": "aho-corasick", + "version": "1.1.3", + "package_url": "https://github.com/BurntSushi/aho-corasick", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/aho-corasick/1.1.3/download", + "sha256": "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" + } + }, + "targets": [ + { + "Library": { + "crate_name": "aho_corasick", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "aho_corasick", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "perf-literal", + "std" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "memchr 2.7.4", + "target": "memchr" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "1.1.3" + }, + "license": "Unlicense OR MIT", + "license_ids": [ + "MIT", + "Unlicense" + ], + "license_file": "LICENSE-MIT" + }, + "android-tzdata 0.1.1": { + "name": "android-tzdata", + "version": "0.1.1", + "package_url": "https://github.com/RumovZ/android-tzdata", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/android-tzdata/0.1.1/download", + "sha256": "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + } + }, + "targets": [ + { + "Library": { + "crate_name": "android_tzdata", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "android_tzdata", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2018", + "version": "0.1.1" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "android_system_properties 0.1.5": { + "name": "android_system_properties", + "version": "0.1.5", + "package_url": "https://github.com/nical/android_system_properties", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/android_system_properties/0.1.5/download", + "sha256": "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" + } + }, + "targets": [ + { + "Library": { + "crate_name": "android_system_properties", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "android_system_properties", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "libc 0.2.169", + "target": "libc" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.1.5" + }, + "license": "MIT/Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "anstream 0.6.18": { + "name": "anstream", + "version": "0.6.18", + "package_url": "https://github.com/rust-cli/anstyle.git", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/anstream/0.6.18/download", + "sha256": "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" + } + }, + "targets": [ + { + "Library": { + "crate_name": "anstream", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "anstream", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "auto", + "default", + "wincon" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "anstyle 1.0.10", + "target": "anstyle" + }, + { + "id": "anstyle-parse 0.2.6", + "target": "anstyle_parse" + }, + { + "id": "anstyle-query 1.1.2", + "target": "anstyle_query" + }, + { + "id": "colorchoice 1.0.3", + "target": "colorchoice" + }, + { + "id": "is_terminal_polyfill 1.70.1", + "target": "is_terminal_polyfill" + }, + { + "id": "utf8parse 0.2.2", + "target": "utf8parse" + } + ], + "selects": { + "aarch64-pc-windows-msvc": [ + { + "id": "anstyle-wincon 3.0.6", + "target": "anstyle_wincon" + } + ], + "i686-pc-windows-msvc": [ + { + "id": "anstyle-wincon 3.0.6", + "target": "anstyle_wincon" + } + ], + "x86_64-pc-windows-msvc": [ + { + "id": "anstyle-wincon 3.0.6", + "target": "anstyle_wincon" + } + ] + } + }, + "edition": "2021", + "version": "0.6.18" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "anstyle 1.0.10": { + "name": "anstyle", + "version": "1.0.10", + "package_url": "https://github.com/rust-cli/anstyle.git", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/anstyle/1.0.10/download", + "sha256": "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + } + }, + "targets": [ + { + "Library": { + "crate_name": "anstyle", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "anstyle", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "std" + ], + "selects": {} + }, + "edition": "2021", + "version": "1.0.10" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "anstyle-parse 0.2.6": { + "name": "anstyle-parse", + "version": "0.2.6", + "package_url": "https://github.com/rust-cli/anstyle.git", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/anstyle-parse/0.2.6/download", + "sha256": "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" + } + }, + "targets": [ + { + "Library": { + "crate_name": "anstyle_parse", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "anstyle_parse", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "utf8" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "utf8parse 0.2.2", + "target": "utf8parse" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.2.6" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "anstyle-query 1.1.2": { + "name": "anstyle-query", + "version": "1.1.2", + "package_url": "https://github.com/rust-cli/anstyle.git", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/anstyle-query/1.1.2/download", + "sha256": "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" + } + }, + "targets": [ + { + "Library": { + "crate_name": "anstyle_query", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "anstyle_query", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [], + "selects": { + "cfg(windows)": [ + { + "id": "windows-sys 0.59.0", + "target": "windows_sys" + } + ] + } + }, + "edition": "2021", + "version": "1.1.2" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "anstyle-wincon 3.0.6": { + "name": "anstyle-wincon", + "version": "3.0.6", + "package_url": "https://github.com/rust-cli/anstyle.git", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/anstyle-wincon/3.0.6/download", + "sha256": "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" + } + }, + "targets": [ + { + "Library": { + "crate_name": "anstyle_wincon", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "anstyle_wincon", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "anstyle 1.0.10", + "target": "anstyle" + } + ], + "selects": { + "cfg(windows)": [ + { + "id": "windows-sys 0.59.0", + "target": "windows_sys" + } + ] + } + }, + "edition": "2021", + "version": "3.0.6" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "anyhow 1.0.95": { + "name": "anyhow", + "version": "1.0.95", + "package_url": "https://github.com/dtolnay/anyhow", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/anyhow/1.0.95/download", + "sha256": "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" + } + }, + "targets": [ + { + "Library": { + "crate_name": "anyhow", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "anyhow", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "std" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "anyhow 1.0.95", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "1.0.95" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "autocfg 1.4.0": { + "name": "autocfg", + "version": "1.4.0", + "package_url": "https://github.com/cuviper/autocfg", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/autocfg/1.4.0/download", + "sha256": "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + } + }, + "targets": [ + { + "Library": { + "crate_name": "autocfg", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "autocfg", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2015", + "version": "1.4.0" + }, + "license": "Apache-2.0 OR MIT", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "block-buffer 0.10.4": { + "name": "block-buffer", + "version": "0.10.4", + "package_url": "https://github.com/RustCrypto/utils", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/block-buffer/0.10.4/download", + "sha256": "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" + } + }, + "targets": [ + { + "Library": { + "crate_name": "block_buffer", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "block_buffer", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "generic-array 0.14.7", + "target": "generic_array" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.10.4" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "bumpalo 3.16.0": { + "name": "bumpalo", + "version": "3.16.0", + "package_url": "https://github.com/fitzgen/bumpalo", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/bumpalo/3.16.0/download", + "sha256": "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + } + }, + "targets": [ + { + "Library": { + "crate_name": "bumpalo", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "bumpalo", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default" + ], + "selects": {} + }, + "edition": "2021", + "version": "3.16.0" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "cc 1.2.6": { + "name": "cc", + "version": "1.2.6", + "package_url": "https://github.com/rust-lang/cc-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/cc/1.2.6/download", + "sha256": "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" + } + }, + "targets": [ + { + "Library": { + "crate_name": "cc", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "cc", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "shlex 1.3.0", + "target": "shlex" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "1.2.6" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "cfg-if 1.0.0": { + "name": "cfg-if", + "version": "1.0.0", + "package_url": "https://github.com/alexcrichton/cfg-if", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/cfg-if/1.0.0/download", + "sha256": "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + } + }, + "targets": [ + { + "Library": { + "crate_name": "cfg_if", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "cfg_if", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2018", + "version": "1.0.0" + }, + "license": "MIT/Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "chrono 0.4.39": { + "name": "chrono", + "version": "0.4.39", + "package_url": "https://github.com/chronotope/chrono", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/chrono/0.4.39/download", + "sha256": "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" + } + }, + "targets": [ + { + "Library": { + "crate_name": "chrono", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "chrono", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "alloc", + "android-tzdata", + "clock", + "iana-time-zone", + "now", + "std", + "winapi", + "windows-targets" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "num-traits 0.2.19", + "target": "num_traits" + } + ], + "selects": { + "aarch64-apple-darwin": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "aarch64-apple-ios": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "aarch64-apple-ios-sim": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "aarch64-linux-android": [ + { + "id": "android-tzdata 0.1.1", + "target": "android_tzdata" + }, + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "aarch64-pc-windows-msvc": [ + { + "id": "windows-targets 0.52.6", + "target": "windows_targets" + } + ], + "aarch64-unknown-fuchsia": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "aarch64-unknown-linux-gnu": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "aarch64-unknown-nixos-gnu": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "aarch64-unknown-nto-qnx710": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "arm-unknown-linux-gnueabi": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "armv7-linux-androideabi": [ + { + "id": "android-tzdata 0.1.1", + "target": "android_tzdata" + }, + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "armv7-unknown-linux-gnueabi": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "i686-apple-darwin": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "i686-linux-android": [ + { + "id": "android-tzdata 0.1.1", + "target": "android_tzdata" + }, + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "i686-pc-windows-msvc": [ + { + "id": "windows-targets 0.52.6", + "target": "windows_targets" + } + ], + "i686-unknown-freebsd": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "i686-unknown-linux-gnu": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "powerpc-unknown-linux-gnu": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "s390x-unknown-linux-gnu": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "x86_64-apple-darwin": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "x86_64-apple-ios": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "x86_64-linux-android": [ + { + "id": "android-tzdata 0.1.1", + "target": "android_tzdata" + }, + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "x86_64-pc-windows-msvc": [ + { + "id": "windows-targets 0.52.6", + "target": "windows_targets" + } + ], + "x86_64-unknown-freebsd": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "x86_64-unknown-fuchsia": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "x86_64-unknown-linux-gnu": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ], + "x86_64-unknown-nixos-gnu": [ + { + "id": "iana-time-zone 0.1.61", + "target": "iana_time_zone" + } + ] + } + }, + "edition": "2021", + "version": "0.4.39" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE.txt" + }, + "clap 4.5.23": { + "name": "clap", + "version": "4.5.23", + "package_url": "https://github.com/clap-rs/clap", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/clap/4.5.23/download", + "sha256": "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" + } + }, + "targets": [ + { + "Library": { + "crate_name": "clap", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "clap", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "color", + "default", + "derive", + "error-context", + "help", + "std", + "suggestions", + "usage" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "clap_builder 4.5.23", + "target": "clap_builder" + } + ], + "selects": {} + }, + "edition": "2021", + "proc_macro_deps": { + "common": [ + { + "id": "clap_derive 4.5.18", + "target": "clap_derive" + } + ], + "selects": {} + }, + "version": "4.5.23" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "clap_builder 4.5.23": { + "name": "clap_builder", + "version": "4.5.23", + "package_url": "https://github.com/clap-rs/clap", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/clap_builder/4.5.23/download", + "sha256": "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" + } + }, + "targets": [ + { + "Library": { + "crate_name": "clap_builder", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "clap_builder", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "color", + "error-context", + "help", + "std", + "suggestions", + "usage" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "anstream 0.6.18", + "target": "anstream" + }, + { + "id": "anstyle 1.0.10", + "target": "anstyle" + }, + { + "id": "clap_lex 0.7.4", + "target": "clap_lex" + }, + { + "id": "strsim 0.11.1", + "target": "strsim" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "4.5.23" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "clap_derive 4.5.18": { + "name": "clap_derive", + "version": "4.5.18", + "package_url": "https://github.com/clap-rs/clap", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/clap_derive/4.5.18/download", + "sha256": "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" + } + }, + "targets": [ + { + "ProcMacro": { + "crate_name": "clap_derive", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "clap_derive", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "heck 0.5.0", + "target": "heck" + }, + { + "id": "proc-macro2 1.0.92", + "target": "proc_macro2" + }, + { + "id": "quote 1.0.38", + "target": "quote" + }, + { + "id": "syn 2.0.94", + "target": "syn" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "4.5.18" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "clap_lex 0.7.4": { + "name": "clap_lex", + "version": "0.7.4", + "package_url": "https://github.com/clap-rs/clap", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/clap_lex/0.7.4/download", + "sha256": "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + } + }, + "targets": [ + { + "Library": { + "crate_name": "clap_lex", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "clap_lex", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2021", + "version": "0.7.4" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "colorchoice 1.0.3": { + "name": "colorchoice", + "version": "1.0.3", + "package_url": "https://github.com/rust-cli/anstyle.git", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/colorchoice/1.0.3/download", + "sha256": "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + } + }, + "targets": [ + { + "Library": { + "crate_name": "colorchoice", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "colorchoice", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2021", + "version": "1.0.3" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "colored 2.2.0": { + "name": "colored", + "version": "2.2.0", + "package_url": "https://github.com/mackwic/colored", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/colored/2.2.0/download", + "sha256": "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" + } + }, + "targets": [ + { + "Library": { + "crate_name": "colored", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "colored", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "lazy_static 1.5.0", + "target": "lazy_static" + } + ], + "selects": { + "cfg(windows)": [ + { + "id": "windows-sys 0.59.0", + "target": "windows_sys" + } + ] + } + }, + "edition": "2021", + "version": "2.2.0" + }, + "license": "MPL-2.0", + "license_ids": [ + "MPL-2.0" + ], + "license_file": "LICENSE" + }, + "core-foundation-sys 0.8.7": { + "name": "core-foundation-sys", + "version": "0.8.7", + "package_url": "https://github.com/servo/core-foundation-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/core-foundation-sys/0.8.7/download", + "sha256": "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + } + }, + "targets": [ + { + "Library": { + "crate_name": "core_foundation_sys", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "core_foundation_sys", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "link" + ], + "selects": {} + }, + "edition": "2018", + "version": "0.8.7" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "cpufeatures 0.2.16": { + "name": "cpufeatures", + "version": "0.2.16", + "package_url": "https://github.com/RustCrypto/utils", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/cpufeatures/0.2.16/download", + "sha256": "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" + } + }, + "targets": [ + { + "Library": { + "crate_name": "cpufeatures", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "cpufeatures", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [], + "selects": { + "aarch64-linux-android": [ + { + "id": "libc 0.2.169", + "target": "libc" + } + ], + "cfg(all(target_arch = \"aarch64\", target_os = \"linux\"))": [ + { + "id": "libc 0.2.169", + "target": "libc" + } + ], + "cfg(all(target_arch = \"aarch64\", target_vendor = \"apple\"))": [ + { + "id": "libc 0.2.169", + "target": "libc" + } + ], + "cfg(all(target_arch = \"loongarch64\", target_os = \"linux\"))": [ + { + "id": "libc 0.2.169", + "target": "libc" + } + ] + } + }, + "edition": "2018", + "version": "0.2.16" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "crypto-common 0.1.6": { + "name": "crypto-common", + "version": "0.1.6", + "package_url": "https://github.com/RustCrypto/traits", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/crypto-common/0.1.6/download", + "sha256": "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" + } + }, + "targets": [ + { + "Library": { + "crate_name": "crypto_common", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "crypto_common", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "std" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "generic-array 0.14.7", + "target": "generic_array" + }, + { + "id": "typenum 1.17.0", + "target": "typenum" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.1.6" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "darling 0.20.10": { + "name": "darling", + "version": "0.20.10", + "package_url": "https://github.com/TedDriggs/darling", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/darling/0.20.10/download", + "sha256": "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" + } + }, + "targets": [ + { + "Library": { + "crate_name": "darling", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "darling", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "suggestions" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "darling_core 0.20.10", + "target": "darling_core" + } + ], + "selects": {} + }, + "edition": "2021", + "proc_macro_deps": { + "common": [ + { + "id": "darling_macro 0.20.10", + "target": "darling_macro" + } + ], + "selects": {} + }, + "version": "0.20.10" + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": "LICENSE" + }, + "darling_core 0.20.10": { + "name": "darling_core", + "version": "0.20.10", + "package_url": "https://github.com/TedDriggs/darling", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/darling_core/0.20.10/download", + "sha256": "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" + } + }, + "targets": [ + { + "Library": { + "crate_name": "darling_core", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "darling_core", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "strsim", + "suggestions" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "fnv 1.0.7", + "target": "fnv" + }, + { + "id": "ident_case 1.0.1", + "target": "ident_case" + }, + { + "id": "proc-macro2 1.0.92", + "target": "proc_macro2" + }, + { + "id": "quote 1.0.38", + "target": "quote" + }, + { + "id": "strsim 0.11.1", + "target": "strsim" + }, + { + "id": "syn 2.0.94", + "target": "syn" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.20.10" + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": "LICENSE" + }, + "darling_macro 0.20.10": { + "name": "darling_macro", + "version": "0.20.10", + "package_url": "https://github.com/TedDriggs/darling", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/darling_macro/0.20.10/download", + "sha256": "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" + } + }, + "targets": [ + { + "ProcMacro": { + "crate_name": "darling_macro", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "darling_macro", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "darling_core 0.20.10", + "target": "darling_core" + }, + { + "id": "quote 1.0.38", + "target": "quote" + }, + { + "id": "syn 2.0.94", + "target": "syn" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.20.10" + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": "LICENSE" + }, + "derive_builder 0.20.2": { + "name": "derive_builder", + "version": "0.20.2", + "package_url": "https://github.com/colin-kiegel/rust-derive-builder", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/derive_builder/0.20.2/download", + "sha256": "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" + } + }, + "targets": [ + { + "Library": { + "crate_name": "derive_builder", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "derive_builder", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "std" + ], + "selects": {} + }, + "edition": "2018", + "proc_macro_deps": { + "common": [ + { + "id": "derive_builder_macro 0.20.2", + "target": "derive_builder_macro" + } + ], + "selects": {} + }, + "version": "0.20.2" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "derive_builder_core 0.20.2": { + "name": "derive_builder_core", + "version": "0.20.2", + "package_url": "https://github.com/colin-kiegel/rust-derive-builder", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/derive_builder_core/0.20.2/download", + "sha256": "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" + } + }, + "targets": [ + { + "Library": { + "crate_name": "derive_builder_core", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "derive_builder_core", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "lib_has_std" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "darling 0.20.10", + "target": "darling" + }, + { + "id": "proc-macro2 1.0.92", + "target": "proc_macro2" + }, + { + "id": "quote 1.0.38", + "target": "quote" + }, + { + "id": "syn 2.0.94", + "target": "syn" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.20.2" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "derive_builder_macro 0.20.2": { + "name": "derive_builder_macro", + "version": "0.20.2", + "package_url": "https://github.com/colin-kiegel/rust-derive-builder", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/derive_builder_macro/0.20.2/download", + "sha256": "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" + } + }, + "targets": [ + { + "ProcMacro": { + "crate_name": "derive_builder_macro", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "derive_builder_macro", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "lib_has_std" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "derive_builder_core 0.20.2", + "target": "derive_builder_core" + }, + { + "id": "syn 2.0.94", + "target": "syn" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.20.2" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "digest 0.10.7": { + "name": "digest", + "version": "0.10.7", + "package_url": "https://github.com/RustCrypto/traits", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/digest/0.10.7/download", + "sha256": "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" + } + }, + "targets": [ + { + "Library": { + "crate_name": "digest", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "digest", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "alloc", + "block-buffer", + "core-api", + "default", + "std" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "block-buffer 0.10.4", + "target": "block_buffer" + }, + { + "id": "crypto-common 0.1.6", + "target": "crypto_common" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.10.7" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "fnv 1.0.7": { + "name": "fnv", + "version": "1.0.7", + "package_url": "https://github.com/servo/rust-fnv", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/fnv/1.0.7/download", + "sha256": "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + } + }, + "targets": [ + { + "Library": { + "crate_name": "fnv", + "crate_root": "lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "fnv", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "std" + ], + "selects": {} + }, + "edition": "2015", + "version": "1.0.7" + }, + "license": "Apache-2.0 / MIT", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "fs-err 3.0.0": { + "name": "fs-err", + "version": "3.0.0", + "package_url": "https://github.com/andrewhickman/fs-err", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/fs-err/3.0.0/download", + "sha256": "8bb60e7409f34ef959985bc9d9c5ee8f5db24ee46ed9775850548021710f807f" + } + }, + "targets": [ + { + "Library": { + "crate_name": "fs_err", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "fs_err", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "fs-err 3.0.0", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "3.0.0" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "autocfg 1.4.0", + "target": "autocfg" + } + ], + "selects": {} + } + }, + "license": "MIT/Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "generic-array 0.14.7": { + "name": "generic-array", + "version": "0.14.7", + "package_url": "https://github.com/fizyk20/generic-array.git", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/generic-array/0.14.7/download", + "sha256": "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" + } + }, + "targets": [ + { + "Library": { + "crate_name": "generic_array", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "generic_array", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "more_lengths" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "generic-array 0.14.7", + "target": "build_script_build" + }, + { + "id": "typenum 1.17.0", + "target": "typenum" + } + ], + "selects": {} + }, + "edition": "2015", + "version": "0.14.7" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "version_check 0.9.5", + "target": "version_check" + } + ], + "selects": {} + } + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": "LICENSE" + }, + "getset 0.1.3": { + "name": "getset", + "version": "0.1.3", + "package_url": "https://github.com/jbaublitz/getset", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/getset/0.1.3/download", + "sha256": "f636605b743120a8d32ed92fc27b6cde1a769f8f936c065151eb66f88ded513c" + } + }, + "targets": [ + { + "ProcMacro": { + "crate_name": "getset", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "getset", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "proc-macro-error2 2.0.1", + "target": "proc_macro_error2" + }, + { + "id": "proc-macro2 1.0.92", + "target": "proc_macro2" + }, + { + "id": "quote 1.0.38", + "target": "quote" + }, + { + "id": "syn 2.0.94", + "target": "syn" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.1.3" + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": "LICENSE" + }, + "heck 0.5.0": { + "name": "heck", + "version": "0.5.0", + "package_url": "https://github.com/withoutboats/heck", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/heck/0.5.0/download", + "sha256": "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + } + }, + "targets": [ + { + "Library": { + "crate_name": "heck", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "heck", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2021", + "version": "0.5.0" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "hex 0.4.3": { + "name": "hex", + "version": "0.4.3", + "package_url": "https://github.com/KokaKiwi/rust-hex", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/hex/0.4.3/download", + "sha256": "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + } + }, + "targets": [ + { + "Library": { + "crate_name": "hex", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "hex", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "alloc", + "default", + "std" + ], + "selects": {} + }, + "edition": "2018", + "version": "0.4.3" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "iana-time-zone 0.1.61": { + "name": "iana-time-zone", + "version": "0.1.61", + "package_url": "https://github.com/strawlab/iana-time-zone", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/iana-time-zone/0.1.61/download", + "sha256": "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" + } + }, + "targets": [ + { + "Library": { + "crate_name": "iana_time_zone", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "iana_time_zone", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "fallback" + ], + "selects": {} + }, + "deps": { + "common": [], + "selects": { + "cfg(all(target_arch = \"wasm32\", target_os = \"unknown\"))": [ + { + "id": "js-sys 0.3.76", + "target": "js_sys" + }, + { + "id": "wasm-bindgen 0.2.99", + "target": "wasm_bindgen" + } + ], + "cfg(any(target_os = \"macos\", target_os = \"ios\"))": [ + { + "id": "core-foundation-sys 0.8.7", + "target": "core_foundation_sys" + } + ], + "cfg(target_os = \"android\")": [ + { + "id": "android_system_properties 0.1.5", + "target": "android_system_properties" + } + ], + "cfg(target_os = \"haiku\")": [ + { + "id": "iana-time-zone-haiku 0.1.2", + "target": "iana_time_zone_haiku" + } + ], + "cfg(target_os = \"windows\")": [ + { + "id": "windows-core 0.52.0", + "target": "windows_core" + } + ] + } + }, + "edition": "2018", + "version": "0.1.61" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "iana-time-zone-haiku 0.1.2": { + "name": "iana-time-zone-haiku", + "version": "0.1.2", + "package_url": "https://github.com/strawlab/iana-time-zone", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/iana-time-zone-haiku/0.1.2/download", + "sha256": "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" + } + }, + "targets": [ + { + "Library": { + "crate_name": "iana_time_zone_haiku", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "iana_time_zone_haiku", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "iana-time-zone-haiku 0.1.2", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.1.2" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "cc 1.2.6", + "target": "cc" + } + ], + "selects": {} + } + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "ident_case 1.0.1": { + "name": "ident_case", + "version": "1.0.1", + "package_url": "https://github.com/TedDriggs/ident_case", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/ident_case/1.0.1/download", + "sha256": "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + } + }, + "targets": [ + { + "Library": { + "crate_name": "ident_case", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "ident_case", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2015", + "version": "1.0.1" + }, + "license": "MIT/Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE" + }, + "is_terminal_polyfill 1.70.1": { + "name": "is_terminal_polyfill", + "version": "1.70.1", + "package_url": "https://github.com/polyfill-rs/is_terminal_polyfill", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/is_terminal_polyfill/1.70.1/download", + "sha256": "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + } + }, + "targets": [ + { + "Library": { + "crate_name": "is_terminal_polyfill", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "is_terminal_polyfill", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default" + ], + "selects": {} + }, + "edition": "2021", + "version": "1.70.1" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "itoa 1.0.14": { + "name": "itoa", + "version": "1.0.14", + "package_url": "https://github.com/dtolnay/itoa", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/itoa/1.0.14/download", + "sha256": "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + } + }, + "targets": [ + { + "Library": { + "crate_name": "itoa", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "itoa", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2018", + "version": "1.0.14" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "js-sys 0.3.76": { + "name": "js-sys", + "version": "0.3.76", + "package_url": "https://github.com/rustwasm/wasm-bindgen/tree/master/crates/js-sys", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/js-sys/0.3.76/download", + "sha256": "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" + } + }, + "targets": [ + { + "Library": { + "crate_name": "js_sys", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "js_sys", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "once_cell 1.20.2", + "target": "once_cell" + }, + { + "id": "wasm-bindgen 0.2.99", + "target": "wasm_bindgen" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.3.76" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "lazy_static 1.5.0": { + "name": "lazy_static", + "version": "1.5.0", + "package_url": "https://github.com/rust-lang-nursery/lazy-static.rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/lazy_static/1.5.0/download", + "sha256": "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + } + }, + "targets": [ + { + "Library": { + "crate_name": "lazy_static", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "lazy_static", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2015", + "version": "1.5.0" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "libc 0.2.169": { + "name": "libc", + "version": "0.2.169", + "package_url": "https://github.com/rust-lang/libc", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/libc/0.2.169/download", + "sha256": "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + } + }, + "targets": [ + { + "Library": { + "crate_name": "libc", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "libc", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "std" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "libc 0.2.169", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.2.169" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "log 0.4.22": { + "name": "log", + "version": "0.4.22", + "package_url": "https://github.com/rust-lang/log", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/log/0.4.22/download", + "sha256": "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + } + }, + "targets": [ + { + "Library": { + "crate_name": "log", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "log", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "std" + ], + "selects": {} + }, + "edition": "2021", + "version": "0.4.22" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "matchers 0.1.0": { + "name": "matchers", + "version": "0.1.0", + "package_url": "https://github.com/hawkw/matchers", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/matchers/0.1.0/download", + "sha256": "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" + } + }, + "targets": [ + { + "Library": { + "crate_name": "matchers", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "matchers", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "regex-automata 0.1.10", + "target": "regex_automata" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.1.0" + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": "LICENSE" + }, + "memchr 2.7.4": { + "name": "memchr", + "version": "2.7.4", + "package_url": "https://github.com/BurntSushi/memchr", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/memchr/2.7.4/download", + "sha256": "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + } + }, + "targets": [ + { + "Library": { + "crate_name": "memchr", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "memchr", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "alloc", + "std" + ], + "selects": {} + }, + "edition": "2021", + "version": "2.7.4" + }, + "license": "Unlicense OR MIT", + "license_ids": [ + "MIT", + "Unlicense" + ], + "license_file": "LICENSE-MIT" + }, + "nu-ansi-term 0.46.0": { + "name": "nu-ansi-term", + "version": "0.46.0", + "package_url": "https://github.com/nushell/nu-ansi-term", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/nu-ansi-term/0.46.0/download", + "sha256": "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" + } + }, + "targets": [ + { + "Library": { + "crate_name": "nu_ansi_term", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "nu_ansi_term", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "overload 0.1.1", + "target": "overload" + } + ], + "selects": { + "cfg(target_os = \"windows\")": [ + { + "id": "winapi 0.3.9", + "target": "winapi" + } + ] + } + }, + "edition": "2018", + "version": "0.46.0" + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": null + }, + "num-traits 0.2.19": { + "name": "num-traits", + "version": "0.2.19", + "package_url": "https://github.com/rust-num/num-traits", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/num-traits/0.2.19/download", + "sha256": "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" + } + }, + "targets": [ + { + "Library": { + "crate_name": "num_traits", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "num_traits", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "num-traits 0.2.19", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.2.19" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "autocfg 1.4.0", + "target": "autocfg" + } + ], + "selects": {} + } + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "oci-spec 0.7.1": { + "name": "oci-spec", + "version": "0.7.1", + "package_url": "https://github.com/containers/oci-spec-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/oci-spec/0.7.1/download", + "sha256": "da406e58efe2eb5986a6139626d611ce426e5324a824133d76367c765cf0b882" + } + }, + "targets": [ + { + "Library": { + "crate_name": "oci_spec", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "oci_spec", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "distribution", + "image", + "runtime" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "derive_builder 0.20.2", + "target": "derive_builder" + }, + { + "id": "regex 1.11.1", + "target": "regex" + }, + { + "id": "serde 1.0.217", + "target": "serde" + }, + { + "id": "serde_json 1.0.134", + "target": "serde_json" + }, + { + "id": "strum 0.26.3", + "target": "strum" + }, + { + "id": "thiserror 2.0.9", + "target": "thiserror" + } + ], + "selects": {} + }, + "edition": "2021", + "proc_macro_deps": { + "common": [ + { + "id": "getset 0.1.3", + "target": "getset" + }, + { + "id": "strum_macros 0.26.4", + "target": "strum_macros" + } + ], + "selects": {} + }, + "version": "0.7.1" + }, + "license": "Apache-2.0", + "license_ids": [ + "Apache-2.0" + ], + "license_file": "LICENSE" + }, + "ocitool 0.1.0": { + "name": "ocitool", + "version": "0.1.0", + "package_url": null, + "repository": null, + "targets": [], + "library_target_name": null, + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "anyhow 1.0.95", + "target": "anyhow" + }, + { + "id": "clap 4.5.23", + "target": "clap" + }, + { + "id": "colored 2.2.0", + "target": "colored" + }, + { + "id": "fs-err 3.0.0", + "target": "fs_err" + }, + { + "id": "hex 0.4.3", + "target": "hex" + }, + { + "id": "oci-spec 0.7.1", + "target": "oci_spec" + }, + { + "id": "serde 1.0.217", + "target": "serde" + }, + { + "id": "serde_json 1.0.134", + "target": "serde_json" + }, + { + "id": "sha2 0.10.8", + "target": "sha2" + }, + { + "id": "tracing 0.1.41", + "target": "tracing" + }, + { + "id": "tracing-subscriber 0.3.19", + "target": "tracing_subscriber" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.1.0" + }, + "license": null, + "license_ids": [], + "license_file": null + }, + "once_cell 1.20.2": { + "name": "once_cell", + "version": "1.20.2", + "package_url": "https://github.com/matklad/once_cell", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/once_cell/1.20.2/download", + "sha256": "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + } + }, + "targets": [ + { + "Library": { + "crate_name": "once_cell", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "once_cell", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "alloc", + "default", + "race", + "std" + ], + "selects": {} + }, + "edition": "2021", + "version": "1.20.2" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "overload 0.1.1": { + "name": "overload", + "version": "0.1.1", + "package_url": "https://github.com/danaugrs/overload", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/overload/0.1.1/download", + "sha256": "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + } + }, + "targets": [ + { + "Library": { + "crate_name": "overload", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "overload", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2018", + "version": "0.1.1" + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": "LICENSE" + }, + "pin-project-lite 0.2.15": { + "name": "pin-project-lite", + "version": "0.2.15", + "package_url": "https://github.com/taiki-e/pin-project-lite", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/pin-project-lite/0.2.15/download", + "sha256": "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + } + }, + "targets": [ + { + "Library": { + "crate_name": "pin_project_lite", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "pin_project_lite", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2018", + "version": "0.2.15" + }, + "license": "Apache-2.0 OR MIT", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "proc-macro-error-attr2 2.0.0": { + "name": "proc-macro-error-attr2", + "version": "2.0.0", + "package_url": "https://github.com/GnomedDev/proc-macro-error-2", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/proc-macro-error-attr2/2.0.0/download", + "sha256": "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" + } + }, + "targets": [ + { + "ProcMacro": { + "crate_name": "proc_macro_error_attr2", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "proc_macro_error_attr2", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "proc-macro2 1.0.92", + "target": "proc_macro2" + }, + { + "id": "quote 1.0.38", + "target": "quote" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "2.0.0" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "proc-macro-error2 2.0.1": { + "name": "proc-macro-error2", + "version": "2.0.1", + "package_url": "https://github.com/GnomedDev/proc-macro-error-2", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/proc-macro-error2/2.0.1/download", + "sha256": "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" + } + }, + "targets": [ + { + "Library": { + "crate_name": "proc_macro_error2", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "proc_macro_error2", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "syn-error" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "proc-macro2 1.0.92", + "target": "proc_macro2" + }, + { + "id": "quote 1.0.38", + "target": "quote" + }, + { + "id": "syn 2.0.94", + "target": "syn" + } + ], + "selects": {} + }, + "edition": "2021", + "proc_macro_deps": { + "common": [ + { + "id": "proc-macro-error-attr2 2.0.0", + "target": "proc_macro_error_attr2" + } + ], + "selects": {} + }, + "version": "2.0.1" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "proc-macro2 1.0.92": { + "name": "proc-macro2", + "version": "1.0.92", + "package_url": "https://github.com/dtolnay/proc-macro2", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/proc-macro2/1.0.92/download", + "sha256": "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" + } + }, + "targets": [ + { + "Library": { + "crate_name": "proc_macro2", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "proc_macro2", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "proc-macro" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "proc-macro2 1.0.92", + "target": "build_script_build" + }, + { + "id": "unicode-ident 1.0.14", + "target": "unicode_ident" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "1.0.92" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "quote 1.0.38": { + "name": "quote", + "version": "1.0.38", + "package_url": "https://github.com/dtolnay/quote", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/quote/1.0.38/download", + "sha256": "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" + } + }, + "targets": [ + { + "Library": { + "crate_name": "quote", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "quote", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "proc-macro" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "proc-macro2 1.0.92", + "target": "proc_macro2" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "1.0.38" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "regex 1.11.1": { + "name": "regex", + "version": "1.11.1", + "package_url": "https://github.com/rust-lang/regex", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/regex/1.11.1/download", + "sha256": "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" + } + }, + "targets": [ + { + "Library": { + "crate_name": "regex", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "regex", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "perf", + "perf-backtrack", + "perf-cache", + "perf-dfa", + "perf-inline", + "perf-literal", + "perf-onepass", + "std", + "unicode", + "unicode-age", + "unicode-bool", + "unicode-case", + "unicode-gencat", + "unicode-perl", + "unicode-script", + "unicode-segment" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "aho-corasick 1.1.3", + "target": "aho_corasick" + }, + { + "id": "memchr 2.7.4", + "target": "memchr" + }, + { + "id": "regex-automata 0.4.9", + "target": "regex_automata" + }, + { + "id": "regex-syntax 0.8.5", + "target": "regex_syntax" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "1.11.1" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "regex-automata 0.1.10": { + "name": "regex-automata", + "version": "0.1.10", + "package_url": "https://github.com/BurntSushi/regex-automata", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/regex-automata/0.1.10/download", + "sha256": "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" + } + }, + "targets": [ + { + "Library": { + "crate_name": "regex_automata", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "regex_automata", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "regex-syntax", + "std" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "regex-syntax 0.6.29", + "target": "regex_syntax" + } + ], + "selects": {} + }, + "edition": "2015", + "version": "0.1.10" + }, + "license": "Unlicense/MIT", + "license_ids": [ + "MIT", + "Unlicense" + ], + "license_file": "LICENSE-MIT" + }, + "regex-automata 0.4.9": { + "name": "regex-automata", + "version": "0.4.9", + "package_url": "https://github.com/rust-lang/regex/tree/master/regex-automata", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/regex-automata/0.4.9/download", + "sha256": "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" + } + }, + "targets": [ + { + "Library": { + "crate_name": "regex_automata", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "regex_automata", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "alloc", + "dfa-onepass", + "hybrid", + "meta", + "nfa-backtrack", + "nfa-pikevm", + "nfa-thompson", + "perf-inline", + "perf-literal", + "perf-literal-multisubstring", + "perf-literal-substring", + "std", + "syntax", + "unicode", + "unicode-age", + "unicode-bool", + "unicode-case", + "unicode-gencat", + "unicode-perl", + "unicode-script", + "unicode-segment", + "unicode-word-boundary" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "aho-corasick 1.1.3", + "target": "aho_corasick" + }, + { + "id": "memchr 2.7.4", + "target": "memchr" + }, + { + "id": "regex-syntax 0.8.5", + "target": "regex_syntax" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.4.9" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "regex-syntax 0.6.29": { + "name": "regex-syntax", + "version": "0.6.29", + "package_url": "https://github.com/rust-lang/regex", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/regex-syntax/0.6.29/download", + "sha256": "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + } + }, + "targets": [ + { + "Library": { + "crate_name": "regex_syntax", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "regex_syntax", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "unicode", + "unicode-age", + "unicode-bool", + "unicode-case", + "unicode-gencat", + "unicode-perl", + "unicode-script", + "unicode-segment" + ], + "selects": {} + }, + "edition": "2018", + "version": "0.6.29" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "regex-syntax 0.8.5": { + "name": "regex-syntax", + "version": "0.8.5", + "package_url": "https://github.com/rust-lang/regex/tree/master/regex-syntax", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/regex-syntax/0.8.5/download", + "sha256": "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + } + }, + "targets": [ + { + "Library": { + "crate_name": "regex_syntax", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "regex_syntax", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "std", + "unicode", + "unicode-age", + "unicode-bool", + "unicode-case", + "unicode-gencat", + "unicode-perl", + "unicode-script", + "unicode-segment" + ], + "selects": {} + }, + "edition": "2021", + "version": "0.8.5" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "rustversion 1.0.19": { + "name": "rustversion", + "version": "1.0.19", + "package_url": "https://github.com/dtolnay/rustversion", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/rustversion/1.0.19/download", + "sha256": "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" + } + }, + "targets": [ + { + "ProcMacro": { + "crate_name": "rustversion", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build/build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "rustversion", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "rustversion 1.0.19", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "1.0.19" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "ryu 1.0.18": { + "name": "ryu", + "version": "1.0.18", + "package_url": "https://github.com/dtolnay/ryu", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/ryu/1.0.18/download", + "sha256": "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + } + }, + "targets": [ + { + "Library": { + "crate_name": "ryu", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "ryu", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2018", + "version": "1.0.18" + }, + "license": "Apache-2.0 OR BSL-1.0", + "license_ids": [ + "Apache-2.0", + "BSL-1.0" + ], + "license_file": "LICENSE-APACHE" + }, + "serde 1.0.217": { + "name": "serde", + "version": "1.0.217", + "package_url": "https://github.com/serde-rs/serde", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/serde/1.0.217/download", + "sha256": "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" + } + }, + "targets": [ + { + "Library": { + "crate_name": "serde", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "serde", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "derive", + "serde_derive", + "std" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "serde 1.0.217", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2018", + "proc_macro_deps": { + "common": [ + { + "id": "serde_derive 1.0.217", + "target": "serde_derive" + } + ], + "selects": {} + }, + "version": "1.0.217" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "serde_derive 1.0.217": { + "name": "serde_derive", + "version": "1.0.217", + "package_url": "https://github.com/serde-rs/serde", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/serde_derive/1.0.217/download", + "sha256": "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" + } + }, + "targets": [ + { + "ProcMacro": { + "crate_name": "serde_derive", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "serde_derive", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "proc-macro2 1.0.92", + "target": "proc_macro2" + }, + { + "id": "quote 1.0.38", + "target": "quote" + }, + { + "id": "syn 2.0.94", + "target": "syn" + } + ], + "selects": {} + }, + "edition": "2015", + "version": "1.0.217" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "serde_json 1.0.134": { + "name": "serde_json", + "version": "1.0.134", + "package_url": "https://github.com/serde-rs/json", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/serde_json/1.0.134/download", + "sha256": "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" + } + }, + "targets": [ + { + "Library": { + "crate_name": "serde_json", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "serde_json", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "std" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "itoa 1.0.14", + "target": "itoa" + }, + { + "id": "memchr 2.7.4", + "target": "memchr" + }, + { + "id": "ryu 1.0.18", + "target": "ryu" + }, + { + "id": "serde 1.0.217", + "target": "serde" + }, + { + "id": "serde_json 1.0.134", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "1.0.134" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "sha2 0.10.8": { + "name": "sha2", + "version": "0.10.8", + "package_url": "https://github.com/RustCrypto/hashes", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/sha2/0.10.8/download", + "sha256": "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" + } + }, + "targets": [ + { + "Library": { + "crate_name": "sha2", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "sha2", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "std" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "cfg-if 1.0.0", + "target": "cfg_if" + }, + { + "id": "digest 0.10.7", + "target": "digest" + } + ], + "selects": { + "cfg(any(target_arch = \"aarch64\", target_arch = \"x86_64\", target_arch = \"x86\"))": [ + { + "id": "cpufeatures 0.2.16", + "target": "cpufeatures" + } + ] + } + }, + "edition": "2018", + "version": "0.10.8" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "sharded-slab 0.1.7": { + "name": "sharded-slab", + "version": "0.1.7", + "package_url": "https://github.com/hawkw/sharded-slab", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/sharded-slab/0.1.7/download", + "sha256": "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" + } + }, + "targets": [ + { + "Library": { + "crate_name": "sharded_slab", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "sharded_slab", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "lazy_static 1.5.0", + "target": "lazy_static" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.1.7" + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": "LICENSE" + }, + "shlex 1.3.0": { + "name": "shlex", + "version": "1.3.0", + "package_url": "https://github.com/comex/rust-shlex", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/shlex/1.3.0/download", + "sha256": "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + } + }, + "targets": [ + { + "Library": { + "crate_name": "shlex", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "shlex", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2015", + "version": "1.3.0" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "smallvec 1.13.2": { + "name": "smallvec", + "version": "1.13.2", + "package_url": "https://github.com/servo/rust-smallvec", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/smallvec/1.13.2/download", + "sha256": "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + } + }, + "targets": [ + { + "Library": { + "crate_name": "smallvec", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "smallvec", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2018", + "version": "1.13.2" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "strsim 0.11.1": { + "name": "strsim", + "version": "0.11.1", + "package_url": "https://github.com/rapidfuzz/strsim-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/strsim/0.11.1/download", + "sha256": "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + } + }, + "targets": [ + { + "Library": { + "crate_name": "strsim", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "strsim", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2015", + "version": "0.11.1" + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": "LICENSE" + }, + "strum 0.26.3": { + "name": "strum", + "version": "0.26.3", + "package_url": "https://github.com/Peternator7/strum", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/strum/0.26.3/download", + "sha256": "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" + } + }, + "targets": [ + { + "Library": { + "crate_name": "strum", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "strum", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "std" + ], + "selects": {} + }, + "edition": "2018", + "version": "0.26.3" + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": "LICENSE" + }, + "strum_macros 0.26.4": { + "name": "strum_macros", + "version": "0.26.4", + "package_url": "https://github.com/Peternator7/strum", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/strum_macros/0.26.4/download", + "sha256": "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" + } + }, + "targets": [ + { + "ProcMacro": { + "crate_name": "strum_macros", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "strum_macros", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "heck 0.5.0", + "target": "heck" + }, + { + "id": "proc-macro2 1.0.92", + "target": "proc_macro2" + }, + { + "id": "quote 1.0.38", + "target": "quote" + }, + { + "id": "syn 2.0.94", + "target": "syn" + } + ], + "selects": {} + }, + "edition": "2018", + "proc_macro_deps": { + "common": [ + { + "id": "rustversion 1.0.19", + "target": "rustversion" + } + ], + "selects": {} + }, + "version": "0.26.4" + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": "LICENSE" + }, + "syn 2.0.94": { + "name": "syn", + "version": "2.0.94", + "package_url": "https://github.com/dtolnay/syn", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/syn/2.0.94/download", + "sha256": "987bc0be1cdea8b10216bd06e2ca407d40b9543468fafd3ddfb02f36e77f71f3" + } + }, + "targets": [ + { + "Library": { + "crate_name": "syn", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "syn", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "clone-impls", + "default", + "derive", + "extra-traits", + "full", + "parsing", + "printing", + "proc-macro", + "visit", + "visit-mut" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "proc-macro2 1.0.92", + "target": "proc_macro2" + }, + { + "id": "quote 1.0.38", + "target": "quote" + }, + { + "id": "unicode-ident 1.0.14", + "target": "unicode_ident" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "2.0.94" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "thiserror 2.0.9": { + "name": "thiserror", + "version": "2.0.9", + "package_url": "https://github.com/dtolnay/thiserror", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/thiserror/2.0.9/download", + "sha256": "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc" + } + }, + "targets": [ + { + "Library": { + "crate_name": "thiserror", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "thiserror", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "std" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "thiserror 2.0.9", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2021", + "proc_macro_deps": { + "common": [ + { + "id": "thiserror-impl 2.0.9", + "target": "thiserror_impl" + } + ], + "selects": {} + }, + "version": "2.0.9" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "thiserror-impl 2.0.9": { + "name": "thiserror-impl", + "version": "2.0.9", + "package_url": "https://github.com/dtolnay/thiserror", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/thiserror-impl/2.0.9/download", + "sha256": "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" + } + }, + "targets": [ + { + "ProcMacro": { + "crate_name": "thiserror_impl", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "thiserror_impl", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "proc-macro2 1.0.92", + "target": "proc_macro2" + }, + { + "id": "quote 1.0.38", + "target": "quote" + }, + { + "id": "syn 2.0.94", + "target": "syn" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "2.0.9" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "thread_local 1.1.8": { + "name": "thread_local", + "version": "1.1.8", + "package_url": "https://github.com/Amanieu/thread_local-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/thread_local/1.1.8/download", + "sha256": "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" + } + }, + "targets": [ + { + "Library": { + "crate_name": "thread_local", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "thread_local", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "cfg-if 1.0.0", + "target": "cfg_if" + }, + { + "id": "once_cell 1.20.2", + "target": "once_cell" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "1.1.8" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "tracing 0.1.41": { + "name": "tracing", + "version": "0.1.41", + "package_url": "https://github.com/tokio-rs/tracing", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/tracing/0.1.41/download", + "sha256": "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" + } + }, + "targets": [ + { + "Library": { + "crate_name": "tracing", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "tracing", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "attributes", + "default", + "log", + "std", + "tracing-attributes" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "log 0.4.22", + "target": "log" + }, + { + "id": "pin-project-lite 0.2.15", + "target": "pin_project_lite" + }, + { + "id": "tracing-core 0.1.33", + "target": "tracing_core" + } + ], + "selects": {} + }, + "edition": "2018", + "proc_macro_deps": { + "common": [ + { + "id": "tracing-attributes 0.1.28", + "target": "tracing_attributes" + } + ], + "selects": {} + }, + "version": "0.1.41" + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": "LICENSE" + }, + "tracing-attributes 0.1.28": { + "name": "tracing-attributes", + "version": "0.1.28", + "package_url": "https://github.com/tokio-rs/tracing", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/tracing-attributes/0.1.28/download", + "sha256": "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" + } + }, + "targets": [ + { + "ProcMacro": { + "crate_name": "tracing_attributes", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "tracing_attributes", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "proc-macro2 1.0.92", + "target": "proc_macro2" + }, + { + "id": "quote 1.0.38", + "target": "quote" + }, + { + "id": "syn 2.0.94", + "target": "syn" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.1.28" + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": "LICENSE" + }, + "tracing-core 0.1.33": { + "name": "tracing-core", + "version": "0.1.33", + "package_url": "https://github.com/tokio-rs/tracing", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/tracing-core/0.1.33/download", + "sha256": "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" + } + }, + "targets": [ + { + "Library": { + "crate_name": "tracing_core", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "tracing_core", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "once_cell", + "std" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "once_cell 1.20.2", + "target": "once_cell" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.1.33" + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": "LICENSE" + }, + "tracing-log 0.2.0": { + "name": "tracing-log", + "version": "0.2.0", + "package_url": "https://github.com/tokio-rs/tracing", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/tracing-log/0.2.0/download", + "sha256": "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" + } + }, + "targets": [ + { + "Library": { + "crate_name": "tracing_log", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "tracing_log", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "log-tracer", + "std" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "log 0.4.22", + "target": "log" + }, + { + "id": "once_cell 1.20.2", + "target": "once_cell" + }, + { + "id": "tracing-core 0.1.33", + "target": "tracing_core" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.2.0" + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": "LICENSE" + }, + "tracing-serde 0.2.0": { + "name": "tracing-serde", + "version": "0.2.0", + "package_url": "https://github.com/tokio-rs/tracing", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/tracing-serde/0.2.0/download", + "sha256": "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" + } + }, + "targets": [ + { + "Library": { + "crate_name": "tracing_serde", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "tracing_serde", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "serde 1.0.217", + "target": "serde" + }, + { + "id": "tracing-core 0.1.33", + "target": "tracing_core" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.2.0" + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": "LICENSE" + }, + "tracing-subscriber 0.3.19": { + "name": "tracing-subscriber", + "version": "0.3.19", + "package_url": "https://github.com/tokio-rs/tracing", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/tracing-subscriber/0.3.19/download", + "sha256": "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" + } + }, + "targets": [ + { + "Library": { + "crate_name": "tracing_subscriber", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "tracing_subscriber", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "alloc", + "ansi", + "chrono", + "default", + "env-filter", + "fmt", + "json", + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "registry", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "std", + "thread_local", + "tracing", + "tracing-log", + "tracing-serde" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "chrono 0.4.39", + "target": "chrono" + }, + { + "id": "matchers 0.1.0", + "target": "matchers" + }, + { + "id": "nu-ansi-term 0.46.0", + "target": "nu_ansi_term" + }, + { + "id": "once_cell 1.20.2", + "target": "once_cell" + }, + { + "id": "regex 1.11.1", + "target": "regex" + }, + { + "id": "serde 1.0.217", + "target": "serde" + }, + { + "id": "serde_json 1.0.134", + "target": "serde_json" + }, + { + "id": "sharded-slab 0.1.7", + "target": "sharded_slab" + }, + { + "id": "smallvec 1.13.2", + "target": "smallvec" + }, + { + "id": "thread_local 1.1.8", + "target": "thread_local" + }, + { + "id": "tracing 0.1.41", + "target": "tracing" + }, + { + "id": "tracing-core 0.1.33", + "target": "tracing_core" + }, + { + "id": "tracing-log 0.2.0", + "target": "tracing_log" + }, + { + "id": "tracing-serde 0.2.0", + "target": "tracing_serde" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.3.19" + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": "LICENSE" + }, + "typenum 1.17.0": { + "name": "typenum", + "version": "1.17.0", + "package_url": "https://github.com/paholg/typenum", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/typenum/1.17.0/download", + "sha256": "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + } + }, + "targets": [ + { + "Library": { + "crate_name": "typenum", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_main", + "crate_root": "build/main.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "typenum", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "typenum 1.17.0", + "target": "build_script_main" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "1.17.0" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE" + }, + "unicode-ident 1.0.14": { + "name": "unicode-ident", + "version": "1.0.14", + "package_url": "https://github.com/dtolnay/unicode-ident", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/unicode-ident/1.0.14/download", + "sha256": "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + } + }, + "targets": [ + { + "Library": { + "crate_name": "unicode_ident", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "unicode_ident", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2018", + "version": "1.0.14" + }, + "license": "(MIT OR Apache-2.0) AND Unicode-3.0", + "license_ids": [ + "Apache-2.0", + "MIT", + "Unicode-3.0" + ], + "license_file": "LICENSE-APACHE" + }, + "utf8parse 0.2.2": { + "name": "utf8parse", + "version": "0.2.2", + "package_url": "https://github.com/alacritty/vte", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/utf8parse/0.2.2/download", + "sha256": "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + } + }, + "targets": [ + { + "Library": { + "crate_name": "utf8parse", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "utf8parse", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default" + ], + "selects": {} + }, + "edition": "2018", + "version": "0.2.2" + }, + "license": "Apache-2.0 OR MIT", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "valuable 0.1.0": { + "name": "valuable", + "version": "0.1.0", + "package_url": "https://github.com/tokio-rs/valuable", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/valuable/0.1.0/download", + "sha256": "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + } + }, + "targets": [ + { + "Library": { + "crate_name": "valuable", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "valuable", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "valuable 0.1.0", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "0.1.0" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT", + "license_ids": [ + "MIT" + ], + "license_file": null + }, + "version_check 0.9.5": { + "name": "version_check", + "version": "0.9.5", + "package_url": "https://github.com/SergioBenitez/version_check", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/version_check/0.9.5/download", + "sha256": "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + } + }, + "targets": [ + { + "Library": { + "crate_name": "version_check", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "version_check", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2015", + "version": "0.9.5" + }, + "license": "MIT/Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "wasm-bindgen 0.2.99": { + "name": "wasm-bindgen", + "version": "0.2.99", + "package_url": "https://github.com/rustwasm/wasm-bindgen", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/wasm-bindgen/0.2.99/download", + "sha256": "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" + } + }, + "targets": [ + { + "Library": { + "crate_name": "wasm_bindgen", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "wasm_bindgen", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "cfg-if 1.0.0", + "target": "cfg_if" + }, + { + "id": "once_cell 1.20.2", + "target": "once_cell" + }, + { + "id": "wasm-bindgen 0.2.99", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2021", + "proc_macro_deps": { + "common": [ + { + "id": "wasm-bindgen-macro 0.2.99", + "target": "wasm_bindgen_macro" + } + ], + "selects": {} + }, + "version": "0.2.99" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "wasm-bindgen-backend 0.2.99": { + "name": "wasm-bindgen-backend", + "version": "0.2.99", + "package_url": "https://github.com/rustwasm/wasm-bindgen/tree/master/crates/backend", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/wasm-bindgen-backend/0.2.99/download", + "sha256": "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" + } + }, + "targets": [ + { + "Library": { + "crate_name": "wasm_bindgen_backend", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "wasm_bindgen_backend", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "bumpalo 3.16.0", + "target": "bumpalo" + }, + { + "id": "log 0.4.22", + "target": "log" + }, + { + "id": "proc-macro2 1.0.92", + "target": "proc_macro2" + }, + { + "id": "quote 1.0.38", + "target": "quote" + }, + { + "id": "syn 2.0.94", + "target": "syn" + }, + { + "id": "wasm-bindgen-shared 0.2.99", + "target": "wasm_bindgen_shared" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.2.99" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "wasm-bindgen-macro 0.2.99": { + "name": "wasm-bindgen-macro", + "version": "0.2.99", + "package_url": "https://github.com/rustwasm/wasm-bindgen/tree/master/crates/macro", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/wasm-bindgen-macro/0.2.99/download", + "sha256": "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" + } + }, + "targets": [ + { + "ProcMacro": { + "crate_name": "wasm_bindgen_macro", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "wasm_bindgen_macro", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "quote 1.0.38", + "target": "quote" + }, + { + "id": "wasm-bindgen-macro-support 0.2.99", + "target": "wasm_bindgen_macro_support" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.2.99" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "wasm-bindgen-macro-support 0.2.99": { + "name": "wasm-bindgen-macro-support", + "version": "0.2.99", + "package_url": "https://github.com/rustwasm/wasm-bindgen/tree/master/crates/macro-support", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/wasm-bindgen-macro-support/0.2.99/download", + "sha256": "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" + } + }, + "targets": [ + { + "Library": { + "crate_name": "wasm_bindgen_macro_support", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "wasm_bindgen_macro_support", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "proc-macro2 1.0.92", + "target": "proc_macro2" + }, + { + "id": "quote 1.0.38", + "target": "quote" + }, + { + "id": "syn 2.0.94", + "target": "syn" + }, + { + "id": "wasm-bindgen-backend 0.2.99", + "target": "wasm_bindgen_backend" + }, + { + "id": "wasm-bindgen-shared 0.2.99", + "target": "wasm_bindgen_shared" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.2.99" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "wasm-bindgen-shared 0.2.99": { + "name": "wasm-bindgen-shared", + "version": "0.2.99", + "package_url": "https://github.com/rustwasm/wasm-bindgen/tree/master/crates/shared", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/wasm-bindgen-shared/0.2.99/download", + "sha256": "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" + } + }, + "targets": [ + { + "Library": { + "crate_name": "wasm_bindgen_shared", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "wasm_bindgen_shared", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "wasm-bindgen-shared 0.2.99", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.2.99" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ], + "links": "wasm_bindgen" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "winapi 0.3.9": { + "name": "winapi", + "version": "0.3.9", + "package_url": "https://github.com/retep998/winapi-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/winapi/0.3.9/download", + "sha256": "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" + } + }, + "targets": [ + { + "Library": { + "crate_name": "winapi", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "winapi", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "consoleapi", + "errhandlingapi", + "fileapi", + "handleapi", + "processenv" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "winapi 0.3.9", + "target": "build_script_build" + } + ], + "selects": { + "i686-pc-windows-gnu": [ + { + "id": "winapi-i686-pc-windows-gnu 0.4.0", + "target": "winapi_i686_pc_windows_gnu" + } + ], + "x86_64-pc-windows-gnu": [ + { + "id": "winapi-x86_64-pc-windows-gnu 0.4.0", + "target": "winapi_x86_64_pc_windows_gnu" + } + ] + } + }, + "edition": "2015", + "version": "0.3.9" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT/Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "LICENSE-APACHE" + }, + "winapi-i686-pc-windows-gnu 0.4.0": { + "name": "winapi-i686-pc-windows-gnu", + "version": "0.4.0", + "package_url": "https://github.com/retep998/winapi-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/winapi-i686-pc-windows-gnu/0.4.0/download", + "sha256": "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + } + }, + "targets": [ + { + "Library": { + "crate_name": "winapi_i686_pc_windows_gnu", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "winapi_i686_pc_windows_gnu", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "winapi-i686-pc-windows-gnu 0.4.0", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2015", + "version": "0.4.0" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT/Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": null + }, + "winapi-x86_64-pc-windows-gnu 0.4.0": { + "name": "winapi-x86_64-pc-windows-gnu", + "version": "0.4.0", + "package_url": "https://github.com/retep998/winapi-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/winapi-x86_64-pc-windows-gnu/0.4.0/download", + "sha256": "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + } + }, + "targets": [ + { + "Library": { + "crate_name": "winapi_x86_64_pc_windows_gnu", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "winapi_x86_64_pc_windows_gnu", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "winapi-x86_64-pc-windows-gnu 0.4.0", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2015", + "version": "0.4.0" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT/Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": null + }, + "windows-core 0.52.0": { + "name": "windows-core", + "version": "0.52.0", + "package_url": "https://github.com/microsoft/windows-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/windows-core/0.52.0/download", + "sha256": "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" + } + }, + "targets": [ + { + "Library": { + "crate_name": "windows_core", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "windows_core", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "windows-targets 0.52.6", + "target": "windows_targets" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.52.0" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "license-apache-2.0" + }, + "windows-sys 0.59.0": { + "name": "windows-sys", + "version": "0.59.0", + "package_url": "https://github.com/microsoft/windows-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/windows-sys/0.59.0/download", + "sha256": "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" + } + }, + "targets": [ + { + "Library": { + "crate_name": "windows_sys", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "windows_sys", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "Win32", + "Win32_Foundation", + "Win32_System", + "Win32_System_Console", + "default" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "windows-targets 0.52.6", + "target": "windows_targets" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.59.0" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "license-apache-2.0" + }, + "windows-targets 0.52.6": { + "name": "windows-targets", + "version": "0.52.6", + "package_url": "https://github.com/microsoft/windows-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/windows-targets/0.52.6/download", + "sha256": "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" + } + }, + "targets": [ + { + "Library": { + "crate_name": "windows_targets", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "windows_targets", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [], + "selects": { + "aarch64-pc-windows-gnullvm": [ + { + "id": "windows_aarch64_gnullvm 0.52.6", + "target": "windows_aarch64_gnullvm" + } + ], + "cfg(all(any(target_arch = \"x86_64\", target_arch = \"arm64ec\"), target_env = \"msvc\", not(windows_raw_dylib)))": [ + { + "id": "windows_x86_64_msvc 0.52.6", + "target": "windows_x86_64_msvc" + } + ], + "cfg(all(target_arch = \"aarch64\", target_env = \"msvc\", not(windows_raw_dylib)))": [ + { + "id": "windows_aarch64_msvc 0.52.6", + "target": "windows_aarch64_msvc" + } + ], + "cfg(all(target_arch = \"x86\", target_env = \"gnu\", not(target_abi = \"llvm\"), not(windows_raw_dylib)))": [ + { + "id": "windows_i686_gnu 0.52.6", + "target": "windows_i686_gnu" + } + ], + "cfg(all(target_arch = \"x86\", target_env = \"msvc\", not(windows_raw_dylib)))": [ + { + "id": "windows_i686_msvc 0.52.6", + "target": "windows_i686_msvc" + } + ], + "cfg(all(target_arch = \"x86_64\", target_env = \"gnu\", not(target_abi = \"llvm\"), not(windows_raw_dylib)))": [ + { + "id": "windows_x86_64_gnu 0.52.6", + "target": "windows_x86_64_gnu" + } + ], + "i686-pc-windows-gnullvm": [ + { + "id": "windows_i686_gnullvm 0.52.6", + "target": "windows_i686_gnullvm" + } + ], + "x86_64-pc-windows-gnullvm": [ + { + "id": "windows_x86_64_gnullvm 0.52.6", + "target": "windows_x86_64_gnullvm" + } + ] + } + }, + "edition": "2021", + "version": "0.52.6" + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "license-apache-2.0" + }, + "windows_aarch64_gnullvm 0.52.6": { + "name": "windows_aarch64_gnullvm", + "version": "0.52.6", + "package_url": "https://github.com/microsoft/windows-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/windows_aarch64_gnullvm/0.52.6/download", + "sha256": "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + } + }, + "targets": [ + { + "Library": { + "crate_name": "windows_aarch64_gnullvm", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "windows_aarch64_gnullvm", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "windows_aarch64_gnullvm 0.52.6", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.52.6" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "license-apache-2.0" + }, + "windows_aarch64_msvc 0.52.6": { + "name": "windows_aarch64_msvc", + "version": "0.52.6", + "package_url": "https://github.com/microsoft/windows-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/windows_aarch64_msvc/0.52.6/download", + "sha256": "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + } + }, + "targets": [ + { + "Library": { + "crate_name": "windows_aarch64_msvc", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "windows_aarch64_msvc", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "windows_aarch64_msvc 0.52.6", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.52.6" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "license-apache-2.0" + }, + "windows_i686_gnu 0.52.6": { + "name": "windows_i686_gnu", + "version": "0.52.6", + "package_url": "https://github.com/microsoft/windows-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/windows_i686_gnu/0.52.6/download", + "sha256": "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + } + }, + "targets": [ + { + "Library": { + "crate_name": "windows_i686_gnu", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "windows_i686_gnu", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "windows_i686_gnu 0.52.6", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.52.6" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "license-apache-2.0" + }, + "windows_i686_gnullvm 0.52.6": { + "name": "windows_i686_gnullvm", + "version": "0.52.6", + "package_url": "https://github.com/microsoft/windows-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/windows_i686_gnullvm/0.52.6/download", + "sha256": "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + } + }, + "targets": [ + { + "Library": { + "crate_name": "windows_i686_gnullvm", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "windows_i686_gnullvm", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "windows_i686_gnullvm 0.52.6", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.52.6" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "license-apache-2.0" + }, + "windows_i686_msvc 0.52.6": { + "name": "windows_i686_msvc", + "version": "0.52.6", + "package_url": "https://github.com/microsoft/windows-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/windows_i686_msvc/0.52.6/download", + "sha256": "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + } + }, + "targets": [ + { + "Library": { + "crate_name": "windows_i686_msvc", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "windows_i686_msvc", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "windows_i686_msvc 0.52.6", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.52.6" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "license-apache-2.0" + }, + "windows_x86_64_gnu 0.52.6": { + "name": "windows_x86_64_gnu", + "version": "0.52.6", + "package_url": "https://github.com/microsoft/windows-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/windows_x86_64_gnu/0.52.6/download", + "sha256": "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + } + }, + "targets": [ + { + "Library": { + "crate_name": "windows_x86_64_gnu", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "windows_x86_64_gnu", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "windows_x86_64_gnu 0.52.6", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.52.6" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "license-apache-2.0" + }, + "windows_x86_64_gnullvm 0.52.6": { + "name": "windows_x86_64_gnullvm", + "version": "0.52.6", + "package_url": "https://github.com/microsoft/windows-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/windows_x86_64_gnullvm/0.52.6/download", + "sha256": "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + } + }, + "targets": [ + { + "Library": { + "crate_name": "windows_x86_64_gnullvm", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "windows_x86_64_gnullvm", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "windows_x86_64_gnullvm 0.52.6", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.52.6" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "license-apache-2.0" + }, + "windows_x86_64_msvc 0.52.6": { + "name": "windows_x86_64_msvc", + "version": "0.52.6", + "package_url": "https://github.com/microsoft/windows-rs", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/windows_x86_64_msvc/0.52.6/download", + "sha256": "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + } + }, + "targets": [ + { + "Library": { + "crate_name": "windows_x86_64_msvc", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "windows_x86_64_msvc", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "windows_x86_64_msvc 0.52.6", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.52.6" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "MIT OR Apache-2.0", + "license_ids": [ + "Apache-2.0", + "MIT" + ], + "license_file": "license-apache-2.0" + } + }, + "binary_crates": [], + "workspace_members": { + "ocitool 0.1.0": "ocitool" + }, + "conditions": { + "aarch64-apple-darwin": [ + "aarch64-apple-darwin" + ], + "aarch64-apple-ios": [ + "aarch64-apple-ios" + ], + "aarch64-apple-ios-sim": [ + "aarch64-apple-ios-sim" + ], + "aarch64-linux-android": [ + "aarch64-linux-android" + ], + "aarch64-pc-windows-gnullvm": [], + "aarch64-pc-windows-msvc": [ + "aarch64-pc-windows-msvc" + ], + "aarch64-unknown-fuchsia": [ + "aarch64-unknown-fuchsia" + ], + "aarch64-unknown-linux-gnu": [ + "aarch64-unknown-linux-gnu", + "aarch64-unknown-nixos-gnu" + ], + "aarch64-unknown-nixos-gnu": [ + "aarch64-unknown-nixos-gnu" + ], + "aarch64-unknown-nto-qnx710": [ + "aarch64-unknown-nto-qnx710" + ], + "arm-unknown-linux-gnueabi": [ + "arm-unknown-linux-gnueabi" + ], + "armv7-linux-androideabi": [ + "armv7-linux-androideabi" + ], + "armv7-unknown-linux-gnueabi": [ + "armv7-unknown-linux-gnueabi" + ], + "cfg(all(any(target_arch = \"x86_64\", target_arch = \"arm64ec\"), target_env = \"msvc\", not(windows_raw_dylib)))": [ + "x86_64-pc-windows-msvc" + ], + "cfg(all(target_arch = \"aarch64\", target_env = \"msvc\", not(windows_raw_dylib)))": [ + "aarch64-pc-windows-msvc" + ], + "cfg(all(target_arch = \"aarch64\", target_os = \"linux\"))": [ + "aarch64-unknown-linux-gnu", + "aarch64-unknown-nixos-gnu" + ], + "cfg(all(target_arch = \"aarch64\", target_vendor = \"apple\"))": [ + "aarch64-apple-darwin", + "aarch64-apple-ios", + "aarch64-apple-ios-sim" + ], + "cfg(all(target_arch = \"loongarch64\", target_os = \"linux\"))": [], + "cfg(all(target_arch = \"wasm32\", target_os = \"unknown\"))": [ + "wasm32-unknown-unknown" + ], + "cfg(all(target_arch = \"x86\", target_env = \"gnu\", not(target_abi = \"llvm\"), not(windows_raw_dylib)))": [ + "i686-unknown-linux-gnu" + ], + "cfg(all(target_arch = \"x86\", target_env = \"msvc\", not(windows_raw_dylib)))": [ + "i686-pc-windows-msvc" + ], + "cfg(all(target_arch = \"x86_64\", target_env = \"gnu\", not(target_abi = \"llvm\"), not(windows_raw_dylib)))": [ + "x86_64-unknown-linux-gnu", + "x86_64-unknown-nixos-gnu" + ], + "cfg(any(target_arch = \"aarch64\", target_arch = \"x86_64\", target_arch = \"x86\"))": [ + "aarch64-apple-darwin", + "aarch64-apple-ios", + "aarch64-apple-ios-sim", + "aarch64-linux-android", + "aarch64-pc-windows-msvc", + "aarch64-unknown-fuchsia", + "aarch64-unknown-linux-gnu", + "aarch64-unknown-nixos-gnu", + "aarch64-unknown-nto-qnx710", + "i686-apple-darwin", + "i686-linux-android", + "i686-pc-windows-msvc", + "i686-unknown-freebsd", + "i686-unknown-linux-gnu", + "x86_64-apple-darwin", + "x86_64-apple-ios", + "x86_64-linux-android", + "x86_64-pc-windows-msvc", + "x86_64-unknown-freebsd", + "x86_64-unknown-fuchsia", + "x86_64-unknown-linux-gnu", + "x86_64-unknown-nixos-gnu", + "x86_64-unknown-none" + ], + "cfg(any(target_os = \"macos\", target_os = \"ios\"))": [ + "aarch64-apple-darwin", + "aarch64-apple-ios", + "aarch64-apple-ios-sim", + "i686-apple-darwin", + "x86_64-apple-darwin", + "x86_64-apple-ios" + ], + "cfg(target_os = \"android\")": [ + "aarch64-linux-android", + "armv7-linux-androideabi", + "i686-linux-android", + "x86_64-linux-android" + ], + "cfg(target_os = \"haiku\")": [], + "cfg(target_os = \"windows\")": [ + "aarch64-pc-windows-msvc", + "i686-pc-windows-msvc", + "x86_64-pc-windows-msvc" + ], + "cfg(windows)": [ + "aarch64-pc-windows-msvc", + "i686-pc-windows-msvc", + "x86_64-pc-windows-msvc" + ], + "i686-apple-darwin": [ + "i686-apple-darwin" + ], + "i686-linux-android": [ + "i686-linux-android" + ], + "i686-pc-windows-gnu": [], + "i686-pc-windows-gnullvm": [], + "i686-pc-windows-msvc": [ + "i686-pc-windows-msvc" + ], + "i686-unknown-freebsd": [ + "i686-unknown-freebsd" + ], + "i686-unknown-linux-gnu": [ + "i686-unknown-linux-gnu" + ], + "powerpc-unknown-linux-gnu": [ + "powerpc-unknown-linux-gnu" + ], + "riscv32imc-unknown-none-elf": [ + "riscv32imc-unknown-none-elf" + ], + "riscv64gc-unknown-none-elf": [ + "riscv64gc-unknown-none-elf" + ], + "s390x-unknown-linux-gnu": [ + "s390x-unknown-linux-gnu" + ], + "thumbv7em-none-eabi": [ + "thumbv7em-none-eabi" + ], + "thumbv8m.main-none-eabi": [ + "thumbv8m.main-none-eabi" + ], + "wasm32-unknown-unknown": [ + "wasm32-unknown-unknown" + ], + "wasm32-wasi": [ + "wasm32-wasi" + ], + "wasm32-wasip1": [ + "wasm32-wasip1" + ], + "x86_64-apple-darwin": [ + "x86_64-apple-darwin" + ], + "x86_64-apple-ios": [ + "x86_64-apple-ios" + ], + "x86_64-linux-android": [ + "x86_64-linux-android" + ], + "x86_64-pc-windows-gnu": [], + "x86_64-pc-windows-gnullvm": [], + "x86_64-pc-windows-msvc": [ + "x86_64-pc-windows-msvc" + ], + "x86_64-unknown-freebsd": [ + "x86_64-unknown-freebsd" + ], + "x86_64-unknown-fuchsia": [ + "x86_64-unknown-fuchsia" + ], + "x86_64-unknown-linux-gnu": [ + "x86_64-unknown-linux-gnu", + "x86_64-unknown-nixos-gnu" + ], + "x86_64-unknown-nixos-gnu": [ + "x86_64-unknown-nixos-gnu" + ], + "x86_64-unknown-none": [ + "x86_64-unknown-none" + ] + }, + "direct_deps": [ + "anyhow 1.0.95", + "clap 4.5.23", + "colored 2.2.0", + "fs-err 3.0.0", + "hex 0.4.3", + "oci-spec 0.7.1", + "serde 1.0.217", + "serde_json 1.0.134", + "sha2 0.10.8", + "tracing 0.1.41", + "tracing-subscriber 0.3.19" + ], + "direct_dev_deps": [] +} diff --git a/docs/defs.md b/docs/defs.md index 93076f9..afd0e3f 100644 --- a/docs/defs.md +++ b/docs/defs.md @@ -2,77 +2,85 @@ public rules - + -## oci_image +## oci_push
-oci_image(name, annotations, arch, base, entrypoint, env, labels, layers, os)
+oci_push(name, headers, manifest, registry, repository, stamp, tag, x_meta_headers)
 
-Creates a new image manifest and config by appending the `layers` to an existing image -manifest and config defined by `base`. If `base` is an image index, then `os` and `arch` will -be used to extract the image manifest. +Pushes a manifest or a list of manifests to an OCI registry. **ATTRIBUTES** | Name | Description | Type | Mandatory | Default | | :------------- | :------------- | :------------- | :------------- | :------------- | -| name | A unique name for this target. | Name | required | | -| annotations | [OCI Annotations](https://github.com/opencontainers/image-spec/blob/main/annotations.md) to add to the manifest. | Dictionary: String -> String | optional | `{}` | -| arch | Used to extract a manifest from base if base is an index | String | optional | `""` | -| base | A base image, as defined by oci_pull or oci_image | Label | required | | -| entrypoint | A list of entrypoints for the image; these will be inserted into the generated OCI image config | List of strings | optional | `[]` | -| env | Entries are in the format of `VARNAME=VARVALUE`. These values act as defaults and are merged with any specified when creating a container. | List of strings | optional | `[]` | -| labels | labels that will be applied to the image configuration, as defined in [the OCI config](https://github.com/opencontainers/image-spec/blob/main/config.md#properties). These behave the same way as [docker LABEL](https://docs.docker.com/engine/reference/builder/#label); in particular, labels from the base image are inherited. An empty value for a label will cause that label to be deleted. For backwards compatibility, if this is not set, then the value of annotations will be used instead. | Dictionary: String -> String | optional | `{}` | -| layers | A list of layers defined by oci_image_layer | List of labels | optional | `[]` | -| os | Used to extract a manifest from base if base is an index | String | optional | `""` | +| name | A unique name for this target. | Name | required | | +| headers | (optional) A list of key/values to to be sent to the registry as headers. | Dictionary: String -> String | optional | `{}` | +| manifest | A manifest to push to a registry. If an OCILayout index, then push all artifacts with a 'org.opencontainers.image.ref.name' annotation. | Label | optional | `None` | +| registry | A registry host to push to, if not present consult the toolchain. | String | optional | `""` | +| repository | A repository to push to, if not present consult the toolchain. | String | optional | `""` | +| stamp | Whether to encode build information into the output. Possible values:

- `stamp = 1`: Always stamp the build information into the output, even in [--nostamp](https://docs.bazel.build/versions/main/user-manual.html#flag--stamp) builds. This setting should be avoided, since it is non-deterministic. It potentially causes remote cache misses for the target and any downstream actions that depend on the result. - `stamp = 0`: Never stamp, instead replace build information by constant values. This gives good build result caching. - `stamp = -1`: Embedding of build information is controlled by the [--[no]stamp](https://docs.bazel.build/versions/main/user-manual.html#flag--stamp) flag. Stamped targets are not rebuilt unless their dependencies change. | Integer | optional | `-1` | +| tag | (optional) A tag to include in the target reference. This will not be included on child images.

Subject to [$(location)](https://bazel.build/reference/be/make-variables#predefined_label_variables) and ["Make variable"](https://bazel.build/reference/be/make-variabmes) substitution.

**Stamping**

You can use values produced by the workspace status command in your tag. To do this write a script that prints key-value pairs separated by spaces, e.g.

#!/usr/bin/env bash
echo "STABLE_KEY1 VALUE1"
echo "STABLE_KEY2 VALUE2"


You can reference these keys in `tag` using curly braces,

oci_push(
    name = "push",
    tag = "v1.0-{STABLE_KEY1}",
)
| String | optional | `""` | +| x_meta_headers | (optional) A list of key/values to to be sent to the registry as headers with an X-Meta- prefix. | Dictionary: String -> String | optional | `{}` | - + -## oci_image_index +## oci_image
-oci_image_index(name, annotations, manifests)
+oci_image(name, base, annotations, arch, entrypoint, env, gzip, labels, layers, os, kwargs)
 
+Creates a "single-arch"" OCI image +Also creates targets for an OCI Layout directory and a .tar.gz file -**ATTRIBUTES** +**PARAMETERS** -| Name | Description | Type | Mandatory | Default | -| :------------- | :------------- | :------------- | :------------- | :------------- | -| name | A unique name for this target. | Name | required | | -| annotations | - | Dictionary: String -> String | optional | `{}` | -| manifests | - | List of labels | optional | `[]` | +| Name | Description | Default Value | +| :------------- | :------------- | :------------- | +| name | A unique name for the rule | none | +| base | A label of an oci_image or oci_image_index | none | +| annotations | A dictionary of annotations to add to the image | `None` | +| arch | The architecture of the image | `None` | +| entrypoint | A list of entrypoints for the image | `None` | +| env | A list of environment variables to add to the image | `None` | +| gzip | If true, creates a tar.gz file. If false, creates a tar file | `True` | +| labels | A dictionary of labels to add to the image | `None` | +| layers | A list of oci_image_layer labels | `None` | +| os | The operating system of the image | `None` | +| kwargs | Additional arguments to pass to the underlying rules, e.g. tags or visibility | none | - -## oci_push + + +## oci_image_index
-oci_push(name, headers, manifest, registry, repository, stamp, tag, x_meta_headers)
+oci_image_index(name, manifests, annotations, gzip, kwargs)
 
-Pushes a manifest or a list of manifests to an OCI registry. +Creates a "multi-arch"" OCI image -**ATTRIBUTES** +Also creates targets for an OCI Layout directory and a .tar.gz file -| Name | Description | Type | Mandatory | Default | -| :------------- | :------------- | :------------- | :------------- | :------------- | -| name | A unique name for this target. | Name | required | | -| headers | (optional) A list of key/values to to be sent to the registry as headers. | Dictionary: String -> String | optional | `{}` | -| manifest | A manifest to push to a registry. If an OCILayout index, then push all artifacts with a 'org.opencontainers.image.ref.name' annotation. | Label | optional | `None` | -| registry | A registry host to push to, if not present consult the toolchain. | String | optional | `""` | -| repository | A repository to push to, if not present consult the toolchain. | String | optional | `""` | -| stamp | Whether to encode build information into the output. Possible values:

- `stamp = 1`: Always stamp the build information into the output, even in [--nostamp](https://docs.bazel.build/versions/main/user-manual.html#flag--stamp) builds. This setting should be avoided, since it is non-deterministic. It potentially causes remote cache misses for the target and any downstream actions that depend on the result. - `stamp = 0`: Never stamp, instead replace build information by constant values. This gives good build result caching. - `stamp = -1`: Embedding of build information is controlled by the [--[no]stamp](https://docs.bazel.build/versions/main/user-manual.html#flag--stamp) flag. Stamped targets are not rebuilt unless their dependencies change. | Integer | optional | `-1` | -| tag | (optional) A tag to include in the target reference. This will not be included on child images.

Subject to [$(location)](https://bazel.build/reference/be/make-variables#predefined_label_variables) and ["Make variable"](https://bazel.build/reference/be/make-variabmes) substitution.

**Stamping**

You can use values produced by the workspace status command in your tag. To do this write a script that prints key-value pairs separated by spaces, e.g.

#!/usr/bin/env bash
echo "STABLE_KEY1 VALUE1"
echo "STABLE_KEY2 VALUE2"


You can reference these keys in `tag` using curly braces,

oci_push(
    name = "push",
    tag = "v1.0-{STABLE_KEY1}",
)
| String | optional | `""` | -| x_meta_headers | (optional) A list of key/values to to be sent to the registry as headers with an X-Meta- prefix. | Dictionary: String -> String | optional | `{}` | +**PARAMETERS** + + +| Name | Description | Default Value | +| :------------- | :------------- | :------------- | +| name | A unique name for the rule | none | +| manifests | A list of oci_image labels | none | +| annotations | A dictionary of annotations to add to the index | `None` | +| gzip | If true, creates a tar.gz file. If false, creates a tar file | `True` | +| kwargs | Additional arguments to pass to the underlying rules, e.g. tags or visibility | none | @@ -98,31 +106,6 @@ oci_image_layer | kwargs | Additional arguments to pass to the rule, e.g. `tags` or `visibility` | none | - - -## oci_image_layout - -
-oci_image_layout(name, image_index, gzip, kwargs)
-
- -Creates targets for an OCI Image Layout directory and a tar file - -See https://github.com/opencontainers/image-spec/blob/main/image-layout.md -for the specification of the OCI Image Format directory. - - -**PARAMETERS** - - -| Name | Description | Default Value | -| :------------- | :------------- | :------------- | -| name | A unique name for the rule | none | -| image_index | An oci_image_index label | none | -| gzip | If true, creates a tar.gz file. If false, creates a tar file | `True` | -| kwargs | Additional arguments to pass to the underlying rules, e.g. tags or visibility | none | - - ## oci_pull diff --git a/docs/providers.md b/docs/providers.md index 336c93c..f65a0fa 100644 --- a/docs/providers.md +++ b/docs/providers.md @@ -7,10 +7,11 @@ public providers ## OCIDescriptor
-OCIDescriptor(file, descriptor_file, media_type, size, urls, digest, annotations)
+OCIDescriptor(file, descriptor_file, artifact_type, data, annotations, digest, media_type, size,
+              urls)
 
- +An OCI descriptor. See https://github.com/opencontainers/image-spec/blob/main/descriptor.md **FIELDS** @@ -19,11 +20,13 @@ OCIDescriptor(file, file | A file object of the content this descriptor describes | | descriptor_file | A file object with the information in this provider | -| media_type | The MIME media type of the file | -| size | The size in bytes of the file | -| urls | Additional URLs where you can find the content of file | -| digest | A digest, including the algorithm, of the file | -| annotations | String map of aribtrary metadata | +| artifact_type | Optional. The type of an artifact when the descriptor points to an artifact | +| data | Optional. An embedded representation of the referenced content | +| annotations | Optional. Arbitrary metadata for this descriptor | +| digest | Required. The digest of the targeted content | +| media_type | Required. The media type of the referenced content | +| size | Required. The size, in bytes, of the raw content | +| urls | Optional. A list of URIs from which this object MAY be downloaded | diff --git a/examples/go-multiarch-image/BUILD.bazel b/examples/go-multiarch-image/BUILD.bazel index 1c69914..cd5bdf3 100644 --- a/examples/go-multiarch-image/BUILD.bazel +++ b/examples/go-multiarch-image/BUILD.bazel @@ -1,10 +1,6 @@ load("@bazel_skylib//rules:write_file.bzl", "write_file") load( "@com_github_datadog_rules_oci//oci:defs.bzl", - "oci_image", - "oci_image_index", - "oci_image_layer", - "oci_image_layout", "oci_push", ) load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -17,6 +13,12 @@ go_library( visibility = ["//visibility:private"], ) +go_binary( + name = "go-multiarch-image", + embed = [":go_default_library"], + visibility = ["//visibility:public"], +) + go_multiarch_image( name = "image", archs = [ @@ -34,60 +36,3 @@ oci_push( registry = "ghcr.io", repository = "datadog/rules_oci/hello-world", ) - -# Add a layer - -write_file( - name = "hello.txt.write_file", - out = "hello.txt", - content = ["Hello, World!"], -) - -oci_image_layer( - name = "layer-hello.txt", - file_map = { - ":hello.txt": "/hello.txt", - }, -) - -_ARCHS = [ - "amd64", - "arm64", -] - -[ - oci_image( - name = "image2.{}".format(arch), - arch = arch, - base = ":image", - layers = [":layer-hello.txt"], - os = "linux", - ) - for arch in _ARCHS -] - -oci_image_index( - name = "image2", - manifests = [ - ":image2.{}".format(arch) - for arch in _ARCHS - ], -) - -oci_image_layout( - name = "image2.dir", - image_index = ":image2", -) - -oci_push( - name = "push2", - manifest = ":image2", - registry = "ghcr.io", - repository = "datadog/rules_oci/hello-world2", -) - -go_binary( - name = "go-multiarch-image", - embed = [":go_default_library"], - visibility = ["//visibility:public"], -) diff --git a/examples/simple/BUILD.bazel b/examples/simple/BUILD.bazel new file mode 100644 index 0000000..d93e901 --- /dev/null +++ b/examples/simple/BUILD.bazel @@ -0,0 +1,43 @@ +load("@bazel_skylib//rules:write_file.bzl", "write_file") +load("//oci:defs.bzl", "oci_image", "oci_image_index", "oci_image_layer") + +write_file( + name = "hello.txt.write_file", + out = "hello.txt", + content = ["Hello, World!"], +) + +oci_image_layer( + name = "layer-hello.txt", + file_map = { + ":hello.txt": "/hello.txt", + }, +) + +[ + oci_image( + name = "image.{}".format(arch), + annotations = { + "foo": "bar", + }, + arch = arch, + base = "@ubuntu_noble//image", + layers = [":layer-hello.txt"], + os = "linux", + ) + for arch in [ + "amd64", + "arm64", + ] +] + +oci_image_index( + name = "image!", + annotations = { + "baz": "qux", + }, + manifests = [ + ":image.amd64", + ":image.arm64", + ], +) diff --git a/go/cmd/ocitool/BUILD.bazel b/go/cmd/ocitool/BUILD.bazel index cb8dce9..40fdd98 100644 --- a/go/cmd/ocitool/BUILD.bazel +++ b/go/cmd/ocitool/BUILD.bazel @@ -1,5 +1,11 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") +go_binary( + name = "ocitool", + embed = [":go_default_library"], + visibility = ["//visibility:public"], +) + go_library( name = "go_default_library", srcs = [ @@ -7,7 +13,6 @@ go_library( "createlayer_cmd.go", "desc_helpers.go", "digest_cmd.go", - "imagelayout_cmd.go", "index_cmd.go", "main.go", "manifest_cmd.go", @@ -16,7 +21,7 @@ go_library( "pushblob_cmd.go", ], importpath = "github.com/DataDog/rules_oci/go/cmd/ocitool", - visibility = ["//visibility:public"], + visibility = ["//visibility:private"], deps = [ "//go/internal/flagutil:go_default_library", "//go/internal/tarutil:go_default_library", @@ -34,9 +39,3 @@ go_library( "@com_github_urfave_cli_v2//:go_default_library", ], ) - -go_binary( - name = "ocitool", - embed = [":go_default_library"], - visibility = ["//visibility:public"], -) diff --git a/go/cmd/ocitool/appendlayer_cmd.go b/go/cmd/ocitool/appendlayer_cmd.go index b3a1312..a8e5db3 100644 --- a/go/cmd/ocitool/appendlayer_cmd.go +++ b/go/cmd/ocitool/appendlayer_cmd.go @@ -176,7 +176,9 @@ func AppendLayersCmd(c *cli.Context) error { c.StringSlice("env"), createdTimestamp, entrypoint, + targetPlatform, ) + if err != nil { return err } diff --git a/go/cmd/ocitool/imagelayout_cmd.go b/go/cmd/ocitool/imagelayout_cmd.go deleted file mode 100644 index cc6a462..0000000 --- a/go/cmd/ocitool/imagelayout_cmd.go +++ /dev/null @@ -1,107 +0,0 @@ -package main - -import ( - "fmt" - "os" - "path" - "strings" - - "github.com/DataDog/rules_oci/go/pkg/blob" - "github.com/DataDog/rules_oci/go/pkg/ociutil" - "github.com/containerd/containerd/images" - "github.com/opencontainers/go-digest" - "github.com/urfave/cli/v2" -) - -// Given a slice of layoutFilePaths, where each path contains a file that may -// be used within an OCI Image Format, return an index that maps sha256 values -// to paths. -// If relPath is non-empty, it is prepended to all layoutFilePaths. -func getLayoutFilesBlobIndex(layoutFilePaths []string, relPath string) (blob.Index, error) { - var result blob.Index - result.Blobs = make(map[digest.Digest]string) - for _, p := range layoutFilePaths { - if len(strings.TrimSpace(p)) == 0 { - // Ignore empty paths. - continue - } - if relPath != "" { - p = path.Join(relPath, p) - } - // Use an immediately invoked function here so that defer closes the - // file at a suitable time. - err := func() error { - f, err := os.Open(p) - if err != nil { - return err - } - defer f.Close() - digester := digest.SHA256.Digester() - _, err = f.WriteTo(digester.Hash()) - if err != nil { - return err - } - digest := digester.Digest() - result.Blobs[digest] = p - return nil - }() - if err != nil { - return blob.Index{}, err - } - } - - return result, nil -} - -// This command creates an OCI Image Layout directory based on the layout parameter. -// The layout-files parameter contains a list of files that are used as blobs -// when referenced by desriptors in the layout parameter. -// See https://github.com/opencontainers/image-spec/blob/main/image-layout.md -// for the structure of OCI Image Layout directories. -func CreateOciImageLayoutCmd(c *cli.Context) error { - relPath := c.String("layout-relative") - // Load providers that read local files, and create a multiprovider that - // contains all of them, as well as providers for base image blobs. - providers, err := LoadLocalProviders(c.StringSlice("layout"), relPath) - if err != nil { - return err - } - - layoutFilesBlobIdx, err := getLayoutFilesBlobIndex(c.StringSlice("layout-files"), relPath) - if err != nil { - return err - } - - if len(layoutFilesBlobIdx.Blobs) > 0 { - providers = append(providers, &layoutFilesBlobIdx) - } - - multiProvider := ociutil.MultiProvider(providers...) - - descriptorFile := c.String("desc") - baseDesc, err := ociutil.ReadDescriptorFromFile(descriptorFile) - if err != nil { - return fmt.Errorf("failed to read base descriptor: %w", err) - } - - outDir := c.String("out-dir") - ociIngester, err := ociutil.NewOciImageLayoutIngester(outDir) - if err != nil { - return err - } - - // Copy the children first; leave the parent (index) to last. - imagesHandler := images.ChildrenHandler(multiProvider) - err = ociutil.CopyChildrenFromHandler(c.Context, imagesHandler, multiProvider, &ociIngester, baseDesc) - if err != nil { - return fmt.Errorf("failed to copy child content to OCI Image Layout: %w", err) - } - - // copy the parent last (in case of image index) - err = ociutil.CopyContent(c.Context, multiProvider, &ociIngester, baseDesc) - if err != nil { - return fmt.Errorf("failed to copy parent content to OCI Image Layout: %w", err) - } - - return nil -} diff --git a/go/cmd/ocitool/main.go b/go/cmd/ocitool/main.go index 173104b..d91ec8a 100644 --- a/go/cmd/ocitool/main.go +++ b/go/cmd/ocitool/main.go @@ -181,28 +181,6 @@ var app = &cli.App{ }, }, }, - { - Name: "create-oci-image-layout", - Description: `Creates a directory containing an OCI Image Layout based on the input layout, -as described in https://github.com/opencontainers/image-spec/blob/main/image-layout.md.`, - Action: CreateOciImageLayoutCmd, - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "layout-relative", - }, - &cli.StringFlag{ - Name: "desc", - }, - &cli.StringSliceFlag{ - Name: "layout-files", - Usage: "A comma separated list of blob files to be placed in the OCI Image Layout (e.g. image layers).", - }, - &cli.StringFlag{ - Name: "out-dir", - Usage: "The directory that the OCI Image Layout will be written to.", - }, - }, - }, { Name: "push-blob", Hidden: true, diff --git a/go/cmd/ocitool/pushblob_cmd.go b/go/cmd/ocitool/pushblob_cmd.go index 667db7c..5f3f107 100644 --- a/go/cmd/ocitool/pushblob_cmd.go +++ b/go/cmd/ocitool/pushblob_cmd.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "os" "github.com/DataDog/rules_oci/go/pkg/ociutil" @@ -11,6 +12,9 @@ import ( func PushBlobCmd(c *cli.Context) error { resolver := ociutil.DefaultResolver() + fmt.Printf("Pushing blob %v to %v\n", c.String("file"), c.String("ref")) + os.Exit(0) + desc, err := resolver.PushBlob(c.Context, c.String("file"), c.String("ref"), "") if err != nil { return fmt.Errorf("failed to push blob: %w", err) diff --git a/go/pkg/layer/append.go b/go/pkg/layer/append.go index ed64c62..24f6289 100644 --- a/go/pkg/layer/append.go +++ b/go/pkg/layer/append.go @@ -19,7 +19,18 @@ import ( // use that. const AnnotationArtifactDescription = "org.opencontainers.artifact.created" -func AppendLayers(ctx context.Context, store content.Store, baseManifestDesc ocispec.Descriptor, layers []ocispec.Descriptor, annotations map[string]string, labels map[string]string, env []string, created time.Time, entrypoint []string) (ocispec.Descriptor, ocispec.Descriptor, error) { +func AppendLayers( + ctx context.Context, + store content.Store, + baseManifestDesc ocispec.Descriptor, + layers []ocispec.Descriptor, + annotations map[string]string, + labels map[string]string, + env []string, + created time.Time, + entrypoint []string, + platform ocispec.Platform, +) (ocispec.Descriptor, ocispec.Descriptor, error) { if annotations == nil { annotations = make(map[string]string) } @@ -128,17 +139,33 @@ func AppendLayers(ctx context.Context, store content.Store, baseManifestDesc oci imageConfig.Config.Entrypoint = entrypoint imageConfig.Config.Env = append(imageConfig.Config.Env, env...) - newConfig, err := ociutil.IngestorJSONEncode(ctx, store, ocispec.MediaTypeImageConfig, imageConfig) + newConfig, err := ociutil.IngestorJSONEncode( + ctx, + store, + nil, + ocispec.MediaTypeImageConfig, + imageConfig, + nil, + ) if err != nil { return ocispec.Descriptor{}, ocispec.Descriptor{}, err } manifest.Config = newConfig - newManifest, err := ociutil.IngestorJSONEncode(ctx, store, ocispec.MediaTypeImageManifest, manifest) + newManifest, err := ociutil.IngestorJSONEncode( + ctx, + store, + manifest.Annotations, + ocispec.MediaTypeImageManifest, + manifest, + &platform, + ) if err != nil { return ocispec.Descriptor{}, ocispec.Descriptor{}, err } + fmt.Printf("Created new manifest %+v\n", newManifest) + return newManifest, newConfig, nil } diff --git a/go/pkg/ociutil/json.go b/go/pkg/ociutil/json.go index 986c0fc..9511473 100644 --- a/go/pkg/ociutil/json.go +++ b/go/pkg/ociutil/json.go @@ -48,15 +48,24 @@ func ProviderJSONDecode(ctx context.Context, provider content.Provider, desc oci } // IngestorJSONEncode encodes json and saves it to a ingester. -func IngestorJSONEncode(ctx context.Context, ing content.Ingester, mediaType string, inf interface{}) (ocispec.Descriptor, error) { +func IngestorJSONEncode( + ctx context.Context, + ing content.Ingester, + annotations map[string]string, + mediaType string, + inf interface{}, + platform *ocispec.Platform, +) (ocispec.Descriptor, error) { data, err := json.Marshal(inf) if err != nil { return ocispec.Descriptor{}, fmt.Errorf("unable to marshal JSON: %w", err) } desc := ocispec.Descriptor{ - MediaType: mediaType, - Size: int64(len(data)), - Digest: digest.SHA256.FromBytes(data), + Annotations: annotations, + Digest: digest.SHA256.FromBytes(data), + MediaType: mediaType, + Platform: platform, + Size: int64(len(data)), } writer, err := ing.Writer(ctx, content.WithDescriptor(desc)) diff --git a/justfile b/justfile new file mode 100644 index 0000000..5f50683 --- /dev/null +++ b/justfile @@ -0,0 +1,38 @@ +build: + bazel build //... + +docs-rust: + #!/usr/bin/env bash + set -euo pipefail + root="$(git rev-parse --show-toplevel)" + bazel build //ocitool:docs + open "${root}/bazel-bin/ocitool/docs.rustdoc/ocitool/index.html" + +format: + bazel run //:format + +gazelle: + bazel run //:gazelle + +release: test + #!/usr/bin/env bash + set -euo pipefail + root="$(git rev-parse --show-toplevel)" + bazel build //:release + bazel run //go/cmd/ocitool -- \ + push-blob \ + --file "${root}/bazel-bin/release.tar.gz" \ + --ref "ghcr.io/datadog/rules_oci/rules:latest" + +test: + bazel test //... + bazel run //:gazelle -- -mode diff || exit 1 + +update-crates: + CARGO_BAZEL_REPIN=1 bazel sync --only=crate_index + +update-docs: + bazel run //docs:update + +foobar: + bzl run //examples/simple:image.load diff --git a/oci/BUILD.bazel b/oci/BUILD.bazel index 697f3fa..633dfee 100644 --- a/oci/BUILD.bazel +++ b/oci/BUILD.bazel @@ -24,17 +24,19 @@ bzl_library( "//oci/private:common.bzl", "//oci/private:debug_flag.bzl", "//oci/private:oci_image.bzl", + "//oci/private:oci_image_dir.bzl", "//oci/private:oci_image_index.bzl", "//oci/private:oci_image_layer.bzl", - "//oci/private:oci_image_layout.bzl", + "//oci/private:oci_image_load.bzl", "//oci/private:oci_push.bzl", + "//oci/private:providers.bzl", "//oci/private/repositories:authn.bzl", "//oci/private/repositories:download.bzl", "//oci/private/repositories:oci_pull.bzl", "@aspect_bazel_lib//lib:base64", + "@aspect_bazel_lib//lib:paths", "@aspect_bazel_lib//lib:repo_utils", "@aspect_bazel_lib//lib:stamping", - "@bazel_skylib//lib:paths", "@bazel_skylib//lib:versions", "@rules_pkg//pkg:bzl_srcs", ], @@ -45,6 +47,7 @@ bzl_library( srcs = ["repositories.bzl"], visibility = ["//visibility:public"], deps = [ + "//oci/private:common.bzl", "//oci/private/repositories:authn.bzl", "//oci/private/repositories:download.bzl", "//oci/private/repositories:oci_pull.bzl", @@ -61,7 +64,7 @@ pkg_files( "*.bazel", ]), prefix = "oci", - visibility = ["//release:__subpackages__"], + visibility = ["//:__subpackages__"], ) bzl_library( diff --git a/oci/defs.bzl b/oci/defs.bzl index 9c48101..ba38c15 100644 --- a/oci/defs.bzl +++ b/oci/defs.bzl @@ -3,14 +3,12 @@ load("//oci/private:oci_image.bzl", _oci_image = "oci_image") load("//oci/private:oci_image_index.bzl", _oci_image_index = "oci_image_index") load("//oci/private:oci_image_layer.bzl", _oci_image_layer = "oci_image_layer") -load("//oci/private:oci_image_layout.bzl", _oci_image_layout = "oci_image_layout") load("//oci/private:oci_push.bzl", _oci_push = "oci_push") load("//oci/private/repositories:oci_pull.bzl", _oci_pull = "oci_pull") oci_image = _oci_image oci_image_index = _oci_image_index oci_image_layer = _oci_image_layer -oci_image_layout = _oci_image_layout oci_push = _oci_push # TODO(brian.myers): Remove this (from defs.bzl, not repositories.bzl) once consumers no longer use it diff --git a/oci/private/BUILD.bazel b/oci/private/BUILD.bazel index 703d0cd..2486397 100644 --- a/oci/private/BUILD.bazel +++ b/oci/private/BUILD.bazel @@ -14,5 +14,5 @@ pkg_files( "*.bazel", ]), prefix = "oci/private", - visibility = ["//release:__subpackages__"], + visibility = ["//:__subpackages__"], ) diff --git a/oci/private/common.bzl b/oci/private/common.bzl index 8c91387..6c8cab1 100644 --- a/oci/private/common.bzl +++ b/oci/private/common.bzl @@ -1,18 +1,73 @@ -# buildifier: disable=function-docstring -def get_descriptor_file(ctx, desc): - if hasattr(desc, "descriptor_file"): - return desc.descriptor_file +""" common utilities """ + +MEDIA_TYPE_DOCKER_INDEX = "application/vnd.docker.distribution.manifest.list.v2+json" +MEDIA_TYPE_DOCKER_MANIFEST = "application/vnd.docker.distribution.manifest.v2+json" +MEDIA_TYPE_OCI_INDEX = "application/vnd.oci.image.index.v1+json" +MEDIA_TYPE_OCI_MANIFEST = "application/vnd.oci.image.manifest.v1+json" + +def get_or_make_descriptor_file( + ctx, + *, + descriptor_provider, # OCIDescriptor + outpath = None): # str | None + """Returns an oci descriptor file + + Some OCIDescriptor's provider already contain a descrptor file, but others + only contain starlark variables (strings, bools, dicts, etc.) that are + the information that would go into a descriptor file. + + This function guarantees you a descriptor file, either by returning the one + that is already there or by making one on the fly from the information + contained in the OCIDescriptor provider + + Args: + ctx: The rule context + descriptor_provider: An OCIDescriptor that may or may not contain a + descriptor file + outpath: Where to declare the new descriptor file if one needs to be + created. Default is the digest of the descriptor provider + Returns: + A descriptor file + """ + descriptor_file = descriptor_provider.descriptor_file + if descriptor_file != None: + return descriptor_file + + if outpath == None: + outpath = descriptor_provider.digest + + out = ctx.actions.declare_file(outpath) + + obj = { + _snake_to_camel(k): v + for k, v in _struct_to_dict(descriptor_provider).items() + if k in [ + # See: https://github.com/opencontainers/image-spec/blob/main/descriptor.md + "artifact_type", + "annotations", + "data", + "digest", + "media_type", + "platform", + "size", + "urls", + ] + } - out = ctx.actions.declare_file(desc.digest) ctx.actions.write( + content = json.encode(obj), output = out, - content = json.encode({ - "mediaType": desc.media_type, - "size": desc.size, - "digest": desc.digest, - "urls": desc.urls, - "annotations": desc.annotations, - }), + is_executable = False, ) return out + +def _snake_to_camel(s): + components = s.split("_") + return components[0] + "".join([x.title() for x in components[1:]]) + +def _struct_to_dict(st): + return { + field: getattr(st, field) + for field in dir(st) + } diff --git a/oci/private/debug_flag.bzl b/oci/private/debug_flag.bzl index 63ba60f..c941ab1 100644 --- a/oci/private/debug_flag.bzl +++ b/oci/private/debug_flag.bzl @@ -1,9 +1,6 @@ """ debug_flag """ -DebugInfo = provider( - "DebugInfo", - fields = ["debug"], -) +load(":providers.bzl", "DebugInfo") def _debug_flag_impl(ctx): return [DebugInfo(debug = ctx.build_setting_value)] diff --git a/oci/private/oci_image.bzl b/oci/private/oci_image.bzl index 848bd50..c1e9ab9 100644 --- a/oci/private/oci_image.bzl +++ b/oci/private/oci_image.bzl @@ -1,10 +1,65 @@ """ oci_image """ +load("@rules_pkg//pkg:mappings.bzl", "pkg_files") +load("@rules_pkg//pkg:pkg.bzl", "pkg_tar") load("//oci:providers.bzl", "OCIDescriptor", "OCILayout") -load(":common.bzl", "get_descriptor_file") +load(":common.bzl", "MEDIA_TYPE_OCI_MANIFEST", "get_or_make_descriptor_file") +load(":oci_image_dir.bzl", "oci_image_dir") + +def oci_image( + name, + base, # label + annotations = None, # dict[str, str] | None + arch = None, # str | None + entrypoint = None, # list[str] | None + env = None, # dict[str, str] | None + gzip = True, # bool + labels = None, # dict[str, str] | None + layers = None, # list[label] | None + os = None, # str | None + **kwargs): + """Creates a "single-arch"" OCI image + + Also creates targets for an OCI Layout directory and a .tar.gz file + + Args: + name: A unique name for the rule + base: A label of an oci_image or oci_image_index + annotations: A dictionary of annotations to add to the image + arch: The architecture of the image + entrypoint: A list of entrypoints for the image + env: A list of environment variables to add to the image + gzip: If true, creates a tar.gz file. If false, creates a tar file + labels: A dictionary of labels to add to the image + layers: A list of oci_image_layer labels + os: The operating system of the image + **kwargs: Additional arguments to pass to the underlying rules, e.g. + tags or visibility + """ + _oci_image( + name = name, + base = base, + annotations = annotations, + arch = arch, + entrypoint = entrypoint, + env = env, + labels = labels, + layers = layers, + os = os, + **kwargs + ) + + oci_image_dir( + image = name, + gzip = gzip, + **kwargs + ) def _impl(ctx): - base_desc = get_descriptor_file(ctx, ctx.attr.base[OCIDescriptor]) + base_desc = get_or_make_descriptor_file( + ctx, + descriptor_provider = ctx.attr.base[OCIDescriptor], + ) base_layout = ctx.attr.base[OCILayout] manifest_desc_file = ctx.actions.declare_file("{}.manifest.descriptor.json".format(ctx.label.name)) @@ -28,7 +83,13 @@ def _impl(ctx): # used as labels labels = ctx.attr.labels or ctx.attr.annotations - layer_descriptor_files = [get_descriptor_file(ctx, f[OCIDescriptor]) for f in ctx.attr.layers] + layer_descriptor_files = [ + get_or_make_descriptor_file( + ctx, + descriptor_provider = f[OCIDescriptor], + ) + for f in ctx.attr.layers + ] layer_and_descriptor_paths = zip( [f.path for f in ctx.files.layers], [f.path for f in layer_descriptor_files], @@ -75,6 +136,7 @@ def _impl(ctx): return [ OCIDescriptor( descriptor_file = manifest_desc_file, + media_type = MEDIA_TYPE_OCI_MANIFEST, ), OCILayout( blob_index = layout_file, @@ -94,53 +156,22 @@ def _impl(ctx): ), ] -oci_image = rule( +_oci_image = rule( implementation = _impl, - doc = """Creates a new image manifest and config by appending the `layers` to an existing image - manifest and config defined by `base`. If `base` is an image index, then `os` and `arch` will - be used to extract the image manifest.""", attrs = { "base": attr.label( - doc = """A base image, as defined by oci_pull or oci_image""", mandatory = True, - providers = [ - OCIDescriptor, - OCILayout, - ], - ), - "entrypoint": attr.string_list( - doc = """A list of entrypoints for the image; these will be inserted into the generated - OCI image config""", - ), - "os": attr.string( - doc = "Used to extract a manifest from base if base is an index", - ), - "arch": attr.string( - doc = "Used to extract a manifest from base if base is an index", - ), - "env": attr.string_list( - doc = """Entries are in the format of `VARNAME=VARVALUE`. These values act as defaults and - are merged with any specified when creating a container.""", + providers = [OCIDescriptor, OCILayout], ), + "entrypoint": attr.string_list(), + "os": attr.string(), + "arch": attr.string(), + "env": attr.string_list(), "layers": attr.label_list( - doc = "A list of layers defined by oci_image_layer", - providers = [ - OCIDescriptor, - ], - ), - "annotations": attr.string_dict( - doc = """[OCI Annotations](https://github.com/opencontainers/image-spec/blob/main/annotations.md) - to add to the manifest.""", - ), - "labels": attr.string_dict( - doc = """labels that will be applied to the image configuration, as defined in - [the OCI config](https://github.com/opencontainers/image-spec/blob/main/config.md#properties). - These behave the same way as - [docker LABEL](https://docs.docker.com/engine/reference/builder/#label); - in particular, labels from the base image are inherited. An empty value for a label - will cause that label to be deleted. For backwards compatibility, if this is not set, - then the value of annotations will be used instead.""", + providers = [OCIDescriptor], ), + "annotations": attr.string_dict(), + "labels": attr.string_dict(), "_ocitool": attr.label( allow_single_file = True, cfg = "exec", diff --git a/oci/private/oci_image_dir.bzl b/oci/private/oci_image_dir.bzl new file mode 100644 index 0000000..c8f6a4a --- /dev/null +++ b/oci/private/oci_image_dir.bzl @@ -0,0 +1,137 @@ +""" oci_image_dir """ + +load("@rules_pkg//pkg:mappings.bzl", "pkg_files") +load("@rules_pkg//pkg:pkg.bzl", "pkg_tar") +load("//oci:providers.bzl", "OCIDescriptor", "OCILayout") +load(":common.bzl", "get_or_make_descriptor_file") +load(":oci_image_load.bzl", "oci_image_load") +load(":providers.bzl", "DebugInfo", "PlatformsInfo") + +def oci_image_dir( + *, + image, # str + gzip = True, # bool + **kwargs): + # -> None + """Adds additional targets to oci_image and oci_image_index. + + Namely, creates targets for an OCI Image Layout directory and a tar file. + + Args: + image: Name of the oci_image or oci_image_index target + gzip: If true, creates a tar.gz file. If false, creates a tar file + image: The label of an oci_image or oci_image_index + **kwargs: Additional arguments to pass to the rule, e.g. tags or visibility + """ + name_dir = "{}.dir".format(image) + name_pkg_files = "{}.pkg_files".format(image) + name_tar = "{}.tar".format(image) + name_load = "{}.load".format(image) + + kwargs = dict(kwargs) + + # Ensure that the "manual" tag is always present + tags = kwargs.pop("tags", None) or [] + tags = {k: True for k in tags} + tags["manual"] = True + tags = [k for k in tags.keys()] + + _oci_image_dir( + name = name_dir, + image = image, + tags = tags, + **kwargs + ) + + pkg_files_kwargs = dict(kwargs) + pkg_files_kwargs["visibility"] = ["//visibility:private"] + pkg_files( + name = name_pkg_files, + srcs = [name_dir], + strip_prefix = ".", + renames = { + name_dir: "./", + }, + tags = tags, + **pkg_files_kwargs + ) + + if gzip: + pkg_tar( + name = name_tar, + extension = "tar.gz", + srcs = [name_pkg_files], + package_file_name = "{}.tar.gz".format(image), + strip_prefix = ".", + tags = tags, + **kwargs + ) + else: + pkg_tar( + name = name_tar, + srcs = [name_pkg_files], + package_file_name = "{}.tar".format(image), + strip_prefix = ".", + tags = tags, + **kwargs + ) + + oci_image_load( + name = name_load, + image = image, + dir = name_dir, + tar = name_tar, + **kwargs + ) + +def _impl(ctx): + descriptor = get_or_make_descriptor_file( + ctx, + descriptor_provider = ctx.attr.image[OCIDescriptor], + outpath = "{name}_/descriptor.json".format(name = ctx.label.name), + ) + files = ctx.attr.image[OCILayout].files.to_list() + + out_dir = ctx.actions.declare_directory("{name}_/{name}".format(name = ctx.label.name)) + out_platforms = ctx.actions.declare_file("{name}_/platforms.json".format(name = ctx.label.name)) + + args = ctx.actions.args() + args.add("oci-dir") + args.add("--descriptor-path", descriptor.path) + args.add("--out-dir", out_dir.path) + args.add("--out-platforms-path", out_platforms.path) + for f in files: + args.add("--file", f.path) + + env = {} if not ctx.attr._debug[DebugInfo].debug else {"RUST_LOG": "debug"} + + ctx.actions.run( + arguments = [args], + executable = ctx.executable._ocitool, + inputs = [descriptor] + files, + outputs = [out_dir, out_platforms], + env = env, + ) + + return [ + DefaultInfo( + files = depset([out_dir]), + ), + PlatformsInfo( + platforms = out_platforms, + ), + ] + +_oci_image_dir = rule( + implementation = _impl, + attrs = { + "image": attr.label(providers = [OCIDescriptor]), + "_debug": attr.label(default = "//oci:debug"), + "_ocitool": attr.label( + allow_single_file = True, + cfg = "exec", + default = "//ocitool", + executable = True, + ), + }, +) diff --git a/oci/private/oci_image_index.bzl b/oci/private/oci_image_index.bzl index e6bdd66..c9b9d16 100644 --- a/oci/private/oci_image_index.bzl +++ b/oci/private/oci_image_index.bzl @@ -1,7 +1,40 @@ """ oci_image_index """ load("//oci:providers.bzl", "OCIDescriptor", "OCILayout") -load(":common.bzl", "get_descriptor_file") +load(":common.bzl", "MEDIA_TYPE_OCI_INDEX", "get_or_make_descriptor_file") +load(":oci_image_dir.bzl", "oci_image_dir") + +def oci_image_index( + *, + name, + manifests, + annotations = None, + gzip = True, + **kwargs): + """Creates a "multi-arch"" OCI image + + Also creates targets for an OCI Layout directory and a .tar.gz file + + Args: + name: A unique name for the rule + manifests: A list of oci_image labels + annotations: A dictionary of annotations to add to the index + gzip: If true, creates a tar.gz file. If false, creates a tar file + **kwargs: Additional arguments to pass to the underlying rules, e.g. + tags or visibility + """ + _oci_image_index( + name = name, + annotations = annotations, + manifests = manifests, + **kwargs + ) + + oci_image_dir( + image = name, + gzip = gzip, + **kwargs + ) def _impl(ctx): layout_files = depset(None, transitive = [m[OCILayout].files for m in ctx.attr.manifests]) @@ -12,7 +45,11 @@ def _impl(ctx): desc_files = [] for manifest in ctx.attr.manifests: - desc_files.append(get_descriptor_file(ctx, manifest[OCIDescriptor])) + desc_file = get_or_make_descriptor_file( + ctx, + descriptor_provider = manifest[OCIDescriptor], + ) + desc_files.append(desc_file) outputs = [ index_file, @@ -38,6 +75,7 @@ def _impl(ctx): return [ OCIDescriptor( descriptor_file = index_desc_file, + media_type = MEDIA_TYPE_OCI_INDEX, ), OCILayout( blob_index = layout_file, @@ -48,7 +86,7 @@ def _impl(ctx): ), ] -oci_image_index = rule( +_oci_image_index = rule( implementation = _impl, doc = """ """, diff --git a/oci/private/oci_image_layout.bzl b/oci/private/oci_image_layout.bzl deleted file mode 100644 index 62a9648..0000000 --- a/oci/private/oci_image_layout.bzl +++ /dev/null @@ -1,115 +0,0 @@ -"""A rule to create a directory in OCI Image Layout format.""" - -load("@rules_pkg//pkg:mappings.bzl", "pkg_files") -load("@rules_pkg//pkg:pkg.bzl", "pkg_tar") -load("//oci:providers.bzl", "OCIDescriptor", "OCILayout") -load(":debug_flag.bzl", "DebugInfo") - -def oci_image_layout( - *, - name, - image_index, - gzip = True, - **kwargs): - """Creates targets for an OCI Image Layout directory and a tar file - - See https://github.com/opencontainers/image-spec/blob/main/image-layout.md - for the specification of the OCI Image Format directory. - - Args: - name: A unique name for the rule - image_index: An oci_image_index label - gzip: If true, creates a tar.gz file. If false, creates a tar file - **kwargs: Additional arguments to pass to the underlying rules, e.g. - tags or visibility - """ - _oci_image_layout( - name = name, - image_index = image_index, - **kwargs - ) - - kwargs_copy = dict(kwargs) - kwargs_copy.pop("visibility", None) - pkg_files( - name = "{}.pkg_files".format(name), - srcs = [":{}".format(name)], - strip_prefix = ".", - renames = { - ":{}".format(name): "./", - }, - visibility = ["//visibility:private"], - **kwargs_copy - ) - - if gzip: - pkg_tar( - name = "{}.tar".format(name), - extension = "tar.gz", - srcs = ["{}.pkg_files".format(name)], - package_file_name = "{}.tar.gz".format(name), - strip_prefix = ".", - **kwargs - ) - else: - pkg_tar( - name = "{}.tar".format(name), - srcs = ["{}.pkg_files".format(name)], - package_file_name = "{}.tar".format(name), - strip_prefix = ".", - **kwargs - ) - -def _impl(ctx): - layout = ctx.attr.image_index[OCILayout] - - # layout_files contains all available blobs for the image. - layout_files = ",".join([p.path for p in layout.files.to_list()]) - - descriptor = ctx.attr.image_index[OCIDescriptor] - out_dir = ctx.actions.declare_directory(ctx.label.name) - - ctx.actions.run( - executable = ctx.executable._ocitool, - arguments = [ - "--layout={layout}".format(layout = layout.blob_index.path), - "--debug={debug}".format(debug = str(ctx.attr._debug[DebugInfo].debug)), - "create-oci-image-layout", - # We need to use the directory one level above bazel-out for the - # layout-relative directory. This is because the paths in - # oci_image_index's index.layout.json are of the form: - # "bazel-out/os_arch-fastbuild/bin/...". Unfortunately, bazel - # provides no direct way to access this directory, so here we traverse - # up 3 levels from the bin directory. - "--layout-relative={root}".format(root = ctx.bin_dir.path + "/../../../"), - "--desc={desc}".format(desc = descriptor.descriptor_file.path), - "--layout-files={layout_files}".format(layout_files = layout_files), - "--out-dir={out_dir}".format(out_dir = out_dir.path), - ], - inputs = depset( - direct = ctx.files.image_index + [layout.blob_index], - transitive = [layout.files], - ), - outputs = [out_dir], - ) - - return [ - DefaultInfo(files = depset([out_dir])), - ] - -_oci_image_layout = rule( - implementation = _impl, - attrs = { - "image_index": attr.label(providers = [OCILayout]), - "_debug": attr.label( - default = "//oci:debug", - providers = [DebugInfo], - ), - "_ocitool": attr.label( - allow_single_file = True, - cfg = "exec", - default = "//go/cmd/ocitool", - executable = True, - ), - }, -) diff --git a/oci/private/oci_image_load.bzl b/oci/private/oci_image_load.bzl new file mode 100644 index 0000000..6139117 --- /dev/null +++ b/oci/private/oci_image_load.bzl @@ -0,0 +1,108 @@ +""" oci_image_load """ + +load("@aspect_bazel_lib//lib:paths.bzl", "BASH_RLOCATION_FUNCTION", "to_rlocation_path") +load("//oci:providers.bzl", "OCIDescriptor") +load(":providers.bzl", "PlatformsInfo") + +def oci_image_load( + name, + dir, + image, + tar, + **kwargs): + """Creates an executable target that loads and OCI image into docker + + Args: + name: Name of the target + dir: The label of the oci_dir target associated with the image + image: The label of the oci_image or oci_image_index target to load + tar: The label of the tar file associated with the image + **kwargs: Additional arguments to pass to the rule, e.g. tags or visibility + """ + kwargs = dict(kwargs) + + # Ensure that the "manual" tag is always present + tags = kwargs.pop("tags", None) or [] + tags = {k: True for k in tags} + tags["manual"] = True + tags = [k for k in tags.keys()] + + _oci_image_load( + name = name, + dir = dir, + image = image, + tar = tar, + tags = tags, + **kwargs + ) + +def _impl(ctx): + platforms = ctx.attr.dir[PlatformsInfo].platforms + ocitool = ctx.executable._ocitool + + repository = "bazel/{}/{}".format( + ctx.attr.image.label.package, + ctx.attr.image.label.name, + ) + + exe = ctx.actions.declare_file("{}_/run.sh".format(ctx.label.name)) + ctx.actions.write( + output = exe, + content = """ +#!/usr/bin/env bash +set -euo pipefail + +{BASH_RLOCATION_FUNCTION} + +ocitool="$(rlocation "{ocitool}")" +platforms="$(rlocation "{platforms}")" +tar="$(rlocation "{tar}")" + +"${{ocitool}}" \\ + oci-load \\ + --platforms-path "${{platforms}}" \\ + --repository "{repository}" \\ + --tar-path "${{tar}}" +""".strip().format( + BASH_RLOCATION_FUNCTION = BASH_RLOCATION_FUNCTION, + ocitool = to_rlocation_path(ctx, ocitool), + platforms = to_rlocation_path(ctx, platforms), + repository = repository, + tar = to_rlocation_path(ctx, ctx.file.tar), + ), + ) + + runfiles = ctx.runfiles(files = [ctx.file.tar, ocitool, platforms]) + runfiles = runfiles.merge(ctx.attr._bash_runfiles.default_runfiles) + runfiles = runfiles.merge(ctx.attr._ocitool.default_runfiles) + + return [ + DefaultInfo( + files = depset([exe]), + runfiles = runfiles, + executable = exe, + ), + ] + +_oci_image_load = rule( + implementation = _impl, + attrs = { + "dir": attr.label( + providers = [PlatformsInfo], + mandatory = True, + ), + "image": attr.label(providers = [OCIDescriptor]), + "tar": attr.label( + allow_single_file = True, + mandatory = True, + ), + "_bash_runfiles": attr.label(default = "@bazel_tools//tools/bash/runfiles"), + "_ocitool": attr.label( + allow_single_file = True, + cfg = "exec", + default = "//ocitool", + executable = True, + ), + }, + executable = True, +) diff --git a/oci/private/oci_push.bzl b/oci/private/oci_push.bzl index c57f1df..cf8ef20 100644 --- a/oci/private/oci_push.bzl +++ b/oci/private/oci_push.bzl @@ -2,7 +2,7 @@ load("@aspect_bazel_lib//lib:stamping.bzl", "STAMP_ATTRS", "maybe_stamp") load("//oci:providers.bzl", "OCIDescriptor", "OCILayout", "OCIReferenceInfo") -load(":debug_flag.bzl", "DebugInfo") +load(":providers.bzl", "DebugInfo") def _impl(ctx): layout = ctx.attr.manifest[OCILayout] diff --git a/oci/private/providers.bzl b/oci/private/providers.bzl new file mode 100644 index 0000000..5aab2dd --- /dev/null +++ b/oci/private/providers.bzl @@ -0,0 +1,13 @@ +""" providers """ + +DebugInfo = provider( + "DebugInfo", + fields = ["debug"], +) + +PlatformsInfo = provider( + doc = "Information about the platforms of each manifest in an OCI image", + fields = { + "platforms": "a json file containing information about the platforms of each manifest in an OCI image", + }, +) diff --git a/oci/private/repositories/BUILD.bazel b/oci/private/repositories/BUILD.bazel index 6bbce16..57c17b9 100644 --- a/oci/private/repositories/BUILD.bazel +++ b/oci/private/repositories/BUILD.bazel @@ -12,5 +12,5 @@ pkg_files( "*.bazel", ]), prefix = "oci/private/repositories", - visibility = ["//release:__subpackages__"], + visibility = ["//:__subpackages__"], ) diff --git a/oci/private/repositories/download.bzl b/oci/private/repositories/download.bzl index 24bbdc8..fd8bd89 100644 --- a/oci/private/repositories/download.bzl +++ b/oci/private/repositories/download.bzl @@ -1,11 +1,13 @@ """ download utilities """ load("@bazel_skylib//lib:versions.bzl", "versions") - -MEDIA_TYPE_DOCKER_INDEX = "application/vnd.docker.distribution.manifest.list.v2+json" -MEDIA_TYPE_DOCKER_MANIFEST = "application/vnd.docker.distribution.manifest.v2+json" -MEDIA_TYPE_OCI_INDEX = "application/vnd.oci.image.index.v1+json" -MEDIA_TYPE_OCI_MANIFEST = "application/vnd.oci.image.manifest.v1+json" +load( + "//oci/private:common.bzl", + "MEDIA_TYPE_DOCKER_INDEX", + "MEDIA_TYPE_DOCKER_MANIFEST", + "MEDIA_TYPE_OCI_INDEX", + "MEDIA_TYPE_OCI_MANIFEST", +) _RESOURCE_BLOB = "blobs" _RESOURCE_INDEX_OR_MANIFEST = "manifests" diff --git a/oci/private/repositories/oci_pull.bzl b/oci/private/repositories/oci_pull.bzl index 8155e19..4fd65f7 100644 --- a/oci/private/repositories/oci_pull.bzl +++ b/oci/private/repositories/oci_pull.bzl @@ -1,12 +1,15 @@ """ oci_pull """ -load(":authn.bzl", _authn = "authn") load( - ":download.bzl", + "//oci/private:common.bzl", "MEDIA_TYPE_DOCKER_INDEX", "MEDIA_TYPE_DOCKER_MANIFEST", "MEDIA_TYPE_OCI_INDEX", "MEDIA_TYPE_OCI_MANIFEST", +) +load(":authn.bzl", _authn = "authn") +load( + ":download.bzl", "download_blob", "download_index_or_manifest", ) diff --git a/oci/private/repositories/oci_pulled_image.bzl b/oci/private/repositories/oci_pulled_image.bzl index 050a91e..069dc85 100644 --- a/oci/private/repositories/oci_pulled_image.bzl +++ b/oci/private/repositories/oci_pulled_image.bzl @@ -1,7 +1,12 @@ """ oci_pulled_image """ -load("@com_github_datadog_rules_oci//oci:providers.bzl", "OCIDescriptor", "OCILayout") -load(":download.bzl", "MEDIA_TYPE_OCI_INDEX") +load( + "@com_github_datadog_rules_oci//oci:providers.bzl", + "OCIDescriptor", + "OCILayout", +) +load("//oci/private:common.bzl", "MEDIA_TYPE_OCI_INDEX") +load("//oci/private:oci_image_dir.bzl", "oci_image_dir") _COREUTILS_TOOLCHAIN = "@aspect_bazel_lib//lib:coreutils_toolchain_type" @@ -26,6 +31,11 @@ def oci_pulled_image( **kwargs ) + oci_image_dir( + image = name, + **kwargs + ) + def _impl(ctx): coreutils = ctx.toolchains[_COREUTILS_TOOLCHAIN].coreutils_info.bin diff --git a/oci/providers.bzl b/oci/providers.bzl index 820e955..4ab4a8a 100644 --- a/oci/providers.bzl +++ b/oci/providers.bzl @@ -2,15 +2,18 @@ # buildifier: disable=name-conventions OCIDescriptor = provider( - doc = "", + doc = "An OCI descriptor. See https://github.com/opencontainers/image-spec/blob/main/descriptor.md", fields = { "file": "A file object of the content this descriptor describes", "descriptor_file": "A file object with the information in this provider", - "media_type": "The MIME media type of the file", - "size": "The size in bytes of the file", - "urls": "Additional URLs where you can find the content of file", - "digest": "A digest, including the algorithm, of the file", - "annotations": "String map of aribtrary metadata", + # + "artifact_type": "Optional. The type of an artifact when the descriptor points to an artifact", + "data": "Optional. An embedded representation of the referenced content", + "annotations": "Optional. Arbitrary metadata for this descriptor", + "digest": "Required. The digest of the targeted content", + "media_type": "Required. The media type of the referenced content", + "size": "Required. The size, in bytes, of the raw content", + "urls": "Optional. A list of URIs from which this object MAY be downloaded", }, ) diff --git a/ocitool/BUILD.bazel b/ocitool/BUILD.bazel new file mode 100644 index 0000000..8ea0300 --- /dev/null +++ b/ocitool/BUILD.bazel @@ -0,0 +1,34 @@ +load("@crate_index//:defs.bzl", "all_crate_deps") +load( + "@rules_rust//rust:defs.bzl", + "rust_binary", + "rust_doc", + "rust_doc_test", + "rust_test", +) + +exports_files(["Cargo.toml"]) + +rust_binary( + name = "ocitool", + srcs = glob(["src/**/*.rs"]), + visibility = ["//visibility:public"], + deps = all_crate_deps(normal = True), +) + +rust_test( + name = "test", + crate = ":ocitool", + deps = all_crate_deps(normal_dev = True), +) + +rust_doc( + name = "docs", + crate = ":ocitool", + rustdoc_flags = ["--document-private-items"], +) + +rust_doc_test( + name = "docs.test", + crate = ":ocitool", +) diff --git a/ocitool/Cargo.toml b/ocitool/Cargo.toml new file mode 100644 index 0000000..7d9bb69 --- /dev/null +++ b/ocitool/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "ocitool" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = { workspace = true } +clap = { workspace = true } +colored = { workspace = true } +fs-err = { workspace = true } +hex = { workspace = true } +oci-spec = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +sha2 = { workspace = true } +tracing = { workspace = true } +tracing-subscriber = { workspace = true } diff --git a/ocitool/src/cmd.rs b/ocitool/src/cmd.rs new file mode 100644 index 0000000..b341e1d --- /dev/null +++ b/ocitool/src/cmd.rs @@ -0,0 +1,5 @@ +mod oci_dir; +mod oci_load; + +pub(crate) use oci_dir::oci_dir; +pub(crate) use oci_load::oci_load; diff --git a/ocitool/src/cmd/oci_dir.rs b/ocitool/src/cmd/oci_dir.rs new file mode 100644 index 0000000..b356ebf --- /dev/null +++ b/ocitool/src/cmd/oci_dir.rs @@ -0,0 +1,216 @@ +mod descriptor; +mod digest; + +use std::collections::HashMap; +use std::io; +use std::path::{Path, PathBuf}; + +use anyhow::Context as _; +use fs_err as fs; +use oci_spec::image::{ + Descriptor, Digest, ImageConfiguration, ImageIndex, ImageIndexBuilder, ImageManifest, + MediaType, Platform, SCHEMA_VERSION, +}; + +use crate::cmd::oci_dir::descriptor::DescriptorExt as _; +use crate::cmd::oci_dir::digest::DigestExt as _; +use crate::utils; + +pub(crate) fn oci_dir( + descriptor_path: PathBuf, + files: Vec, + out_dir: PathBuf, + out_platforms_path: PathBuf, +) -> Result<(), anyhow::Error> { + // Deserialize the descriptor provided by the user + let descriptor = Descriptor::from_path(&descriptor_path)?; + + // Create a map of Digest->Path for all 'files' provided by the user, e.g. + // { + // Digest("sha256:9c03df60186916e2ab82ec082c4c841409e0399d66647acf72343b3865c68139"): "bazel-out/darwin_arm64-fastbuild/bin/examples/rust/image.layout.json", + // Digest("sha256:5c7ce68406b22986555d3c0922c75b60bcec49796addd09f86d9557d1897f76d"): "external/_main~_repo_rules~ubuntu_noble/blobs/sha256/5c7ce68406b22986555d3c0922c75b60bcec49796addd09f86d9557d1897f76d", + // } + let files_map = files + .into_iter() + .map(|path| Digest::calculate_from_path(&path).map(|digest| (digest, path))) + .collect::, _>>()?; + + // Construct the an OCI layout directory (the output)... + + // An OCI layout directory should look like this: + // ./oci-layout + // ./index.json + // ./blobs/sha256/9c03df60186916e2ab82ec082c4c841409e0399d66647acf72343b3865c68139 + // ./blobs/sha256/5c7ce68406b22986555d3c0922c75b60bcec49796addd09f86d9557d1897f76d + // ./blobs/sha256/... + // + // where... + // - ./oci-layout is a file containing the json '{"imageLayoutVersion": "1.0.0"}' + // - ./index.json is a file containing the json representation of the index + // - ./blobs/sha256/... contains all the manifests, configs, and layers pointed to by the + // index, as well as the index itself + // + // See https://github.com/opencontainers/image-spec/blob/main/image-layout.md + + // Make the blobs/sha256 directory + fs::create_dir_all(out_dir.join("blobs").join("sha256"))?; + + // Write the oci-layout file + fs::write( + out_dir.join("oci-layout"), + br#"{"imageLayoutVersion": "1.0.0"}"#, + )?; + + // Handle the rest differently depending on if the user provided an index or a manifest + let mut out_platforms = HashMap::::new(); + match descriptor.media_type() { + MediaType::ImageIndex => { + // Find the path of the index in the files_map + let index_path = files_map.get(descriptor.digest()).ok_or_else(|| { + anyhow::anyhow!("Failed to find index with digest {}", descriptor.digest()) + })?; + + // Copy the index to index.json + utils::fs::copy(index_path, out_dir.join("index.json"))?; + + // Copy the index to the blobs directory + utils::fs::copy(index_path, out_dir.join(descriptor.digest().path()))?; + + // Deserialize the index + let index = { + let reader = io::BufReader::new(fs::File::open(index_path)?); + serde_json::from_reader::<_, ImageIndex>(reader)? + }; + + // Write all the manifests, configs, and layers to the blobs directory + for manifest_descriptor in index.manifests() { + write_manifest_and_associated_config_and_associated_layers_to_blobs_directory( + &files_map, + manifest_descriptor, + &out_dir, + &mut out_platforms, + )?; + } + } + MediaType::ImageManifest => { + // Create an index + let index = ImageIndexBuilder::default() + .manifests(vec![descriptor]) + .media_type(MediaType::ImageIndex) + .schema_version(SCHEMA_VERSION) + // Note: You are also allowed to set 'annotations', 'artifactType', and 'subject' + // on an index, but we don't do that here + .build()?; + + // Write the index to index.json + let index_str = serde_json::to_string_pretty(&index)?; + fs::write(out_dir.join("index.json"), index_str.as_bytes())?; + + // Write the index to the blobs directory + let index_digest = Digest::calculate_from_str(&index_str)?; + fs::write(out_dir.join(index_digest.path()), index_str.as_bytes())?; + + // Write the manifest, config, and all the layers to the blobs directory + for manifest_descriptor in index.manifests() { + write_manifest_and_associated_config_and_associated_layers_to_blobs_directory( + &files_map, + manifest_descriptor, + &out_dir, + &mut out_platforms, + )?; + } + } + _ => { + unreachable!( + "checked the validity of media types in the constructor of 'descriptor' above" + ) + } + } + + // Write the platforms information to the out_platforms_path + let mut writer = io::BufWriter::new(fs::File::create(out_platforms_path)?); + serde_json::to_writer_pretty(&mut writer, &out_platforms)?; + + Ok(()) +} + +fn write_manifest_and_associated_config_and_associated_layers_to_blobs_directory( + files_map: &HashMap, + manifest_descriptor: &oci_spec::image::Descriptor, + out_dir: &Path, + out_platforms: &mut HashMap, +) -> Result<(), anyhow::Error> { + // Record information about the platform of the manifest + out_platforms.insert( + manifest_descriptor.digest().clone(), + manifest_descriptor.platform().clone().ok_or_else(|| { + anyhow::anyhow!( + "Failed to find platform for manifest with digest {}", + manifest_descriptor.digest() + ) + })?, + ); + + // Get the manifest path + let manifest_path = files_map.get(manifest_descriptor.digest()).ok_or_else(|| { + anyhow::anyhow!( + "Failed to find manifest with digest {}", + manifest_descriptor.digest() + ) + })?; + + // Deserialize the manifest + let manifest = { + let reader = io::BufReader::new(fs::File::open(manifest_path)?); + serde_json::from_reader::<_, ImageManifest>(reader).with_context(|| { + format!( + "Failed to deserialize {} into a valid ImageManifest", + manifest_path.display() + ) + })? + }; + + // Copy the manifest to the blobs directory + utils::fs::copy( + manifest_path, + out_dir.join(manifest_descriptor.digest().path()), + )?; + + // Get the config path + let config_path = files_map.get(manifest.config().digest()).ok_or_else(|| { + anyhow::anyhow!( + "Failed to find config with digest {}", + manifest.config().digest() + ) + })?; + + // Deserialize the config (not required, but adds an extra check that the config is well-formed) + let _config = { + let reader = io::BufReader::new(fs::File::open(config_path)?); + serde_json::from_reader::<_, ImageConfiguration>(reader).with_context(|| { + format!( + "Failed to deserialize {} into a valid ImageConfiguration", + config_path.display() + ) + })? + }; + + // Copy the config to the blobs directory + utils::fs::copy(config_path, out_dir.join(manifest.config().digest().path()))?; + + // For each layer + for layer_descriptor in manifest.layers() { + // Get the layer path + let layer_path = files_map.get(layer_descriptor.digest()).ok_or_else(|| { + anyhow::anyhow!( + "Failed to find layer with digest {}", + layer_descriptor.digest() + ) + })?; + + // Copy the layer to the blobs directory + utils::fs::copy(layer_path, out_dir.join(layer_descriptor.digest().path()))?; + } + + Ok(()) +} diff --git a/ocitool/src/cmd/oci_dir/descriptor.rs b/ocitool/src/cmd/oci_dir/descriptor.rs new file mode 100644 index 0000000..f1fe391 --- /dev/null +++ b/ocitool/src/cmd/oci_dir/descriptor.rs @@ -0,0 +1,106 @@ +use std::collections::HashMap; +use std::io; +use std::path::Path; + +use anyhow::Context as _; +use fs_err as fs; +use oci_spec::image::{Descriptor, Digest, MediaType, Platform}; +use serde::Deserialize; + +/// Adds an extra method to the external oci_spec::image::Descriptor type +pub(crate) trait DescriptorExt: Sized { + fn from_path

(path: P) -> Result + where + P: AsRef; +} + +impl DescriptorExt for Descriptor { + /// Constructs a Descriptor by deserializing the file at the provided path + fn from_path

(path: P) -> Result + where + P: AsRef, + { + let path = path.as_ref(); + + let raw = { + let reader = io::BufReader::new(fs::File::open(path)?); + serde_json::from_reader::<_, DescriptorRaw>(reader).with_context(|| { + format!( + "Failed to deserialize {} into a valid Descriptor", + path.display() + ) + })? + }; + + let mut errors = Vec::new(); + if raw.digest.is_none() { + errors.push("digest"); + } + if raw.media_type.is_none() { + errors.push("media_type"); + } + if raw.size.is_none() { + errors.push("size"); + } + if !errors.is_empty() { + anyhow::bail!( + "Descriptor is missing required fields: {}", + errors.join(", ") + ); + } + + let digest = raw.digest.expect("checked above"); + let media_type = raw.media_type.expect("checked above"); + let size = raw.size.expect("checked above"); + + let supported_media_types = [MediaType::ImageIndex, MediaType::ImageManifest]; + if !supported_media_types.contains(&media_type) { + anyhow::bail!( + "Invalid media type in descriptor. Got {}. Expected one of: {}", + media_type, + supported_media_types + .iter() + .map(|mt| mt.to_string()) + .collect::>() + .join(", ") + ); + } + + let mut this = oci_spec::image::Descriptor::new(media_type, size, digest); + this.set_artifact_type(raw.artifact_type); + this.set_annotations(raw.annotations); + this.set_data(raw.data); + this.set_platform(raw.platform); + this.set_urls(raw.urls); + + Ok(this) + } +} + +#[derive(Clone, Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +struct DescriptorRaw { + #[serde(default)] + annotations: Option>, + + #[serde(default)] + artifact_type: Option, + + #[serde(default)] + data: Option, + + #[serde(default)] + digest: Option, + + #[serde(default)] + media_type: Option, + + #[serde(default)] + platform: Option, + + #[serde(default)] + size: Option, + + #[serde(default)] + urls: Option>, +} diff --git a/ocitool/src/cmd/oci_dir/digest.rs b/ocitool/src/cmd/oci_dir/digest.rs new file mode 100644 index 0000000..4f64e7e --- /dev/null +++ b/ocitool/src/cmd/oci_dir/digest.rs @@ -0,0 +1,109 @@ +use std::io; +use std::path::{Path, PathBuf}; + +use fs_err as fs; +use oci_spec::image::Digest; +use sha2::{Digest as _, Sha256}; + +/// Adds an extra method to the external oci_spec::image::Digest type +pub(crate) trait DigestExt: Sized { + fn calculate_from_str(s: S) -> Result + where + S: AsRef; + + fn calculate_from_path

(path: P) -> Result + where + P: AsRef; + + fn path(&self) -> PathBuf; +} + +impl DigestExt for Digest { + /// Returns the digest of the provided string + fn calculate_from_str(s: S) -> Result + where + S: AsRef, + { + let s = s.as_ref(); + let mut reader = s.as_bytes(); + let mut hasher = Sha256::new(); + io::copy(&mut reader, &mut hasher)?; + let sha256 = hex::encode(hasher.finalize()); + let digest = format!("sha256:{}", sha256).parse::()?; + Ok(digest) + } + + /// Returns the digest of the file at the provided path + /// + /// Exploits the fact that paths in the blobs directory already encode the digests of the files + /// contained inside, so this function tries to get the digest from the file's path. Only if that + /// fails, does it fall back to actually calculating the sha256 hash of the file + fn calculate_from_path

(path: P) -> Result + where + P: AsRef, + { + let path = path.as_ref(); + + let fallback = |path| { + let mut reader = io::BufReader::new(fs::File::open(path)?); + let mut hasher = Sha256::new(); + io::copy(&mut reader, &mut hasher)?; + let sha256 = hex::encode(hasher.finalize()); + let digest = format!("sha256:{}", sha256).parse::()?; + Ok(digest) + }; + + let filename = match path + .file_name() + .ok_or_else(|| anyhow::anyhow!("Called .file_name() on the root of the filesystem"))? + .to_str() + { + Some(filename) => filename, + None => return fallback(path), + }; + + let parent = match path.parent().and_then(|parent| parent.to_str()) { + Some(parent) => parent, + None => return fallback(path), + }; + + for (algo, algo_hex_len) in [ + ("sha256", 64), // a hex-encoded sha256 hash is 64 bytes in length + ("sha384", 96), // sha384 96 + ("sha512", 128), // sha512 128 + ] { + if parent == algo && filename.len() == algo_hex_len { + let digest_str = format!("{}:{}", algo, filename); + match digest_str.parse::() { + Ok(digest) => return Ok(digest), + Err(_) => return fallback(path), + } + } + } + + fallback(path) + } + + /// Returns the path to write a file with this digest to (relative to the OCI layout directory root) + fn path(&self) -> PathBuf { + Path::new("blobs") + .join(self.algorithm().to_string()) + .join(self.digest()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_path() -> Result<(), anyhow::Error> { + let digest = "sha256:bac5da5a7201f802fe318150094700ae1bc7b59ab093eb1abacb787049239a9e" + .parse::()?; + let expected = Path::new("blobs") + .join("sha256") + .join("bac5da5a7201f802fe318150094700ae1bc7b59ab093eb1abacb787049239a9e"); + assert_eq!(digest.path(), expected); + Ok(()) + } +} diff --git a/ocitool/src/cmd/oci_load.rs b/ocitool/src/cmd/oci_load.rs new file mode 100644 index 0000000..442c983 --- /dev/null +++ b/ocitool/src/cmd/oci_load.rs @@ -0,0 +1,151 @@ +use std::collections::HashMap; +use std::io::{self, IsTerminal}; +use std::path::{Path, PathBuf}; +use std::process::{Command, Stdio}; + +use anyhow::Context as _; +use colored::Colorize as _; +use fs_err as fs; +use oci_spec::image::{Digest, Platform}; + +pub(crate) fn oci_load( + platforms_path: PathBuf, + repository: String, + tar_path: PathBuf, +) -> Result<(), anyhow::Error> { + docker_load(&tar_path)?; + + let platforms = { + let s = fs::read_to_string(&platforms_path)?; + let platforms = + serde_json::from_str::>(&s).with_context(|| { + format!( + "Failed to deserialize {} into a valid HashMap", + platforms_path.display() + ) + })?; + if platforms.is_empty() { + anyhow::bail!("No platforms found in {}", platforms_path.display()); + } + platforms + }; + + let image_name = match validate_image_name(&repository) { + Some(image_name) => image_name, + None => { + let msg = format!( + concat!( + "WARN: Loaded image(s) into the docker daemon, but failed to retag it(them) ", + "with the image name '{}' because that name contains invalid characters. ", + "Docker only allows the following characters in image names: ['a..=z', ", + "'0..=9', '.', '_', '-', '/']. You can still access the image(s) via ", + "its(their) digest(s) above", + ), + repository, + ); + if io::stderr().is_terminal() { + eprintln!("{}", msg.yellow()); + } else { + eprintln!("{}", msg); + }; + return Ok(()); + } + }; + + let is_multi_arch = platforms.len() > 1; + for (digest, platform) in &platforms { + let old_id = digest.to_string(); + let new_id = if is_multi_arch { + format!("{}:latest-{}", image_name, platform.architecture()) + } else { + format!("{}:latest", image_name) + }; + docker_tag(&old_id, &new_id)?; + } + + Ok(()) +} + +fn docker_load(tar_path: &Path) -> Result<(), anyhow::Error> { + let cmd = "docker load"; + + let msg = format!("{} < {}", cmd, tar_path.display()); + if io::stdout().is_terminal() { + println!("{}", msg.blue()); + } else { + println!("{}", msg); + } + + let mut child = Command::new("bash") + .arg("-c") + .arg(cmd) + .stdin(Stdio::piped()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .spawn() + .with_context(|| format!("Failed to spawn command '{}'", cmd))?; + + { + let mut tar_reader = io::BufReader::new(fs::File::open(tar_path)?); + let mut stdin = child.stdin.take().expect("cannot fail"); + io::copy(&mut tar_reader, &mut stdin) + .with_context(|| format!("Failed to copy {} to stdin", tar_path.display()))?; + // Note: stdin is dropped here + } + + let status = child + .wait() + .with_context(|| format!("Failed to wait on command '{}'", cmd))?; + + if !status.success() { + anyhow::bail!( + "Command '{}'. Exit code: {}", + cmd, + status.code().unwrap_or(-1), + ); + } + + Ok(()) +} + +fn docker_tag(old_id: &str, new_id: &str) -> Result<(), anyhow::Error> { + let cmd = format!("docker tag {} {}", old_id, new_id); + + if io::stdout().is_terminal() { + println!("{}", cmd.blue()); + } else { + println!("{}", cmd); + } + + let mut child = Command::new("bash") + .arg("-c") + .arg(&cmd) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .spawn() + .with_context(|| format!("Failed to spawn command '{}'", cmd))?; + + let status = child + .wait() + .with_context(|| format!("Failed to wait on command '{}'", cmd))?; + + if !status.success() { + anyhow::bail!( + "Command '{}'. Exit code: {}", + cmd, + status.code().unwrap_or(-1), + ); + } + + Ok(()) +} + +fn validate_image_name(name: &str) -> Option { + name.chars() + .map(|c| match c { + 'a'..='z' | '0'..='9' | '.' | '_' | '-' | '/' => Some(c), + 'A'..='Z' => Some(c.to_ascii_lowercase()), + _ => None, + }) + .collect() +} diff --git a/ocitool/src/main.rs b/ocitool/src/main.rs new file mode 100644 index 0000000..6da8c36 --- /dev/null +++ b/ocitool/src/main.rs @@ -0,0 +1,84 @@ +mod cmd; +mod utils; + +use std::io::{self, IsTerminal}; +use std::path::PathBuf; + +use clap::{Parser, Subcommand}; +use colored::Colorize as _; + +/// A tool to be called from bazel rules that works with OCI images +#[derive(Debug, Parser)] +struct Args { + #[command(subcommand)] + cmd: Cmd, +} + +#[derive(Debug, Subcommand)] +enum Cmd { + /// Creates an OCI layout directory from a descriptor file and a set of files + OciDir { + /// Path to the json-encoded descriptor file for the index or manifest + #[arg(long)] + descriptor_path: PathBuf, + + /// Path to a file to potentially include in the blobs directory + #[arg(long = "file")] + files: Vec, + + /// Path to the output directory + #[arg(long)] + out_dir: PathBuf, + + /// Path to the output platforms.json file + #[arg(long)] + out_platforms_path: PathBuf, + }, + /// Load an OCI index into the docker daemon + OciLoad { + /// Path to a json file containin a map of Digest->Platform for the + /// manifests in the index + #[arg(long)] + platforms_path: PathBuf, + + /// The name of the repository to tag the loaded images with + #[arg(long)] + repository: String, + + /// Path to the tarball containing the OCI index + #[arg(long)] + tar_path: PathBuf, + }, +} + +fn main() { + if let Err(e) = run() { + let msg = format!("Error: {}", e); + if io::stderr().is_terminal() { + eprintln!("{}", msg.red()); + } else { + eprintln!("{}", msg); + } + std::process::exit(1); + } +} + +fn run() -> Result<(), anyhow::Error> { + let Args { cmd } = Args::parse(); + + utils::init_logging(); + + match cmd { + Cmd::OciDir { + descriptor_path, + files, + out_dir, + out_platforms_path, + } => cmd::oci_dir(descriptor_path, files, out_dir, out_platforms_path), + Cmd::OciLoad { + platforms_path, + repository, + tar_path, + } => cmd::oci_load(platforms_path, repository, tar_path), + } +} diff --git a/ocitool/src/utils.rs b/ocitool/src/utils.rs new file mode 100644 index 0000000..ad16d6b --- /dev/null +++ b/ocitool/src/utils.rs @@ -0,0 +1,33 @@ +use tracing_subscriber::EnvFilter; + +/// Initializes logging +pub(crate) fn init_logging() { + let _ = tracing_subscriber::fmt() + .with_env_filter(EnvFilter::from_default_env()) + .try_init(); +} + +pub(crate) mod fs { + use std::io; + use std::path::Path; + + use anyhow::Context as _; + use fs_err as fs; + + /// Copies the file at src to dst + /// + /// Note: We use this instead of fs::copy to avoid copying file permissions + pub(crate) fn copy(src: P, dst: Q) -> Result<(), anyhow::Error> + where + P: AsRef, + Q: AsRef, + { + let src = src.as_ref(); + let dst = dst.as_ref(); + let mut reader = io::BufReader::new(fs::File::open(src)?); + let mut writer = io::BufWriter::new(fs::File::create(dst)?); + io::copy(&mut reader, &mut writer) + .with_context(|| format!("Failed to copy {} to {}", src.display(), dst.display()))?; + Ok(()) + } +} diff --git a/release/BUILD.bazel b/release/BUILD.bazel deleted file mode 100644 index 851588a..0000000 --- a/release/BUILD.bazel +++ /dev/null @@ -1,12 +0,0 @@ -load("@rules_pkg//pkg:pkg.bzl", "pkg_tar") - -pkg_tar( - name = "release", - srcs = [ - "//oci:files", - "//oci/private:files", - "//oci/private/repositories:files", - ], - empty_files = ["BUILD.bazel"], - extension = "tar.gz", -) diff --git a/release/README.md b/release/README.md deleted file mode 100644 index fbd4ba5..0000000 --- a/release/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# Releasing `rules_oci` - -``` -# Build the release package tar -bzl build //release:release - -# Push the package to registry -bzl run //go/cmd/ocitool -- push-blob --ref "ghcr.io/datadog/rules_oci/rules:latest" --file $(pwd)/bazel-bin/release/release.tar.gz -``` - -## Updating Licenses and Headers - -``` -bzl run //:go -- install github.com/DataDog/temporalite/internal/licensecheck@latest -bzl run //:go -- install github.com/DataDog/temporalite/internal/copyright@latest -licensecheck -copyright -``` diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..bbf217f --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "1.81.0" +profile = "default" diff --git a/tools/format/BUILD.bazel b/tools/format/BUILD.bazel index b029f97..d7d163b 100644 --- a/tools/format/BUILD.bazel +++ b/tools/format/BUILD.bazel @@ -18,6 +18,7 @@ format_multirun( name = "format", go = "@go_sdk//:bin/gofmt", markdown = ":prettier", + rust = "@rules_rust//tools/upstream_wrapper:rustfmt", starlark = "@buildifier_prebuilt//:buildifier", yaml = "@aspect_rules_lint//format:yamlfmt", )