From 5bcfc1795728cd566f0855015b4b841b023294b6 Mon Sep 17 00:00:00 2001
From: Jeff Dickey <216188+jdx@users.noreply.github.com>
Date: Sat, 13 Jan 2024 13:38:49 -0600
Subject: [PATCH] wip
---
.idea/usage.iml | 2 +
Cargo.lock | 333 +++++++++++++++----------------
Cargo.toml | 1 +
cli/Cargo.toml | 5 +-
cli/src/cli/generate/markdown.rs | 148 ++++++++------
cli/src/cli/generate/mod.rs | 6 +-
examples/MISE_README.md | 189 ++++++++++++------
src/context.rs | 11 +
src/lib.rs | 11 +-
src/parse/spec.rs | 38 ++--
10 files changed, 436 insertions(+), 308 deletions(-)
create mode 100644 src/context.rs
diff --git a/.idea/usage.iml b/.idea/usage.iml
index 798678f..ebd7cd5 100644
--- a/.idea/usage.iml
+++ b/.idea/usage.iml
@@ -6,9 +6,11 @@
+
+
diff --git a/Cargo.lock b/Cargo.lock
index 84a2450..05411c8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -28,9 +28,9 @@ dependencies = [
[[package]]
name = "anstream"
-version = "0.6.5"
+version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6"
+checksum = "4cd2405b3ac1faab2990b74d728624cd9fd115651fcecc7c2d8daf01376275ba"
dependencies = [
"anstyle",
"anstyle-parse",
@@ -61,7 +61,7 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
dependencies = [
- "windows-sys 0.52.0",
+ "windows-sys",
]
[[package]]
@@ -71,7 +71,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
dependencies = [
"anstyle",
- "windows-sys 0.52.0",
+ "windows-sys",
]
[[package]]
@@ -98,6 +98,12 @@ dependencies = [
"backtrace",
]
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
[[package]]
name = "bitflags"
version = "2.4.1"
@@ -121,9 +127,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
-version = "4.4.11"
+version = "4.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2"
+checksum = "58e54881c004cec7895b0068a0a954cd5d62da01aef83fa35b1e594497bf5445"
dependencies = [
"clap_builder",
"clap_derive",
@@ -131,9 +137,9 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.4.11"
+version = "4.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb"
+checksum = "59cb82d7f531603d2fd1f507441cdd35184fa81beff7bd489570de7f773460bb"
dependencies = [
"anstream",
"anstyle",
@@ -150,7 +156,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.48",
]
[[package]]
@@ -167,16 +173,33 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "console"
-version = "0.15.7"
+version = "0.15.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8"
+checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
- "windows-sys 0.45.0",
+ "windows-sys",
]
+[[package]]
+name = "contracts"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1d1429e3bd78171c65aa010eabcdf8f863ba3254728dbfb0ad4b1545beac15c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "diff"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
+
[[package]]
name = "either"
version = "1.9.0"
@@ -226,7 +249,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
dependencies = [
"libc",
- "windows-sys 0.52.0",
+ "windows-sys",
]
[[package]]
@@ -249,6 +272,12 @@ dependencies = [
"libc",
]
+[[package]]
+name = "fastrand"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
+
[[package]]
name = "gimli"
version = "0.28.1"
@@ -304,13 +333,13 @@ dependencies = [
[[package]]
name = "is-terminal"
-version = "0.4.9"
+version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
+checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455"
dependencies = [
"hermit-abi",
"rustix",
- "windows-sys 0.48.0",
+ "windows-sys",
]
[[package]]
@@ -347,9 +376,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
-version = "0.2.151"
+version = "0.2.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
+checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7"
[[package]]
name = "linked-hash-map"
@@ -371,9 +400,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "memchr"
-version = "2.6.4"
+version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
+checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]]
name = "miette"
@@ -404,7 +433,7 @@ checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.48",
]
[[package]]
@@ -434,9 +463,9 @@ dependencies = [
[[package]]
name = "object"
-version = "0.32.1"
+version = "0.32.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
+checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
dependencies = [
"memchr",
]
@@ -453,6 +482,16 @@ version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
+[[package]]
+name = "pretty_assertions"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66"
+dependencies = [
+ "diff",
+ "yansi",
+]
+
[[package]]
name = "proc-macro2"
version = "1.0.76"
@@ -471,6 +510,15 @@ dependencies = [
"proc-macro2",
]
+[[package]]
+name = "redox_syscall"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
+dependencies = [
+ "bitflags 1.3.2",
+]
+
[[package]]
name = "regex"
version = "1.10.2"
@@ -508,17 +556,23 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustix"
-version = "0.38.28"
+version = "0.38.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
+checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca"
dependencies = [
- "bitflags",
+ "bitflags 2.4.1",
"errno 0.3.8",
"libc",
"linux-raw-sys",
- "windows-sys 0.52.0",
+ "windows-sys",
]
+[[package]]
+name = "rustversion"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
+
[[package]]
name = "shell-escape"
version = "0.1.5"
@@ -527,9 +581,9 @@ checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f"
[[package]]
name = "similar"
-version = "2.3.0"
+version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2aeaf503862c419d66959f5d7ca015337d864e9c49485d771b732e2a20453597"
+checksum = "32fea41aca09ee824cc9724996433064c89f7777e60762749a4170a14abbfa21"
[[package]]
name = "smawk"
@@ -543,6 +597,28 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+[[package]]
+name = "strum"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125"
+dependencies = [
+ "strum_macros",
+]
+
+[[package]]
+name = "strum_macros"
+version = "0.25.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "rustversion",
+ "syn 2.0.48",
+]
+
[[package]]
name = "supports-color"
version = "2.1.0"
@@ -571,6 +647,17 @@ dependencies = [
"is-terminal",
]
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
[[package]]
name = "syn"
version = "2.0.48"
@@ -582,11 +669,24 @@ dependencies = [
"unicode-ident",
]
+[[package]]
+name = "tempfile"
+version = "3.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "redox_syscall",
+ "rustix",
+ "windows-sys",
+]
+
[[package]]
name = "termcolor"
-version = "1.4.0"
+version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449"
+checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
dependencies = [
"winapi-util",
]
@@ -629,7 +729,7 @@ checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.48",
]
[[package]]
@@ -655,6 +755,7 @@ name = "usage-cli"
version = "0.1.0"
dependencies = [
"clap",
+ "contracts",
"env_logger",
"exec",
"itertools",
@@ -663,8 +764,10 @@ dependencies = [
"miette",
"once_cell",
"regex",
+ "strum",
"thiserror",
"usage-lib",
+ "xx",
]
[[package]]
@@ -681,6 +784,7 @@ dependencies = [
"once_cell",
"shell-escape",
"thiserror",
+ "xx",
]
[[package]]
@@ -720,61 +824,13 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-[[package]]
-name = "windows-sys"
-version = "0.45.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
-dependencies = [
- "windows-targets 0.42.2",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
-dependencies = [
- "windows-targets 0.48.5",
-]
-
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
- "windows-targets 0.52.0",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-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 = "windows-targets"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
-dependencies = [
- "windows_aarch64_gnullvm 0.48.5",
- "windows_aarch64_msvc 0.48.5",
- "windows_i686_gnu 0.48.5",
- "windows_i686_msvc 0.48.5",
- "windows_x86_64_gnu 0.48.5",
- "windows_x86_64_gnullvm 0.48.5",
- "windows_x86_64_msvc 0.48.5",
+ "windows-targets",
]
[[package]]
@@ -783,141 +839,68 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
dependencies = [
- "windows_aarch64_gnullvm 0.52.0",
- "windows_aarch64_msvc 0.52.0",
- "windows_i686_gnu 0.52.0",
- "windows_i686_msvc 0.52.0",
- "windows_x86_64_gnu 0.52.0",
- "windows_x86_64_gnullvm 0.52.0",
- "windows_x86_64_msvc 0.52.0",
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
]
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
-
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
-
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
-[[package]]
-name = "windows_i686_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
-
[[package]]
name = "windows_i686_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
-[[package]]
-name = "windows_i686_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
-
[[package]]
name = "windows_i686_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
-
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
-[[package]]
-name = "windows_x86_64_gnullvm"
-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.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
-
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
-
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
+[[package]]
+name = "xx"
+version = "0.2.0"
+dependencies = [
+ "miette",
+ "once_cell",
+ "pretty_assertions",
+ "tempfile",
+ "thiserror",
+]
+
[[package]]
name = "yaml-rust"
version = "0.4.5"
@@ -926,3 +909,9 @@ checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
+
+[[package]]
+name = "yansi"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
diff --git a/Cargo.toml b/Cargo.toml
index 2591bf9..a56c710 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -26,6 +26,7 @@ shell-escape = "0.1"
log = "0.4"
itertools = "0.12.0"
once_cell = "1.19.0"
+xx = {path= "./xx"}
[features]
default = ["clap"]
diff --git a/cli/Cargo.toml b/cli/Cargo.toml
index bcc3cc6..a04df38 100644
--- a/cli/Cargo.toml
+++ b/cli/Cargo.toml
@@ -15,6 +15,7 @@ path = "src/lib.rs"
[dependencies]
clap = { version = "4", features = ["derive", "string"] }
+contracts = "0.6.3"
env_logger = "0.10"
exec = "0.3.1"
itertools = "0.12.0"
@@ -23,5 +24,7 @@ log = "0.4"
miette = { version = "5", features = ["fancy"] }
once_cell = "1"
regex = "1"
+strum = { version = "0.25.0", features = ["derive"] }
+thiserror = "1"
usage-lib = { path = "..", features=["clap"] }
-thiserror = "1.0.56"
+xx = {path= "../xx"}
diff --git a/cli/src/cli/generate/markdown.rs b/cli/src/cli/generate/markdown.rs
index 96e0863..492c043 100644
--- a/cli/src/cli/generate/markdown.rs
+++ b/cli/src/cli/generate/markdown.rs
@@ -1,17 +1,20 @@
+use std::fs;
use std::fs::File;
use std::io::Write;
use std::iter::once;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::sync::Mutex;
-use std::{env, fs};
use clap::Args;
+use contracts::requires;
use kdl::{KdlDocument, KdlNode};
-use miette::{IntoDiagnostic, Result, SourceSpan};
+use miette::{IntoDiagnostic, SourceSpan};
+use strum::EnumIs;
use thiserror::Error;
use usage::{SchemaCmd, Spec};
+use xx::{context, file};
#[derive(Args)]
#[clap(visible_alias = "md")]
@@ -45,29 +48,27 @@ impl Markdown {
Ok(())
}
- fn inject_file(&self, inject: &Path) -> Result<()> {
- let raw = fs::read_to_string(inject).into_diagnostic()?;
- println!("{}", raw);
- let root = inject.parent().unwrap().to_path_buf();
- let cwd = env::current_dir().into_diagnostic()?;
- env::set_current_dir(&root).into_diagnostic()?;
+ fn inject_file(&self, inject: &Path) -> miette::Result<()> {
+ let raw = file::read_to_string(inject).into_diagnostic()?;
+ context::set_load_root(inject.parent().unwrap().to_path_buf());
let out = raw
.lines()
.map(|line| line.parse())
- .collect::>>()?
+ .collect::>>()?
.into_iter()
- .try_fold(UsageMdContext::new(root), |ctx, d| d.run(ctx))?
+ .try_fold(UsageMdContext::new(), |ctx, d| d.run(ctx))?
.out
.lock()
.unwrap()
- .join("\n");
- env::set_current_dir(cwd).into_diagnostic()?;
- println!("{}", out);
+ .join("\n")
+ + "\n";
+ print!("{}", out);
fs::write(inject, out).into_diagnostic()?;
Ok(())
}
- fn _print(&self, spec: &Spec, dir: &Path, cmds: &[&SchemaCmd]) -> Result<()> {
+ //noinspection RsFormatMacroWithoutFormatArguments
+ fn _print(&self, spec: &Spec, dir: &Path, cmds: &[&SchemaCmd]) -> miette::Result<()> {
let cmd = cmds.last().unwrap();
let mut out = vec![];
let cmd_path = cmds
@@ -148,8 +149,10 @@ impl Markdown {
}
}
+#[derive(Debug, EnumIs)]
enum UsageMdDirective {
Load { file: PathBuf },
+ Title,
UsageOverview,
GlobalArgs,
GlobalFlags,
@@ -160,16 +163,14 @@ enum UsageMdDirective {
}
struct UsageMdContext {
- _root: PathBuf,
plain: bool,
spec: Option,
out: Mutex>,
}
impl UsageMdContext {
- fn new(_root: PathBuf) -> Self {
+ fn new() -> Self {
Self {
- _root,
plain: true,
spec: None,
out: Mutex::new(vec![]),
@@ -182,27 +183,33 @@ impl UsageMdContext {
}
impl UsageMdDirective {
+ //noinspection RsFormatMacroWithoutFormatArguments
+ #[requires(self.requires_spec() -> ctx.spec.is_some())]
+ #[requires(self.is_load() -> ctx.spec.is_none())]
fn run(&self, mut ctx: UsageMdContext) -> miette::Result {
match self {
UsageMdDirective::Load { file } => {
- // let file = match file.is_relative() {
- // true => ctx.root.join(file),
- // false => file.clone(),
- // };
- ctx.spec = Some(fs::read_to_string(file).into_diagnostic()?.parse()?);
+ let file = context::prepend_load_root(file);
+ ctx.spec = Some(fs::read_to_string(&file).into_diagnostic()?.parse()?);
ctx.push(format!("", file.display()));
}
+ UsageMdDirective::Title => {
+ ensure!(ctx.spec.is_some(), "spec must be loaded before title");
+ ctx.plain = false;
+ let spec = ctx.spec.as_ref().unwrap();
+ ctx.push(format!(""));
+ ctx.push(format!("# {name}", name = spec.name));
+ ctx.push(format!(""));
+ }
UsageMdDirective::UsageOverview => {
ctx.plain = false;
let spec = ctx.spec.as_ref().unwrap();
ctx.push("".to_string());
- ctx.push(format!("# {name}", name = spec.name));
- ctx.push("## Usage".to_string());
ctx.push("```".to_string());
ctx.push(format!("{bin} [flags] [args]", bin = spec.bin));
ctx.push("```".to_string());
- ctx.push("\n".to_string());
+ ctx.push("".to_string());
}
UsageMdDirective::GlobalArgs => {
ctx.plain = false;
@@ -211,7 +218,6 @@ impl UsageMdDirective {
ctx.push("".to_string());
let args = spec.cmd.args.iter().filter(|a| !a.hide).collect::>();
if !args.is_empty() {
- ctx.push(format!("## Args"));
for arg in args {
let name = &arg.usage();
if let Some(about) = &arg.long_help {
@@ -224,7 +230,7 @@ impl UsageMdDirective {
}
}
}
- ctx.push(format!("\n"));
+ ctx.push(format!(""));
}
UsageMdDirective::GlobalFlags => {
ctx.plain = false;
@@ -238,7 +244,6 @@ impl UsageMdDirective {
.filter(|f| !f.hide)
.collect::>();
if !flags.is_empty() {
- ctx.push(format!("## Flags"));
for flag in flags {
let name = flag.usage();
if let Some(about) = &flag.long_help {
@@ -251,47 +256,21 @@ impl UsageMdDirective {
}
}
}
- ctx.push(format!("\n"));
+ ctx.push(format!(""));
}
UsageMdDirective::CommandIndex => {
ctx.plain = false;
let spec = ctx.spec.as_ref().unwrap();
ctx.push(format!(""));
-
- let subcommands = spec
- .cmd
- .subcommands
- .values()
- .filter(|c| !c.hide)
- .collect::>();
- if !subcommands.is_empty() {
- ctx.push(format!("## Commands"));
- for cmd in subcommands {
- let name = cmd.name.as_str();
- if let Some(about) = &cmd.help {
- ctx.push(format!(
- "- [`{name}`](./{name}): {about}",
- name = name,
- about = about
- ));
- } else {
- ctx.push(format!("- [`{name}`](./{name})", name = name));
- }
- }
- }
-
- ctx.push(format!("\n"));
+ print_commands_index(&ctx, &[&spec.cmd])?;
+ ctx.push(format!(""));
}
UsageMdDirective::Commands => {
ctx.plain = false;
let spec = ctx.spec.as_ref().unwrap();
ctx.push(format!(""));
- ctx.push(format!("# {name}", name = spec.name));
- ctx.push(format!("## Usage"));
- ctx.push(format!("```"));
- ctx.push(format!("{bin} [flags] [args]", bin = spec.bin));
- ctx.push(format!("```"));
- ctx.push(format!("\n"));
+ print_commands(&ctx, &[&spec.cmd])?;
+ ctx.push(format!(""));
}
UsageMdDirective::EndToken => {
ctx.plain = true;
@@ -304,6 +283,56 @@ impl UsageMdDirective {
};
Ok(ctx)
}
+
+ fn requires_spec(&self) -> bool {
+ !matches!(
+ self,
+ UsageMdDirective::Load { .. } | UsageMdDirective::Plain(_)
+ )
+ }
+}
+
+fn print_commands_index(ctx: &UsageMdContext, cmds: &[&SchemaCmd]) -> miette::Result<()> {
+ let subcommands = cmds[cmds.len() - 1]
+ .subcommands
+ .values()
+ .filter(|c| !c.hide)
+ .collect::>();
+ for cmd in subcommands {
+ let cmds = cmds.iter().cloned().chain(once(cmd)).collect::>();
+ let full_name = cmds
+ .iter()
+ .skip(1)
+ .map(|c| c.name.as_str())
+ .collect::>()
+ .join(" ");
+ let slug = full_name.replace(" ", "-");
+ ctx.push(format!("- [`{full_name}`](#{slug})",));
+ print_commands_index(ctx, &cmds)?;
+ }
+
+ Ok(())
+}
+
+fn print_commands(ctx: &UsageMdContext, cmds: &[&SchemaCmd]) -> miette::Result<()> {
+ let subcommands = cmds[cmds.len() - 1]
+ .subcommands
+ .values()
+ .filter(|c| !c.hide)
+ .collect::>();
+ for cmd in subcommands {
+ let cmds = cmds.iter().cloned().chain(once(cmd)).collect::>();
+ let full_name = cmds
+ .iter()
+ .skip(1)
+ .map(|c| c.name.as_str())
+ .collect::>()
+ .join(" ");
+ ctx.push(format!("### `{full_name}`"));
+ print_commands(ctx, &cmds)?;
+ }
+
+ Ok(())
}
#[derive(Error, Diagnostic, Debug)]
@@ -348,6 +377,7 @@ impl FromStr for UsageMdDirective {
"load" => UsageMdDirective::Load {
file: PathBuf::from(get_string(node, "file")?),
},
+ "title" => UsageMdDirective::Title,
"usage_overview" => UsageMdDirective::UsageOverview,
"global_args" => UsageMdDirective::GlobalArgs,
"global_flags" => UsageMdDirective::GlobalFlags,
diff --git a/cli/src/cli/generate/mod.rs b/cli/src/cli/generate/mod.rs
index 69d1bc8..c7fd452 100644
--- a/cli/src/cli/generate/mod.rs
+++ b/cli/src/cli/generate/mod.rs
@@ -1,7 +1,5 @@
use std::path::PathBuf;
-use miette::IntoDiagnostic;
-
use usage::Spec;
mod completion;
@@ -31,9 +29,9 @@ impl Generate {
pub fn file_or_spec(file: &Option, spec: &Option) -> miette::Result {
if let Some(file) = file {
- let (spec, _) = Spec::parse_file(file).into_diagnostic()?;
+ let (spec, _) = Spec::parse_file(file)?;
Ok(spec)
} else {
- spec.as_ref().unwrap().parse().into_diagnostic()
+ spec.as_ref().unwrap().parse()
}
}
diff --git a/examples/MISE_README.md b/examples/MISE_README.md
index 398cd81..1a40531 100644
--- a/examples/MISE_README.md
+++ b/examples/MISE_README.md
@@ -1,74 +1,151 @@
-# mise-en-place
-
-
+
+
# mise
+
## Usage
+
```
[flags] [args]
```
-
-
+## Global Args
-
+## Global Flags
-## Flags
- `-C,--cd `: Change directory before running command
- `-q,--quiet`: Suppress non-error messages
- `-v,--verbose`: Show extra output (use -vv for even more)
- `-y,--yes`: Answer yes to all confirmation prompts
-
+## Commands Index
-## Commands
-- [`activate`](./activate)
-- [`alias`](./alias)
-- [`bin-paths`](./bin-paths)
-- [`cache`](./cache)
-- [`completion`](./completion)
-- [`config`](./config)
-- [`current`](./current)
-- [`deactivate`](./deactivate)
-- [`direnv`](./direnv)
-- [`doctor`](./doctor)
-- [`env`](./env)
-- [`exec`](./exec)
-- [`implode`](./implode)
-- [`install`](./install)
-- [`latest`](./latest)
-- [`link`](./link)
-- [`ls`](./ls)
-- [`ls-remote`](./ls-remote)
-- [`outdated`](./outdated)
-- [`plugins`](./plugins)
-- [`prune`](./prune)
-- [`reshim`](./reshim)
-- [`run`](./run)
-- [`self-update`](./self-update)
-- [`set`](./set)
-- [`settings`](./settings)
-- [`shell`](./shell)
-- [`sync`](./sync)
-- [`task`](./task)
-- [`trust`](./trust)
-- [`uninstall`](./uninstall)
-- [`unset`](./unset)
-- [`upgrade`](./upgrade)
-- [`usage`](./usage)
-- [`use`](./use)
-- [`version`](./version)
-- [`watch`](./watch)
-- [`where`](./where)
-- [`which`](./which)
-
+- [`activate`](#activate)
+- [`alias`](#alias)
+- [`alias get`](#alias-get)
+- [`alias ls`](#alias-ls)
+- [`alias set`](#alias-set)
+- [`alias unset`](#alias-unset)
+- [`bin-paths`](#bin-paths)
+- [`cache`](#cache)
+- [`cache clear`](#cache-clear)
+- [`completion`](#completion)
+- [`config`](#config)
+- [`config ls`](#config-ls)
+- [`config generate`](#config-generate)
+- [`current`](#current)
+- [`deactivate`](#deactivate)
+- [`direnv`](#direnv)
+- [`direnv activate`](#direnv-activate)
+- [`doctor`](#doctor)
+- [`env`](#env)
+- [`exec`](#exec)
+- [`implode`](#implode)
+- [`install`](#install)
+- [`latest`](#latest)
+- [`link`](#link)
+- [`ls`](#ls)
+- [`ls-remote`](#ls-remote)
+- [`outdated`](#outdated)
+- [`plugins`](#plugins)
+- [`plugins install`](#plugins-install)
+- [`plugins link`](#plugins-link)
+- [`plugins ls`](#plugins-ls)
+- [`plugins ls-remote`](#plugins-ls-remote)
+- [`plugins uninstall`](#plugins-uninstall)
+- [`plugins update`](#plugins-update)
+- [`prune`](#prune)
+- [`reshim`](#reshim)
+- [`run`](#run)
+- [`self-update`](#self-update)
+- [`set`](#set)
+- [`settings`](#settings)
+- [`settings get`](#settings-get)
+- [`settings ls`](#settings-ls)
+- [`settings set`](#settings-set)
+- [`settings unset`](#settings-unset)
+- [`shell`](#shell)
+- [`sync`](#sync)
+- [`sync node`](#sync-node)
+- [`sync python`](#sync-python)
+- [`task`](#task)
+- [`task edit`](#task-edit)
+- [`task ls`](#task-ls)
+- [`task run`](#task-run)
+- [`trust`](#trust)
+- [`uninstall`](#uninstall)
+- [`unset`](#unset)
+- [`upgrade`](#upgrade)
+- [`usage`](#usage)
+- [`use`](#use)
+- [`version`](#version)
+- [`watch`](#watch)
+- [`where`](#where)
+- [`which`](#which)
+## Commands
-# mise
-## Usage
-```
- [flags] [args]
-```
-
-
\ No newline at end of file
+### `activate`
+### `alias`
+### `alias get`
+### `alias ls`
+### `alias set`
+### `alias unset`
+### `bin-paths`
+### `cache`
+### `cache clear`
+### `completion`
+### `config`
+### `config ls`
+### `config generate`
+### `current`
+### `deactivate`
+### `direnv`
+### `direnv activate`
+### `doctor`
+### `env`
+### `exec`
+### `implode`
+### `install`
+### `latest`
+### `link`
+### `ls`
+### `ls-remote`
+### `outdated`
+### `plugins`
+### `plugins install`
+### `plugins link`
+### `plugins ls`
+### `plugins ls-remote`
+### `plugins uninstall`
+### `plugins update`
+### `prune`
+### `reshim`
+### `run`
+### `self-update`
+### `set`
+### `settings`
+### `settings get`
+### `settings ls`
+### `settings set`
+### `settings unset`
+### `shell`
+### `sync`
+### `sync node`
+### `sync python`
+### `task`
+### `task edit`
+### `task ls`
+### `task run`
+### `trust`
+### `uninstall`
+### `unset`
+### `upgrade`
+### `usage`
+### `use`
+### `version`
+### `watch`
+### `where`
+### `which`
+
diff --git a/src/context.rs b/src/context.rs
new file mode 100644
index 0000000..ed5c4ff
--- /dev/null
+++ b/src/context.rs
@@ -0,0 +1,11 @@
+use std::path::PathBuf;
+use std::sync::Mutex;
+
+static LOAD_ROOT: Mutex