From 7f234269a583d4efd2fbcd4ba43d53e90e7fa245 Mon Sep 17 00:00:00 2001 From: Hannah Wolfe Date: Fri, 21 Sep 2018 13:06:02 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Pretty=20CLI=20-=20provide=20a=20st?= =?UTF-8?q?yled=20sywac=20instance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Initial commit - Added a mini module to style sywac (http://sywac.io) - Makes really pretty, easy to read, CLI instances --- ghost/pretty-cli/.eslintrc.js | 6 ++++ ghost/pretty-cli/LICENSE | 21 ++++++++++++ ghost/pretty-cli/README.md | 41 +++++++++++++++++++++++ ghost/pretty-cli/index.js | 1 + ghost/pretty-cli/package.json | 27 +++++++++++++++ ghost/pretty-cli/pretty-cli.js | 27 +++++++++++++++ ghost/pretty-cli/styles.js | 21 ++++++++++++ ghost/pretty-cli/test/.eslintrc.js | 6 ++++ ghost/pretty-cli/test/pretty-cli.test.js | 32 ++++++++++++++++++ ghost/pretty-cli/test/utils/assertions.js | 11 ++++++ ghost/pretty-cli/test/utils/index.js | 11 ++++++ ghost/pretty-cli/test/utils/overrides.js | 10 ++++++ 12 files changed, 214 insertions(+) create mode 100644 ghost/pretty-cli/.eslintrc.js create mode 100644 ghost/pretty-cli/LICENSE create mode 100644 ghost/pretty-cli/README.md create mode 100644 ghost/pretty-cli/index.js create mode 100644 ghost/pretty-cli/package.json create mode 100644 ghost/pretty-cli/pretty-cli.js create mode 100644 ghost/pretty-cli/styles.js create mode 100644 ghost/pretty-cli/test/.eslintrc.js create mode 100644 ghost/pretty-cli/test/pretty-cli.test.js create mode 100644 ghost/pretty-cli/test/utils/assertions.js create mode 100644 ghost/pretty-cli/test/utils/index.js create mode 100644 ghost/pretty-cli/test/utils/overrides.js diff --git a/ghost/pretty-cli/.eslintrc.js b/ghost/pretty-cli/.eslintrc.js new file mode 100644 index 0000000000..6a5eab530d --- /dev/null +++ b/ghost/pretty-cli/.eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: ['ghost'], + extends: [ + 'plugin:ghost/node', + ] +}; diff --git a/ghost/pretty-cli/LICENSE b/ghost/pretty-cli/LICENSE new file mode 100644 index 0000000000..97c52a346d --- /dev/null +++ b/ghost/pretty-cli/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Ghost Foundation + +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/ghost/pretty-cli/README.md b/ghost/pretty-cli/README.md new file mode 100644 index 0000000000..4ee285cb4f --- /dev/null +++ b/ghost/pretty-cli/README.md @@ -0,0 +1,41 @@ +# Pretty CLI + +A mini-module to style a [sywac](http://sywac.io/) instance in a standard way + +## Install + +Either: `npm i @tryghost/pretty-cli --save` + +Or: `yarn add @tryghost/pretty-cli` + +## Usage + +E.g. `const prettyCLI = require('@tryghost/pretty-cli');` + +`prettyCLI` is a pre-styled instance of the [sywac](http://sywac.io/) API. + +See the [sywac quickstart](http://sywac.io/docs/) and [config guide](http://sywac.io/docs/sync-config.html) for full usage. + +Example: + +``` +#!/usr/bin/env node +const prettyCLI = require('@tryghost/pretty-cli'); + + +prettyCLI + .command({ + flags: 'myTask [option]', + desc: 'Run myTask', + run: (argv) => { ... do something here } + }) + .parseAndExit(); +``` + +You can also grab a fresh instance of the api with `prettyCLI.Api.get()`. + +The style rules used are available at `prettyCLI.styles`. + +# Copyright & License + +Copyright (c) 2018 Ghost Foundation - Released under the [MIT license](LICENSE). diff --git a/ghost/pretty-cli/index.js b/ghost/pretty-cli/index.js new file mode 100644 index 0000000000..b1fd8b2b6f --- /dev/null +++ b/ghost/pretty-cli/index.js @@ -0,0 +1 @@ +module.exports = require('./pretty-cli'); diff --git a/ghost/pretty-cli/package.json b/ghost/pretty-cli/package.json new file mode 100644 index 0000000000..a168925213 --- /dev/null +++ b/ghost/pretty-cli/package.json @@ -0,0 +1,27 @@ +{ + "name": "@tryghost/pretty-cli", + "version": "0.0.0", + "description": "A mini-module to style a sywac instance in a standard way", + "repository": "https://github.com/TryGhost/slimer/tree/master/packages/pretty-cli", + "author": "Ghost Foundation", + "license": "MIT", + "main": "index.js", + "scripts": { + "dev": "echo \"Implement me!\"", + "test": "NODE_ENV=testing mocha ./test/**/*.test.js", + "lint": "eslint . --ext .js --cache", + "posttest": "yarn lint" + }, + "publishConfig": { + "access": "public" + }, + "devDependencies": { + "mocha": "5.2.0", + "should": "13.2.3", + "sinon": "6.3.4" + }, + "dependencies": { + "chalk": "^2.4.1", + "sywac": "^1.2.1" + } +} diff --git a/ghost/pretty-cli/pretty-cli.js b/ghost/pretty-cli/pretty-cli.js new file mode 100644 index 0000000000..80063c3fc6 --- /dev/null +++ b/ghost/pretty-cli/pretty-cli.js @@ -0,0 +1,27 @@ +const Api = require('sywac/api'); +const styles = require('./styles'); + +/** + * Pretty CLI + * + * A mini-module to style a sywac instance in a standard way + */ + +// Exports a pre-configured version of sywac +module.exports = Api.get() +// Use help & version with short forms AND +// group them into a Global Options group to keep them separate from per-command options + .help('-h, --help', {group: 'Global Options:'}) + .version('-v, --version', {group: 'Global Options:'}) + // Load our style rules + .style(styles) + // Add some padding at the end + .epilogue(' ') + // If no command is passed, output the help menu + .showHelpByDefault(); + +// Expose a clean version, just in case +module.exports.Api = Api; + +// Export the styles +module.exports.styles = styles; diff --git a/ghost/pretty-cli/styles.js b/ghost/pretty-cli/styles.js new file mode 100644 index 0000000000..f7204c5e88 --- /dev/null +++ b/ghost/pretty-cli/styles.js @@ -0,0 +1,21 @@ +const chalk = require('chalk'); + +module.exports = { + // Usage: script [options] etc + usagePrefix: (str) => { + return chalk.yellow(str.slice(0, 6)) + '\n ' + str.slice(7); + }, + // Options: Arguments: etc + group: str => chalk.yellow(str), + // --help etc + flags: str => chalk.green(str), + // [required] [boolean] etc + hints: str => chalk.dim(str), + // Use different style when a type is invalid + groupError: str => chalk.red(str), + flagsError: str => chalk.red(str), + descError: str => chalk.yellow(str), + hintsError: str => chalk.red(str), + // style error messages + messages: str => chalk.red(str) +}; diff --git a/ghost/pretty-cli/test/.eslintrc.js b/ghost/pretty-cli/test/.eslintrc.js new file mode 100644 index 0000000000..edb3308632 --- /dev/null +++ b/ghost/pretty-cli/test/.eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: ['ghost'], + extends: [ + 'plugin:ghost/test', + ] +}; diff --git a/ghost/pretty-cli/test/pretty-cli.test.js b/ghost/pretty-cli/test/pretty-cli.test.js new file mode 100644 index 0000000000..fb0b959a53 --- /dev/null +++ b/ghost/pretty-cli/test/pretty-cli.test.js @@ -0,0 +1,32 @@ +// Switch these lines once there are useful utils +// const testUtils = require('./utils'); +require('./utils'); + +const prettyCLI = require('../pretty-cli'); + +// Check the API is as we depend on in other modules; +describe('API', function () { + it('Exposes styled-sywac, styles & the sywac API', function () { + // Detect a basic prestyled sywac instance + prettyCLI.should.be.an.Object().with.property('types'); + prettyCLI.parseAndExit.should.be.a.Function(); + + // Detect the basic sywac Api + prettyCLI.Api.should.be.a.Function(); + prettyCLI.Api.get.should.be.a.Function(); + + // Detect style rules + prettyCLI.styles.should.be.an.Object(); + prettyCLI.styles.should.have.properties([ + 'usagePrefix', + 'group', + 'flags', + 'hints', + 'groupError', + 'flagsError', + 'descError', + 'hintsError', + 'messages' + ]); + }); +}); diff --git a/ghost/pretty-cli/test/utils/assertions.js b/ghost/pretty-cli/test/utils/assertions.js new file mode 100644 index 0000000000..7364ee8aa1 --- /dev/null +++ b/ghost/pretty-cli/test/utils/assertions.js @@ -0,0 +1,11 @@ +/** + * Custom Should Assertions + * + * Add any custom assertions to this file. + */ + +// Example Assertion +// should.Assertion.add('ExampleAssertion', function () { +// this.params = {operator: 'to be a valid Example Assertion'}; +// this.obj.should.be.an.Object; +// }); diff --git a/ghost/pretty-cli/test/utils/index.js b/ghost/pretty-cli/test/utils/index.js new file mode 100644 index 0000000000..0d67d86ff8 --- /dev/null +++ b/ghost/pretty-cli/test/utils/index.js @@ -0,0 +1,11 @@ +/** + * Test Utilities + * + * Shared utils for writing tests + */ + +// Require overrides - these add globals for tests +require('./overrides'); + +// Require assertions - adds custom should assertions +require('./assertions'); diff --git a/ghost/pretty-cli/test/utils/overrides.js b/ghost/pretty-cli/test/utils/overrides.js new file mode 100644 index 0000000000..90203424ee --- /dev/null +++ b/ghost/pretty-cli/test/utils/overrides.js @@ -0,0 +1,10 @@ +// This file is required before any test is run + +// Taken from the should wiki, this is how to make should global +// Should is a global in our eslint test config +global.should = require('should').noConflict(); +should.extend(); + +// Sinon is a simple case +// Sinon is a global in our eslint test config +global.sinon = require('sinon');