From 82c932ff6147853f67c4a35c3492708ee5075916 Mon Sep 17 00:00:00 2001 From: Mike Pham Date: Sun, 23 Jun 2019 12:47:12 -0400 Subject: [PATCH 1/7] chore: citools update --- .citools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.citools b/.citools index 7a5388e..fcbd341 160000 --- a/.citools +++ b/.citools @@ -1 +1 @@ -Subproject commit 7a5388ebc168d7919274134d3f41c53920b16f42 +Subproject commit fcbd34190e58622ff9d82b4c57420aa552a7518c From 4cd3f1b65af9c366ef772453041ceeddc33eb54c Mon Sep 17 00:00:00 2001 From: Mike Pham Date: Sun, 23 Jun 2019 18:41:50 -0400 Subject: [PATCH 2/7] wip: saving progress --- binaries/clam/.npmignore | 14 + binaries/clam/LICENSE | 16 + binaries/clam/README.md | 19 + binaries/clam/package-lock.json | 538 ++++++++++++++++++++ binaries/clam/package.json | 44 ++ binaries/clam/src/ConfigLoader.ts | 13 + binaries/clam/src/Loader.ts | 27 + binaries/clam/src/clam-config.json | 6 + binaries/clam/src/clam-plugins.json | 14 + binaries/clam/src/clam.ts | 70 +++ binaries/clam/src/commands/info/cpu.ts | 16 + binaries/clam/src/commands/info/disks.ts | 16 + binaries/clam/src/commands/info/os.ts | 16 + binaries/clam/src/models/Config.ts | 3 + binaries/clam/src/models/Manifest.ts | 6 + binaries/clam/src/models/ManifestCommand.ts | 6 + binaries/clam/src/plugins/Plugin.ts | 20 + binaries/clam/src/plugins/PluginLoader.ts | 18 + binaries/clam/tasks.json | 18 + binaries/clam/tsconfig.json | 17 + 20 files changed, 897 insertions(+) create mode 100644 binaries/clam/.npmignore create mode 100644 binaries/clam/LICENSE create mode 100644 binaries/clam/README.md create mode 100644 binaries/clam/package-lock.json create mode 100644 binaries/clam/package.json create mode 100644 binaries/clam/src/ConfigLoader.ts create mode 100644 binaries/clam/src/Loader.ts create mode 100644 binaries/clam/src/clam-config.json create mode 100644 binaries/clam/src/clam-plugins.json create mode 100644 binaries/clam/src/clam.ts create mode 100644 binaries/clam/src/commands/info/cpu.ts create mode 100644 binaries/clam/src/commands/info/disks.ts create mode 100644 binaries/clam/src/commands/info/os.ts create mode 100644 binaries/clam/src/models/Config.ts create mode 100644 binaries/clam/src/models/Manifest.ts create mode 100644 binaries/clam/src/models/ManifestCommand.ts create mode 100644 binaries/clam/src/plugins/Plugin.ts create mode 100644 binaries/clam/src/plugins/PluginLoader.ts create mode 100644 binaries/clam/tasks.json create mode 100644 binaries/clam/tsconfig.json diff --git a/binaries/clam/.npmignore b/binaries/clam/.npmignore new file mode 100644 index 0000000..563a299 --- /dev/null +++ b/binaries/clam/.npmignore @@ -0,0 +1,14 @@ +.cache +artifacts/ +node_modules/ +specs/ +src/ + +mocha.opts +tasks.json +tsconfig.json + +*.map +*.log +*.tgz +*.tsbuildinfo diff --git a/binaries/clam/LICENSE b/binaries/clam/LICENSE new file mode 100644 index 0000000..c209506 --- /dev/null +++ b/binaries/clam/LICENSE @@ -0,0 +1,16 @@ +Copyright 2018 NativeCode Development + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software +and associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/binaries/clam/README.md b/binaries/clam/README.md new file mode 100644 index 0000000..bd498f3 --- /dev/null +++ b/binaries/clam/README.md @@ -0,0 +1,19 @@ +# @nativecode/clam + +# License +Copyright 2018 NativeCode Development + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without +limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the +Software, and to permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/binaries/clam/package-lock.json b/binaries/clam/package-lock.json new file mode 100644 index 0000000..5bc0045 --- /dev/null +++ b/binaries/clam/package-lock.json @@ -0,0 +1,538 @@ +{ + "name": "@nativecode/clam", + "version": "0.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@nofrills/collections": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@nofrills/collections/-/collections-4.0.1.tgz", + "integrity": "sha512-kY9l4BmAWGEWe38qHNJ6+u00icnhldhrTcXkfQLhjvDQYkYmzX+DEXhRZEVUD4PRrvYByHgDIvPEaUKTeTnoZA==" + }, + "@nofrills/fs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@nofrills/fs/-/fs-4.0.1.tgz", + "integrity": "sha512-P/PMQmPkgLAhcJbdLEarMEy2POuyDIyz3H/PssSBzpG+ontAdiZa91SMfBW0oidNokI1BfCLD0AxsGeXPgCmJw==", + "requires": { + "@nofrills/lincoln-debug": "^4.0.1", + "glob": "^7.1.2", + "mkdirp": "^0.5.1", + "rxjs": "^6.3.3" + } + }, + "@nofrills/lincoln": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@nofrills/lincoln/-/lincoln-4.0.1.tgz", + "integrity": "sha512-dCPLoWfRdCweuYn1NqysA1o/FpztgG816bQgPi0WqcuvHtte2vrPS2scgnJK7RXpiNq4UPnNVyCKZndrH1cI0w==", + "requires": { + "@nofrills/collections": "^4.0.1", + "uuidjs": "^4.0.3" + } + }, + "@nofrills/lincoln-debug": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@nofrills/lincoln-debug/-/lincoln-debug-4.0.1.tgz", + "integrity": "sha512-OI/bkiSoo/d3/1R9OPp5KH6b0bZxwy9oNfY/GemvbwinFLAUNL9OUXdFDw8wF5uTSQriIc92laJfuIZYJy3DoQ==", + "requires": { + "@nofrills/collections": "^4.0.1", + "debug": "^4.1.0" + } + }, + "@types/yargs": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.0.tgz", + "integrity": "sha512-hY0o+kcz9M6kH32NUeb6VURghqMuCVkiUx+8Btsqhj4Hhov/hVGUx9DmBJeIkzlp1uAQK4wngQBCjqWdUUkFyA==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-13.0.0.tgz", + "integrity": "sha512-wBlsw+8n21e6eTd4yVv8YD/E3xq0O6nNnJIquutAsFGE7EyMKz7W6RNT6BRu1SmdgmlCZ9tb0X+j+D6HGr8pZw==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "requires": { + "once": "^1.4.0" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "requires": { + "invert-kv": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "requires": { + "p-defer": "^1.0.0" + } + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "^2.0.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==" + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "rxjs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "requires": { + "tslib": "^1.9.0" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + }, + "uuidjs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/uuidjs/-/uuidjs-4.2.3.tgz", + "integrity": "sha512-heQNgAyxYUWRfDbSfxMznmW4XyJg1LvFLFDs1cXStU++h3uibXYuDS8bO1j39xvkZrnIH0+68VjTE1rdT/Uipg==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yargs": { + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", + "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.0" + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/binaries/clam/package.json b/binaries/clam/package.json new file mode 100644 index 0000000..980a471 --- /dev/null +++ b/binaries/clam/package.json @@ -0,0 +1,44 @@ +{ + "author": "opensource@nativecode.com", + "description": "Clam CLI", + "homepage": "https://github.com/nativecode-dev/cli-tools", + "license": "MIT", + "main": "./bin/clam.js", + "name": "@nativecode/clam", + "private": false, + "types": "./bin/clam.d.ts", + "version": "0.0.0", + "bin": { + "clam": "./bin/clam.js" + }, + "bugs": { + "url": "https://github.com/nativecode-dev/cli-tools/issues" + }, + "dependencies": { + "@nofrills/fs": "^4.0.1", + "@nofrills/lincoln": "^4.0.1", + "yargs": "^13.2.4" + }, + "directories": { + "lib": "bin", + "test": "specs" + }, + "files": [ + "bin" + ], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/nativecode-dev/cli-tools.git" + }, + "scripts": { + "build": "ts-node ../tasks/src/cli-tasks build", + "exec": "ts-node src/clam", + "upgrade": "npm-check -y" + }, + "devDependencies": { + "@types/yargs": "^13.0.0" + } +} diff --git a/binaries/clam/src/ConfigLoader.ts b/binaries/clam/src/ConfigLoader.ts new file mode 100644 index 0000000..05743a1 --- /dev/null +++ b/binaries/clam/src/ConfigLoader.ts @@ -0,0 +1,13 @@ +import { Loader } from './Loader' +import { Config } from './models/Config' + +export class ConfigLoader extends Loader { + constructor(filepaths: string[]) { + super('clam-config.json', filepaths) + } + + async configurations(): Promise { + const configs = await super.load() + return configs.map(config => config.json) + } +} diff --git a/binaries/clam/src/Loader.ts b/binaries/clam/src/Loader.ts new file mode 100644 index 0000000..ecf66f9 --- /dev/null +++ b/binaries/clam/src/Loader.ts @@ -0,0 +1,27 @@ +import { CreateResolver, FileResolver, fs } from '@nofrills/fs' + +export interface LoaderMap { + cwd: string + json: T +} + +export abstract class Loader { + protected readonly resolvers: FileResolver[] + + constructor(private readonly loadfile: string, private readonly filepaths: string[]) { + this.resolvers = this.filepaths.map(filepath => CreateResolver(filepath)) + } + + protected async load(): Promise[]> { + const resolved = await Promise.all(this.resolvers.map(resolver => resolver.find(this.loadfile))) + const filenames = resolved.reduce((files, current) => files.concat(current), []) + + return Promise.all( + filenames.map(async filename => { + const cwd = fs.dirname(filename) + const json = await fs.json(filename) + return { cwd, json } + }), + ) + } +} diff --git a/binaries/clam/src/clam-config.json b/binaries/clam/src/clam-config.json new file mode 100644 index 0000000..34b08b1 --- /dev/null +++ b/binaries/clam/src/clam-config.json @@ -0,0 +1,6 @@ +{ + "plugins": [ + "${PWD}", + "${HOME}/.clam" + ] +} diff --git a/binaries/clam/src/clam-plugins.json b/binaries/clam/src/clam-plugins.json new file mode 100644 index 0000000..c6cb2cb --- /dev/null +++ b/binaries/clam/src/clam-plugins.json @@ -0,0 +1,14 @@ +{ + "plugins": [ + { + "command": "info", + "description": "displays system information", + "files": [ + "commands/info/cpu", + "commands/info/disks", + "commands/info/os" + ], + "name": "info" + } + ] +} diff --git a/binaries/clam/src/clam.ts b/binaries/clam/src/clam.ts new file mode 100644 index 0000000..bf45faf --- /dev/null +++ b/binaries/clam/src/clam.ts @@ -0,0 +1,70 @@ +import yargs, { Argv } from 'yargs' + +import { fs } from '@nofrills/fs' +import { EventEmitter } from 'events' + +import { ConfigLoader } from './ConfigLoader' +import { PluginLoader } from './plugins/PluginLoader' + +import { Config } from './models/Config' + +const regex = new RegExp(/\$\{?([A-Za-z,0-9,_]+)\}?/g) + +export class Clam extends EventEmitter { + private readonly regex = new RegExp(/\$\{?[A-Za-z,0-9,_]+\}?\/?/g) + + constructor(private readonly booty: yargs.Argv<{}>) { + super() + } + + initialize(): Promise { + return Promise.resolve() + } + + async load(): Promise> { + const configs = await this.configs() + const loaders = await this.plugins(configs) + const manifests = await Promise.all(loaders.map(loader => loader.manifests())) + const plugins = manifests.reduce((result, current) => result.concat(current), []) + return plugins.reduce((result, plugin) => plugin.create(result), this.booty) + } + + protected async configs(): Promise { + const loader = new ConfigLoader([__dirname, process.cwd()]) + const configs = await loader.configurations() + return configs + } + + protected environment(value: string): string { + const replacement = value.replace(regex, (_, part) => { + return process.env[part] || '' + }) + return replacement + } + + protected async plugins(configs: Config[]): Promise { + const directories = [ + __dirname, + ...configs + .map(config => config.plugins) + .reduce((result, current) => result.concat(current), []) + .map(directory => this.environment(directory)) + .map(directory => fs.resolve(directory)), + ] + + const dirmap = await Promise.all( + directories.map(async directory => ({ directory, exists: await fs.exists(directory) })), + ) + + return dirmap.filter(dir => dir.exists).map(dir => new PluginLoader(dir.directory)) + } +} + +async function main() { + const clam = new Clam(yargs) + const booty = await clam.load() + + console.log(booty.help().argv) +} + +main().catch(console.error) diff --git a/binaries/clam/src/commands/info/cpu.ts b/binaries/clam/src/commands/info/cpu.ts new file mode 100644 index 0000000..e57b570 --- /dev/null +++ b/binaries/clam/src/commands/info/cpu.ts @@ -0,0 +1,16 @@ +import { Arguments, CommandModule } from 'yargs' + +export interface CpuOptions {} + +class CpuCommand implements CommandModule<{}, CpuOptions> { + readonly aliases = [] + readonly builder = {} + readonly command = 'os' + readonly describe = 'shows operating system information' + + handler = (args: Arguments): void => { + return + } +} + +export default new CpuCommand() diff --git a/binaries/clam/src/commands/info/disks.ts b/binaries/clam/src/commands/info/disks.ts new file mode 100644 index 0000000..e9c8342 --- /dev/null +++ b/binaries/clam/src/commands/info/disks.ts @@ -0,0 +1,16 @@ +import { Arguments, CommandModule } from 'yargs' + +export interface DiskOptions {} + +class DisksCommand implements CommandModule<{}, DiskOptions> { + readonly aliases = [] + readonly builder = {} + readonly command = 'os' + readonly describe = 'shows operating system information' + + handler = (args: Arguments): void => { + return + } +} + +export default new DisksCommand() diff --git a/binaries/clam/src/commands/info/os.ts b/binaries/clam/src/commands/info/os.ts new file mode 100644 index 0000000..06aec4c --- /dev/null +++ b/binaries/clam/src/commands/info/os.ts @@ -0,0 +1,16 @@ +import { Arguments, CommandModule } from 'yargs' + +export interface OsOptions {} + +class OsCommand implements CommandModule<{}, OsOptions> { + readonly aliases = [] + readonly builder = {} + readonly command = 'os' + readonly describe = 'shows operating system information' + + handler = (args: Arguments): void => { + return + } +} + +export default new OsCommand() diff --git a/binaries/clam/src/models/Config.ts b/binaries/clam/src/models/Config.ts new file mode 100644 index 0000000..d3cef0a --- /dev/null +++ b/binaries/clam/src/models/Config.ts @@ -0,0 +1,3 @@ +export interface Config { + plugins: string[] +} diff --git a/binaries/clam/src/models/Manifest.ts b/binaries/clam/src/models/Manifest.ts new file mode 100644 index 0000000..e54d7d1 --- /dev/null +++ b/binaries/clam/src/models/Manifest.ts @@ -0,0 +1,6 @@ +import { ManifestCommand } from './ManifestCommand' + +export interface Manifest { + cwd: string + commands: ManifestCommand[] +} diff --git a/binaries/clam/src/models/ManifestCommand.ts b/binaries/clam/src/models/ManifestCommand.ts new file mode 100644 index 0000000..246fb91 --- /dev/null +++ b/binaries/clam/src/models/ManifestCommand.ts @@ -0,0 +1,6 @@ +export interface ManifestCommand { + command: string + description: string + files: string[] + name: string +} diff --git a/binaries/clam/src/plugins/Plugin.ts b/binaries/clam/src/plugins/Plugin.ts new file mode 100644 index 0000000..dd99649 --- /dev/null +++ b/binaries/clam/src/plugins/Plugin.ts @@ -0,0 +1,20 @@ +import { Argv } from 'yargs' +import { Manifest } from '../models/Manifest' + +export class Plugin { + constructor(private readonly manifest: Manifest) {} + + get commands(): string[] { + return this.manifest.commands.map(command => command.name) + } + + get cwd(): string { + return this.manifest.cwd + } + + create(args: Argv<{}>): Argv<{}> { + return this.manifest.commands.reduce((yargs, command) => { + return command.files.reduce((_, file) => _.command(require(file)), yargs) + }, args) + } +} diff --git a/binaries/clam/src/plugins/PluginLoader.ts b/binaries/clam/src/plugins/PluginLoader.ts new file mode 100644 index 0000000..1d9018d --- /dev/null +++ b/binaries/clam/src/plugins/PluginLoader.ts @@ -0,0 +1,18 @@ +import { Loader } from '../Loader' +import { Plugin } from './Plugin' + +import { Manifest } from '../models/Manifest' + +export class PluginLoader extends Loader { + constructor(filepath: string) { + super('clam-plugins.json', [filepath]) + } + + async manifests(): Promise { + const manifests = await super.load() + + return manifests.map(manifest => { + return new Plugin(manifest.json) + }) + } +} diff --git a/binaries/clam/tasks.json b/binaries/clam/tasks.json new file mode 100644 index 0000000..c6e4021 --- /dev/null +++ b/binaries/clam/tasks.json @@ -0,0 +1,18 @@ +{ + "tasks": { + "build": [ + "[build:compile]", + "[shebang]" + ], + "build:compile": [ + "tsc --project tsconfig.json" + ], + "clean": [ + "rimraf bin", + "rimraf *.tsbuildinfo" + ], + "shebang": [ + "ts-node ../tasks/src/cli-shebang" + ] + } +} diff --git a/binaries/clam/tsconfig.json b/binaries/clam/tsconfig.json new file mode 100644 index 0000000..47b7727 --- /dev/null +++ b/binaries/clam/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tsconfig.settings", + "compilerOptions": { + "rootDir": "src", + "outDir": "bin", + "lib": [ + "es2018" + ] + }, + "exclude": [ + "node_modules", + "specs" + ], + "include": [ + "src/**/*.ts" + ] +} From 9d42116d12b82f26543202be81724b4f5ac84df3 Mon Sep 17 00:00:00 2001 From: Mike Pham Date: Sun, 23 Jun 2019 21:52:55 -0400 Subject: [PATCH 3/7] feat: expanding plugin support --- binaries/clam/src/Logging.ts | 5 +++ binaries/clam/src/clam-plugins.json | 2 +- binaries/clam/src/clam.ts | 37 +++++++++++++------ .../clam/src/{models => config}/Config.ts | 0 .../clam/src/{ => config}/ConfigLoader.ts | 4 +- .../clam/src/{models => plugins}/Manifest.ts | 1 - .../{models => plugins}/ManifestCommand.ts | 0 binaries/clam/src/plugins/Plugin.ts | 29 +++++++++++---- binaries/clam/src/plugins/PluginLoader.ts | 4 +- clam | 5 +++ 10 files changed, 61 insertions(+), 26 deletions(-) create mode 100644 binaries/clam/src/Logging.ts rename binaries/clam/src/{models => config}/Config.ts (100%) rename binaries/clam/src/{ => config}/ConfigLoader.ts (78%) rename binaries/clam/src/{models => plugins}/Manifest.ts (88%) rename binaries/clam/src/{models => plugins}/ManifestCommand.ts (100%) create mode 100755 clam diff --git a/binaries/clam/src/Logging.ts b/binaries/clam/src/Logging.ts new file mode 100644 index 0000000..2c92f21 --- /dev/null +++ b/binaries/clam/src/Logging.ts @@ -0,0 +1,5 @@ +import { CreateLogger } from '@nofrills/lincoln-debug' + +const Logger = CreateLogger('nativecode:clam') + +export default Logger diff --git a/binaries/clam/src/clam-plugins.json b/binaries/clam/src/clam-plugins.json index c6cb2cb..f061f95 100644 --- a/binaries/clam/src/clam-plugins.json +++ b/binaries/clam/src/clam-plugins.json @@ -1,5 +1,5 @@ { - "plugins": [ + "commands": [ { "command": "info", "description": "displays system information", diff --git a/binaries/clam/src/clam.ts b/binaries/clam/src/clam.ts index bf45faf..e23c8ed 100644 --- a/binaries/clam/src/clam.ts +++ b/binaries/clam/src/clam.ts @@ -3,30 +3,30 @@ import yargs, { Argv } from 'yargs' import { fs } from '@nofrills/fs' import { EventEmitter } from 'events' -import { ConfigLoader } from './ConfigLoader' +import Logger from './Logging' + +import { ConfigLoader } from './config/ConfigLoader' import { PluginLoader } from './plugins/PluginLoader' -import { Config } from './models/Config' +import { Config } from './config/Config' const regex = new RegExp(/\$\{?([A-Za-z,0-9,_]+)\}?/g) export class Clam extends EventEmitter { + private readonly log = Logger + private readonly regex = new RegExp(/\$\{?[A-Za-z,0-9,_]+\}?\/?/g) - constructor(private readonly booty: yargs.Argv<{}>) { + constructor(private readonly yargs: Argv<{}>) { super() } - initialize(): Promise { - return Promise.resolve() - } - - async load(): Promise> { + async initialize(): Promise> { const configs = await this.configs() const loaders = await this.plugins(configs) const manifests = await Promise.all(loaders.map(loader => loader.manifests())) const plugins = manifests.reduce((result, current) => result.concat(current), []) - return plugins.reduce((result, plugin) => plugin.create(result), this.booty) + return plugins.reduce(async (result, plugin) => plugin.create(await result), Promise.resolve(this.yargs)) } protected async configs(): Promise { @@ -61,10 +61,23 @@ export class Clam extends EventEmitter { } async function main() { - const clam = new Clam(yargs) - const booty = await clam.load() + const booty = yargs + .option('config', { + alias: 'c', + default: null, + string: true, + }) + .option('cwd', { + default: process.cwd(), + string: true, + }) + .help() + .showHelpOnFail(false) + .scriptName(fs.basename(__filename, false)) - console.log(booty.help().argv) + const clam = new Clam(booty) + const final = await clam.initialize() + final.parse() } main().catch(console.error) diff --git a/binaries/clam/src/models/Config.ts b/binaries/clam/src/config/Config.ts similarity index 100% rename from binaries/clam/src/models/Config.ts rename to binaries/clam/src/config/Config.ts diff --git a/binaries/clam/src/ConfigLoader.ts b/binaries/clam/src/config/ConfigLoader.ts similarity index 78% rename from binaries/clam/src/ConfigLoader.ts rename to binaries/clam/src/config/ConfigLoader.ts index 05743a1..af2331f 100644 --- a/binaries/clam/src/ConfigLoader.ts +++ b/binaries/clam/src/config/ConfigLoader.ts @@ -1,5 +1,5 @@ -import { Loader } from './Loader' -import { Config } from './models/Config' +import { Loader } from '../Loader' +import { Config } from './Config' export class ConfigLoader extends Loader { constructor(filepaths: string[]) { diff --git a/binaries/clam/src/models/Manifest.ts b/binaries/clam/src/plugins/Manifest.ts similarity index 88% rename from binaries/clam/src/models/Manifest.ts rename to binaries/clam/src/plugins/Manifest.ts index e54d7d1..206ac8b 100644 --- a/binaries/clam/src/models/Manifest.ts +++ b/binaries/clam/src/plugins/Manifest.ts @@ -1,6 +1,5 @@ import { ManifestCommand } from './ManifestCommand' export interface Manifest { - cwd: string commands: ManifestCommand[] } diff --git a/binaries/clam/src/models/ManifestCommand.ts b/binaries/clam/src/plugins/ManifestCommand.ts similarity index 100% rename from binaries/clam/src/models/ManifestCommand.ts rename to binaries/clam/src/plugins/ManifestCommand.ts diff --git a/binaries/clam/src/plugins/Plugin.ts b/binaries/clam/src/plugins/Plugin.ts index dd99649..3b6996c 100644 --- a/binaries/clam/src/plugins/Plugin.ts +++ b/binaries/clam/src/plugins/Plugin.ts @@ -1,20 +1,33 @@ import { Argv } from 'yargs' -import { Manifest } from '../models/Manifest' + +import Logger from '../Logging' + +import { Manifest } from './Manifest' +import { fs } from '@nofrills/fs' +import { ManifestCommand } from './ManifestCommand' export class Plugin { - constructor(private readonly manifest: Manifest) {} + private readonly log = Logger.extend('plugin') + + constructor(public readonly cwd: string, private readonly manifest: Manifest) { + this.log.trace(':constructor', manifest) + } get commands(): string[] { return this.manifest.commands.map(command => command.name) } - get cwd(): string { - return this.manifest.cwd + create(args: Argv<{}>): Promise> { + return this.manifest.commands.reduce(async (yargs, command) => { + return command.files.reduce(async (inner, file) => { + return this.createCommand(await inner, file, command) + }, Promise.resolve(args.command(command.command, command.description))) + }, Promise.resolve(args)) } - create(args: Argv<{}>): Argv<{}> { - return this.manifest.commands.reduce((yargs, command) => { - return command.files.reduce((_, file) => _.command(require(file)), yargs) - }, args) + private async createCommand(yargs: Argv<{}>, file: string, command: ManifestCommand): Promise> { + const filepath = fs.join(this.cwd, file) + this.log.trace(':create-command', command.name, filepath) + return yargs.command(await import(filepath)) } } diff --git a/binaries/clam/src/plugins/PluginLoader.ts b/binaries/clam/src/plugins/PluginLoader.ts index 1d9018d..6f70518 100644 --- a/binaries/clam/src/plugins/PluginLoader.ts +++ b/binaries/clam/src/plugins/PluginLoader.ts @@ -1,7 +1,7 @@ import { Loader } from '../Loader' import { Plugin } from './Plugin' -import { Manifest } from '../models/Manifest' +import { Manifest } from './Manifest' export class PluginLoader extends Loader { constructor(filepath: string) { @@ -12,7 +12,7 @@ export class PluginLoader extends Loader { const manifests = await super.load() return manifests.map(manifest => { - return new Plugin(manifest.json) + return new Plugin(manifest.cwd, manifest.json) }) } } diff --git a/clam b/clam new file mode 100755 index 0000000..9cafa5c --- /dev/null +++ b/clam @@ -0,0 +1,5 @@ +#!/bin/bash + +PATH=./node_modules/.bin:${PATH} + +ts-node binaries/clam/src/clam.ts "$@" From 8d4b021f26b9cf92a37a12fc829baed695734004 Mon Sep 17 00:00:00 2001 From: Mike Pham Date: Thu, 27 Jun 2019 04:09:10 -0400 Subject: [PATCH 4/7] chore: adding engine requirements --- binaries/clam/package.json | 3 +++ binaries/env/package.json | 3 +++ binaries/ssh/package.json | 3 +++ binaries/tasks/package.json | 3 +++ 4 files changed, 12 insertions(+) diff --git a/binaries/clam/package.json b/binaries/clam/package.json index 980a471..a11553b 100644 --- a/binaries/clam/package.json +++ b/binaries/clam/package.json @@ -23,6 +23,9 @@ "lib": "bin", "test": "specs" }, + "engines": { + "node": ">=10.0.0" + }, "files": [ "bin" ], diff --git a/binaries/env/package.json b/binaries/env/package.json index bb6a058..1537e7d 100644 --- a/binaries/env/package.json +++ b/binaries/env/package.json @@ -34,6 +34,9 @@ "lib": "bin", "test": "specs" }, + "engines": { + "node": ">=10.0.0" + }, "files": [ "bin" ], diff --git a/binaries/ssh/package.json b/binaries/ssh/package.json index ffc7bba..5431575 100644 --- a/binaries/ssh/package.json +++ b/binaries/ssh/package.json @@ -33,6 +33,9 @@ "lib": "bin", "test": "specs" }, + "engines": { + "node": ">=10.0.0" + }, "files": [ "bin" ], diff --git a/binaries/tasks/package.json b/binaries/tasks/package.json index 3583d72..0f09f22 100644 --- a/binaries/tasks/package.json +++ b/binaries/tasks/package.json @@ -40,6 +40,9 @@ "lib": "bin", "test": "specs" }, + "engines": { + "node": ">=10.0.0" + }, "files": [ "bin" ], From d2533e01e22150fe1e084aa5bc4805aac9357193 Mon Sep 17 00:00:00 2001 From: Mike Pham Date: Thu, 27 Jun 2019 20:46:24 -0400 Subject: [PATCH 5/7] chore: package locks --- binaries/env/package-lock.json | 2 +- binaries/ssh/package-lock.json | 2 +- binaries/tasks/package-lock.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/binaries/env/package-lock.json b/binaries/env/package-lock.json index fc13c16..6284f52 100644 --- a/binaries/env/package-lock.json +++ b/binaries/env/package-lock.json @@ -1,6 +1,6 @@ { "name": "@nofrills/cli-env", - "version": "0.6.27", + "version": "0.6.30", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/binaries/ssh/package-lock.json b/binaries/ssh/package-lock.json index 2364d3f..a729161 100644 --- a/binaries/ssh/package-lock.json +++ b/binaries/ssh/package-lock.json @@ -1,6 +1,6 @@ { "name": "@nofrills/ssh", - "version": "1.0.11", + "version": "1.0.14", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/binaries/tasks/package-lock.json b/binaries/tasks/package-lock.json index 20350d7..b24c4fc 100644 --- a/binaries/tasks/package-lock.json +++ b/binaries/tasks/package-lock.json @@ -1,6 +1,6 @@ { "name": "@nofrills/tasks", - "version": "7.1.10", + "version": "7.1.13", "lockfileVersion": 1, "requires": true, "dependencies": { From 15b2b3675eea4b85992f6337ea22388015a49e6a Mon Sep 17 00:00:00 2001 From: Mike Pham Date: Thu, 27 Jun 2019 22:10:46 -0400 Subject: [PATCH 6/7] chore: wip --- binaries/clam/src/.clamrc.json | 8 +++++ binaries/clam/src/.pluginsrc.json | 10 ++++++ binaries/clam/src/clam-config.json | 6 ---- binaries/clam/src/clam-plugins.json | 14 --------- binaries/clam/src/clam.ts | 33 +++++--------------- binaries/clam/src/cli.ts | 19 +++++++++++ binaries/clam/src/commands/info/cpu.ts | 6 ++-- binaries/clam/src/commands/info/disks.ts | 6 ++-- binaries/clam/src/commands/info/os.ts | 2 +- binaries/clam/src/config/Config.ts | 6 +++- binaries/clam/src/config/ConfigLoader.ts | 2 +- binaries/clam/src/plugins/Manifest.ts | 7 +++-- binaries/clam/src/plugins/ManifestCommand.ts | 6 ---- binaries/clam/src/plugins/Plugin.ts | 22 ++++++------- binaries/clam/src/plugins/PluginLoader.ts | 2 +- 15 files changed, 72 insertions(+), 77 deletions(-) create mode 100644 binaries/clam/src/.clamrc.json create mode 100644 binaries/clam/src/.pluginsrc.json delete mode 100644 binaries/clam/src/clam-config.json delete mode 100644 binaries/clam/src/clam-plugins.json create mode 100644 binaries/clam/src/cli.ts delete mode 100644 binaries/clam/src/plugins/ManifestCommand.ts diff --git a/binaries/clam/src/.clamrc.json b/binaries/clam/src/.clamrc.json new file mode 100644 index 0000000..1a3d806 --- /dev/null +++ b/binaries/clam/src/.clamrc.json @@ -0,0 +1,8 @@ +{ + "locations": { + "plugins": [ + "${PWD}", + "${HOME}/.clam" + ] + } +} diff --git a/binaries/clam/src/.pluginsrc.json b/binaries/clam/src/.pluginsrc.json new file mode 100644 index 0000000..8260ef0 --- /dev/null +++ b/binaries/clam/src/.pluginsrc.json @@ -0,0 +1,10 @@ +{ + "description": "info plugins", + "files": [ + "commands/info/cpu", + "commands/info/disks", + "commands/info/os" + ], + "name": "info", + "version": "1.0" +} diff --git a/binaries/clam/src/clam-config.json b/binaries/clam/src/clam-config.json deleted file mode 100644 index 34b08b1..0000000 --- a/binaries/clam/src/clam-config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "plugins": [ - "${PWD}", - "${HOME}/.clam" - ] -} diff --git a/binaries/clam/src/clam-plugins.json b/binaries/clam/src/clam-plugins.json deleted file mode 100644 index f061f95..0000000 --- a/binaries/clam/src/clam-plugins.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "commands": [ - { - "command": "info", - "description": "displays system information", - "files": [ - "commands/info/cpu", - "commands/info/disks", - "commands/info/os" - ], - "name": "info" - } - ] -} diff --git a/binaries/clam/src/clam.ts b/binaries/clam/src/clam.ts index e23c8ed..f5bac69 100644 --- a/binaries/clam/src/clam.ts +++ b/binaries/clam/src/clam.ts @@ -1,4 +1,4 @@ -import yargs, { Argv } from 'yargs' +import { Argv } from 'yargs' import { fs } from '@nofrills/fs' import { EventEmitter } from 'events' @@ -8,6 +8,7 @@ import Logger from './Logging' import { ConfigLoader } from './config/ConfigLoader' import { PluginLoader } from './plugins/PluginLoader' +import cli from './cli' import { Config } from './config/Config' const regex = new RegExp(/\$\{?([A-Za-z,0-9,_]+)\}?/g) @@ -17,16 +18,12 @@ export class Clam extends EventEmitter { private readonly regex = new RegExp(/\$\{?[A-Za-z,0-9,_]+\}?\/?/g) - constructor(private readonly yargs: Argv<{}>) { - super() - } - - async initialize(): Promise> { + async initialize(yargs: Argv<{}>): Promise> { const configs = await this.configs() const loaders = await this.plugins(configs) const manifests = await Promise.all(loaders.map(loader => loader.manifests())) const plugins = manifests.reduce((result, current) => result.concat(current), []) - return plugins.reduce(async (result, plugin) => plugin.create(await result), Promise.resolve(this.yargs)) + return plugins.reduce(async (result, plugin) => plugin.create(await result), Promise.resolve(yargs)) } protected async configs(): Promise { @@ -46,7 +43,7 @@ export class Clam extends EventEmitter { const directories = [ __dirname, ...configs - .map(config => config.plugins) + .map(config => config.locations.plugins) .reduce((result, current) => result.concat(current), []) .map(directory => this.environment(directory)) .map(directory => fs.resolve(directory)), @@ -61,23 +58,9 @@ export class Clam extends EventEmitter { } async function main() { - const booty = yargs - .option('config', { - alias: 'c', - default: null, - string: true, - }) - .option('cwd', { - default: process.cwd(), - string: true, - }) - .help() - .showHelpOnFail(false) - .scriptName(fs.basename(__filename, false)) - - const clam = new Clam(booty) - const final = await clam.initialize() - final.parse() + const clam = new Clam() + const host = await clam.initialize(cli()) + return host.parse() } main().catch(console.error) diff --git a/binaries/clam/src/cli.ts b/binaries/clam/src/cli.ts new file mode 100644 index 0000000..ea518f1 --- /dev/null +++ b/binaries/clam/src/cli.ts @@ -0,0 +1,19 @@ +import yargs, { Argv } from 'yargs' + +import { fs } from '@nofrills/fs' + +export default function cli(): Argv<{}> { + return yargs + .option('config', { + alias: 'c', + default: null, + string: true, + }) + .option('cwd', { + default: process.cwd(), + string: true, + }) + .help() + .showHelpOnFail(false) + .scriptName(fs.basename(__filename, false)) +} diff --git a/binaries/clam/src/commands/info/cpu.ts b/binaries/clam/src/commands/info/cpu.ts index e57b570..0ab671e 100644 --- a/binaries/clam/src/commands/info/cpu.ts +++ b/binaries/clam/src/commands/info/cpu.ts @@ -5,11 +5,11 @@ export interface CpuOptions {} class CpuCommand implements CommandModule<{}, CpuOptions> { readonly aliases = [] readonly builder = {} - readonly command = 'os' - readonly describe = 'shows operating system information' + readonly command = 'cpu' + readonly describe = 'shows processor information' handler = (args: Arguments): void => { - return + console.log(':cpu', args) } } diff --git a/binaries/clam/src/commands/info/disks.ts b/binaries/clam/src/commands/info/disks.ts index e9c8342..31d7b51 100644 --- a/binaries/clam/src/commands/info/disks.ts +++ b/binaries/clam/src/commands/info/disks.ts @@ -5,11 +5,11 @@ export interface DiskOptions {} class DisksCommand implements CommandModule<{}, DiskOptions> { readonly aliases = [] readonly builder = {} - readonly command = 'os' - readonly describe = 'shows operating system information' + readonly command = 'disks' + readonly describe = 'shows device information' handler = (args: Arguments): void => { - return + console.log(':disks', args) } } diff --git a/binaries/clam/src/commands/info/os.ts b/binaries/clam/src/commands/info/os.ts index 06aec4c..40bfdd3 100644 --- a/binaries/clam/src/commands/info/os.ts +++ b/binaries/clam/src/commands/info/os.ts @@ -9,7 +9,7 @@ class OsCommand implements CommandModule<{}, OsOptions> { readonly describe = 'shows operating system information' handler = (args: Arguments): void => { - return + console.log(':os', args) } } diff --git a/binaries/clam/src/config/Config.ts b/binaries/clam/src/config/Config.ts index d3cef0a..f51f8a8 100644 --- a/binaries/clam/src/config/Config.ts +++ b/binaries/clam/src/config/Config.ts @@ -1,3 +1,7 @@ -export interface Config { +export interface ConfigPlugins { plugins: string[] } + +export interface Config { + locations: ConfigPlugins +} diff --git a/binaries/clam/src/config/ConfigLoader.ts b/binaries/clam/src/config/ConfigLoader.ts index af2331f..b82dcff 100644 --- a/binaries/clam/src/config/ConfigLoader.ts +++ b/binaries/clam/src/config/ConfigLoader.ts @@ -3,7 +3,7 @@ import { Config } from './Config' export class ConfigLoader extends Loader { constructor(filepaths: string[]) { - super('clam-config.json', filepaths) + super('.clamrc.json', filepaths) } async configurations(): Promise { diff --git a/binaries/clam/src/plugins/Manifest.ts b/binaries/clam/src/plugins/Manifest.ts index 206ac8b..0f6cc74 100644 --- a/binaries/clam/src/plugins/Manifest.ts +++ b/binaries/clam/src/plugins/Manifest.ts @@ -1,5 +1,6 @@ -import { ManifestCommand } from './ManifestCommand' - export interface Manifest { - commands: ManifestCommand[] + files: string[] + description?: string + name: string + version: string } diff --git a/binaries/clam/src/plugins/ManifestCommand.ts b/binaries/clam/src/plugins/ManifestCommand.ts deleted file mode 100644 index 246fb91..0000000 --- a/binaries/clam/src/plugins/ManifestCommand.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface ManifestCommand { - command: string - description: string - files: string[] - name: string -} diff --git a/binaries/clam/src/plugins/Plugin.ts b/binaries/clam/src/plugins/Plugin.ts index 3b6996c..c0ae3b6 100644 --- a/binaries/clam/src/plugins/Plugin.ts +++ b/binaries/clam/src/plugins/Plugin.ts @@ -4,7 +4,6 @@ import Logger from '../Logging' import { Manifest } from './Manifest' import { fs } from '@nofrills/fs' -import { ManifestCommand } from './ManifestCommand' export class Plugin { private readonly log = Logger.extend('plugin') @@ -13,21 +12,18 @@ export class Plugin { this.log.trace(':constructor', manifest) } - get commands(): string[] { - return this.manifest.commands.map(command => command.name) - } - create(args: Argv<{}>): Promise> { - return this.manifest.commands.reduce(async (yargs, command) => { - return command.files.reduce(async (inner, file) => { - return this.createCommand(await inner, file, command) - }, Promise.resolve(args.command(command.command, command.description))) + return this.manifest.files.reduce(async (inner, filename) => { + const yargs = await inner + return this.createCommand(yargs, filename) }, Promise.resolve(args)) } - private async createCommand(yargs: Argv<{}>, file: string, command: ManifestCommand): Promise> { - const filepath = fs.join(this.cwd, file) - this.log.trace(':create-command', command.name, filepath) - return yargs.command(await import(filepath)) + private async createCommand(yargs: Argv<{}>, filename: string): Promise> { + const filepath = fs.join(this.cwd, filename) + const command = (await require(filepath)).default + const path = fs.relative(process.cwd(), filepath) + this.log.trace(':create-command', this.manifest.name, path, command) + return yargs.command(command) } } diff --git a/binaries/clam/src/plugins/PluginLoader.ts b/binaries/clam/src/plugins/PluginLoader.ts index 6f70518..d941c30 100644 --- a/binaries/clam/src/plugins/PluginLoader.ts +++ b/binaries/clam/src/plugins/PluginLoader.ts @@ -5,7 +5,7 @@ import { Manifest } from './Manifest' export class PluginLoader extends Loader { constructor(filepath: string) { - super('clam-plugins.json', [filepath]) + super('.pluginsrc.json', [filepath]) } async manifests(): Promise { From c2d6d04b3cb0ef29dbcaccdbb7f5a2a5a7a03475 Mon Sep 17 00:00:00 2001 From: Mike Pham Date: Sun, 1 Sep 2019 13:08:29 -0400 Subject: [PATCH 7/7] chore(wip): --- binaries/clam/package-lock.json | 117 +++++++++++++++--- binaries/clam/package.json | 12 +- binaries/clam/src/.clamrc.json | 8 -- binaries/clam/src/.pluginsrc.json | 10 -- binaries/clam/src/ClamConfig.ts | 3 + binaries/clam/src/ClamOptions.ts | 28 +++++ binaries/clam/src/ClamShell.ts | 9 ++ binaries/clam/src/Loader.ts | 27 ---- binaries/clam/src/Logging.ts | 24 +++- binaries/clam/src/clam.ts | 77 ++++-------- binaries/clam/src/cli.ts | 19 --- binaries/clam/src/commands/info/cpu.ts | 16 --- binaries/clam/src/commands/info/disks.ts | 16 --- binaries/clam/src/commands/info/os.ts | 16 --- binaries/clam/src/config/Config.ts | 7 -- binaries/clam/src/config/ConfigLoader.ts | 13 -- .../clam/src/middleware/LoggingMiddleware.ts | 8 ++ binaries/clam/src/plugins/Manifest.ts | 6 - binaries/clam/src/plugins/Plugin.ts | 29 ----- binaries/clam/src/plugins/PluginLoader.ts | 18 --- 20 files changed, 205 insertions(+), 258 deletions(-) delete mode 100644 binaries/clam/src/.clamrc.json delete mode 100644 binaries/clam/src/.pluginsrc.json create mode 100644 binaries/clam/src/ClamConfig.ts create mode 100644 binaries/clam/src/ClamOptions.ts create mode 100644 binaries/clam/src/ClamShell.ts delete mode 100644 binaries/clam/src/Loader.ts delete mode 100644 binaries/clam/src/cli.ts delete mode 100644 binaries/clam/src/commands/info/cpu.ts delete mode 100644 binaries/clam/src/commands/info/disks.ts delete mode 100644 binaries/clam/src/commands/info/os.ts delete mode 100644 binaries/clam/src/config/Config.ts delete mode 100644 binaries/clam/src/config/ConfigLoader.ts create mode 100644 binaries/clam/src/middleware/LoggingMiddleware.ts delete mode 100644 binaries/clam/src/plugins/Manifest.ts delete mode 100644 binaries/clam/src/plugins/Plugin.ts delete mode 100644 binaries/clam/src/plugins/PluginLoader.ts diff --git a/binaries/clam/package-lock.json b/binaries/clam/package-lock.json index 5bc0045..df78ddd 100644 --- a/binaries/clam/package-lock.json +++ b/binaries/clam/package-lock.json @@ -29,6 +29,11 @@ "uuidjs": "^4.0.3" } }, + "@nofrills/lincoln-console": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@nofrills/lincoln-console/-/lincoln-console-4.0.7.tgz", + "integrity": "sha512-2xl20cB5BRhQ0k28fXNuFRob+xIkfc6XduWXM73zl1uC8KPqc1cqHpQ+M/iWATjvc8RCh2kCF1ZJoZGG3LO6Yw==" + }, "@nofrills/lincoln-debug": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@nofrills/lincoln-debug/-/lincoln-debug-4.0.1.tgz", @@ -38,6 +43,21 @@ "debug": "^4.1.0" } }, + "@types/deepmerge": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/deepmerge/-/deepmerge-2.2.0.tgz", + "integrity": "sha512-FEQYDHh6+Q+QXKSrIY46m+/lAmAj/bk4KpLaam+hArmzaVpMBHLcfwOH2Q2UOkWM7XsdY9PmZpGyPAjh/JRGhQ==", + "dev": true, + "requires": { + "deepmerge": "*" + } + }, + "@types/find-up": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/find-up/-/find-up-2.1.1.tgz", + "integrity": "sha512-60LC501bQRN9/3yfVaEEMd7IndaufffL56PBRAejPpUrY304Ps1jfnjNqPw5jmM5R8JHWiKBAe5IHzNcPV41AA==", + "dev": true + }, "@types/yargs": { "version": "13.0.0", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.0.tgz", @@ -85,6 +105,16 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -138,6 +168,11 @@ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, + "deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==" + }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", @@ -151,6 +186,11 @@ "once": "^1.4.0" } }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, "execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", @@ -166,11 +206,12 @@ } }, "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "requires": { - "locate-path": "^3.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, "fs.realpath": { @@ -204,6 +245,11 @@ "path-is-absolute": "^1.0.0" } }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -247,12 +293,11 @@ } }, "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" } }, "map-age-cleaner": { @@ -359,11 +404,11 @@ } }, "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "requires": { - "p-limit": "^2.0.0" + "p-limit": "^2.2.0" } }, "p-try": { @@ -372,9 +417,9 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "path-is-absolute": { "version": "1.0.1", @@ -464,6 +509,14 @@ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", @@ -523,6 +576,38 @@ "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^13.1.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + } } }, "yargs-parser": { diff --git a/binaries/clam/package.json b/binaries/clam/package.json index a11553b..b7fb342 100644 --- a/binaries/clam/package.json +++ b/binaries/clam/package.json @@ -17,8 +17,17 @@ "dependencies": { "@nofrills/fs": "^4.0.1", "@nofrills/lincoln": "^4.0.1", + "@nofrills/lincoln-console": "^4.0.7", + "chalk": "^2.4.2", + "deepmerge": "^3.3.0", + "find-up": "^4.1.0", "yargs": "^13.2.4" }, + "devDependencies": { + "@types/deepmerge": "^2.2.0", + "@types/find-up": "^2.1.1", + "@types/yargs": "^13.0.0" + }, "directories": { "lib": "bin", "test": "specs" @@ -40,8 +49,5 @@ "build": "ts-node ../tasks/src/cli-tasks build", "exec": "ts-node src/clam", "upgrade": "npm-check -y" - }, - "devDependencies": { - "@types/yargs": "^13.0.0" } } diff --git a/binaries/clam/src/.clamrc.json b/binaries/clam/src/.clamrc.json deleted file mode 100644 index 1a3d806..0000000 --- a/binaries/clam/src/.clamrc.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "locations": { - "plugins": [ - "${PWD}", - "${HOME}/.clam" - ] - } -} diff --git a/binaries/clam/src/.pluginsrc.json b/binaries/clam/src/.pluginsrc.json deleted file mode 100644 index 8260ef0..0000000 --- a/binaries/clam/src/.pluginsrc.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "description": "info plugins", - "files": [ - "commands/info/cpu", - "commands/info/disks", - "commands/info/os" - ], - "name": "info", - "version": "1.0" -} diff --git a/binaries/clam/src/ClamConfig.ts b/binaries/clam/src/ClamConfig.ts new file mode 100644 index 0000000..c3a42b8 --- /dev/null +++ b/binaries/clam/src/ClamConfig.ts @@ -0,0 +1,3 @@ +export interface ClamConfig { + plugins: string[] +} diff --git a/binaries/clam/src/ClamOptions.ts b/binaries/clam/src/ClamOptions.ts new file mode 100644 index 0000000..4e03ba8 --- /dev/null +++ b/binaries/clam/src/ClamOptions.ts @@ -0,0 +1,28 @@ +import { Argv } from 'yargs' +import { LogMessageType } from '@nofrills/lincoln' + +export interface ClamOptions { + cwd: string + logLevel: LogMessageType +} + +export default function ClamOptions(yargs: Argv): Argv { + return yargs + .option('cwd', { + describe: 'Set the current directory', + default: process.cwd(), + }) + .option('log-level', { + choices: [ + LogMessageType.debug, + LogMessageType.error, + LogMessageType.fatal, + LogMessageType.info, + LogMessageType.silly, + LogMessageType.trace, + LogMessageType.warn, + ], + describe: 'Set the logging level', + default: LogMessageType.warn, + }) +} diff --git a/binaries/clam/src/ClamShell.ts b/binaries/clam/src/ClamShell.ts new file mode 100644 index 0000000..ee0f108 --- /dev/null +++ b/binaries/clam/src/ClamShell.ts @@ -0,0 +1,9 @@ +import yargs, { Argv } from 'yargs' + +export default function ClamShell(): Argv<{}> { + return yargs + .env('CLAM_') + .help() + .showHelpOnFail(false) + .strict() +} diff --git a/binaries/clam/src/Loader.ts b/binaries/clam/src/Loader.ts deleted file mode 100644 index ecf66f9..0000000 --- a/binaries/clam/src/Loader.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { CreateResolver, FileResolver, fs } from '@nofrills/fs' - -export interface LoaderMap { - cwd: string - json: T -} - -export abstract class Loader { - protected readonly resolvers: FileResolver[] - - constructor(private readonly loadfile: string, private readonly filepaths: string[]) { - this.resolvers = this.filepaths.map(filepath => CreateResolver(filepath)) - } - - protected async load(): Promise[]> { - const resolved = await Promise.all(this.resolvers.map(resolver => resolver.find(this.loadfile))) - const filenames = resolved.reduce((files, current) => files.concat(current), []) - - return Promise.all( - filenames.map(async filename => { - const cwd = fs.dirname(filename) - const json = await fs.json(filename) - return { cwd, json } - }), - ) - } -} diff --git a/binaries/clam/src/Logging.ts b/binaries/clam/src/Logging.ts index 2c92f21..b8ae5ec 100644 --- a/binaries/clam/src/Logging.ts +++ b/binaries/clam/src/Logging.ts @@ -1,5 +1,25 @@ -import { CreateLogger } from '@nofrills/lincoln-debug' +import { Log, LogMessageType } from '@nofrills/lincoln' +import { CreateLogger, CreateOptions } from '@nofrills/lincoln-console' -const Logger = CreateLogger('nativecode:clam') +const options = CreateOptions('nativecode:clam') +const Logger = CreateLogger(options) + +const map: { [key: string]: number } = { none: 0 } + +map[LogMessageType.info] = 1 +map[LogMessageType.silly] = 2 +map[LogMessageType.debug] = 3 +map[LogMessageType.warn] = 4 +map[LogMessageType.error] = 5 +map[LogMessageType.fatal] = 6 +map[LogMessageType.trace] = 7 + +export function SetLogLevel(loglevel: LogMessageType): void { + options.filters.register('log-level', (log: Log) => { + const requested = map[loglevel] + const current = map[log.type] + return Promise.resolve(requested > current) + }) +} export default Logger diff --git a/binaries/clam/src/clam.ts b/binaries/clam/src/clam.ts index f5bac69..b9b6ab3 100644 --- a/binaries/clam/src/clam.ts +++ b/binaries/clam/src/clam.ts @@ -1,66 +1,39 @@ -import { Argv } from 'yargs' +import findup from 'find-up' +import deepmerge from 'deepmerge' +import { Argv } from 'yargs' import { fs } from '@nofrills/fs' -import { EventEmitter } from 'events' import Logger from './Logging' +import ClamShell from './ClamShell' -import { ConfigLoader } from './config/ConfigLoader' -import { PluginLoader } from './plugins/PluginLoader' - -import cli from './cli' -import { Config } from './config/Config' - -const regex = new RegExp(/\$\{?([A-Za-z,0-9,_]+)\}?/g) +import ClamOptions, { ClamOptions as Options } from './ClamOptions' +import { ClamConfig } from './ClamConfig' -export class Clam extends EventEmitter { - private readonly log = Logger - - private readonly regex = new RegExp(/\$\{?[A-Za-z,0-9,_]+\}?\/?/g) - - async initialize(yargs: Argv<{}>): Promise> { - const configs = await this.configs() - const loaders = await this.plugins(configs) - const manifests = await Promise.all(loaders.map(loader => loader.manifests())) - const plugins = manifests.reduce((result, current) => result.concat(current), []) - return plugins.reduce(async (result, plugin) => plugin.create(await result), Promise.resolve(yargs)) - } +import LoggingMiddleware from './middleware/LoggingMiddleware' - protected async configs(): Promise { - const loader = new ConfigLoader([__dirname, process.cwd()]) - const configs = await loader.configurations() - return configs - } - - protected environment(value: string): string { - const replacement = value.replace(regex, (_, part) => { - return process.env[part] || '' - }) - return replacement - } - - protected async plugins(configs: Config[]): Promise { - const directories = [ - __dirname, - ...configs - .map(config => config.locations.plugins) - .reduce((result, current) => result.concat(current), []) - .map(directory => this.environment(directory)) - .map(directory => fs.resolve(directory)), - ] - - const dirmap = await Promise.all( - directories.map(async directory => ({ directory, exists: await fs.exists(directory) })), - ) +const DefaultConfig: ClamConfig = { + plugins: [], +} - return dirmap.filter(dir => dir.exists).map(dir => new PluginLoader(dir.directory)) +async function configuration() { + const log = Logger.extend('configuration') + const filename = await findup(['.clamrc', '.clamrc.json']) + + if (filename) { + log.trace(':configuration', filename) + const json = await fs.json(filename) + const merged = deepmerge.all([DefaultConfig, json]) + return ClamShell().config(merged) + } else { + log.trace(':configuration', 'none') + return ClamShell().config(DefaultConfig) } } async function main() { - const clam = new Clam() - const host = await clam.initialize(cli()) - return host.parse() + const yargs = await configuration() + ClamOptions(LoggingMiddleware(yargs as Argv)).parse() } -main().catch(console.error) +main().catch(Logger.error) diff --git a/binaries/clam/src/cli.ts b/binaries/clam/src/cli.ts deleted file mode 100644 index ea518f1..0000000 --- a/binaries/clam/src/cli.ts +++ /dev/null @@ -1,19 +0,0 @@ -import yargs, { Argv } from 'yargs' - -import { fs } from '@nofrills/fs' - -export default function cli(): Argv<{}> { - return yargs - .option('config', { - alias: 'c', - default: null, - string: true, - }) - .option('cwd', { - default: process.cwd(), - string: true, - }) - .help() - .showHelpOnFail(false) - .scriptName(fs.basename(__filename, false)) -} diff --git a/binaries/clam/src/commands/info/cpu.ts b/binaries/clam/src/commands/info/cpu.ts deleted file mode 100644 index 0ab671e..0000000 --- a/binaries/clam/src/commands/info/cpu.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Arguments, CommandModule } from 'yargs' - -export interface CpuOptions {} - -class CpuCommand implements CommandModule<{}, CpuOptions> { - readonly aliases = [] - readonly builder = {} - readonly command = 'cpu' - readonly describe = 'shows processor information' - - handler = (args: Arguments): void => { - console.log(':cpu', args) - } -} - -export default new CpuCommand() diff --git a/binaries/clam/src/commands/info/disks.ts b/binaries/clam/src/commands/info/disks.ts deleted file mode 100644 index 31d7b51..0000000 --- a/binaries/clam/src/commands/info/disks.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Arguments, CommandModule } from 'yargs' - -export interface DiskOptions {} - -class DisksCommand implements CommandModule<{}, DiskOptions> { - readonly aliases = [] - readonly builder = {} - readonly command = 'disks' - readonly describe = 'shows device information' - - handler = (args: Arguments): void => { - console.log(':disks', args) - } -} - -export default new DisksCommand() diff --git a/binaries/clam/src/commands/info/os.ts b/binaries/clam/src/commands/info/os.ts deleted file mode 100644 index 40bfdd3..0000000 --- a/binaries/clam/src/commands/info/os.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Arguments, CommandModule } from 'yargs' - -export interface OsOptions {} - -class OsCommand implements CommandModule<{}, OsOptions> { - readonly aliases = [] - readonly builder = {} - readonly command = 'os' - readonly describe = 'shows operating system information' - - handler = (args: Arguments): void => { - console.log(':os', args) - } -} - -export default new OsCommand() diff --git a/binaries/clam/src/config/Config.ts b/binaries/clam/src/config/Config.ts deleted file mode 100644 index f51f8a8..0000000 --- a/binaries/clam/src/config/Config.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface ConfigPlugins { - plugins: string[] -} - -export interface Config { - locations: ConfigPlugins -} diff --git a/binaries/clam/src/config/ConfigLoader.ts b/binaries/clam/src/config/ConfigLoader.ts deleted file mode 100644 index b82dcff..0000000 --- a/binaries/clam/src/config/ConfigLoader.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Loader } from '../Loader' -import { Config } from './Config' - -export class ConfigLoader extends Loader { - constructor(filepaths: string[]) { - super('.clamrc.json', filepaths) - } - - async configurations(): Promise { - const configs = await super.load() - return configs.map(config => config.json) - } -} diff --git a/binaries/clam/src/middleware/LoggingMiddleware.ts b/binaries/clam/src/middleware/LoggingMiddleware.ts new file mode 100644 index 0000000..a33b52d --- /dev/null +++ b/binaries/clam/src/middleware/LoggingMiddleware.ts @@ -0,0 +1,8 @@ +import { Argv } from 'yargs' + +import { ClamOptions } from '../ClamOptions' +import { SetLogLevel } from '../Logging' + +export default function LoggingMiddleware(yargs: Argv): Argv { + return yargs.middleware(args => SetLogLevel(args.logLevel)) +} diff --git a/binaries/clam/src/plugins/Manifest.ts b/binaries/clam/src/plugins/Manifest.ts deleted file mode 100644 index 0f6cc74..0000000 --- a/binaries/clam/src/plugins/Manifest.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface Manifest { - files: string[] - description?: string - name: string - version: string -} diff --git a/binaries/clam/src/plugins/Plugin.ts b/binaries/clam/src/plugins/Plugin.ts deleted file mode 100644 index c0ae3b6..0000000 --- a/binaries/clam/src/plugins/Plugin.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Argv } from 'yargs' - -import Logger from '../Logging' - -import { Manifest } from './Manifest' -import { fs } from '@nofrills/fs' - -export class Plugin { - private readonly log = Logger.extend('plugin') - - constructor(public readonly cwd: string, private readonly manifest: Manifest) { - this.log.trace(':constructor', manifest) - } - - create(args: Argv<{}>): Promise> { - return this.manifest.files.reduce(async (inner, filename) => { - const yargs = await inner - return this.createCommand(yargs, filename) - }, Promise.resolve(args)) - } - - private async createCommand(yargs: Argv<{}>, filename: string): Promise> { - const filepath = fs.join(this.cwd, filename) - const command = (await require(filepath)).default - const path = fs.relative(process.cwd(), filepath) - this.log.trace(':create-command', this.manifest.name, path, command) - return yargs.command(command) - } -} diff --git a/binaries/clam/src/plugins/PluginLoader.ts b/binaries/clam/src/plugins/PluginLoader.ts deleted file mode 100644 index d941c30..0000000 --- a/binaries/clam/src/plugins/PluginLoader.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Loader } from '../Loader' -import { Plugin } from './Plugin' - -import { Manifest } from './Manifest' - -export class PluginLoader extends Loader { - constructor(filepath: string) { - super('.pluginsrc.json', [filepath]) - } - - async manifests(): Promise { - const manifests = await super.load() - - return manifests.map(manifest => { - return new Plugin(manifest.cwd, manifest.json) - }) - } -}