diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ac22eaa..5e21862 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,15 +21,6 @@ jobs: - name: Build run: nix build -L - Spelling: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: DeterminateSystems/nix-installer-action@main - - uses: codespell-project/codespell-problem-matcher@v1 - - name: Check Spelling - run: nix develop --command codespell --ignore-words-list crate,pullrequest,pullrequests,ser . - NixFormatting: runs-on: ubuntu-latest steps: diff --git a/Cargo.lock b/Cargo.lock index f9b8a76..1bee5e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,46 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "anstream" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-wincon", + "concolor-override", + "concolor-query", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2" + +[[package]] +name = "anstyle-parse" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-wincon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa" +dependencies = [ + "anstyle", + "windows-sys 0.45.0", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -19,9 +59,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -31,27 +71,35 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.1.4" +version = "4.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76" +checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3" dependencies = [ - "bitflags", + "clap_builder", "clap_derive", - "clap_lex", - "is-terminal", "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "223163f58c9a40c3b0a43e1c4b50a9ce09f007ea2cb1ec258a687945b4b7929f" +dependencies = [ + "anstream", + "anstyle", + "bitflags", + "clap_lex", "strsim", - "termcolor", ] [[package]] name = "clap_derive" -version = "4.1.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" +checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" dependencies = [ "heck", - "proc-macro-error", "proc-macro2", "quote", "syn", @@ -59,22 +107,34 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" + +[[package]] +name = "concolor-override" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f" + +[[package]] +name = "concolor-query" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" dependencies = [ - "os_str_bytes", + "windows-sys 0.45.0", ] [[package]] name = "errno" -version = "0.2.8" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -89,27 +149,24 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.7.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] [[package]] name = "heck" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.2.6" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] name = "instant" @@ -122,150 +179,112 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.3" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" dependencies = [ + "hermit-abi", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "is-terminal" -version = "0.4.2" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi", "io-lifetimes", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.141" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" [[package]] name = "linux-raw-sys" -version = "0.1.4" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" [[package]] name = "once_cell" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" - -[[package]] -name = "os_str_bytes" -version = "6.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "029d8d0b2f198229de29dca79676f2738ff952edf3fde542eb8bf94d8c21b435" - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.18" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] [[package]] name = "redox_syscall" -version = "0.2.13" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ "bitflags", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rustix" -version = "0.36.5" +version = "0.37.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588" +checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77" dependencies = [ "bitflags", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "serde" -version = "1.0.152" +version = "1.0.160" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.152" +version = "1.0.160" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" dependencies = [ "proc-macro2", "quote", @@ -274,9 +293,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.91" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ "itoa", "ryu", @@ -291,9 +310,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.105" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "fcf316d5356ed6847742d036f8a39c3b8435cac10bd528a4bd461928a6ab34d5" dependencies = [ "proc-macro2", "quote", @@ -312,32 +331,28 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.3.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ "cfg-if", "fastrand", - "libc", "redox_syscall", - "remove_dir_all", - "winapi", + "rustix", + "windows-sys 0.45.0", ] [[package]] -name = "termcolor" -version = "1.1.3" +name = "unicode-ident" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] -name = "unicode-ident" -version = "1.0.5" +name = "utf8parse" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "validate" @@ -348,95 +363,133 @@ dependencies = [ ] [[package]] -name = "version_check" -version = "0.9.4" +name = "windows-sys" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] [[package]] -name = "winapi" -version = "0.3.9" +name = "windows-sys" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows-targets 0.48.0", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "windows-targets" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] [[package]] -name = "winapi-util" -version = "0.1.5" +name = "windows-targets" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" dependencies = [ - "winapi", + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "windows_aarch64_gnullvm" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] -name = "windows-sys" -version = "0.42.0" +name = "windows_aarch64_gnullvm" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.0" +name = "windows_aarch64_msvc" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" diff --git a/bootspec/Cargo.toml b/bootspec/Cargo.toml index 4461abd..40c3c7c 100644 --- a/bootspec/Cargo.toml +++ b/bootspec/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "bootspec" version = "0.1.0" -edition = "2018" +edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -10,4 +10,4 @@ serde = { version = "1.0.152", features = ["derive"] } serde_json = "1.0.91" [dev-dependencies] -tempfile = "3.3.0" +tempfile = "3.5.0" diff --git a/bootspec/rfc0125_spec.json b/bootspec/rfc0125_spec.json new file mode 100644 index 0000000..4d7cdf1 --- /dev/null +++ b/bootspec/rfc0125_spec.json @@ -0,0 +1,44 @@ +{ + "org.nixos.bootspec.v1": { + "system": "x86_64-linux", + "init": "/nix/store/xxx-nixos-system-xxx/init", + "initrd": "/nix/store/xxx-initrd-linux/initrd", + "initrdSecrets": "/nix/store/xxx-append-secrets/bin/append-initrd-secrets", + "kernel": "/nix/store/xxx-linux/bzImage", + "kernelParams": [ + "amd_iommu=on", + "amd_iommu=pt", + "iommu=pt", + "kvm.ignore_msrs=1", + "kvm.report_ignored_msrs=0", + "udev.log_priority=3", + "systemd.unified_cgroup_hierarchy=1", + "loglevel=4" + ], + "label": "NixOS 21.11.20210810.dirty (Linux 5.15.30)", + "toplevel": "/nix/store/xxx-nixos-system-xxx" + }, + "org.nixos.specialisation.v1": { + "": { + "org.nixos.bootspec.v1": { + "system": "x86_64-linux", + "init": "/nix/store/xxx-nixos-system-xxx/init", + "initrd": "/nix/store/xxx-initrd-linux/initrd", + "initrdSecrets": "/nix/store/xxx-append-secrets/bin/append-initrd-secrets", + "kernel": "/nix/store/xxx-linux/bzImage", + "kernelParams": [ + "amd_iommu=on", + "amd_iommu=pt", + "iommu=pt", + "kvm.ignore_msrs=1", + "kvm.report_ignored_msrs=0", + "udev.log_priority=3", + "systemd.unified_cgroup_hierarchy=1", + "loglevel=4" + ], + "label": "NixOS 21.11.20210810.dirty (Linux 5.15.30)", + "toplevel": "/nix/store/xxx-nixos-system-xxx" + } + } + } +} diff --git a/bootspec/src/deser.rs b/bootspec/src/deser.rs new file mode 100644 index 0000000..e71be99 --- /dev/null +++ b/bootspec/src/deser.rs @@ -0,0 +1,47 @@ +use std::collections::HashMap; +use std::fmt; + +use serde::de::{Deserializer, MapAccess, Visitor}; + +use crate::{Extension, Extensions}; + +struct BootSpecExtensionsVisitor; + +impl<'de> Visitor<'de> for BootSpecExtensionsVisitor { + type Value = Extensions; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a map of bootspec extensions") + } + + fn visit_map(self, mut access: M) -> Result + where + M: MapAccess<'de>, + { + let mut map = HashMap::with_capacity(access.size_hint().unwrap_or(0)); + + while let Some((key, value)) = access.next_entry::()? { + // This is very hacky, but necessary because serde does not consume fields in flattened + // enums (which `Generation` is). Without this, the bootspec and specialisation objects + // would be duplicated under the `extensions` field. + // See: https://github.com/serde-rs/serde/issues/2200 + if ["org.nixos.bootspec.", "org.nixos.specialisation."] + .iter() + .any(|field| key.starts_with(field)) + { + continue; + } + + map.insert(key, value); + } + + Ok(map) + } +} + +pub fn skip_generation_fields<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + deserializer.deserialize_map(BootSpecExtensionsVisitor) +} diff --git a/bootspec/src/generation.rs b/bootspec/src/generation.rs index 385d974..3fd1f2d 100644 --- a/bootspec/src/generation.rs +++ b/bootspec/src/generation.rs @@ -1,18 +1,24 @@ +//! Provides a helper enum for deserializing from all available bootspec versions. use serde::{Deserialize, Serialize}; use crate::v1; -#[derive(Debug, Clone, Deserialize, Serialize)] -#[serde(rename_all = "lowercase")] -#[non_exhaustive] /// An enum of all available bootspec versions. /// -/// This enum should be used when attempting to serialize or deserialize a bootspec document, in -/// order to verify the contents match the version of the document. -/// /// This enum is nonexhaustive, because there may be future versions added at any point, and tools /// should explicitly handle them (e.g. by noting they're currently unsupported). +/// +/// ## Warnings +/// +/// If you attempt to deserialize using this struct, you will not get any information about +/// user-provided extensions. For that, you must deserialize with [`crate::BootJson`]. +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +#[non_exhaustive] +#[serde(untagged)] pub enum Generation { + // WARNING: Add new versions to the _top_ of this list. Untagged enums in `serde` always + // deserialize to the first variant that succeeds, and new versions should succeed before old + // versions. V1(v1::GenerationV1), } @@ -32,13 +38,15 @@ mod tests { use std::collections::HashMap; use std::path::PathBuf; - use super::Generation; - use crate::SystemConfigurationRoot; - use crate::SCHEMA_VERSION; - use serde::de::IntoDeserializer; use serde::{Deserialize, Serialize}; + use super::Generation; + use crate::{ + v1::{BootSpecV1, GenerationV1}, + BootJson, SpecialisationName, SystemConfigurationRoot, SCHEMA_VERSION, + }; + #[derive(Debug, Deserialize, Serialize, PartialEq, Default)] struct TestExtension { #[serde(rename = "key")] @@ -52,10 +60,27 @@ mod tests { } #[test] - fn valid_v1_json() { + fn valid_v1_rfc0125_json() { + // Adapted from the official JSON5 document from the RFC (converted to JSON and modified to + // have a valid `org.nixos.specialisation.v1`). + // https://github.com/NixOS/rfcs/blob/02458c2ecc9f915b143b1923213b40be8ac02a96/rfcs/0125-bootspec.md#bootspec-format-v1 + let rfc_json = include_str!("../rfc0125_spec.json"); + let from_json = serde_json::from_str::(&rfc_json).unwrap(); + assert_eq!(from_json.version(), 1); + + let Generation::V1(from_json) = from_json; + let keys = from_json + .specialisations + .keys() + .map(ToOwned::to_owned) + .collect::>(); + assert!(keys.contains(&SpecialisationName(String::from("")))); + } + + #[test] + fn valid_v1_json_basic() { let json = r#"{ - "v1": { - "system": "x86_64-linux", + "org.nixos.bootspec.v1": { "init": "/nix/store/xxx-nixos-system-xxx/init", "initrd": "/nix/store/xxx-initrd-linux/initrd", "initrdSecrets": "/nix/store/xxx-append-secrets/bin/append-initrd-secrets", @@ -71,16 +96,16 @@ mod tests { "loglevel=4" ], "label": "NixOS 21.11.20210810.dirty (Linux 5.15.30)", - "toplevel": "/nix/store/xxx-nixos-system-xxx", - "specialisation": {}, - "extensions": {} - } + "system": "x86_64-linux", + "toplevel": "/nix/store/xxx-nixos-system-xxx" + }, + "org.nixos.specialisation.v1": {} }"#; let from_json: Generation = serde_json::from_str(&json).unwrap(); let Generation::V1(from_json) = from_json; - let expected = crate::v1::GenerationV1 { + let bootspec = BootSpecV1 { system: String::from("x86_64-linux"), label: String::from("NixOS 21.11.20210810.dirty (Linux 5.15.30)"), kernel: PathBuf::from("/nix/store/xxx-linux/bzImage"), @@ -102,10 +127,12 @@ mod tests { initrd_secrets: Some(PathBuf::from( "/nix/store/xxx-append-secrets/bin/append-initrd-secrets", )), - specialisation: HashMap::new(), - extensions: HashMap::new(), toplevel: SystemConfigurationRoot(PathBuf::from("/nix/store/xxx-nixos-system-xxx")), }; + let expected = GenerationV1 { + bootspec, + specialisations: HashMap::new(), + }; assert_eq!(from_json, expected); } @@ -113,8 +140,7 @@ mod tests { #[test] fn valid_v1_json_with_typed_extension() { let json = r#"{ - "v1": { - "system": "x86_64-linux", + "org.nixos.bootspec.v1": { "init": "/nix/store/xxx-nixos-system-xxx/init", "initrd": "/nix/store/xxx-initrd-linux/initrd", "initrdSecrets": "/nix/store/xxx-append-secrets/bin/append-initrd-secrets", @@ -130,16 +156,16 @@ mod tests { "loglevel=4" ], "label": "NixOS 21.11.20210810.dirty (Linux 5.15.30)", - "toplevel": "/nix/store/xxx-nixos-system-xxx", - "specialisation": {}, - "extensions": { "org.test": { "key": "hello" } } - } + "system": "x86_64-linux", + "toplevel": "/nix/store/xxx-nixos-system-xxx" + }, + "org.nixos.specialisation.v1": {}, + "org.test": { "key": "hello" } }"#; - let from_json: Generation = serde_json::from_str(&json).unwrap(); - let Generation::V1(from_json) = from_json; + let from_json: BootJson = serde_json::from_str(&json).unwrap(); - let expected = crate::v1::GenerationV1 { + let bootspec = BootSpecV1 { system: String::from("x86_64-linux"), label: String::from("NixOS 21.11.20210810.dirty (Linux 5.15.30)"), kernel: PathBuf::from("/nix/store/xxx-linux/bzImage"), @@ -161,12 +187,18 @@ mod tests { initrd_secrets: Some(PathBuf::from( "/nix/store/xxx-append-secrets/bin/append-initrd-secrets", )), - specialisation: HashMap::new(), + toplevel: SystemConfigurationRoot(PathBuf::from("/nix/store/xxx-nixos-system-xxx")), + }; + let generation = GenerationV1 { + bootspec, + specialisations: HashMap::new(), + }; + let expected = BootJson { + generation: Generation::V1(generation), extensions: HashMap::from([( "org.test".into(), HashMap::from([("key".into(), serde_json::to_value("hello").unwrap())]), )]), - toplevel: SystemConfigurationRoot(PathBuf::from("/nix/store/xxx-nixos-system-xxx")), }; let from_extension: TestExtension = Deserialize::deserialize( @@ -189,8 +221,7 @@ mod tests { #[test] fn valid_v1_json_with_typed_optional_extension_fields_and_empty_object() { let json = r#"{ - "v1": { - "system": "x86_64-linux", + "org.nixos.bootspec.v1": { "init": "/nix/store/xxx-nixos-system-xxx/init", "initrd": "/nix/store/xxx-initrd-linux/initrd", "initrdSecrets": "/nix/store/xxx-append-secrets/bin/append-initrd-secrets", @@ -206,16 +237,15 @@ mod tests { "loglevel=4" ], "label": "NixOS 21.11.20210810.dirty (Linux 5.15.30)", - "toplevel": "/nix/store/xxx-nixos-system-xxx", - "specialisation": {}, - "extensions": {} - } + "system": "x86_64-linux", + "toplevel": "/nix/store/xxx-nixos-system-xxx" + }, + "org.nixos.specialisation.v1": {} }"#; - let from_json: Generation = serde_json::from_str(&json).unwrap(); - let Generation::V1(from_json) = from_json; + let from_json: BootJson = serde_json::from_str(&json).unwrap(); - let expected = crate::v1::GenerationV1 { + let bootspec = BootSpecV1 { system: String::from("x86_64-linux"), label: String::from("NixOS 21.11.20210810.dirty (Linux 5.15.30)"), kernel: PathBuf::from("/nix/store/xxx-linux/bzImage"), @@ -237,10 +267,16 @@ mod tests { initrd_secrets: Some(PathBuf::from( "/nix/store/xxx-append-secrets/bin/append-initrd-secrets", )), - specialisation: HashMap::new(), - extensions: HashMap::new(), toplevel: SystemConfigurationRoot(PathBuf::from("/nix/store/xxx-nixos-system-xxx")), }; + let generation = GenerationV1 { + bootspec, + specialisations: HashMap::new(), + }; + let expected = BootJson { + generation: Generation::V1(generation), + extensions: HashMap::new(), + }; assert_eq!(from_json, expected); } @@ -248,7 +284,7 @@ mod tests { #[test] fn invalid_v1_json_with_null_extension() { let json = r#"{ - "v1": { + "org.nixos.bootspec.v1": { "init": "/nix/store/xxx-nixos-system-xxx/init", "initrd": "/nix/store/xxx-initrd-linux/initrd", "initrdSecrets": "/nix/store/xxx-append-secrets/bin/append-initrd-secrets", @@ -264,20 +300,20 @@ mod tests { "loglevel=4" ], "label": "NixOS 21.11.20210810.dirty (Linux 5.15.30)", - "toplevel": "/nix/store/xxx-nixos-system-xxx", - "specialisation": {}, - "extensions": null - } + "system": "x86_64-linux", + "toplevel": "/nix/store/xxx-nixos-system-xxx" + }, + "org.nixos.specialisation.v1": {}, + "org.test": null }"#; - let json_err = serde_json::from_str::(&json).unwrap_err(); + let json_err = serde_json::from_str::(&json).unwrap_err(); assert!(json_err.to_string().contains("expected a map")); } #[test] fn valid_v1_json_without_extension() { let json = r#"{ - "v1": { - "system": "x86_64-linux", + "org.nixos.bootspec.v1": { "init": "/nix/store/xxx-nixos-system-xxx/init", "initrd": "/nix/store/xxx-initrd-linux/initrd", "initrdSecrets": "/nix/store/xxx-append-secrets/bin/append-initrd-secrets", @@ -293,15 +329,15 @@ mod tests { "loglevel=4" ], "label": "NixOS 21.11.20210810.dirty (Linux 5.15.30)", - "toplevel": "/nix/store/xxx-nixos-system-xxx", - "specialisation": {} - } + "system": "x86_64-linux", + "toplevel": "/nix/store/xxx-nixos-system-xxx" + }, + "org.nixos.specialisation.v1": {} }"#; - let from_json: Generation = serde_json::from_str(&json).unwrap(); - let Generation::V1(from_json) = from_json; + let from_json: BootJson = serde_json::from_str(&json).unwrap(); - let expected = crate::v1::GenerationV1 { + let bootspec = BootSpecV1 { system: String::from("x86_64-linux"), label: String::from("NixOS 21.11.20210810.dirty (Linux 5.15.30)"), kernel: PathBuf::from("/nix/store/xxx-linux/bzImage"), @@ -323,10 +359,16 @@ mod tests { initrd_secrets: Some(PathBuf::from( "/nix/store/xxx-append-secrets/bin/append-initrd-secrets", )), - specialisation: HashMap::new(), - extensions: HashMap::new(), toplevel: SystemConfigurationRoot(PathBuf::from("/nix/store/xxx-nixos-system-xxx")), }; + let generation = GenerationV1 { + bootspec, + specialisations: HashMap::new(), + }; + let expected = BootJson { + generation: Generation::V1(generation), + extensions: HashMap::new(), + }; assert_eq!(from_json, expected); } @@ -334,8 +376,7 @@ mod tests { #[test] fn valid_v1_json_without_initrd_and_specialisation() { let json = r#"{ - "v1": { - "system": "x86_64-linux", + "org.nixos.bootspec.v1": { "init": "/nix/store/xxx-nixos-system-xxx/init", "kernel": "/nix/store/xxx-linux/bzImage", "kernelParams": [ @@ -349,15 +390,14 @@ mod tests { "loglevel=4" ], "label": "NixOS 21.11.20210810.dirty (Linux 5.15.30)", - "toplevel": "/nix/store/xxx-nixos-system-xxx", - "extensions": {} + "system": "x86_64-linux", + "toplevel": "/nix/store/xxx-nixos-system-xxx" } }"#; - let from_json: Generation = serde_json::from_str(&json).unwrap(); - let Generation::V1(from_json) = from_json; + let from_json: BootJson = serde_json::from_str(&json).unwrap(); - let expected = crate::v1::GenerationV1 { + let bootspec = BootSpecV1 { system: String::from("x86_64-linux"), label: String::from("NixOS 21.11.20210810.dirty (Linux 5.15.30)"), kernel: PathBuf::from("/nix/store/xxx-linux/bzImage"), @@ -377,10 +417,16 @@ mod tests { init: PathBuf::from("/nix/store/xxx-nixos-system-xxx/init"), initrd: None, initrd_secrets: None, - specialisation: HashMap::new(), - extensions: HashMap::new(), toplevel: SystemConfigurationRoot(PathBuf::from("/nix/store/xxx-nixos-system-xxx")), }; + let generation = GenerationV1 { + bootspec, + specialisations: HashMap::new(), + }; + let expected = BootJson { + generation: Generation::V1(generation), + extensions: HashMap::new(), + }; assert_eq!(from_json, expected); } @@ -388,7 +434,7 @@ mod tests { #[test] fn invalid_v1_json_with_null_specialisation() { let json = r#"{ - "v1": { + "org.nixos.bootspec.v1": { "init": "/nix/store/xxx-nixos-system-xxx/init", "initrd": "/nix/store/xxx-initrd-linux/initrd", "initrdSecrets": "/nix/store/xxx-append-secrets/bin/append-initrd-secrets", @@ -404,12 +450,13 @@ mod tests { "loglevel=4" ], "label": "NixOS 21.11.20210810.dirty (Linux 5.15.30)", - "toplevel": "/nix/store/xxx-nixos-system-xxx", - "specialisation": null - } + "system": "x86_64-linux", + "toplevel": "/nix/store/xxx-nixos-system-xxx" + }, + "org.nixos.specialisation.v1": null }"#; - let json_err = serde_json::from_str::(&json).unwrap_err(); + let json_err = serde_json::from_str::(&json).unwrap_err(); assert!(json_err.to_string().contains("expected a map")); } @@ -417,7 +464,7 @@ mod tests { fn invalid_json_invalid_version() { let json = format!( r#"{{ - "v{}": {{ + "org.nixos.bootspec.v{}": {{ "init": "/nix/store/xxx-nixos-system-xxx/init", "initrd": "/nix/store/xxx-initrd-linux/initrd", "initrdSecrets": "/nix/store/xxx-append-secrets/bin/append-initrd-secrets", @@ -433,14 +480,16 @@ mod tests { "loglevel=4" ], "label": "NixOS 21.11.20210810.dirty (Linux 5.15.30)", - "toplevel": "/nix/store/xxx-nixos-system-xxx", - "specialisation": {{}} - }} + "system": "x86_64-linux", + "toplevel": "/nix/store/xxx-nixos-system-xxx" + }}, + "org.nixos.specialisation.v{}": {{}} }}"#, + SCHEMA_VERSION + 1, SCHEMA_VERSION + 1 ); let json_err = serde_json::from_str::(&json).unwrap_err(); - assert!(json_err.to_string().contains("unknown variant")); + assert!(json_err.to_string().contains("did not match any variant")); } } diff --git a/bootspec/src/lib.rs b/bootspec/src/lib.rs index 3ae127f..d8734a1 100644 --- a/bootspec/src/lib.rs +++ b/bootspec/src/lib.rs @@ -1,18 +1,21 @@ -use std::convert::TryFrom; +use std::collections::HashMap; use std::error::Error; use std::fmt; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use serde::{Deserialize, Serialize}; +use crate::generation::Generation; + +mod deser; pub mod generation; pub mod v1; #[doc(hidden)] pub type Result> = core::result::Result; -#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq, Hash)] /// A wrapper type describing the name of a NixOS specialisation. +#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq, Hash)] pub struct SpecialisationName(pub String); impl fmt::Display for SpecialisationName { @@ -21,28 +24,76 @@ impl fmt::Display for SpecialisationName { } } -#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq)] /// A wrapper type describing the root directory of a NixOS system configuration. +#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq)] pub struct SystemConfigurationRoot(pub PathBuf); /// The bootspec schema filename. pub const JSON_FILENAME: &str = "boot.json"; +/// The type for a generic extensions. +pub type Extension = HashMap; +/// The type for a collection of generic extensions. +pub type Extensions = HashMap; -// !!! IMPORTANT: KEEP `BootJson`, `Extension`, and `SCHEMA_VERSION` IN SYNC !!! -/// The current bootspec schema. -pub type BootJson = v1::GenerationV1; -/// The current Extension type. -pub type Extension = v1::Extension; +// !!! IMPORTANT: KEEP `BootSpec`, `Specialisations`, and `SCHEMA_VERSION` IN SYNC !!! +/// The current bootspec generation type. +pub type BootSpec = v1::GenerationV1; +/// The current specialisations type. +pub type Specialisations = v1::SpecialisationsV1; /// The current bootspec schema version. pub const SCHEMA_VERSION: u64 = v1::SCHEMA_VERSION; -// Enable conversions from Generation into the current Bootspec schema. -impl TryFrom for BootJson { - type Error = &'static str; +/// The current bootspec schema. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct BootJson { + #[serde(flatten)] + pub generation: Generation, + #[serde( + default = "HashMap::new", + skip_serializing_if = "HashMap::is_empty", + deserialize_with = "deser::skip_generation_fields", + flatten + )] + pub extensions: Extensions, +} + +impl BootJson { + /// Synthesize a [`BootJson`] struct from the path to a generation using the latest + /// specification version defined in this crate ([`SCHEMA_VERSION`]). + /// + /// See also [`BootJson::synthesize_version`]. + /// + /// ## Warnings + /// + /// Extensions will not be synthesized and will be an empty [`HashMap`]. + pub fn synthesize_latest(generation_path: &Path) -> Result { + Self::synthesize_version(generation_path, SCHEMA_VERSION) + } + + /// Synthesize a [`BootJson`] struct from the path to a generation and a specific version. + /// + /// This is useful when used on generations that do not have a bootspec attached to it. + /// This will not synthesize arbitrary extensions. + /// + /// ## Warnings + /// + /// Extensions will not be synthesized and will be an empty [`HashMap`]. + pub fn synthesize_version(generation_path: &Path, version: u64) -> Result { + let generation = match version { + v1::SCHEMA_VERSION => { + let generation = v1::GenerationV1::synthesize(generation_path)?; + Generation::V1(generation) + } + v => { + return Err( + format!("Cannot synthesize for unsupported schema version {}", v).into(), + ) + } + }; - fn try_from(value: generation::Generation) -> Result { - match value { - generation::Generation::V1(boot_json) => Ok(boot_json), - } + Ok(BootJson { + generation, + extensions: HashMap::new(), + }) } } diff --git a/bootspec/src/v1.rs b/bootspec/src/v1.rs index f74c467..2130302 100644 --- a/bootspec/src/v1.rs +++ b/bootspec/src/v1.rs @@ -1,3 +1,4 @@ +//! The V1 bootspec format. use std::collections::HashMap; use std::fs; use std::path::{Path, PathBuf}; @@ -9,19 +10,66 @@ use crate::{Result, SpecialisationName, SystemConfigurationRoot}; /// The V1 bootspec schema version. pub const SCHEMA_VERSION: u64 = 1; -/// User-specified extension data -pub type Extension = HashMap; - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -#[serde(rename_all = "camelCase")] -/// V1 of the bootspec schema. +/// A V1 bootspec generation. +/// +/// This structure represents an entire V1 generation (i.e. it includes the `org.nixos.bootspec.v1` +/// and `org.nixos.specialisation.v1` structures). /// /// ## Warnings /// -/// Do not attempt to deserialize this struct from a bootspec document, as it does not enforce -/// versioning. You want to use the [`crate::generation::Generation`] enum for both -/// serialization and deserialization. +/// If you attempt to deserialize using this struct, you will not get any information about +/// user-provided extensions. For that, you must deserialize with [`crate::BootJson`]. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct GenerationV1 { + #[serde(rename = "org.nixos.bootspec.v1")] + pub bootspec: BootSpecV1, + #[serde(rename = "org.nixos.specialisation.v1", default = "HashMap::new")] + pub specialisations: SpecialisationsV1, +} + +impl GenerationV1 { + /// Synthesize a [`GenerationV1`] struct from the path to a NixOS generation. + /// + /// This is useful when used on generations that do not have a bootspec attached to it. + pub fn synthesize(generation_path: &Path) -> Result { + let bootspec = BootSpecV1::synthesize(generation_path)?; + + let mut specialisations = HashMap::new(); + if let Ok(specialisations_dirs) = fs::read_dir(generation_path.join("specialisation")) { + for specialisation in specialisations_dirs.map(|res| res.map(|e| e.path())) { + let specialisation = specialisation?; + let name = specialisation + .file_name() + .ok_or("Could not get name of specialisation dir")? + .to_str() + .ok_or("Specialisation dir name was invalid UTF8")?; + let toplevel = fs::canonicalize(generation_path.join("specialisation").join(name))?; + + specialisations.insert( + SpecialisationName(name.to_string()), + Self::synthesize(&toplevel)?, + ); + } + } + + Ok(Self { + bootspec, + specialisations, + }) + } +} + +/// A mapping of V1 bootspec specialisations. +/// +/// This structure represents the contents of the `org.nixos.specialisations.v1` key. +pub type SpecialisationsV1 = HashMap; + +/// A V1 bootspec toplevel. +/// +/// This structure represents the contents of the `org.nixos.bootspec.v1` key. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct BootSpecV1 { /// Label for the system closure pub label: String, /// Path to kernel (bzImage) -- $toplevel/kernel @@ -36,44 +84,12 @@ pub struct GenerationV1 { pub initrd_secrets: Option, /// System double, e.g. x86_64-linux, for the system closure pub system: String, - /// Mapping of specialisation names to their boot.json - #[serde(default = "HashMap::new")] - pub specialisation: HashMap, /// config.system.build.toplevel path pub toplevel: SystemConfigurationRoot, - /// User extensions for this specification - #[serde(default = "HashMap::new", skip_serializing_if = "HashMap::is_empty")] - pub extensions: HashMap, } -impl GenerationV1 { - /// Synthesize a [`GenerationV1`] struct from the path to a generation. - /// - /// This is useful when used on generations that do not have a bootspec attached to it. - pub fn synthesize(generation: &Path) -> Result { - let mut toplevelspec = GenerationV1::describe_system(generation)?; - - if let Ok(specialisations) = fs::read_dir(generation.join("specialisation")) { - for spec in specialisations.map(|res| res.map(|e| e.path())) { - let spec = spec?; - let name = spec - .file_name() - .ok_or("Could not get name of specialisation dir")? - .to_str() - .ok_or("Specialisation dir name was invalid UTF8")?; - let toplevel = fs::canonicalize(generation.join("specialisation").join(name))?; - - toplevelspec.specialisation.insert( - SpecialisationName(name.to_string()), - GenerationV1::describe_system(&toplevel)?, - ); - } - } - - Ok(toplevelspec) - } - - fn describe_system(generation: &Path) -> Result { +impl BootSpecV1 { + pub(crate) fn synthesize(generation: &Path) -> Result { let generation = generation .canonicalize() .map_err(|e| format!("Failed to canonicalize generation dir:\n{}", e))?; @@ -123,7 +139,7 @@ impl GenerationV1 { None }; - Ok(GenerationV1 { + Ok(Self { label: format!("NixOS {} (Linux {})", system_version, kernel_version), kernel, kernel_params, @@ -132,18 +148,16 @@ impl GenerationV1 { initrd_secrets, system, toplevel: SystemConfigurationRoot(generation), - specialisation: HashMap::new(), - extensions: HashMap::new(), }) } } #[cfg(test)] mod tests { + use std::fs; use std::path::PathBuf; - use std::{collections::HashMap, fs}; - use super::{GenerationV1, SystemConfigurationRoot}; + use super::{BootSpecV1, SystemConfigurationRoot}; use crate::JSON_FILENAME; use tempfile::TempDir; @@ -240,11 +254,11 @@ mod tests { None, false, ); - let spec = GenerationV1::synthesize(&generation).unwrap(); + let spec = BootSpecV1::synthesize(&generation).unwrap(); assert_eq!( spec, - GenerationV1 { + BootSpecV1 { system, label: "NixOS test-version-1 (Linux 1.1.1-test1)".into(), kernel: generation.join("kernel-modules/bzImage"), @@ -252,9 +266,7 @@ mod tests { init: generation.join("init"), initrd: Some(generation.join("initrd")), initrd_secrets: Some(generation.join("append-initrd-secrets")), - specialisation: HashMap::new(), toplevel: SystemConfigurationRoot(generation), - extensions: HashMap::new() } ); } @@ -283,7 +295,7 @@ mod tests { false, ); - GenerationV1::synthesize(&generation).unwrap(); + BootSpecV1::synthesize(&generation).unwrap(); } #[test] @@ -311,11 +323,11 @@ mod tests { fs::write(generation.join(JSON_FILENAME), "").expect("Failed to write to test generation"); - let spec = GenerationV1::synthesize(&generation).unwrap(); + let spec = BootSpecV1::synthesize(&generation).unwrap(); assert_eq!( spec, - GenerationV1 { + BootSpecV1 { system, label: "NixOS test-version-3 (Linux 1.1.1-test3)".into(), kernel: generation.join("kernel-modules/bzImage"), @@ -323,9 +335,7 @@ mod tests { init: generation.join("init"), initrd: Some(generation.join("initrd")), initrd_secrets: Some(generation.join("append-initrd-secrets")), - specialisation: HashMap::new(), - toplevel: SystemConfigurationRoot(generation), - extensions: HashMap::new() + toplevel: SystemConfigurationRoot(generation) } ); } @@ -357,6 +367,6 @@ mod tests { fs::write(generation.join("bootspec").join(JSON_FILENAME), "") .expect("Failed to write to test generation"); - GenerationV1::synthesize(&generation).unwrap(); + BootSpecV1::synthesize(&generation).unwrap(); } } diff --git a/synthesize/Cargo.toml b/synthesize/Cargo.toml index dc3d1ce..0e2ec60 100644 --- a/synthesize/Cargo.toml +++ b/synthesize/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [dependencies] serde_json = "1.0.91" -tempfile = "3.3.0" +tempfile = "3.5.0" bootspec = { path = "../bootspec" } clap = { version = "4.1.4", features = ["derive"] } diff --git a/synthesize/integration-test-cases/expected-synthesis/15.09-plain.json b/synthesize/integration-test-cases/expected-synthesis/15.09-plain.json index 7e1f1dd..54bd7fa 100644 --- a/synthesize/integration-test-cases/expected-synthesis/15.09-plain.json +++ b/synthesize/integration-test-cases/expected-synthesis/15.09-plain.json @@ -1,5 +1,5 @@ { - "v1": { + "org.nixos.bootspec.v1": { "label": "NixOS 15.09pre-git (Linux 3.18.21)", "kernel": "/nix/store/vvabsbnxmh8nx6pq0bkk6vpsy5cqf9i5-linux-3.18.21/bzImage", "kernelParams": [ @@ -9,7 +9,7 @@ "initrd": "/nix/store/gqdm8dk6my53kvn23r81win9vadjqv80-initrd/initrd", "initrdSecrets": null, "system": "x86_64-linux", - "specialisation": {}, "toplevel": "/nix/store/fl1c8cclzzri16zimdfz8wp31w5yc7dp-nixos-15.09pre-git" - } + }, + "org.nixos.specialisation.v1": {} } \ No newline at end of file diff --git a/synthesize/integration-test-cases/expected-synthesis/16.03-plain.json b/synthesize/integration-test-cases/expected-synthesis/16.03-plain.json index f871f12..3ddde9e 100644 --- a/synthesize/integration-test-cases/expected-synthesis/16.03-plain.json +++ b/synthesize/integration-test-cases/expected-synthesis/16.03-plain.json @@ -1,5 +1,5 @@ { - "v1": { + "org.nixos.bootspec.v1": { "label": "NixOS 16.03pre-git (Linux 4.4.6)", "kernel": "/nix/store/vmsl93kyx72kh03m0h6r2w5ivywbjxm6-linux-4.4.6/bzImage", "kernelParams": [ @@ -9,7 +9,7 @@ "initrd": "/nix/store/q1hg158mvnc9bscc22cv45ys484c4g9x-initrd/initrd", "initrdSecrets": null, "system": "x86_64-linux", - "specialisation": {}, "toplevel": "/nix/store/k0lfhjxd5znyrqkgrdi3hh7wxr885fcj-nixos-system-nixos-16.03pre-git" - } + }, + "org.nixos.specialisation.v1": {} } \ No newline at end of file diff --git a/synthesize/integration-test-cases/expected-synthesis/16.09-plain.json b/synthesize/integration-test-cases/expected-synthesis/16.09-plain.json index c4ac95b..6e38d14 100644 --- a/synthesize/integration-test-cases/expected-synthesis/16.09-plain.json +++ b/synthesize/integration-test-cases/expected-synthesis/16.09-plain.json @@ -1,5 +1,5 @@ { - "v1": { + "org.nixos.bootspec.v1": { "label": "NixOS 16.09pre-git (Linux 4.4.23)", "kernel": "/nix/store/x58d7k8lczvh4qsqaj4jky1hzpc788b4-linux-4.4.23/bzImage", "kernelParams": [ @@ -9,7 +9,7 @@ "initrd": "/nix/store/rv6i771w5z01z1xvylxhymp5pw44wc6j-initrd/initrd", "initrdSecrets": null, "system": "x86_64-linux", - "specialisation": {}, "toplevel": "/nix/store/jfwlp9s434kijn4i53fr5pvrryzspwc4-nixos-system-nixos-16.09pre-git" - } + }, + "org.nixos.specialisation.v1": {} } \ No newline at end of file diff --git a/synthesize/integration-test-cases/expected-synthesis/17.03-plain.json b/synthesize/integration-test-cases/expected-synthesis/17.03-plain.json index 986a50b..9e5b383 100644 --- a/synthesize/integration-test-cases/expected-synthesis/17.03-plain.json +++ b/synthesize/integration-test-cases/expected-synthesis/17.03-plain.json @@ -1,5 +1,5 @@ { - "v1": { + "org.nixos.bootspec.v1": { "label": "NixOS 17.03pre-git (Linux 4.9.18)", "kernel": "/nix/store/syp5ycwxv6yvfv2c9aq3wwqilxpnjvry-linux-4.9.18/bzImage", "kernelParams": [ @@ -9,7 +9,7 @@ "initrd": "/nix/store/spbi6va9dmd41rg15nd9wxjj94097q49-initrd/initrd", "initrdSecrets": null, "system": "x86_64-linux", - "specialisation": {}, "toplevel": "/nix/store/51yf3by1xpzawi30a1rny34gm1047vg8-nixos-system-nixos-17.03pre-git" - } + }, + "org.nixos.specialisation.v1": {} } \ No newline at end of file diff --git a/synthesize/integration-test-cases/expected-synthesis/17.09-plain.json b/synthesize/integration-test-cases/expected-synthesis/17.09-plain.json index 424bfc7..a1dea58 100644 --- a/synthesize/integration-test-cases/expected-synthesis/17.09-plain.json +++ b/synthesize/integration-test-cases/expected-synthesis/17.09-plain.json @@ -1,5 +1,5 @@ { - "v1": { + "org.nixos.bootspec.v1": { "label": "NixOS 17.09pre-git (Linux 4.9.52)", "kernel": "/nix/store/8i1sk0wbwliz0rrpmcq19nm1xlyjn6zg-linux-4.9.52/bzImage", "kernelParams": [ @@ -9,7 +9,7 @@ "initrd": "/nix/store/nnyp0dqb62dicr9wyw2ykcrc0vk7f5mf-initrd/initrd", "initrdSecrets": "/nix/store/bxahnn6p04ydz5a02002pjcmgqfmq509-nixos-system-nixos-17.09pre-git/append-initrd-secrets", "system": "x86_64-linux", - "specialisation": {}, "toplevel": "/nix/store/bxahnn6p04ydz5a02002pjcmgqfmq509-nixos-system-nixos-17.09pre-git" - } + }, + "org.nixos.specialisation.v1": {} } \ No newline at end of file diff --git a/synthesize/integration-test-cases/expected-synthesis/18.03-plain.json b/synthesize/integration-test-cases/expected-synthesis/18.03-plain.json index 24f63f8..f0cdea8 100644 --- a/synthesize/integration-test-cases/expected-synthesis/18.03-plain.json +++ b/synthesize/integration-test-cases/expected-synthesis/18.03-plain.json @@ -1,5 +1,5 @@ { - "v1": { + "org.nixos.bootspec.v1": { "label": "NixOS 18.03pre-git (Linux 4.14.32)", "kernel": "/nix/store/n1fhfw5pyggaybsixvm0haq2h67biah0-linux-4.14.32/bzImage", "kernelParams": [ @@ -9,7 +9,7 @@ "initrd": "/nix/store/gnjk07h7ynhp3f8x145dv224j0wf0s1h-initrd/initrd", "initrdSecrets": "/nix/store/jr5bql6xdfhhv4bmibiz3b74pjp8sdca-nixos-system-nixos-18.03pre-git/append-initrd-secrets", "system": "x86_64-linux", - "specialisation": {}, "toplevel": "/nix/store/jr5bql6xdfhhv4bmibiz3b74pjp8sdca-nixos-system-nixos-18.03pre-git" - } + }, + "org.nixos.specialisation.v1": {} } \ No newline at end of file diff --git a/synthesize/integration-test-cases/expected-synthesis/18.09-plain.json b/synthesize/integration-test-cases/expected-synthesis/18.09-plain.json index cd99ef8..cf87856 100644 --- a/synthesize/integration-test-cases/expected-synthesis/18.09-plain.json +++ b/synthesize/integration-test-cases/expected-synthesis/18.09-plain.json @@ -1,5 +1,5 @@ { - "v1": { + "org.nixos.bootspec.v1": { "label": "NixOS 18.09pre-git (Linux 4.14.74)", "kernel": "/nix/store/s1kjv7xs8gaqw2mfhga0yppyl7k78jnf-linux-4.14.74/bzImage", "kernelParams": [ @@ -9,7 +9,7 @@ "initrd": "/nix/store/2ib32agl00qy7sf7ka5sdbrl6kg4b9gi-initrd/initrd", "initrdSecrets": "/nix/store/b96sr7vmv90wxfjfk2d7icxh7d77a1na-nixos-system-nixos-18.09pre-git/append-initrd-secrets", "system": "x86_64-linux", - "specialisation": {}, "toplevel": "/nix/store/b96sr7vmv90wxfjfk2d7icxh7d77a1na-nixos-system-nixos-18.09pre-git" - } + }, + "org.nixos.specialisation.v1": {} } \ No newline at end of file diff --git a/synthesize/integration-test-cases/expected-synthesis/19.03-plain.json b/synthesize/integration-test-cases/expected-synthesis/19.03-plain.json index 52a38c3..4ef5e9d 100644 --- a/synthesize/integration-test-cases/expected-synthesis/19.03-plain.json +++ b/synthesize/integration-test-cases/expected-synthesis/19.03-plain.json @@ -1,5 +1,5 @@ { - "v1": { + "org.nixos.bootspec.v1": { "label": "NixOS 19.03pre-git (Linux 4.19.34)", "kernel": "/nix/store/3wbab1zxpil3ia7flkmzl8j3qds09dbw-linux-4.19.34/bzImage", "kernelParams": [ @@ -9,7 +9,7 @@ "initrd": "/nix/store/fv9ag95k2ww4w87grwj6hg0b25is5giy-initrd/initrd", "initrdSecrets": "/nix/store/wp2gq8zzcixy2d1dvswhbhdl532jxhsf-nixos-system-nixos-19.03pre-git/append-initrd-secrets", "system": "x86_64-linux", - "specialisation": {}, "toplevel": "/nix/store/wp2gq8zzcixy2d1dvswhbhdl532jxhsf-nixos-system-nixos-19.03pre-git" - } + }, + "org.nixos.specialisation.v1": {} } \ No newline at end of file diff --git a/synthesize/integration-test-cases/expected-synthesis/19.09-plain.json b/synthesize/integration-test-cases/expected-synthesis/19.09-plain.json index 050e20b..446b740 100644 --- a/synthesize/integration-test-cases/expected-synthesis/19.09-plain.json +++ b/synthesize/integration-test-cases/expected-synthesis/19.09-plain.json @@ -1,5 +1,5 @@ { - "v1": { + "org.nixos.bootspec.v1": { "label": "NixOS 19.09pre-git (Linux 4.19.78)", "kernel": "/nix/store/s7zp6i6r73a0sri2fihmpnwbqrpsk8fs-linux-4.19.78/bzImage", "kernelParams": [ @@ -10,7 +10,7 @@ "initrd": "/nix/store/d6xpsfsby2y1d2hvfhdgss45swrazipf-initrd-linux-4.19.78/initrd", "initrdSecrets": "/nix/store/wqr3p7hd4x59g14zx7qkz8sqvgl9ngvl-nixos-system-nixos-19.09pre-git/append-initrd-secrets", "system": "x86_64-linux", - "specialisation": {}, "toplevel": "/nix/store/wqr3p7hd4x59g14zx7qkz8sqvgl9ngvl-nixos-system-nixos-19.09pre-git" - } + }, + "org.nixos.specialisation.v1": {} } \ No newline at end of file diff --git a/synthesize/integration-test-cases/expected-synthesis/20.03-plain.json b/synthesize/integration-test-cases/expected-synthesis/20.03-plain.json index 5551e13..9df7171 100644 --- a/synthesize/integration-test-cases/expected-synthesis/20.03-plain.json +++ b/synthesize/integration-test-cases/expected-synthesis/20.03-plain.json @@ -1,5 +1,5 @@ { - "v1": { + "org.nixos.bootspec.v1": { "label": "NixOS 20.03pre-git (Linux 5.4.33)", "kernel": "/nix/store/li3v6p9mqsspm0zgglzba2szab2zdmiv-linux-5.4.33/bzImage", "kernelParams": [ @@ -10,7 +10,7 @@ "initrd": "/nix/store/1j7s94v0axvgwcv4s0ka56xmgvffdlc0-initrd-linux-5.4.33/initrd", "initrdSecrets": "/nix/store/l651p9fhdwkn7p49vawif8a2b4v1nsfl-nixos-system-nixos-20.03pre-git/append-initrd-secrets", "system": "x86_64-linux", - "specialisation": {}, "toplevel": "/nix/store/l651p9fhdwkn7p49vawif8a2b4v1nsfl-nixos-system-nixos-20.03pre-git" - } + }, + "org.nixos.specialisation.v1": {} } \ No newline at end of file diff --git a/synthesize/integration-test-cases/expected-synthesis/20.09-plain.json b/synthesize/integration-test-cases/expected-synthesis/20.09-plain.json index 0bb9e6a..8a89f8e 100644 --- a/synthesize/integration-test-cases/expected-synthesis/20.09-plain.json +++ b/synthesize/integration-test-cases/expected-synthesis/20.09-plain.json @@ -1,5 +1,5 @@ { - "v1": { + "org.nixos.bootspec.v1": { "label": "NixOS 20.09pre-git (Linux 5.4.72)", "kernel": "/nix/store/ysrwgw1wp9ha0484dh8q1awysn9vfxdy-linux-5.4.72/bzImage", "kernelParams": [ @@ -10,7 +10,7 @@ "initrd": "/nix/store/r7ifs7qvxb5fdz7hhjh5m8a65k34ik25-initrd-linux-5.4.72/initrd", "initrdSecrets": "/nix/store/6621qzx8dlvwgpjjs1sarw9lxv4x38ps-nixos-system-nixos-20.09pre-git/append-initrd-secrets", "system": "x86_64-linux", - "specialisation": {}, "toplevel": "/nix/store/6621qzx8dlvwgpjjs1sarw9lxv4x38ps-nixos-system-nixos-20.09pre-git" - } + }, + "org.nixos.specialisation.v1": {} } \ No newline at end of file diff --git a/synthesize/integration-test-cases/expected-synthesis/21.05-plain.json b/synthesize/integration-test-cases/expected-synthesis/21.05-plain.json index 36c29c5..244a41f 100644 --- a/synthesize/integration-test-cases/expected-synthesis/21.05-plain.json +++ b/synthesize/integration-test-cases/expected-synthesis/21.05-plain.json @@ -1,5 +1,5 @@ { - "v1": { + "org.nixos.bootspec.v1": { "label": "NixOS 21.05pre-git (Linux 5.10.37)", "kernel": "/nix/store/rrmsyrg9ksd9x2cqb01pmbw0yd0anf7v-linux-5.10.37/bzImage", "kernelParams": [ @@ -10,7 +10,7 @@ "initrd": "/nix/store/5ci6pag0hclx1642nm5rs6zjl60drns4-initrd-linux-5.10.37/initrd", "initrdSecrets": "/nix/store/sz7d2wmq5jx4rrdmx2ksb9wmc5raqvwn-nixos-system-nixos-21.05pre-git/append-initrd-secrets", "system": "x86_64-linux", - "specialisation": {}, "toplevel": "/nix/store/sz7d2wmq5jx4rrdmx2ksb9wmc5raqvwn-nixos-system-nixos-21.05pre-git" - } + }, + "org.nixos.specialisation.v1": {} } \ No newline at end of file diff --git a/synthesize/integration-test-cases/expected-synthesis/21.11-plain.json b/synthesize/integration-test-cases/expected-synthesis/21.11-plain.json index 1f39040..e4b96a4 100644 --- a/synthesize/integration-test-cases/expected-synthesis/21.11-plain.json +++ b/synthesize/integration-test-cases/expected-synthesis/21.11-plain.json @@ -1,5 +1,5 @@ { - "v1": { + "org.nixos.bootspec.v1": { "label": "NixOS 21.11pre-git (Linux 5.10.81)", "kernel": "/nix/store/hprwry55jwyd71ng7v7c2rhk3a3z1im8-linux-5.10.81/bzImage", "kernelParams": [ @@ -10,7 +10,7 @@ "initrd": "/nix/store/69bhfdfv77y0vclnlxqrd8pxjzbkz47w-initrd-linux-5.10.81/initrd", "initrdSecrets": "/nix/store/7xvzw9yxw91vklhyzf0isg9256xh1l5l-nixos-system-nixos-21.11pre-git/append-initrd-secrets", "system": "x86_64-linux", - "specialisation": {}, "toplevel": "/nix/store/7xvzw9yxw91vklhyzf0isg9256xh1l5l-nixos-system-nixos-21.11pre-git" - } + }, + "org.nixos.specialisation.v1": {} } \ No newline at end of file diff --git a/synthesize/integration-test-cases/expected-synthesis/21.11-specialisations.json b/synthesize/integration-test-cases/expected-synthesis/21.11-specialisations.json index b2c03c6..27dda0a 100644 --- a/synthesize/integration-test-cases/expected-synthesis/21.11-specialisations.json +++ b/synthesize/integration-test-cases/expected-synthesis/21.11-specialisations.json @@ -1,5 +1,5 @@ { - "v1": { + "org.nixos.bootspec.v1": { "label": "NixOS 21.11pre-git (Linux 5.10.81)", "kernel": "/nix/store/hprwry55jwyd71ng7v7c2rhk3a3z1im8-linux-5.10.81/bzImage", "kernelParams": [ @@ -10,8 +10,11 @@ "initrd": "/nix/store/69bhfdfv77y0vclnlxqrd8pxjzbkz47w-initrd-linux-5.10.81/initrd", "initrdSecrets": "/nix/store/kgkjwhscv52r2y1ha1y19lb9h4j3lfrc-nixos-system-nixos-21.11pre-git/append-initrd-secrets", "system": "x86_64-linux", - "specialisation": { - "example": { + "toplevel": "/nix/store/kgkjwhscv52r2y1ha1y19lb9h4j3lfrc-nixos-system-nixos-21.11pre-git" + }, + "org.nixos.specialisation.v1": { + "example": { + "org.nixos.bootspec.v1": { "label": "NixOS 21.11pre-git (Linux 5.10.81)", "kernel": "/nix/store/hprwry55jwyd71ng7v7c2rhk3a3z1im8-linux-5.10.81/bzImage", "kernelParams": [ @@ -22,10 +25,9 @@ "initrd": "/nix/store/69bhfdfv77y0vclnlxqrd8pxjzbkz47w-initrd-linux-5.10.81/initrd", "initrdSecrets": "/nix/store/3w5kr91xq46638fd310q2sa9mjm6r6hn-nixos-system-nixos-21.11pre-git/append-initrd-secrets", "system": "x86_64-linux", - "specialisation": {}, "toplevel": "/nix/store/3w5kr91xq46638fd310q2sa9mjm6r6hn-nixos-system-nixos-21.11pre-git" - } - }, - "toplevel": "/nix/store/kgkjwhscv52r2y1ha1y19lb9h4j3lfrc-nixos-system-nixos-21.11pre-git" + }, + "org.nixos.specialisation.v1": {} + } } } \ No newline at end of file diff --git a/synthesize/src/main.rs b/synthesize/src/main.rs index 8a76d26..06c6b66 100644 --- a/synthesize/src/main.rs +++ b/synthesize/src/main.rs @@ -2,9 +2,7 @@ use std::fs; use std::io::{self, Write}; use std::path::PathBuf; -use bootspec::generation::Generation; -use bootspec::v1; -use bootspec::Result; +use bootspec::{BootJson, Result}; #[derive(clap::Parser)] struct Cli { @@ -30,21 +28,7 @@ fn cli() -> Result<()> { let out_path = args.out_path; let version = args.version; - let versioned_spec = match version { - v1::SCHEMA_VERSION => { - let spec = v1::GenerationV1::synthesize(&generation_dir).map_err(|e| { - format!( - "Failed to synthesize v{} bootspec for {}:\n{}", - version, - generation_dir.display(), - e - ) - })?; - - Generation::V1(spec) - } - v => return Err(format!("Cannot synthesize for unsupported schema version {}", v).into()), - }; + let versioned_spec = BootJson::synthesize_version(&generation_dir, version)?; let pretty = serde_json::to_string_pretty(&versioned_spec) .map_err(|e| format!("Failed to make pretty JSON from bootspec:\n{}", e))?; diff --git a/validate/Cargo.toml b/validate/Cargo.toml index c277df3..84f3aa8 100644 --- a/validate/Cargo.toml +++ b/validate/Cargo.toml @@ -6,5 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bootspec = { version = "0.1.0", path = "../bootspec" } +bootspec = { path = "../bootspec" } serde_json = "1.0.91" diff --git a/validate/src/main.rs b/validate/src/main.rs index 9f4f4a2..5f3585e 100644 --- a/validate/src/main.rs +++ b/validate/src/main.rs @@ -2,8 +2,7 @@ use std::fs; use std::io::{self, Write}; use std::path::PathBuf; -use bootspec::generation::Generation; -use bootspec::Result; +use bootspec::{BootJson, Result}; fn main() -> Result<()> { if let Err(e) = self::cli() { @@ -20,16 +19,19 @@ fn cli() -> Result<()> { let contents = fs::read_to_string(&bootspec_path)?; - match serde_json::from_str::(&contents) { - Ok(generation) => writeln!( - io::stdout(), - "Bootspec document at '{}' IS a valid v{} document.", - bootspec_path.display(), - generation.version() - )?, + match serde_json::from_str::(&contents) { + Ok(boot_json) => { + let generation = boot_json.generation; + writeln!( + io::stdout(), + "Bootspec document at '{}' DOES CONTAIN a valid v{} document.", + bootspec_path.display(), + generation.version() + )?; + } Err(err) => { return Err(format!( - "Bootspec document at '{}' IS NOT a valid document:\n{}", + "Bootspec document at '{}' DOES NOT CONTAIN a valid document:\n{}", bootspec_path.display(), err )