From 161847bf1bc6b53b799cfc9c12b0d80a4b8d2e21 Mon Sep 17 00:00:00 2001 From: Simon Lecoq <22963968+lowlighter@users.noreply.github.com> Date: Wed, 1 Nov 2023 21:50:55 -0400 Subject: [PATCH] feat(make): initial commit --- .gitignore | 5 + README.md | 103 ++++++++ demo.jsonc | 57 +++++ demo.png | Bin 0 -> 17001 bytes deno.jsonc | 53 +++++ deno.lock | 206 ++++++++++++++++ mod.ts | 445 +++++++++++++++++++++++++++++++++++ mod_bench.ts | 3 + mod_test.ts | 46 ++++ tests/.deno.lock | 4 + tests/.imports.json | 1 + tests/deno_cache.jsonc | 10 + tests/deno_check.jsonc | 18 ++ tests/deno_common.jsonc | 63 +++++ tests/deno_coverage.jsonc | 28 +++ tests/deno_doc.jsonc | 19 ++ tests/deno_fmt.jsonc | 26 ++ tests/deno_info.jsonc | 34 +++ tests/deno_lint.jsonc | 66 ++++++ tests/deno_make.jsonc | 25 ++ tests/deno_make_empty.jsonc | 5 + tests/deno_make_error.jsonc | 8 + tests/deno_permissions.jsonc | 108 +++++++++ tests/deno_run.jsonc | 63 +++++ tests/deno_test.jsonc | 87 +++++++ tests/deno_types.jsonc | 10 + tests/deno_vendor.jsonc | 47 ++++ tests/mod.ts | 1 + tests/mod_test.ts | 1 + 29 files changed, 1542 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 demo.jsonc create mode 100644 demo.png create mode 100644 deno.jsonc create mode 100644 deno.lock create mode 100644 mod.ts create mode 100644 mod_bench.ts create mode 100644 mod_test.ts create mode 100644 tests/.deno.lock create mode 100644 tests/.imports.json create mode 100644 tests/deno_cache.jsonc create mode 100644 tests/deno_check.jsonc create mode 100644 tests/deno_common.jsonc create mode 100644 tests/deno_coverage.jsonc create mode 100644 tests/deno_doc.jsonc create mode 100644 tests/deno_fmt.jsonc create mode 100644 tests/deno_info.jsonc create mode 100644 tests/deno_lint.jsonc create mode 100644 tests/deno_make.jsonc create mode 100644 tests/deno_make_empty.jsonc create mode 100644 tests/deno_make_error.jsonc create mode 100644 tests/deno_permissions.jsonc create mode 100644 tests/deno_run.jsonc create mode 100644 tests/deno_test.jsonc create mode 100644 tests/deno_types.jsonc create mode 100644 tests/deno_vendor.jsonc create mode 100644 tests/mod.ts create mode 100644 tests/mod_test.ts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..49f5818 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.coverage +.deno-make.json +tests/.coverage +tests/.coverage.report +tests/.junit.xml diff --git a/README.md b/README.md new file mode 100644 index 0000000..d95df18 --- /dev/null +++ b/README.md @@ -0,0 +1,103 @@ +# 🍳🦕 deno make + +_deno make_ integrates seemlessly within your `deno.jsonc` configuration file to provide an extended set of features to +the [deno](https://deno.land) task runner. + +You can assign default permissions and flags to deno subcommands, environment variables, assign descriptions and more. + +## 💭 Why ? + +While the default [deno task runner](https://docs.deno.com/runtime/manual/tools/task_runner) is great, it is not always +suitable for long scripts as it's not possible to split them into multiple lines, and passing flags to deno subcommands +is often tedious. + +_deno make_ solves these issues by computing dynamically deno commands flags before calling the default deno task +runner, in addition to providing a few extra features. + +## 📚 Usage + +### 1. Register _deno make_ in `deno.jsonc` + +```jsonc +// deno.jsonc +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno https://deno.land/x/make/mod.ts $0" + } +} +``` + +### 2. Configure `"deno-make"` tasks in `deno.jsonc` + +```jsonc +// deno.jsonc +{ + "+tasks": { + "start": { + "description": "🍱 Start application", + "task": "deno run mod.ts", + "deno": { + "run": { // For "deno run" subcommand + "unstable": true, // ➡️ --unstable + "permissions": { + "prompt": false, // ➡️ --no-prompt + "read": true, // ➡️ --allow-read + "run": false, // ➡️ --deny-run + "net": [ // ➡️ --allow-net=https://deno.land,https://example.com + "https://deno.land", + "https://example.com" + ], + "write": { // ➡️ --allow-write=/tmp --deny-write=/root + "allow": [ + "/tmp" + ], + "deny": [ + "/root" + ] + } + } + } + }, + // Configure environment variables + "env": { + "FOO": true, // ➡️ Inherit FOO environment variable + "BAR": "bar" // ➡️ Set BAR environment variable to "bar" + } + }, + // Write "multi-line" tasks using arrays (they will be joined with "\n") + "test": { + "description": "🧪 Run tests and print collected coverage", + "task": [ + "rm -rf .coverage &&", + "deno test &&", + "deno coverage .coverage" + ], + "deno": { + "test": { // For "deno test" subcommand + "unstable": true, // ➡️ --unstable + "permissions": { // ➡️ --allow-all + "all": true + }, + "coverage": ".coverage", // ➡️ --coverage=.coverage + "parallel": true // ➡️ --parallel + }, + "coverage": { // For "deno coverage" subcommand + "quiet": true // ➡️ --quiet + } + } + } + } +} +``` + +### 3. Run tasks with `deno task make` instead + +```bash +deno task make run +``` + +#### Print all available _deno make_ tasks + +```bash +deno task make +``` diff --git a/demo.jsonc b/demo.jsonc new file mode 100644 index 0000000..84b1138 --- /dev/null +++ b/demo.jsonc @@ -0,0 +1,57 @@ +{ + "+tasks": { + "start": { + "description": "🍱 Start application", + "task": "deno run mod.ts", + "deno": { + "run": { // For "deno run" subcommand + "unstable": true, // ➡️ --unstable + "permissions": { + "prompt": false, // ➡️ --no-prompt + "read": true, // ➡️ --allow-read + "run": false, // ➡️ --deny-run + "net": [ // ➡️ --allow-net=https://deno.land,https://example.com + "https://deno.land", + "https://example.com" + ], + "write": { // ➡️ --allow-write=/tmp --deny-write=/root + "allow": [ + "/tmp" + ], + "deny": [ + "/root" + ] + } + } + } + }, + // Configure environment variables + "env": { + "FOO": true, // ➡️ Inherit FOO environment variable + "BAR": "bar" // ➡️ Set BAR environment variable to "bar" + } + }, + // Write "multi-line" tasks using arrays (they will be joined with "\n") + "test": { + "description": "🧪 Run tests and print collected coverage", + "task": [ + "rm -rf .coverage &&", + "deno test &&", + "deno coverage .coverage" + ], + "deno": { + "test": { // For "deno test" subcommand + "unstable": true, // ➡️ --unstable + "permissions": { // ➡️ --allow-all + "all": true + }, + "coverage": ".coverage", // ➡️ --coverage=.coverage + "parallel": true // ➡️ --parallel + }, + "coverage": { // For "deno coverage" subcommand + "quiet": true // ➡️ --quiet + } + } + } + } +} diff --git a/demo.png b/demo.png new file mode 100644 index 0000000000000000000000000000000000000000..8d3bac40654f2e6af61f86816d7c5f892943c4d0 GIT binary patch literal 17001 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 U`()Dh;^HLpQvOB$GkyR60}QHJKL7v# literal 0 HcmV?d00001 diff --git a/deno.jsonc b/deno.jsonc new file mode 100644 index 0000000..7fa1b8c --- /dev/null +++ b/deno.jsonc @@ -0,0 +1,53 @@ +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno ./mod.ts $0" + }, + "+tasks": { + "test": { + "description": "🧪 Run tests and benchmarks. Print collected coverage", + "task": [ + "rm -rf .coverage &&", + "deno test &&", + "deno coverage .coverage" + ], + "deno": { + "test": { + "coverage": ".coverage", + "doc": true, + "traceOps": true, + "permissions": { + "read": true, + "write": [".deno-make.json"], + "run": ["deno"] + } + } + }, + "env": { + "DINOSAUR": "🦕" + } + }, + "code": { + "description": "🧼 Lint and format code", + "task": "deno lint && deno fmt" + }, + "code:check": { + "description": "🤖 Lint and check code fomatting", + "task": "deno lint && deno fmt --check" + } + }, + "fmt": { + "lineWidth": 120, + "semiColons": false, + "exclude": [".coverage", ".deno-make.json"] + } +} +/* +bench +bundle +compile +_eval +fmt +install +uninstall +repl +*/ diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..b113fbe --- /dev/null +++ b/deno.lock @@ -0,0 +1,206 @@ +{ + "version": "3", + "packages": { + "specifiers": { + "npm:@types/node": "npm:@types/node@18.16.19" + }, + "npm": { + "@types/node@18.16.19": { + "integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==", + "dependencies": {} + } + } + }, + "redirects": { + "https://esm.sh/v132/@types/chai@~4.3/index.d.ts": "https://esm.sh/v132/@types/chai@4.3.8/index.d.ts" + }, + "remote": { + "https://deno.land/std@0.203.0/assert/_constants.ts": "8a9da298c26750b28b326b297316cdde860bc237533b07e1337c021379e6b2a9", + "https://deno.land/std@0.203.0/assert/_diff.ts": "1a3c044aedf77647d6cac86b798c6417603361b66b54c53331b312caeb447aea", + "https://deno.land/std@0.203.0/assert/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7", + "https://deno.land/std@0.203.0/assert/assert.ts": "9a97dad6d98c238938e7540736b826440ad8c1c1e54430ca4c4e623e585607ee", + "https://deno.land/std@0.203.0/assert/assert_almost_equals.ts": "e15ca1f34d0d5e0afae63b3f5d975cbd18335a132e42b0c747d282f62ad2cd6c", + "https://deno.land/std@0.203.0/assert/assert_array_includes.ts": "6856d7f2c3544bc6e62fb4646dfefa3d1df5ff14744d1bca19f0cbaf3b0d66c9", + "https://deno.land/std@0.203.0/assert/assert_equals.ts": "d8ec8a22447fbaf2fc9d7c3ed2e66790fdb74beae3e482855d75782218d68227", + "https://deno.land/std@0.203.0/assert/assert_exists.ts": "407cb6b9fb23a835cd8d5ad804e2e2edbbbf3870e322d53f79e1c7a512e2efd7", + "https://deno.land/std@0.203.0/assert/assert_false.ts": "0ccbcaae910f52c857192ff16ea08bda40fdc79de80846c206bfc061e8c851c6", + "https://deno.land/std@0.203.0/assert/assert_greater.ts": "ae2158a2d19313bf675bf7251d31c6dc52973edb12ac64ac8fc7064152af3e63", + "https://deno.land/std@0.203.0/assert/assert_greater_or_equal.ts": "1439da5ebbe20855446cac50097ac78b9742abe8e9a43e7de1ce1426d556e89c", + "https://deno.land/std@0.203.0/assert/assert_instance_of.ts": "3aedb3d8186e120812d2b3a5dea66a6e42bf8c57a8bd927645770bd21eea554c", + "https://deno.land/std@0.203.0/assert/assert_is_error.ts": "c21113094a51a296ffaf036767d616a78a2ae5f9f7bbd464cd0197476498b94b", + "https://deno.land/std@0.203.0/assert/assert_less.ts": "aec695db57db42ec3e2b62e97e1e93db0063f5a6ec133326cc290ff4b71b47e4", + "https://deno.land/std@0.203.0/assert/assert_less_or_equal.ts": "5fa8b6a3ffa20fd0a05032fe7257bf985d207b85685fdbcd23651b70f928c848", + "https://deno.land/std@0.203.0/assert/assert_match.ts": "c4083f80600bc190309903c95e397a7c9257ff8b5ae5c7ef91e834704e672e9b", + "https://deno.land/std@0.203.0/assert/assert_not_equals.ts": "9f1acab95bd1f5fc9a1b17b8027d894509a745d91bac1718fdab51dc76831754", + "https://deno.land/std@0.203.0/assert/assert_not_instance_of.ts": "0c14d3dfd9ab7a5276ed8ed0b18c703d79a3d106102077ec437bfe7ed912bd22", + "https://deno.land/std@0.203.0/assert/assert_not_match.ts": "3796a5b0c57a1ce6c1c57883dd4286be13a26f715ea662318ab43a8491a13ab0", + "https://deno.land/std@0.203.0/assert/assert_not_strict_equals.ts": "ca6c6d645e95fbc873d25320efeb8c4c6089a9a5e09f92d7c1c4b6e935c2a6ad", + "https://deno.land/std@0.203.0/assert/assert_object_match.ts": "d8fc2867cfd92eeacf9cea621e10336b666de1874a6767b5ec48988838370b54", + "https://deno.land/std@0.203.0/assert/assert_rejects.ts": "45c59724de2701e3b1f67c391d6c71c392363635aad3f68a1b3408f9efca0057", + "https://deno.land/std@0.203.0/assert/assert_strict_equals.ts": "b1f538a7ea5f8348aeca261d4f9ca603127c665e0f2bbfeb91fa272787c87265", + "https://deno.land/std@0.203.0/assert/assert_string_includes.ts": "b821d39ebf5cb0200a348863c86d8c4c4b398e02012ce74ad15666fc4b631b0c", + "https://deno.land/std@0.203.0/assert/assert_throws.ts": "63784e951475cb7bdfd59878cd25a0931e18f6dc32a6077c454b2cd94f4f4bcd", + "https://deno.land/std@0.203.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56", + "https://deno.land/std@0.203.0/assert/equal.ts": "9f1a46d5993966d2596c44e5858eec821859b45f783a5ee2f7a695dfc12d8ece", + "https://deno.land/std@0.203.0/assert/fail.ts": "c36353d7ae6e1f7933d45f8ea51e358c8c4b67d7e7502028598fe1fea062e278", + "https://deno.land/std@0.203.0/assert/mod.ts": "37c49a26aae2b254bbe25723434dc28cd7532e444cf0b481a97c045d110ec085", + "https://deno.land/std@0.203.0/assert/unimplemented.ts": "d56fbeecb1f108331a380f72e3e010a1f161baa6956fd0f7cf3e095ae1a4c75a", + "https://deno.land/std@0.203.0/assert/unreachable.ts": "4600dc0baf7d9c15a7f7d234f00c23bca8f3eba8b140286aaca7aa998cf9a536", + "https://deno.land/std@0.203.0/dotenv/mod.ts": "1da8c6d0e7f7d8a5c2b19400b763bc11739df24acec235dda7ea2cfd3d300057", + "https://deno.land/std@0.203.0/fmt/colors.ts": "c51c4642678eb690dcf5ffee5918b675bf01a33fba82acf303701ae1a4f8c8d9", + "https://deno.land/std@0.203.0/fs/_util.ts": "fbf57dcdc9f7bc8128d60301eece608246971a7836a3bb1e78da75314f08b978", + "https://deno.land/std@0.203.0/fs/expand_glob.ts": "52b8b6f5b1fa585c348250da1c80ce5d820746cb4a75d874b3599646f677d3a7", + "https://deno.land/std@0.203.0/fs/walk.ts": "a16146724a6aaf9efdb92023a74e9805195c3469900744ce5de4113b07b29779", + "https://deno.land/std@0.203.0/json/common.ts": "ecd5e87d45b5f0df33238ed8b1746e1444da7f5c86ae53d0f0b04280f41a25bb", + "https://deno.land/std@0.203.0/jsonc/mod.ts": "b88dce28eb3645667caa856538ae2fe87af51410822544a0b45a4177ef3bd7dd", + "https://deno.land/std@0.203.0/jsonc/parse.ts": "c1096e2b7ffb4996d7ed841dfdb29a4fccc78edcc55299beaa20d6fe5facf7b6", + "https://deno.land/std@0.203.0/path/_basename.ts": "057d420c9049821f983f784fd87fa73ac471901fb628920b67972b0f44319343", + "https://deno.land/std@0.203.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0", + "https://deno.land/std@0.203.0/path/_dirname.ts": "355e297236b2218600aee7a5301b937204c62e12da9db4b0b044993d9e658395", + "https://deno.land/std@0.203.0/path/_extname.ts": "eaaa5aae1acf1f03254d681bd6a8ce42a9cb5b7ff2213a9d4740e8ab31283664", + "https://deno.land/std@0.203.0/path/_format.ts": "4a99270d6810f082e614309164fad75d6f1a483b68eed97c830a506cc589f8b4", + "https://deno.land/std@0.203.0/path/_from_file_url.ts": "6eadfae2e6f63ad9ee46b26db4a1b16583055c0392acedfb50ed2fc694b6f581", + "https://deno.land/std@0.203.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b", + "https://deno.land/std@0.203.0/path/_is_absolute.ts": "05dac10b5e93c63198b92e3687baa2be178df5321c527dc555266c0f4f51558c", + "https://deno.land/std@0.203.0/path/_join.ts": "815f5e85b042285175b1492dd5781240ce126c23bd97bad6b8211fe7129c538e", + "https://deno.land/std@0.203.0/path/_normalize.ts": "a19ec8706b2707f9dd974662a5cd89fad438e62ab1857e08b314a8eb49a34d81", + "https://deno.land/std@0.203.0/path/_os.ts": "30b0c2875f360c9296dbe6b7f2d528f0f9c741cecad2e97f803f5219e91b40a2", + "https://deno.land/std@0.203.0/path/_parse.ts": "0f9b0ff43682dd9964eb1c4398610c4e165d8db9d3ac9d594220217adf480cfa", + "https://deno.land/std@0.203.0/path/_relative.ts": "27bdeffb5311a47d85be26d37ad1969979359f7636c5cd9fcf05dcd0d5099dc5", + "https://deno.land/std@0.203.0/path/_resolve.ts": "7a3616f1093735ed327e758313b79c3c04ea921808ca5f19ddf240cb68d0adf6", + "https://deno.land/std@0.203.0/path/_to_file_url.ts": "a141e4a525303e1a3a0c0571fd024552b5f3553a2af7d75d1ff3a503dcbb66d8", + "https://deno.land/std@0.203.0/path/_to_namespaced_path.ts": "0d5f4caa2ed98ef7a8786286df6af804b50e38859ae897b5b5b4c8c5930a75c8", + "https://deno.land/std@0.203.0/path/_util.ts": "4e191b1bac6b3bf0c31aab42e5ca2e01a86ab5a0d2e08b75acf8585047a86221", + "https://deno.land/std@0.203.0/path/basename.ts": "bdfa5a624c6a45564dc6758ef2077f2822978a6dbe77b0a3514f7d1f81362930", + "https://deno.land/std@0.203.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000", + "https://deno.land/std@0.203.0/path/dirname.ts": "b6533f4ee4174a526dec50c279534df5345836dfdc15318400b08c62a62a39dd", + "https://deno.land/std@0.203.0/path/extname.ts": "62c4b376300795342fe1e4746c0de518b4dc9c4b0b4617bfee62a2973a9555cf", + "https://deno.land/std@0.203.0/path/format.ts": "110270b238514dd68455a4c54956215a1aff7e37e22e4427b7771cefe1920aa5", + "https://deno.land/std@0.203.0/path/from_file_url.ts": "9f5cb58d58be14c775ec2e57fc70029ac8b17ed3bd7fe93e475b07280adde0ac", + "https://deno.land/std@0.203.0/path/glob.ts": "593e2c3573883225c25c5a21aaa8e9382a696b8e175ea20a3b6a1471ad17aaed", + "https://deno.land/std@0.203.0/path/is_absolute.ts": "0b92eb35a0a8780e9f16f16bb23655b67dace6a8e0d92d42039e518ee38103c1", + "https://deno.land/std@0.203.0/path/join.ts": "31c5419f23d91655b08ec7aec403f4e4cd1a63d39e28f6e42642ea207c2734f8", + "https://deno.land/std@0.203.0/path/mod.ts": "6e1efb0b13121463aedb53ea51dabf5639a3172ab58c89900bbb72b486872532", + "https://deno.land/std@0.203.0/path/normalize.ts": "6ea523e0040979dd7ae2f1be5bf2083941881a252554c0f32566a18b03021955", + "https://deno.land/std@0.203.0/path/parse.ts": "be8de342bb9e1924d78dc4d93c45215c152db7bf738ec32475560424b119b394", + "https://deno.land/std@0.203.0/path/posix.ts": "0a1c1952d132323a88736d03e92bd236f3ed5f9f079e5823fae07c8d978ee61b", + "https://deno.land/std@0.203.0/path/relative.ts": "8bedac226afd360afc45d451a6c29fabceaf32978526bcb38e0c852661f66c61", + "https://deno.land/std@0.203.0/path/resolve.ts": "133161e4949fc97f9ca67988d51376b0f5eef8968a6372325ab84d39d30b80dc", + "https://deno.land/std@0.203.0/path/separator.ts": "40a3e9a4ad10bef23bc2cd6c610291b6c502a06237c2c4cd034a15ca78dedc1f", + "https://deno.land/std@0.203.0/path/to_file_url.ts": "00e6322373dd51ad109956b775e4e72e5f9fa68ce2c6b04e4af2a6eed3825d31", + "https://deno.land/std@0.203.0/path/to_namespaced_path.ts": "1b1db3055c343ab389901adfbda34e82b7386bcd1c744d54f9c1496ee0fd0c3d", + "https://deno.land/std@0.203.0/path/win32.ts": "8b3f80ef7a462511d5e8020ff490edcaa0a0d118f1b1e9da50e2916bdd73f9dd", + "https://deno.land/std@0.204.0/assert/assert.ts": "9a97dad6d98c238938e7540736b826440ad8c1c1e54430ca4c4e623e585607ee", + "https://deno.land/std@0.204.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56", + "https://deno.land/std@0.204.0/fs/_util.ts": "fbf57dcdc9f7bc8128d60301eece608246971a7836a3bb1e78da75314f08b978", + "https://deno.land/std@0.204.0/fs/copy.ts": "ca19e4837965914471df38fbd61e16f9e8adfe89f9cffb0c83615c83ea3fc2bf", + "https://deno.land/std@0.204.0/fs/empty_dir.ts": "0b4a2508232446eed232ad1243dd4b0f07ac503a281633ae1324d1528df70964", + "https://deno.land/std@0.204.0/fs/ensure_dir.ts": "dc64c4c75c64721d4e3fb681f1382f803ff3d2868f08563ff923fdd20d071c40", + "https://deno.land/std@0.204.0/fs/ensure_file.ts": "39ac83cc283a20ec2735e956adf5de3e8a3334e0b6820547b5772f71c49ae083", + "https://deno.land/std@0.204.0/fs/ensure_link.ts": "c15e69c48556d78aae31b83e0c0ece04b7b8bc0951412f5b759aceb6fde7f0ac", + "https://deno.land/std@0.204.0/fs/ensure_symlink.ts": "b389c8568f0656d145ac7ece472afe710815cccbb2ebfd19da7978379ae143fe", + "https://deno.land/std@0.204.0/fs/eol.ts": "f1f2eb348a750c34500741987b21d65607f352cf7205f48f4319d417fff42842", + "https://deno.land/std@0.204.0/fs/exists.ts": "cb59a853d84871d87acab0e7936a4dac11282957f8e195102c5a7acb42546bb8", + "https://deno.land/std@0.204.0/fs/expand_glob.ts": "52b8b6f5b1fa585c348250da1c80ce5d820746cb4a75d874b3599646f677d3a7", + "https://deno.land/std@0.204.0/fs/mod.ts": "bc3d0acd488cc7b42627044caf47d72019846d459279544e1934418955ba4898", + "https://deno.land/std@0.204.0/fs/move.ts": "b4f8f46730b40c32ea3c0bc8eb0fd0e8139249a698883c7b3756424cf19785c9", + "https://deno.land/std@0.204.0/fs/walk.ts": "a16146724a6aaf9efdb92023a74e9805195c3469900744ce5de4113b07b29779", + "https://deno.land/std@0.204.0/path/_common/assert_path.ts": "061e4d093d4ba5aebceb2c4da3318bfe3289e868570e9d3a8e327d91c2958946", + "https://deno.land/std@0.204.0/path/_common/basename.ts": "0d978ff818f339cd3b1d09dc914881f4d15617432ae519c1b8fdc09ff8d3789a", + "https://deno.land/std@0.204.0/path/_common/common.ts": "9e4233b2eeb50f8b2ae10ecc2108f58583aea6fd3e8907827020282dc2b76143", + "https://deno.land/std@0.204.0/path/_common/constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0", + "https://deno.land/std@0.204.0/path/_common/dirname.ts": "2ba7fb4cc9fafb0f38028f434179579ce61d4d9e51296fad22b701c3d3cd7397", + "https://deno.land/std@0.204.0/path/_common/format.ts": "11aa62e316dfbf22c126917f5e03ea5fe2ee707386555a8f513d27ad5756cf96", + "https://deno.land/std@0.204.0/path/_common/from_file_url.ts": "ef1bf3197d2efbf0297a2bdbf3a61d804b18f2bcce45548ae112313ec5be3c22", + "https://deno.land/std@0.204.0/path/_common/glob_to_reg_exp.ts": "5c3c2b79fc2294ec803d102bd9855c451c150021f452046312819fbb6d4dc156", + "https://deno.land/std@0.204.0/path/_common/is_glob.ts": "567dce5c6656bdedfc6b3ee6c0833e1e4db2b8dff6e62148e94a917f289c06ad", + "https://deno.land/std@0.204.0/path/_common/normalize.ts": "2ba7fb4cc9fafb0f38028f434179579ce61d4d9e51296fad22b701c3d3cd7397", + "https://deno.land/std@0.204.0/path/_common/normalize_string.ts": "88c472f28ae49525f9fe82de8c8816d93442d46a30d6bb5063b07ff8a89ff589", + "https://deno.land/std@0.204.0/path/_common/relative.ts": "1af19d787a2a84b8c534cc487424fe101f614982ae4851382c978ab2216186b4", + "https://deno.land/std@0.204.0/path/_common/strip_trailing_separators.ts": "7ffc7c287e97bdeeee31b155828686967f222cd73f9e5780bfe7dfb1b58c6c65", + "https://deno.land/std@0.204.0/path/_common/to_file_url.ts": "a8cdd1633bc9175b7eebd3613266d7c0b6ae0fb0cff24120b6092ac31662f9ae", + "https://deno.land/std@0.204.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b", + "https://deno.land/std@0.204.0/path/_os.ts": "30b0c2875f360c9296dbe6b7f2d528f0f9c741cecad2e97f803f5219e91b40a2", + "https://deno.land/std@0.204.0/path/basename.ts": "04bb5ef3e86bba8a35603b8f3b69537112cdd19ce64b77f2522006da2977a5f3", + "https://deno.land/std@0.204.0/path/common.ts": "f4d061c7d0b95a65c2a1a52439edec393e906b40f1caf4604c389fae7caa80f5", + "https://deno.land/std@0.204.0/path/dirname.ts": "88a0a71c21debafc4da7a4cd44fd32e899462df458fbca152390887d41c40361", + "https://deno.land/std@0.204.0/path/extname.ts": "2da4e2490f3b48b7121d19fb4c91681a5e11bd6bd99df4f6f47d7a71bb6ecdf2", + "https://deno.land/std@0.204.0/path/format.ts": "3457530cc85d1b4bab175f9ae73998b34fd456c830d01883169af0681b8894fb", + "https://deno.land/std@0.204.0/path/from_file_url.ts": "e7fa233ea1dff9641e8d566153a24d95010110185a6f418dd2e32320926043f8", + "https://deno.land/std@0.204.0/path/glob.ts": "9c77cf47db1d786e2ebf66670824d03fd84ecc7c807cac24441eb9d5cb6a2986", + "https://deno.land/std@0.204.0/path/is_absolute.ts": "67232b41b860571c5b7537f4954c88d86ae2ba45e883ee37d3dec27b74909d13", + "https://deno.land/std@0.204.0/path/join.ts": "98d3d76c819af4a11a81d5ba2dbb319f1ce9d63fc2b615597d4bcfddd4a89a09", + "https://deno.land/std@0.204.0/path/mod.ts": "2d62a0a8b78a60e8e6f485d881bac6b61d58573b11cf585fb7c8fc50d9b20d80", + "https://deno.land/std@0.204.0/path/normalize.ts": "aa95be9a92c7bd4f9dc0ba51e942a1973e2b93d266cd74f5ca751c136d520b66", + "https://deno.land/std@0.204.0/path/parse.ts": "d87ff0deef3fb495bc0d862278ff96da5a06acf0625ca27769fc52ac0d3d6ece", + "https://deno.land/std@0.204.0/path/posix/_util.ts": "ecf49560fedd7dd376c6156cc5565cad97c1abe9824f4417adebc7acc36c93e5", + "https://deno.land/std@0.204.0/path/posix/basename.ts": "a630aeb8fd8e27356b1823b9dedd505e30085015407caa3396332752f6b8406a", + "https://deno.land/std@0.204.0/path/posix/common.ts": "e781d395dc76f6282e3f7dd8de13194abb8b04a82d109593141abc6e95755c8b", + "https://deno.land/std@0.204.0/path/posix/dirname.ts": "f48c9c42cc670803b505478b7ef162c7cfa9d8e751b59d278b2ec59470531472", + "https://deno.land/std@0.204.0/path/posix/extname.ts": "ee7f6571a9c0a37f9218fbf510c440d1685a7c13082c348d701396cc795e0be0", + "https://deno.land/std@0.204.0/path/posix/format.ts": "b94876f77e61bfe1f147d5ccb46a920636cd3cef8be43df330f0052b03875968", + "https://deno.land/std@0.204.0/path/posix/from_file_url.ts": "b97287a83e6407ac27bdf3ab621db3fccbf1c27df0a1b1f20e1e1b5acf38a379", + "https://deno.land/std@0.204.0/path/posix/glob.ts": "86c3f06d1c98303613c74650961c3e24bdb871cde2a97c3ae7f0f6d4abbef445", + "https://deno.land/std@0.204.0/path/posix/is_absolute.ts": "159900a3422d11069d48395568217eb7fc105ceda2683d03d9b7c0f0769e01b8", + "https://deno.land/std@0.204.0/path/posix/join.ts": "0c0d84bdc344876930126640011ec1b888e6facf74153ffad9ef26813aa2a076", + "https://deno.land/std@0.204.0/path/posix/mod.ts": "6bfa8a42d85345b12dbe8571028ca2c62d460b6ef968125e498602b43b6cf6b6", + "https://deno.land/std@0.204.0/path/posix/normalize.ts": "11de90a94ab7148cc46e5a288f7d732aade1d616bc8c862f5560fa18ff987b4b", + "https://deno.land/std@0.204.0/path/posix/parse.ts": "199208f373dd93a792e9c585352bfc73a6293411bed6da6d3bc4f4ef90b04c8e", + "https://deno.land/std@0.204.0/path/posix/relative.ts": "e2f230608b0f083e6deaa06e063943e5accb3320c28aef8d87528fbb7fe6504c", + "https://deno.land/std@0.204.0/path/posix/resolve.ts": "51579d83159d5c719518c9ae50812a63959bbcb7561d79acbdb2c3682236e285", + "https://deno.land/std@0.204.0/path/posix/separator.ts": "0b6573b5f3269a3164d8edc9cefc33a02dd51003731c561008c8bb60220ebac1", + "https://deno.land/std@0.204.0/path/posix/to_file_url.ts": "08d43ea839ee75e9b8b1538376cfe95911070a655cd312bc9a00f88ef14967b6", + "https://deno.land/std@0.204.0/path/posix/to_namespaced_path.ts": "c9228a0e74fd37e76622cd7b142b8416663a9b87db643302fa0926b5a5c83bdc", + "https://deno.land/std@0.204.0/path/relative.ts": "23d45ede8b7ac464a8299663a43488aad6b561414e7cbbe4790775590db6349c", + "https://deno.land/std@0.204.0/path/resolve.ts": "5b184efc87155a0af9fa305ff68a109e28de9aee81fc3e77cd01380f19daf867", + "https://deno.land/std@0.204.0/path/separator.ts": "40a3e9a4ad10bef23bc2cd6c610291b6c502a06237c2c4cd034a15ca78dedc1f", + "https://deno.land/std@0.204.0/path/to_file_url.ts": "edaafa089e0bce386e1b2d47afe7c72e379ff93b28a5829a5885e4b6c626d864", + "https://deno.land/std@0.204.0/path/to_namespaced_path.ts": "cf8734848aac3c7527d1689d2adf82132b1618eff3cc523a775068847416b22a", + "https://deno.land/std@0.204.0/path/windows/_util.ts": "f32b9444554c8863b9b4814025c700492a2b57ff2369d015360970a1b1099d54", + "https://deno.land/std@0.204.0/path/windows/basename.ts": "8a9dbf7353d50afbc5b221af36c02a72c2d1b2b5b9f7c65bf6a5a2a0baf88ad3", + "https://deno.land/std@0.204.0/path/windows/common.ts": "e781d395dc76f6282e3f7dd8de13194abb8b04a82d109593141abc6e95755c8b", + "https://deno.land/std@0.204.0/path/windows/dirname.ts": "5c2aa541384bf0bd9aca821275d2a8690e8238fa846198ef5c7515ce31a01a94", + "https://deno.land/std@0.204.0/path/windows/extname.ts": "07f4fa1b40d06a827446b3e3bcc8d619c5546b079b8ed0c77040bbef716c7614", + "https://deno.land/std@0.204.0/path/windows/format.ts": "343019130d78f172a5c49fdc7e64686a7faf41553268961e7b6c92a6d6548edf", + "https://deno.land/std@0.204.0/path/windows/from_file_url.ts": "d53335c12b0725893d768be3ac6bf0112cc5b639d2deb0171b35988493b46199", + "https://deno.land/std@0.204.0/path/windows/glob.ts": "0286fb89ecd21db5cbf3b6c79e2b87c889b03f1311e66fb769e6b905d4142332", + "https://deno.land/std@0.204.0/path/windows/is_absolute.ts": "245b56b5f355ede8664bd7f080c910a97e2169972d23075554ae14d73722c53c", + "https://deno.land/std@0.204.0/path/windows/join.ts": "e6600bf88edeeef4e2276e155b8de1d5dec0435fd526ba2dc4d37986b2882f16", + "https://deno.land/std@0.204.0/path/windows/mod.ts": "c3d1a36fbf9f6db1320bcb4fbda8de011d25461be3497105e15cbea1e3726198", + "https://deno.land/std@0.204.0/path/windows/normalize.ts": "9deebbf40c81ef540b7b945d4ccd7a6a2c5a5992f791e6d3377043031e164e69", + "https://deno.land/std@0.204.0/path/windows/parse.ts": "120faf778fe1f22056f33ded069b68e12447668fcfa19540c0129561428d3ae5", + "https://deno.land/std@0.204.0/path/windows/relative.ts": "026855cd2c36c8f28f1df3c6fbd8f2449a2aa21f48797a74700c5d872b86d649", + "https://deno.land/std@0.204.0/path/windows/resolve.ts": "5ff441ab18a2346abadf778121128ee71bda4d0898513d4639a6ca04edca366b", + "https://deno.land/std@0.204.0/path/windows/separator.ts": "ae21f27015f10510ed1ac4a0ba9c4c9c967cbdd9d9e776a3e4967553c397bd5d", + "https://deno.land/std@0.204.0/path/windows/to_file_url.ts": "8e9ea9e1ff364aa06fa72999204229952d0a279dbb876b7b838b2b2fea55cce3", + "https://deno.land/std@0.204.0/path/windows/to_namespaced_path.ts": "e0f4d4a5e77f28a5708c1a33ff24360f35637ba6d8f103d19661255ef7bfd50d", + "https://deno.land/x/zod@v3.21.4/ZodError.ts": "4de18ff525e75a0315f2c12066b77b5c2ae18c7c15ef7df7e165d63536fdf2ea", + "https://deno.land/x/zod@v3.21.4/errors.ts": "5285922d2be9700cc0c70c95e4858952b07ae193aa0224be3cbd5cd5567eabef", + "https://deno.land/x/zod@v3.21.4/external.ts": "a6cfbd61e9e097d5f42f8a7ed6f92f93f51ff927d29c9fbaec04f03cbce130fe", + "https://deno.land/x/zod@v3.21.4/helpers/enumUtil.ts": "54efc393cc9860e687d8b81ff52e980def00fa67377ad0bf8b3104f8a5bf698c", + "https://deno.land/x/zod@v3.21.4/helpers/errorUtil.ts": "7a77328240be7b847af6de9189963bd9f79cab32bbc61502a9db4fe6683e2ea7", + "https://deno.land/x/zod@v3.21.4/helpers/parseUtil.ts": "51a76c126ee212be86013d53a9d07f87e9ae04bb1496f2558e61b62cb74a6aa8", + "https://deno.land/x/zod@v3.21.4/helpers/partialUtil.ts": "998c2fe79795257d4d1cf10361e74492f3b7d852f61057c7c08ac0a46488b7e7", + "https://deno.land/x/zod@v3.21.4/helpers/typeAliases.ts": "0fda31a063c6736fc3cf9090dd94865c811dfff4f3cb8707b932bf937c6f2c3e", + "https://deno.land/x/zod@v3.21.4/helpers/util.ts": "8baf19b19b2fca8424380367b90364b32503b6b71780269a6e3e67700bb02774", + "https://deno.land/x/zod@v3.21.4/index.ts": "d27aabd973613985574bc31f39e45cb5d856aa122ef094a9f38a463b8ef1a268", + "https://deno.land/x/zod@v3.21.4/locales/en.ts": "a7a25cd23563ccb5e0eed214d9b31846305ddbcdb9c5c8f508b108943366ab4c", + "https://deno.land/x/zod@v3.21.4/mod.ts": "64e55237cb4410e17d968cd08975566059f27638ebb0b86048031b987ba251c4", + "https://deno.land/x/zod@v3.21.4/types.ts": "b5d061babea250de14fc63764df5b3afa24f2b088a1d797fc060ba49a0ddff28", + "https://esm.sh/chai@4.3.10": "e413ea40e1248a0a06e8812f22ec265c4a41cb57829c19017af5cb1def62880f", + "https://esm.sh/string-argv@0.3.2": "ba1d5479e1ed6293e5a7ffd3297e0eb55a23a5d5d7ac71306ee829fba4243402", + "https://esm.sh/v132/assertion-error@1.1.0/denonext/assertion-error.mjs": "0a4a5dccfb89070dd1e09fad036e706aa51d9dd3236ab019aed08bef1841695b", + "https://esm.sh/v132/chai@4.3.10/denonext/chai.mjs": "eb28e3e1d5467e55c014b1767e535640a04e5b1c3e343b642edb7d7cdcc66941", + "https://esm.sh/v132/check-error@1.0.3/denonext/check-error.mjs": "006d00eabb40c1db268edf0deaabe1e012e8f258ec1d9e9d401e1d70404f1860", + "https://esm.sh/v132/deep-eql@4.1.3/denonext/deep-eql.mjs": "9b0070fc82ccece1b925fcba27afc531ed0d2666f70c62f7d0c15618c0c1a857", + "https://esm.sh/v132/get-func-name@2.0.0/denonext/get-func-name.mjs": "61be7375a13cecc61c2b868186b99500b5645d701e1710d1d089fd141df2324b", + "https://esm.sh/v132/get-func-name@2.0.2/denonext/get-func-name.mjs": "351ff55c7e8628cae42ebcbfe38ab07c2182a916cd7cbaa8b261700a47c92e81", + "https://esm.sh/v132/loupe@2.3.6/denonext/loupe.mjs": "92b3d5229812bbb2fc5eddca3639e019bb98ff35a412af6f1934f38200e2c6f5", + "https://esm.sh/v132/pathval@1.1.1/denonext/pathval.mjs": "d34809f4ad27fae1b72ca58c5961b077400f86c01ac0406373d74f2f7650ca83", + "https://esm.sh/v132/string-argv@0.3.2/denonext/string-argv.mjs": "a7977920da1d72bf89b1db36d2c24fdfa82df6ce4f6c2b59a930b641a6ba9b37", + "https://esm.sh/v132/type-detect@4.0.8/denonext/type-detect.mjs": "deb58bd7203992249a5795f7da35d00b67077fe6c03019349cb614ba22ef52ad", + "https://esm.sh/v133/zod-validation-error@1.5.0/denonext/zod-validation-error.mjs": "5668026e1c5e48df41677eb1c0bf1b7c66e0fd125c40934f37d32bf72610543a", + "https://esm.sh/v133/zod@3.22.4/denonext/zod.mjs": "660128af5d1e921745c4d452472d103d9f2fc5afa508bbf233b83d35a272ad67", + "https://esm.sh/zod-validation-error@1.5.0": "78c876230174f315432e87ae4c761c2a833f2abddf0544a335ff5c80fdb42ddb" + } +} diff --git a/mod.ts b/mod.ts new file mode 100644 index 0000000..64964e7 --- /dev/null +++ b/mod.ts @@ -0,0 +1,445 @@ +// Imports +import * as JSONC from "https://deno.land/std@0.203.0/jsonc/mod.ts" +import { z as is } from "https://deno.land/x/zod@v3.21.4/mod.ts" +import { fromZodError } from "https://esm.sh/zod-validation-error@1.5.0" +import { bgBrightBlue, bold, gray, italic, underline, yellow } from "https://deno.land/std@0.203.0/fmt/colors.ts" + +// Structure flags ========================================================================================================= + +/** Common flags */ +const common = is.object({ + unstable: is.boolean().optional().transform((v) => v ? "--unstable" : ""), + quiet: is.boolean().optional().transform((v) => v ? "--quiet" : ""), + config: is.union([ + is.boolean().transform((v) => v === false ? "--no-config" : ""), + is.string().min(1).transform((v) => `--config='${v}'`), + ]).optional(), + importMap: is.string().optional().transform((v) => v ? `--import-map='${v}'` : ""), + cert: is.string().optional().transform((v) => v ? `--cert='${v}'` : ""), +}) + +/** Common runnable flags */ +const runnable = is.object({ + location: is.string().optional().transform((v) => v ? `--location='${v}'` : ""), + seed: is.number().optional().transform((v) => typeof v === "number" ? `--seed=${v}` : ""), + v8Flags: is.array(is.string()).optional().transform((v) => v?.length ? `--v8-flags='${v.join(",")}'` : ""), + ignoreCertificateErrors: is.boolean().optional().transform((v) => + v === true ? "--unsafely-ignore-certificate-errors" : "" + ), +}) + +/** Lock file flags */ +const lock = { + check: is.string().min(1).optional().transform((v) => `--lock='${v}'`), + read: is.union([ + is.boolean().transform((v) => v === false ? "--no-lock" : ""), + is.string().min(1).transform((v) => `--lock='${v}'`), + ]).optional(), + write: is.union([ + is.boolean().transform((v) => v === false ? "--no-lock" : ""), + is.string().min(1).transform((v) => `--lock='${v}'`), + is.object({ + file: is.string().optional().transform((v) => v ? `--lock='${v}'` : ""), + write: is.boolean().optional().transform((v) => v ? "--lock-write" : ""), + }).transform((v) => Object.values(v).filter(Boolean).join(" ")), + ]).optional(), +} + +/** Permissions flags */ +const permissions = is.union([ + is.object({ + all: is.boolean().transform((v) => v ? "--allow-all" : "--deny-all"), + prompt: is.boolean().optional().transform((v) => v === false ? "--no-prompt" : ""), + }).transform((v) => Object.values(v).filter(Boolean).join(" ")), + is.object({ + read: is.union([ + is.boolean().transform((v) => v ? "--allow-read" : "--deny-read"), + is.array(is.string()).transform((v) => v.length ? `--allow-read=${v.join(",")}` : ""), + is.object({ + allow: is.array(is.string()).transform((v) => v.length ? `--allow-read=${v.join(",")}` : ""), + deny: is.array(is.string()).transform((v) => v.length ? `--deny-read=${v.join(",")}` : ""), + }).transform((v) => Object.values(v).filter(Boolean).join(" ")), + ]).optional(), + write: is.union([ + is.boolean().transform((v) => v ? "--allow-write" : "--deny-write"), + is.array(is.string()).transform((v) => v.length ? `--allow-write=${v.join(",")}` : ""), + is.object({ + allow: is.array(is.string()).transform((v) => v.length ? `--allow-write=${v.join(",")}` : ""), + deny: is.array(is.string()).transform((v) => v.length ? `--deny-write=${v.join(",")}` : ""), + }).transform((v) => Object.values(v).filter(Boolean).join(" ")), + ]).optional(), + net: is.union([ + is.boolean().transform((v) => v ? "--allow-net" : "--deny-net"), + is.array(is.string()).transform((v) => v.length ? `--allow-net=${v.join(",")}` : ""), + is.object({ + allow: is.array(is.string()).transform((v) => v.length ? `--allow-net=${v.join(",")}` : ""), + deny: is.array(is.string()).transform((v) => v.length ? `--deny-net=${v.join(",")}` : ""), + }).transform((v) => Object.values(v).filter(Boolean).join(" ")), + ]).optional(), + env: is.union([ + is.boolean().transform((v) => v ? "--allow-env" : "--deny-env"), + is.array(is.string()).transform((v) => v.length ? `--allow-env=${v.join(",")}` : ""), + is.object({ + allow: is.array(is.string()).transform((v) => v.length ? `--allow-env=${v.join(",")}` : ""), + deny: is.array(is.string()).transform((v) => v.length ? `--deny-env=${v.join(",")}` : ""), + }).transform((v) => Object.values(v).filter(Boolean).join(" ")), + ]).optional(), + sys: is.union([ + is.boolean().transform((v) => v ? "--allow-sys" : "--deny-sys"), + is.array(is.string()).transform((v) => v.length ? `--allow-sys=${v.join(",")}` : ""), + is.object({ + allow: is.array(is.string()).transform((v) => v.length ? `--allow-sys=${v.join(",")}` : ""), + deny: is.array(is.string()).transform((v) => v.length ? `--deny-sys=${v.join(",")}` : ""), + }).transform((v) => Object.values(v).filter(Boolean).join(" ")), + ]).optional(), + run: is.union([ + is.boolean().transform((v) => v ? "--allow-run" : "--deny-run"), + is.array(is.string()).transform((v) => v.length ? `--allow-run=${v.join(",")}` : ""), + is.object({ + allow: is.array(is.string()).transform((v) => v.length ? `--allow-run=${v.join(",")}` : ""), + deny: is.array(is.string()).transform((v) => v.length ? `--deny-run=${v.join(",")}` : ""), + }).transform((v) => Object.values(v).filter(Boolean).join(" ")), + ]).optional(), + ffi: is.union([ + is.boolean().transform((v) => v ? "--allow-ffi" : "--deny-ffi"), + is.array(is.string()).transform((v) => v.length ? `--allow-ffi=${v.join(",")}` : ""), + is.object({ + allow: is.array(is.string()).transform((v) => v.length ? `--allow-ffi=${v.join(",")}` : ""), + deny: is.array(is.string()).transform((v) => v.length ? `--deny-ffi=${v.join(",")}` : ""), + }).transform((v) => Object.values(v).filter(Boolean).join(" ")), + ]).optional(), + hrtime: is.boolean().optional().transform((v) => v ? "--allow-hrtime" : "--deny-hrtime"), + prompt: is.boolean().optional().transform((v) => v === false ? "--no-prompt" : ""), + }).transform((v) => Object.values(v).filter(Boolean).join(" ")), +]).optional() + +/** Module flags (internal) */ +const _modules = is.object({ + cached: is.boolean().optional().transform((v) => v ? "--cached-only" : ""), + remote: is.boolean().optional().transform((v) => v === false ? "--no-remote" : ""), + npm: is.boolean().optional().transform((v) => v === false ? "--no-npm" : ""), + check: is.union([ + is.boolean().transform((v) => v ? "--check=all" : "--no-check"), + is.object({ + remote: is.boolean().transform((v) => v ? "--check=all" : "--check=all --no-check=remote"), + }).transform((v) => Object.values(v).filter(Boolean).join(" ")), + ]).optional().transform((v) => Object.values(v ?? {}).filter(Boolean).join(" ")), + reload: is.union([ + is.boolean().transform((v) => v ? "--reload" : ""), + is.array(is.string()).transform((v) => v.length ? `--reload=${v.join(",")}` : ""), + ]).optional().transform((v) => Object.values(v ?? {}).filter(Boolean).join(" ")), + node_modules: is.boolean().optional().transform((v) => typeof v === "boolean" ? `--node-modules-dir=${v}` : ""), + vendor: is.boolean().optional().transform((v) => typeof v === "boolean" ? `--vendor=${v}` : ""), +}) + +/** Module flags */ +const modules = { + all: _modules.optional().transform((v) => Object.values(v ?? {}).filter(Boolean).join(" ")), + nocache: _modules.pick({ check: true, reload: true, npm: true, remote: true, node_modules: true, vendor: true }) + .optional() + .transform((v) => Object.values(v ?? {}).filter(Boolean).join(" ")), + vendor: _modules.pick({ + reload: true, + node_modules: true, + vendor: true, + }).optional().transform((v) => Object.values(v ?? {}).filter(Boolean).join(" ")), + doc: _modules.pick({ reload: true, npm: true, remote: true }).optional().transform((v) => + Object.values(v ?? {}).filter(Boolean).join(" ") + ), + nocheck: _modules.pick({ reload: true, npm: true, remote: true, node_modules: true, vendor: true }).optional() + .transform((v) => Object.values(v ?? {}).filter(Boolean).join(" ")), +} + +/** Inspect flags */ +const inspect = is.union([ + is.string().transform((v) => v ? `--inspect='${v}'` : ""), + is.object({ + listen: is.string().transform((v) => v ? `--inspect='${v}'` : ""), + break: is.string().transform((v) => v ? `--inspect-brk='${v}'` : ""), + wait: is.string().transform((v) => v.length ? `--inspect-wait='${v}'` : ""), + }), +]).optional().transform((v) => Object.values(v ?? {}).filter(Boolean).join(" ")) + +/** Watch flags */ +const watch = is.union([ + is.boolean().transform((v) => v ? "--watch" : ""), + is.array(is.string()).transform((v) => v.length ? `--watch='${v.join(",")}'` : ""), + is.object({ + files: is.array(is.string()).transform((v) => v.length ? `--watch='${v.join(",")}'` : ""), + clearScreen: is.boolean().transform((v) => v === false ? "--no-clear-screen" : ""), + }), +]).optional().transform((v) => Object.values(v ?? {}).filter(Boolean).join(" ")) + +// Deno flags ========================================================================================================= + +const bench = common.merge(runnable).extend({ + lock: lock.write, + modules: modules.all, + json: is.boolean().optional().transform((v) => v ? "--json" : ""), + run: is.boolean().optional().transform((v) => v === false ? "--no-run" : ""), + watch, + ignore: is.array(is.string()).optional().transform((v) => v?.length ? `--ignore='${v.join(",")}'` : ""), + filter: is.string().optional().transform((v) => v ? `--filter='${v}'` : ""), +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +const bundle = common.extend({ + lock: lock.write, + modules: modules.nocache, + watch, + ext: is.string().optional().transform((v) => v ? `--ext=${v}` : ""), +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +const cache = common.extend({ + lock: lock.write, + modules: modules.nocache, +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +const check = common.extend({ + lock: lock.write, + modules: modules.nocheck, + all: is.boolean().optional().transform((v) => v ? "--all" : ""), +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +const compile = common.merge(runnable).extend({ + permissions, + lock: lock.write, + modules: modules.all, + include: is.array(is.string()).optional().transform((v) => v?.length ? v.map((w) => `--include=${w}`).join(" ") : ""), + output: is.string().optional().transform((v) => v ? `--output='${v}'` : ""), + target: is.string().optional().transform((v) => v ? `--target='${v}'` : ""), + terminal: is.boolean().optional().transform((v) => v === false ? "--no-terminal" : ""), +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +const coverage = common.pick({ unstable: true, quiet: true }).extend({ + ignore: is.array(is.string()).optional().transform((v) => v?.length ? `--ignore='${v.join(",")}'` : ""), //TODO + lcov: is.boolean().optional().transform((v) => v ? "--lcov" : ""), + include: is.string().optional().transform((v) => v ? `--include='${v}'` : ""), + exclude: is.string().optional().transform((v) => v ? `--exclude='${v}'` : ""), + output: is.string().optional().transform((v) => v ? `--output='${v}'` : ""), +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +const doc = common.pick({ unstable: true, quiet: true, importMap: true }).extend({ + lock: lock.read, + modules: modules.doc, + private: is.boolean().optional().transform((v) => v ? "--private" : ""), + json: is.boolean().optional().transform((v) => v ? "--json" : ""), +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +const _eval = common.merge(runnable.pick({ location: true, v8Flags: true, seed: true })).extend({ + lock: lock.write, + modules: modules.all, + inspect, + ext: is.string().optional().transform((v) => v ? `--ext=${v}` : ""), + print: is.boolean().optional().transform((v) => v ? "--print" : ""), +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +const fmt = common.pick({ config: true, unstable: true, quiet: true }).extend({ + watch, + check: is.boolean().optional().transform((v) => v ? "--check" : ""), + tabs: is.boolean().optional().transform((v) => typeof v === "boolean" ? `--use-tabs=${v}` : ""), + lineWidth: is.number().optional().transform((v) => v ? `--line-width=${v}` : ""), + indentWidth: is.number().optional().transform((v) => v ? `--indent-width=${v}` : ""), + singleQuote: is.boolean().optional().transform((v) => typeof v === "boolean" ? `--single-quote=${v}` : ""), + semicolons: is.boolean().optional().transform((v) => v === false ? "--no-semicolons" : ""), + proseWrap: is.string().optional().transform((v) => v ? `--prose-wrap=${v}` : ""), + ignore: is.array(is.string()).optional().transform((v) => v?.length ? `--ignore='${v.join(",")}'` : ""), + ext: is.string().optional().transform((v) => v ? `--ext=${v}` : ""), +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +const info = common.merge(runnable.pick({ location: true })).extend({ + lock: lock.read, + json: is.boolean().optional().transform((v) => v ? "--json" : ""), + modules: modules.nocache, +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +const install = common.merge(runnable).extend({ + permissions, + lock: lock.write, + modules: modules.all, + inspect, + root: is.string().optional().transform((v) => v ? `--root='${v}'` : ""), + name: is.string().optional().transform((v) => v ? `--name='${v}'` : ""), + force: is.boolean().optional().transform((v) => v ? "--force" : ""), +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +const uninstall = common.pick({ quiet: true, unstable: true }).extend({ + root: is.string().optional().transform((v) => v ? `--root='${v}'` : ""), +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +const lint = common.pick({ config: true, unstable: true, quiet: true }).extend({ + rules: is.object({ + tags: is.array(is.string()).optional().transform((v) => v?.length ? `--rules-tags=${v.join(",")}` : ""), + include: is.array(is.string()).optional().transform((v) => v?.length ? `--rules-include=${v.join(",")}` : ""), + exclude: is.array(is.string()).optional().transform((v) => v?.length ? `--rules-exclude=${v.join(",")}` : ""), + }).optional().transform((v) => Object.values(v ?? {}).filter(Boolean).join(" ")), + ignore: is.array(is.string()).optional().transform((v) => v?.length ? `--ignore='${v.join(",")}'` : ""), + json: is.boolean().optional().transform((v) => v ? "--json" : ""), + compact: is.boolean().optional().transform((v) => v ? "--compact" : ""), + watch, +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +const repl = common.merge(runnable).extend({ + lock: lock.write, + modules: modules.all, + inspect, + eval: is.string().optional().transform((v) => v ? `--eval='${v}'` : ""), + evalFile: is.array(is.string()).optional().transform((v) => v?.length ? `--eval-file='${v.join(",")}'` : ""), +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +const run = common.merge(runnable).extend({ + permissions, + lock: lock.write, + inspect, + modules: modules.all, + watch, + ext: is.string().optional().transform((v) => v ? `--ext=${v}` : ""), +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +const test = common.merge(runnable).extend({ + permissions, + lock: lock.write, + modules: modules.all, + inspect, + watch, + doc: is.boolean().optional().transform((v) => v ? "--doc" : ""), + traceOps: is.boolean().optional().transform((v) => v ? "--trace-ops" : ""), + run: is.boolean().optional().transform((v) => v === false ? "--no-run" : ""), + allowNone: is.boolean().optional().transform((v) => v === true ? "--allow-none" : ""), + failFast: is.union([ + is.boolean().transform((v) => v ? "--fail-fast" : ""), + is.number().transform((v) => `--fail-fast=${v}`), + ]).optional(), + shuffle: is.union([ + is.boolean().transform((v) => v ? "--shuffle" : ""), + is.number().transform((v) => `--shuffle=${v}`), + ]).optional(), + parallel: is.boolean().optional().transform((v) => v ? "--parallel" : ""), + coverage: is.string().optional().transform((v) => v ? `--coverage='${v}'` : ""), + reporter: is.string().optional().transform((v) => v ? `--reporter=${v}` : ""), + ignore: is.array(is.string()).optional().transform((v) => v?.length ? `--ignore='${v.join(",")}'` : ""), + filter: is.string().optional().transform((v) => v ? `--filter='${v}'` : ""), + junitPath: is.string().optional().transform((v) => v ? `--junit-path='${v}'` : ""), +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +const types = common.pick({ + unstable: true, + quiet: true, +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +const vendor = common.extend({ + lock: lock.check, + modules: modules.vendor, + output: is.union([ + is.string().min(1).transform((v) => `--output='${v}'`), + is.object({ + path: is.string().optional().transform((v) => v ? `--output='${v}'` : ""), + force: is.boolean().optional().transform((v) => v ? "--force" : ""), + }).transform((v) => Object.values(v).filter(Boolean).join(" ")), + ]).optional(), +}).transform((v) => Object.values(v).filter(Boolean).join(" ")) + +// deno_task flags ========================================================================================================= + +const _make = is.object({ + task: is.union([is.string(), is.array(is.string())]).transform((v) => Array.isArray(v) ? v.join(" ") : v), + description: is.union([is.string(), is.array(is.string())]).transform((v) => Array.isArray(v) ? v.join(" ") : v) + .default(""), + env: is.record(is.string(), is.union([is.boolean(), is.string()])).transform((v) => + Object.fromEntries( + Object.entries(v).map(([k, v]) => [k, v === true ? Deno.env.get(k) ?? "" : v === false ? "" : v]), + ) + ).default(() => ({})), + deno: is.object({ + bench, + bundle, + cache, + check, + compile, + coverage, + doc, + eval: _eval, + fmt, + info, + install, + uninstall, + lint, + repl, + run, + test, + types, + vendor, + }).partial().default(() => ({})), +}) + +/** Compute command to execute after applying deno flags */ +export function command(raw: string, { deno }: Pick, "deno">, { colors = false } = {}) { + for (const [subcommand, flags] of Object.entries(deno)) { + raw = raw.replaceAll(`deno ${subcommand}`, `deno ${subcommand} ${colors ? italic(underline(flags)) : flags}`) + } + return raw +} + +/** Entry point */ +export async function make( + { task = "", config = "deno.jsonc", log = console.log, exit = true, stdio = "inherit" as "inherit" | "null" } = {}, +) { + const { "+tasks": _tasks = {} } = JSONC.parse(await Deno.readTextFile(config)) as { + "+tasks"?: Record + } + const tasks = Object.fromEntries( + Object.entries(_tasks).map(([k, v]) => { + try { + return [k, _make.parse(v)] + } catch (error) { + throw Object.assign(fromZodError(error), { stack: "" }) + } + }), + ) + if (task) { + const temp = ".deno-make.json" + const { task: raw, env, deno } = tasks[task] + try { + const make = command(raw, { deno }) + await Deno.writeTextFile(temp, JSON.stringify({ tasks: { make } })) + const process = new Deno.Command("deno", { + args: ["task", "--config", temp, "make"], + stdout: stdio, + stderr: stdio, + stdin: stdio, + env, + windowsRawArguments: true, + }) + const { code } = await process.output() + if (exit) { + Deno.exit(code) + } + return { code } + } finally { + await Deno.remove(temp) + } + } else if (Object.keys(tasks).length) { + for (const [name, { task, description, env, deno }] of Object.entries(tasks)) { + const { icon = "" } = description.match(/^(?[\p{Emoji}\u200d]+) /u)?.groups ?? {} + log(bgBrightBlue(`${icon} ${bold(name)}`.trim().padEnd(32))) + log(description.replace(icon, "").trim()) + if (Object.keys(env).length) { + log(gray(`Environment variables:`)) + for (const [k, v] of Object.entries(env)) { + const inherited = + ((_tasks as Record>)[name].env[k] as unknown as string | boolean) === true + log(gray(` ${k}=${v}${inherited ? underline(italic("→ inherited")) : ""}`.trim())) + } + } + log(gray(`Task:`)) + log(gray(` ${command(task, { deno }, { colors: true })}`)) + log("") + } + return { code: 0 } + } + log(yellow(`"+tasks" is empty in ${config}`)) + return { code: 0 } +} + +if (import.meta.main) { + await make({ task: Deno.args[0] }) +} diff --git a/mod_bench.ts b/mod_bench.ts new file mode 100644 index 0000000..ca817ca --- /dev/null +++ b/mod_bench.ts @@ -0,0 +1,3 @@ +Deno.bench("URL parsing", () => { + new URL("https://deno.land") +}) diff --git a/mod_test.ts b/mod_test.ts new file mode 100644 index 0000000..775b54e --- /dev/null +++ b/mod_test.ts @@ -0,0 +1,46 @@ +import { make } from "./mod.ts" +import { expandGlob } from "https://deno.land/std@0.204.0/fs/mod.ts" +import * as JSONC from "https://deno.land/std@0.203.0/jsonc/mod.ts" +import { expect } from "https://esm.sh/chai@4.3.10" + +for await (const { path, name: _name } of expandGlob("tests/*.jsonc")) { + const name = _name.replace(".jsonc", "").replaceAll("_", " ") + const { "+tasks": tasks = {} } = JSONC.parse(await Deno.readTextFile(path)) as { "+tasks"?: Record } + for (const task in tasks) { + if (name.startsWith("deno make")) { + continue + } + Deno.test(`${name}: ${task}`, async () => { + const { code } = await make({ task, config: path, log: () => null, exit: false, stdio: "null" }) + expect(code).to.equal(0) + }) + } +} + +/*Deno.test("deno task make: exit code", async () => { + const {code} = await make({task:"make", config:"tests/deno_make.jsonc", log:() => null, exit:true}) + expect(code).to.equal(1) +})*/ + +Deno.test("deno task make: print tasks", async () => { + const stdio = [] as string[] + const { code } = await make({ config: "tests/deno_make.jsonc", log: (message) => stdio.push(message), exit: false }) + expect(stdio.join("\n")).to.include("🦕") + expect(code).to.equal(0) +}) + +Deno.test("deno task make: tasks empty", async () => { + const stdio = [] as string[] + const { code } = await make({ + config: "tests/deno_make_empty.jsonc", + log: (message) => stdio.push(message), + exit: false, + }) + expect(stdio.join("\n")).to.include('"+tasks" is empty') + expect(code).to.equal(0) +}) + +Deno.test("deno task make: tasks error", async () => { + const result = await make({ config: "tests/deno_make_error.jsonc", exit: false }).catch((error) => error) + expect(result).to.be.an.instanceOf(Error) +}) diff --git a/tests/.deno.lock b/tests/.deno.lock new file mode 100644 index 0000000..37f10ce --- /dev/null +++ b/tests/.deno.lock @@ -0,0 +1,4 @@ +{ + "version": "3", + "remote": {} +} diff --git a/tests/.imports.json b/tests/.imports.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/.imports.json @@ -0,0 +1 @@ +{} diff --git a/tests/deno_cache.jsonc b/tests/deno_cache.jsonc new file mode 100644 index 0000000..0c6c783 --- /dev/null +++ b/tests/deno_cache.jsonc @@ -0,0 +1,10 @@ +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno ./mod.ts $0" + }, + "+tasks": { + "flags:none": { + "task": "deno cache tests/mod.ts" + } + } +} diff --git a/tests/deno_check.jsonc b/tests/deno_check.jsonc new file mode 100644 index 0000000..ddaddfb --- /dev/null +++ b/tests/deno_check.jsonc @@ -0,0 +1,18 @@ +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno ./mod.ts $0" + }, + "+tasks": { + "flags:none": { + "task": "deno check tests/mod.ts" + }, + "flags:all": { + "task": "deno check tests/mod.ts", + "deno": { + "check": { + "all": true + } + } + } + } +} diff --git a/tests/deno_common.jsonc b/tests/deno_common.jsonc new file mode 100644 index 0000000..6b0b288 --- /dev/null +++ b/tests/deno_common.jsonc @@ -0,0 +1,63 @@ +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno ./mod.ts $0" + }, + "+tasks": { + "flags:general": { + "task": "deno run tests/mod.ts", + "deno": { + "run": { + "unstable": true, + "quiet": true, + "seed": 0, + "ignoreCertificateErrors": true + } + } + }, + "flags:resolution": { + "task": "deno run tests/mod.ts", + "deno": { + "run": { + "importMap": "tests/.imports.json", + "location": "https://deno.test" + } + } + }, + "flags:config": { + "task": "deno run tests/mod.ts", + "deno": { + "run": { + "config": "tests/deno_common.jsonc" + }, + "lint": { + "config": false + }, + "fmt": { + "config": true + } + } + }, + "flags:v8_flags": { + "task": "deno run tests/mod.ts", + "deno": { + "run": { + "v8Flags": ["--print-code"] + }, + "test": { + "v8Flags": [] + } + } + } + } +} + +/** Common flags +const common = is.object({ + config: is.union([ + is.boolean().transform((v) => v === false ? "--no-config" : ""), + is.string().transform((v) => v ? `--config='${v}'` : ""), + ]).optional(), + cert: is.string().optional().transform((v) => v ? `--cert='${v}'` : ""), +}) + +*/ diff --git a/tests/deno_coverage.jsonc b/tests/deno_coverage.jsonc new file mode 100644 index 0000000..c17fa28 --- /dev/null +++ b/tests/deno_coverage.jsonc @@ -0,0 +1,28 @@ +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno ./mod.ts $0" + }, + "+tasks": { + "flags:none": { + "task": "deno coverage tests/.coverage" + }, + "flags:filters": { + "task": "deno coverage tests/.coverage", + "deno": { + "coverage": { + "include": "^file:", + "exclude": "(js|mjs|ts|jsx|tsx)" + } + } + }, + "flags:lcov": { + "task": "deno coverage tests/.coverage", + "deno": { + "coverage": { + "lcov": true, + "output": "tests/.coverage.report" + } + } + } + } +} diff --git a/tests/deno_doc.jsonc b/tests/deno_doc.jsonc new file mode 100644 index 0000000..0125b17 --- /dev/null +++ b/tests/deno_doc.jsonc @@ -0,0 +1,19 @@ +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno ./mod.ts $0" + }, + "+tasks": { + "flags:none": { + "task": "deno doc tests/mod.ts" + }, + "flags:options": { + "task": "deno doc tests/mod.ts", + "deno": { + "doc": { + "private": true, + "json": true + } + } + } + } +} diff --git a/tests/deno_fmt.jsonc b/tests/deno_fmt.jsonc new file mode 100644 index 0000000..b87fe2e --- /dev/null +++ b/tests/deno_fmt.jsonc @@ -0,0 +1,26 @@ +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno ./mod.ts $0" + }, + "+tasks": { + "flags:none": { + "task": "deno check tests/mod.ts" + }, + "flags:fmt": { + "task": "deno check tests/mod.ts", + "deno": { + "fmt": { + "check": true, + "tabs": true, + "lineWidth": 80, + "indentWidth": 2, + "singleQuote": true, + "semicolons": false, + "proseWrap": "always", + "ignore": ["*"], + "ext": "js" + } + } + } + } +} diff --git a/tests/deno_info.jsonc b/tests/deno_info.jsonc new file mode 100644 index 0000000..01540ad --- /dev/null +++ b/tests/deno_info.jsonc @@ -0,0 +1,34 @@ +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno ./mod.ts $0" + }, + "+tasks": { + "flags:none": { + "task": "deno info" + }, + "flags:lock_1": { + "task": "deno info", + "deno": { + "info": { + "lock": true + } + } + }, + "flags:lock_2": { + "task": "deno info", + "deno": { + "info": { + "lock": false + } + } + }, + "flags:lock_3": { + "task": "deno info", + "deno": { + "info": { + "lock": "deno.lock" + } + } + } + } +} diff --git a/tests/deno_lint.jsonc b/tests/deno_lint.jsonc new file mode 100644 index 0000000..0cdea17 --- /dev/null +++ b/tests/deno_lint.jsonc @@ -0,0 +1,66 @@ +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno ./mod.ts $0" + }, + "+tasks": { + "flags:none": { + "task": "deno types" + }, + "flags:rules_1": { + "task": "deno lint", + "deno": { + "lint": { + "rules": { + "tags": ["recommended"], + "include": ["single-var-declarator"], + "exclude": ["no-deprecated-deno-api"] + } + } + } + }, + "flags:rules_2": { + "task": "deno lint", + "deno": { + "lint": { + "rules": { + "tags": [], + "include": [], + "exclude": [] + } + } + } + }, + "flags:json": { + "task": "deno lint", + "deno": { + "lint": { + "json": true + } + } + }, + "flags:compact": { + "task": "deno lint", + "deno": { + "lint": { + "compact": true + } + } + }, + "flags:ignore_1": { + "task": "deno lint", + "deno": { + "lint": { + "ignore": ["*.js"] + } + } + }, + "flags:ignore_2": { + "task": "deno lint", + "deno": { + "lint": { + "ignore": [] + } + } + } + } +} diff --git a/tests/deno_make.jsonc b/tests/deno_make.jsonc new file mode 100644 index 0000000..00ed5d9 --- /dev/null +++ b/tests/deno_make.jsonc @@ -0,0 +1,25 @@ +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno ./mod.ts $0" + }, + "+tasks": { + "make": { + "task": "exit 1", + "description": "🦕 test", + "env": { + "DINOSAUR": "🦖" + } + }, + "make:no_description": { + "task": "exit 1" + }, + "make:deno": { + "task": "deno quiet", + "deno": { + "info": { + "quiet": true + } + } + } + } +} diff --git a/tests/deno_make_empty.jsonc b/tests/deno_make_empty.jsonc new file mode 100644 index 0000000..150c709 --- /dev/null +++ b/tests/deno_make_empty.jsonc @@ -0,0 +1,5 @@ +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno ./mod.ts $0" + } +} diff --git a/tests/deno_make_error.jsonc b/tests/deno_make_error.jsonc new file mode 100644 index 0000000..83dc0ea --- /dev/null +++ b/tests/deno_make_error.jsonc @@ -0,0 +1,8 @@ +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno ./mod.ts $0" + }, + "+tasks": { + "error": true + } +} diff --git a/tests/deno_permissions.jsonc b/tests/deno_permissions.jsonc new file mode 100644 index 0000000..a175b96 --- /dev/null +++ b/tests/deno_permissions.jsonc @@ -0,0 +1,108 @@ +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno ./mod.ts $0" + }, + "+tasks": { + "flags:all": { + "task": "deno run tests/mod.ts", + "deno": { + "run": { + "permissions": { + "allow": true, + "prompt": true + } + }, + "test": { + "permissions": { + "allow": false + } + } + } + }, + "flags:booleans": { + "task": "deno run tests/mod.ts", + "deno": { + "run": { + "permissions": { + "read": true, + "write": true, + "net": true, + "env": true, + "sys": true, + "run": true, + "ffi": true, + "hrtime": true, + "prompt": true + } + }, + "test": { + "permissions": { + "read": false, + "write": false, + "net": false, + "env": false, + "sys": false, + "run": false, + "ffi": false, + "hrtime": false, + "prompt": false + } + } + } + }, + "flags:paths": { + "task": "deno run tests/mod.ts", + "deno": { + "run": { + "permissions": { + "read": ["test"], + "write": ["test"], + "net": ["https://example.com"], + "env": ["FOO"], + "sys": ["osRelease"], + "run": ["deno"], + "ffi": ["test"] + } + }, + "test": { + "permissions": { + "read": [], + "write": [], + "net": [], + "env": [], + "sys": [], + "run": [], + "ffi": [] + } + } + } + }, + "flags:allow_deny": { + "task": "deno run tests/mod.ts", + "deno": { + "run": { + "permissions": { + "read": { "allow": ["test"], "deny": ["test"] }, + "write": { "allow": ["test"], "deny": ["test"] }, + "net": { "allow": ["https://example.com"], "deny": ["https://example.com"] }, + "env": { "allow": ["FOO"], "deny": ["FOO"] }, + "sys": { "allow": ["osRelease"], "deny": ["osRelease"] }, + "run": { "allow": ["deno"], "deny": ["deno"] }, + "ffi": { "allow": ["test"], "deny": ["test"] } + } + }, + "test": { + "permissions": { + "read": { "allow": [], "deny": [] }, + "write": { "allow": [], "deny": [] }, + "net": { "allow": [], "deny": [] }, + "env": { "allow": [], "deny": [] }, + "sys": { "allow": [], "deny": [] }, + "run": { "allow": [], "deny": [] }, + "ffi": { "allow": [], "deny": [] } + } + } + } + } + } +} diff --git a/tests/deno_run.jsonc b/tests/deno_run.jsonc new file mode 100644 index 0000000..d0cd378 --- /dev/null +++ b/tests/deno_run.jsonc @@ -0,0 +1,63 @@ +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno ./mod.ts $0" + }, + "+tasks": { + "flags:none": { + "task": "deno run tests/mod.ts" + }, + "flags:ext": { + "task": "deno run tests/mod.ts", + "deno": { + "run": { + "ext": "ts" + } + } + }, + "flags:lock_1": { + "task": "deno run tests/mod.ts", + "deno": { + "run": { + "lock": true + } + } + }, + "flags:lock_2": { + "task": "deno run tests/mod.ts", + "deno": { + "run": { + "lock": false + } + } + }, + "flags:lock_3": { + "task": "deno run tests/mod.ts", + "deno": { + "run": { + "lock": { + "write": false + } + } + } + }, + "flags:lock_4": { + "task": "deno run tests/mod.ts", + "deno": { + "run": { + "lock": { + "file": "tests/.deno.lock", + "write": true + } + } + } + }, + "flags:lock_5": { + "task": "deno run tests/mod.ts", + "deno": { + "run": { + "lock": "deno.lock" + } + } + } + } +} diff --git a/tests/deno_test.jsonc b/tests/deno_test.jsonc new file mode 100644 index 0000000..97185f5 --- /dev/null +++ b/tests/deno_test.jsonc @@ -0,0 +1,87 @@ +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno ./mod.ts $0" + }, + "+tasks": { + "flags:none": { + "task": "deno test tests/mod_test.ts" + }, + "flags:doc": { + "task": "deno test tests/mod_test.ts", + "deno": { + "test": { + "doc": true + } + } + }, + "flags:execution_1": { + "task": "deno test tests/mod_test.ts", + "deno": { + "test": { + "traceOps": true, + "failFast": true, + "shuffle": true, + "parallel": true, + "run": true, + "allowNone": true + } + } + }, + "flags:execution_2": { + "task": "deno test tests/mod_test.ts", + "deno": { + "test": { + "traceOps": false, + "failFast": false, + "shuffle": false, + "parallel": false, + "run": false, + "allowNone": false + } + } + }, + "flags:execution_number": { + "task": "deno test tests/mod_test.ts", + "deno": { + "test": { + "failFast": 1, + "shuffle": 1 + } + } + }, + "flags:reporter": { + "task": "deno test tests/mod_test.ts", + "deno": { + "test": { + "coverage": "tests/.coverage", + "reporter": "junit", + "junitPath": "tests/.junit.xml" + } + } + }, + "flags:ignore_1": { + "task": "deno test tests/mod_test.ts", + "deno": { + "test": { + "ignore": ["*_test.ts"] + } + } + }, + "flags:ignore_2": { + "task": "deno test tests/mod_test.ts", + "deno": { + "test": { + "ignore": [] + } + } + }, + "flags:filter": { + "task": "deno test tests/mod_test.ts", + "deno": { + "test": { + "filter": "dummy" + } + } + } + } +} diff --git a/tests/deno_types.jsonc b/tests/deno_types.jsonc new file mode 100644 index 0000000..0f338f6 --- /dev/null +++ b/tests/deno_types.jsonc @@ -0,0 +1,10 @@ +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno ./mod.ts $0" + }, + "+tasks": { + "flags:none": { + "task": "deno types" + } + } +} diff --git a/tests/deno_vendor.jsonc b/tests/deno_vendor.jsonc new file mode 100644 index 0000000..c1f559b --- /dev/null +++ b/tests/deno_vendor.jsonc @@ -0,0 +1,47 @@ +{ + "tasks": { + "make": "deno run --allow-env --allow-read --allow-write=.deno-make.json --allow-run=deno ./mod.ts $0" + }, + "+tasks": { + "flags:none": { + "task": "deno vendor 'data:application/typescript;base64,Y29uc29sZS5sb2coJ2Zvbycp'" + }, + "flags:output_1": { + "task": "deno run 'data:application/typescript;base64,Y29uc29sZS5sb2coJ2Zvbycp'", + "deno": { + "vendor": { + "output": "vendor" + } + } + }, + "flags:output_2": { + "task": "deno run 'data:application/typescript;base64,Y29uc29sZS5sb2coJ2Zvbycp'", + "deno": { + "vendor": { + "output": { + "path": "vendor", + "force:": true + } + } + } + }, + "flags:output_3": { + "task": "deno run 'data:application/typescript;base64,Y29uc29sZS5sb2coJ2Zvbycp'", + "deno": { + "vendor": { + "output": { + "force:": false + } + } + } + }, + "flags:lock": { + "task": "deno run 'data:application/typescript;base64,Y29uc29sZS5sb2coJ2Zvbycp'", + "deno": { + "vendor": { + "lock": "deno.lock" + } + } + } + } +} diff --git a/tests/mod.ts b/tests/mod.ts new file mode 100644 index 0000000..b44668f --- /dev/null +++ b/tests/mod.ts @@ -0,0 +1 @@ +console.log("baguette") diff --git a/tests/mod_test.ts b/tests/mod_test.ts new file mode 100644 index 0000000..a953c85 --- /dev/null +++ b/tests/mod_test.ts @@ -0,0 +1 @@ +Deno.test("dummy test", () => void null)