From aa83f2248952ab55e3a632155da0fb0d95e4b7ff Mon Sep 17 00:00:00 2001 From: Mike Pirog Date: Mon, 4 Jun 2018 17:12:58 -0400 Subject: [PATCH] #789: Switch most of our non-plugins stuff to stricter es6 googlisms --- .eslintrc.json | 328 +++---------------------------- .eslintrc.old.json | 304 +++++++++++++++++++++++++++++ bin/lando.js | 17 +- docs/api/api.md | 339 ++++++++++++++++++++------------- docs/helpers/helpers.js | 6 +- lib/cache.js | 34 +--- lib/config.js | 38 ++-- lib/events.js | 43 ++--- lib/plugins.js | 18 +- lib/promise.js | 96 +++------- lib/serializer.js | 12 +- lib/tasks.js | 27 +-- lib/updates.js | 59 +++--- lib/user.js | 18 +- lib/yaml.js | 23 +-- package.json | 2 +- scripts/bump.js | 50 ++--- scripts/dev-version.js | 37 ++-- scripts/docs.js | 47 +++-- scripts/pkg.js | 3 +- scripts/pkg/functions.js | 122 ++++++------ scripts/util.js | 65 +++---- test/helpers/functional/cli.js | 13 +- test/unit/cache.spec.js | 5 +- test/unit/config.spec.js | 8 +- test/unit/events.spec.js | 1 - test/unit/node.spec.js | 2 - test/unit/plugins.spec.js | 2 +- test/unit/serializer.spec.js | 2 - test/unit/shell.spec.js | 2 +- test/unit/tasks.spec.js | 11 +- test/unit/updates.spec.js | 64 +++---- test/unit/user.spec.js | 8 +- test/unit/yaml.spec.js | 6 +- 34 files changed, 893 insertions(+), 919 deletions(-) create mode 100644 .eslintrc.old.json diff --git a/.eslintrc.json b/.eslintrc.json index 8c0051c51..6865388d0 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,304 +1,28 @@ { - "env": { - "node": true, - "mocha": true - }, - "parserOptions": { - "ecmaVersion": 6 - }, - "extends": "google", - "rules": { - "accessor-pairs": "error", - "no-console": 0, - "no-useless-escape": 0, - "array-bracket-newline": "off", - "array-bracket-spacing": [ - "error", - "never" - ], - "array-callback-return": "off", - "array-element-newline": "off", - "arrow-body-style": "error", - "arrow-parens": [ - "error", - "as-needed" - ], - "arrow-spacing": "error", - "block-scoped-var": "error", - "block-spacing": [ - "error", - "always" - ], - "brace-style": "off", - "callback-return": "error", - "camelcase": "error", - "capitalized-comments": "off", - "class-methods-use-this": "off", - "comma-dangle": "off", - "comma-spacing": [ - "error", - { - "after": true, - "before": false - } - ], - "comma-style": [ - "error", - "last" - ], - "complexity": "error", - "computed-property-spacing": [ - "error", - "never" - ], - "consistent-return": "off", - "consistent-this": "off", - "curly": "error", - "default-case": "off", - "dot-location": [ - "error", - "property" - ], - "dot-notation": [ - "error", - { - "allowKeywords": true - } - ], - "eol-last": "error", - "eqeqeq": "error", - "for-direction": "error", - "func-call-spacing": "error", - "func-name-matching": "error", - "func-names": [ - "error", - "never" - ], - "func-style": "off", - "function-paren-newline": "off", - "generator-star-spacing": "error", - "getter-return": "error", - "global-require": "off", - "guard-for-in": "error", - "handle-callback-err": "error", - "id-blacklist": "error", - "id-length": "off", - "id-match": "error", - "implicit-arrow-linebreak": "error", - "indent": "off", - "indent-legacy": "off", - "init-declarations": "off", - "jsx-quotes": "error", - "key-spacing": "off", - "keyword-spacing": [ - "error", - { - "after": true, - "before": true - } - ], - "line-comment-position": "error", - "linebreak-style": [ - "error", - "unix" - ], - "lines-around-comment": "off", - "lines-around-directive": "off", - "lines-between-class-members": "error", - "max-depth": "error", - "max-len": "off", - "max-lines": "off", - "max-nested-callbacks": "error", - "max-params": "off", - "max-statements": "off", - "max-statements-per-line": "off", - "multiline-comment-style": "off", - "new-parens": "error", - "newline-after-var": "off", - "newline-before-return": "off", - "newline-per-chained-call": "off", - "no-alert": "error", - "no-array-constructor": "error", - "no-await-in-loop": "error", - "no-bitwise": "error", - "no-buffer-constructor": "error", - "no-caller": "error", - "no-catch-shadow": "error", - "no-confusing-arrow": "error", - "no-continue": "error", - "no-div-regex": "error", - "no-duplicate-imports": "error", - "no-else-return": "off", - "no-empty-function": "off", - "no-eq-null": "error", - "no-eval": "error", - "no-extend-native": "error", - "no-extra-bind": "error", - "no-extra-label": "error", - "no-extra-parens": "off", - "no-floating-decimal": "error", - "no-implicit-globals": "error", - "no-implied-eval": "error", - "no-inline-comments": "error", - "no-inner-declarations": [ - "error", - "functions" - ], - "no-invalid-this": "off", - "no-iterator": "error", - "no-label-var": "error", - "no-labels": "error", - "no-lone-blocks": "error", - "no-lonely-if": "error", - "no-loop-func": "error", - "no-magic-numbers": "off", - "no-mixed-operators": "error", - "no-mixed-requires": "error", - "no-multi-assign": "error", - "no-multi-spaces": "off", - "no-multi-str": "error", - "no-multiple-empty-lines": "error", - "no-native-reassign": "error", - "no-negated-condition": "off", - "no-negated-in-lhs": "error", - "no-nested-ternary": "error", - "no-new": "error", - "no-new-func": "error", - "no-new-object": "error", - "no-new-require": "off", - "no-new-wrappers": "error", - "no-octal-escape": "error", - "no-param-reassign": "off", - "no-path-concat": "error", - "no-plusplus": "error", - "no-process-env": "off", - "no-process-exit": "off", - "no-proto": "error", - "no-prototype-builtins": "error", - "no-restricted-globals": "error", - "no-restricted-imports": "error", - "no-restricted-modules": "error", - "no-restricted-properties": "error", - "no-restricted-syntax": "error", - "no-return-assign": "error", - "no-return-await": "error", - "no-script-url": "error", - "no-self-compare": "error", - "no-sequences": "error", - "no-shadow": "off", - "no-shadow-restricted-names": "error", - "no-spaced-func": "error", - "no-sync": "off", - "no-tabs": "error", - "no-template-curly-in-string": "error", - "no-ternary": "off", - "no-throw-literal": "error", - "no-trailing-spaces": "error", - "no-undef": "error", - "no-undef-init": "error", - "no-undefined": "off", - "no-underscore-dangle": "off", - "no-unmodified-loop-condition": "error", - "no-unneeded-ternary": "off", - "no-unused-expressions": "off", - "no-use-before-define": "error", - "no-useless-call": "error", - "no-useless-computed-key": "error", - "no-useless-concat": "off", - "no-useless-constructor": "error", - "no-useless-rename": "error", - "no-useless-return": "error", - "no-var": "off", - "no-void": "error", - "no-warning-comments": [ - "error", - { - "location": "start" - } - ], - "no-whitespace-before-property": "error", - "no-with": "error", - "nonblock-statement-body-position": "error", - "object-curly-newline": "off", - "object-curly-spacing": [ - "error", - "never" - ], - "object-property-newline": [ - "error", - { - "allowMultiplePropertiesPerLine": true - } - ], - "object-shorthand": "off", - "one-var": "off", - "one-var-declaration-per-line": "error", - "operator-assignment": [ - "error", - "never" - ], - "operator-linebreak": "error", - "padded-blocks": "off", - "padding-line-between-statements": "error", - "prefer-arrow-callback": "off", - "prefer-const": "error", - "prefer-destructuring": "off", - "prefer-numeric-literals": "error", - "prefer-promise-reject-errors": "off", - "prefer-reflect": "off", - "prefer-rest-params": "off", - "prefer-spread": "error", - "prefer-template": "off", - "quote-props": "off", - "quotes": [ - "error", - "single" - ], - "radix": "error", - "require-await": "error", - "require-jsdoc": "off", - "rest-spread-spacing": "error", - "semi": "error", - "semi-spacing": "off", - "semi-style": [ - "error", - "last" - ], - "sort-imports": "error", - "sort-keys": "off", - "sort-vars": "error", - "space-before-blocks": "error", - "space-before-function-paren": "off", - "space-in-parens": [ - "error", - "never" - ], - "space-infix-ops": "error", - "space-unary-ops": "error", - "spaced-comment": "off", - "strict": "error", - "switch-colon-spacing": [ - "error", - { - "after": true, - "before": false - } - ], - "symbol-description": "error", - "template-curly-spacing": "error", - "template-tag-spacing": "error", - "unicode-bom": [ - "error", - "never" - ], - "valid-jsdoc": "off", - "vars-on-top": "off", - "wrap-iife": "error", - "wrap-regex": "error", - "yield-star-spacing": "error", - "yoda": [ - "error", - "never" - ] - } + "env": { + "node": true, + "mocha": true + }, + "parserOptions": { + "ecmaVersion": 6 + }, + "extends": "google", + "rules": { + "arrow-parens": ["error", + "as-needed" + ], + "max-len": ["error", { + "code": 120, + "ignoreComments": true + }], + "require-jsdoc": ["error", { + "require": { + "FunctionDeclaration": true, + "MethodDefinition": false, + "ClassDeclaration": false, + "ArrowFunctionExpression": false, + "FunctionExpression": false + } + }] + } } diff --git a/.eslintrc.old.json b/.eslintrc.old.json new file mode 100644 index 000000000..8c0051c51 --- /dev/null +++ b/.eslintrc.old.json @@ -0,0 +1,304 @@ +{ + "env": { + "node": true, + "mocha": true + }, + "parserOptions": { + "ecmaVersion": 6 + }, + "extends": "google", + "rules": { + "accessor-pairs": "error", + "no-console": 0, + "no-useless-escape": 0, + "array-bracket-newline": "off", + "array-bracket-spacing": [ + "error", + "never" + ], + "array-callback-return": "off", + "array-element-newline": "off", + "arrow-body-style": "error", + "arrow-parens": [ + "error", + "as-needed" + ], + "arrow-spacing": "error", + "block-scoped-var": "error", + "block-spacing": [ + "error", + "always" + ], + "brace-style": "off", + "callback-return": "error", + "camelcase": "error", + "capitalized-comments": "off", + "class-methods-use-this": "off", + "comma-dangle": "off", + "comma-spacing": [ + "error", + { + "after": true, + "before": false + } + ], + "comma-style": [ + "error", + "last" + ], + "complexity": "error", + "computed-property-spacing": [ + "error", + "never" + ], + "consistent-return": "off", + "consistent-this": "off", + "curly": "error", + "default-case": "off", + "dot-location": [ + "error", + "property" + ], + "dot-notation": [ + "error", + { + "allowKeywords": true + } + ], + "eol-last": "error", + "eqeqeq": "error", + "for-direction": "error", + "func-call-spacing": "error", + "func-name-matching": "error", + "func-names": [ + "error", + "never" + ], + "func-style": "off", + "function-paren-newline": "off", + "generator-star-spacing": "error", + "getter-return": "error", + "global-require": "off", + "guard-for-in": "error", + "handle-callback-err": "error", + "id-blacklist": "error", + "id-length": "off", + "id-match": "error", + "implicit-arrow-linebreak": "error", + "indent": "off", + "indent-legacy": "off", + "init-declarations": "off", + "jsx-quotes": "error", + "key-spacing": "off", + "keyword-spacing": [ + "error", + { + "after": true, + "before": true + } + ], + "line-comment-position": "error", + "linebreak-style": [ + "error", + "unix" + ], + "lines-around-comment": "off", + "lines-around-directive": "off", + "lines-between-class-members": "error", + "max-depth": "error", + "max-len": "off", + "max-lines": "off", + "max-nested-callbacks": "error", + "max-params": "off", + "max-statements": "off", + "max-statements-per-line": "off", + "multiline-comment-style": "off", + "new-parens": "error", + "newline-after-var": "off", + "newline-before-return": "off", + "newline-per-chained-call": "off", + "no-alert": "error", + "no-array-constructor": "error", + "no-await-in-loop": "error", + "no-bitwise": "error", + "no-buffer-constructor": "error", + "no-caller": "error", + "no-catch-shadow": "error", + "no-confusing-arrow": "error", + "no-continue": "error", + "no-div-regex": "error", + "no-duplicate-imports": "error", + "no-else-return": "off", + "no-empty-function": "off", + "no-eq-null": "error", + "no-eval": "error", + "no-extend-native": "error", + "no-extra-bind": "error", + "no-extra-label": "error", + "no-extra-parens": "off", + "no-floating-decimal": "error", + "no-implicit-globals": "error", + "no-implied-eval": "error", + "no-inline-comments": "error", + "no-inner-declarations": [ + "error", + "functions" + ], + "no-invalid-this": "off", + "no-iterator": "error", + "no-label-var": "error", + "no-labels": "error", + "no-lone-blocks": "error", + "no-lonely-if": "error", + "no-loop-func": "error", + "no-magic-numbers": "off", + "no-mixed-operators": "error", + "no-mixed-requires": "error", + "no-multi-assign": "error", + "no-multi-spaces": "off", + "no-multi-str": "error", + "no-multiple-empty-lines": "error", + "no-native-reassign": "error", + "no-negated-condition": "off", + "no-negated-in-lhs": "error", + "no-nested-ternary": "error", + "no-new": "error", + "no-new-func": "error", + "no-new-object": "error", + "no-new-require": "off", + "no-new-wrappers": "error", + "no-octal-escape": "error", + "no-param-reassign": "off", + "no-path-concat": "error", + "no-plusplus": "error", + "no-process-env": "off", + "no-process-exit": "off", + "no-proto": "error", + "no-prototype-builtins": "error", + "no-restricted-globals": "error", + "no-restricted-imports": "error", + "no-restricted-modules": "error", + "no-restricted-properties": "error", + "no-restricted-syntax": "error", + "no-return-assign": "error", + "no-return-await": "error", + "no-script-url": "error", + "no-self-compare": "error", + "no-sequences": "error", + "no-shadow": "off", + "no-shadow-restricted-names": "error", + "no-spaced-func": "error", + "no-sync": "off", + "no-tabs": "error", + "no-template-curly-in-string": "error", + "no-ternary": "off", + "no-throw-literal": "error", + "no-trailing-spaces": "error", + "no-undef": "error", + "no-undef-init": "error", + "no-undefined": "off", + "no-underscore-dangle": "off", + "no-unmodified-loop-condition": "error", + "no-unneeded-ternary": "off", + "no-unused-expressions": "off", + "no-use-before-define": "error", + "no-useless-call": "error", + "no-useless-computed-key": "error", + "no-useless-concat": "off", + "no-useless-constructor": "error", + "no-useless-rename": "error", + "no-useless-return": "error", + "no-var": "off", + "no-void": "error", + "no-warning-comments": [ + "error", + { + "location": "start" + } + ], + "no-whitespace-before-property": "error", + "no-with": "error", + "nonblock-statement-body-position": "error", + "object-curly-newline": "off", + "object-curly-spacing": [ + "error", + "never" + ], + "object-property-newline": [ + "error", + { + "allowMultiplePropertiesPerLine": true + } + ], + "object-shorthand": "off", + "one-var": "off", + "one-var-declaration-per-line": "error", + "operator-assignment": [ + "error", + "never" + ], + "operator-linebreak": "error", + "padded-blocks": "off", + "padding-line-between-statements": "error", + "prefer-arrow-callback": "off", + "prefer-const": "error", + "prefer-destructuring": "off", + "prefer-numeric-literals": "error", + "prefer-promise-reject-errors": "off", + "prefer-reflect": "off", + "prefer-rest-params": "off", + "prefer-spread": "error", + "prefer-template": "off", + "quote-props": "off", + "quotes": [ + "error", + "single" + ], + "radix": "error", + "require-await": "error", + "require-jsdoc": "off", + "rest-spread-spacing": "error", + "semi": "error", + "semi-spacing": "off", + "semi-style": [ + "error", + "last" + ], + "sort-imports": "error", + "sort-keys": "off", + "sort-vars": "error", + "space-before-blocks": "error", + "space-before-function-paren": "off", + "space-in-parens": [ + "error", + "never" + ], + "space-infix-ops": "error", + "space-unary-ops": "error", + "spaced-comment": "off", + "strict": "error", + "switch-colon-spacing": [ + "error", + { + "after": true, + "before": false + } + ], + "symbol-description": "error", + "template-curly-spacing": "error", + "template-tag-spacing": "error", + "unicode-bom": [ + "error", + "never" + ], + "valid-jsdoc": "off", + "vars-on-top": "off", + "wrap-iife": "error", + "wrap-regex": "error", + "yield-star-spacing": "error", + "yoda": [ + "error", + "never" + ] + } +} diff --git a/bin/lando.js b/bin/lando.js index 2c52766e4..cb8b555d5 100755 --- a/bin/lando.js +++ b/bin/lando.js @@ -7,7 +7,7 @@ * @name lando */ - 'use strict'; +'use strict'; // Modules const _ = require('lodash'); @@ -30,7 +30,7 @@ const ENVPREFIX = process.env.LANDO_CORE_ENVPREFIX || 'LANDO'; const USERCONFROOT = process.env.LANDO_CORE_USERCONFROOT || userConfRoot; // If we have CLI verbosity args let's use those instead -if (cli.largv.verbose) { LOGLEVELCONSOLE = cli.largv.verbose + 1; } +if (cli.largv.verbose) LOGLEVELCONSOLE = cli.largv.verbose + 1; // Define the start up options const options = { @@ -41,18 +41,16 @@ const options = { mode: 'cli', pluginDirs: [USERCONFROOT], userConfRoot: USERCONFROOT, - version + version, }; // Error handler const handleError = ({hide, message, stack, code}, log, metrics) => { - // Log error or not if (!hide && log) { if (cli.largv.verbose > 0) { log.error(stack); - } - else { + } else { log.error(message); } } @@ -64,7 +62,6 @@ const handleError = ({hide, message, stack, code}, log, metrics) => { // Exit this process process.exit(code || 1); - }; // Kick off our bootstrap @@ -72,7 +69,6 @@ bootstrap(options) // Initialize the CLI .then(lando => { - // Bind to outside scope // @TODO: do this better metrics = lando.metrics; @@ -154,7 +150,6 @@ bootstrap(options) // Print the CLI .then(() => { - // Loop through the tasks and add them to the CLI _.forEach(_.sortBy(tasks, 'command'), task => { lando.log.verbose('Loading cli task %s', task.name); @@ -171,7 +166,7 @@ bootstrap(options) const epilogue = [ lando.node.chalk.green('Global Options:\n'), ' --help, -h Show help\n', - ' --verbose, -v, -vv, -vvv, -vvvv Change verbosity of output' + ' --verbose, -v, -vv, -vvv, -vvvv Change verbosity of output', ]; // Finish up the yargs @@ -184,9 +179,7 @@ bootstrap(options) // Log the CLI args lando.log.debug('CLI args', argv); - }); - }) // Handle all other errors diff --git a/docs/api/api.md b/docs/api/api.md index 2bc6e3b7f..74cf46924 100644 --- a/docs/api/api.md +++ b/docs/api/api.md @@ -64,17 +64,6 @@ This means all the options passed in after the `--` flag. var largv = lando.tasks.largv; ``` - - -

- lando.events

-
- -This extends the core node event emitter except where otherwise documented -below - -**See**: https://nodejs.org/api/events.html -

@@ -219,6 +208,21 @@ Get semver var semver = lando.node.semver; ``` + + +

+ lando.tasks.tasks

+
+ +A singleton array that contains all the tasks that have been added. + +**Since**: 3.0.0 +**Example** +```js +// Gets all the tasks that have been loaded +var task = lando.tasks.tasks; +``` +

@@ -231,22 +235,15 @@ so that our promises have some retry functionality. All functionality should be the same as bluebird except where indicated below -**See**: http://bluebirdjs.com/docs/api-reference.html - - +Note that bluebird currently wants you to use scoped prototypes to extend +it rather than the normal extend syntax so that is why this is using the "old" +way -

- lando.tasks.tasks

-
+**See** -A singleton array that contains all the tasks that have been added. +- http://bluebirdjs.com/docs/api-reference.html +- https://github.com/petkaantonov/bluebird/issues/1397 -**Since**: 3.0.0 -**Example** -```js -// Gets all the tasks that have been loaded -var task = lando.tasks.tasks; -``` @@ -319,41 +316,44 @@ Manually remove an item from the cache. lando.cache.remove('mykey'); ``` - + -

- lando.utils.config.merge()

+

+ lando.utils.config.tryConvertJson(value) ⇒ Object

-Uses _.mergeWith to concat arrays, this helps replicate how Docker -Compose merges its things +Attempt to parse a JSON string to an objects **Since**: 3.0.0 -**Example** -```js -// Take an object and write a docker compose file -var newObject = _.mergeWith(a, b, lando.utils.merger); -``` + +| Param | Type | Description | +| --- | --- | --- | +| value | String | The string to convert | + +**Returns**: Object - A parsed object or the inputted value - + -

- lando.utils.config.updatePath(dir) ⇒ String

+

+ lando.utils.config.merge(old, fresh) ⇒ Object \| Object

-Updates the PATH with dir. This adds dir to the beginning of PATH. +Uses _.mergeWith to concat arrays, this helps replicate how Docker Compose +merges its things +**See**: https://lodash.com/docs#mergeWith **Since**: 3.0.0 | Param | Type | Description | | --- | --- | --- | -| dir | String | The dir to add | +| old | Object | object to be merged | +| fresh | Object | object to be merged | -**Returns**: String - Updated PATH string +**Returns**: Object - The new objectObject - Merged object or arrays **Example** ```js -// Update the path -var config.path = config.updatePath(path); +// Take an object and write a docker compose file +var newObject = _.mergeWith(a, b, lando.utils.merger); ``` @@ -362,7 +362,9 @@ var config.path = config.updatePath(path); lando.utils.config.stripEnv(prefix) ⇒ Object
-Strips process.env of all envvars with PREFIX +Strips process.env of all envvars with PREFIX and returns process.env + +NOTE: this actually returns process.env not a NEW object cloned from process.env **Since**: 3.0.0 @@ -373,39 +375,52 @@ Strips process.env of all envvars with PREFIX **Returns**: Object - Updated process.env **Example** ```js -// Reset the process.env without any LANDO_ prefixed envvars -process.env = config.stripEnv('LANDO_'); +// Reset the process.env without any DOCKER_ prefixed envvars +process.env = config.stripEnv('DOCKER_'); ```

- lando.utils.config.defaults()

+ lando.utils.config.defaults() ⇒ Object
Define default config **Since**: 3.0.0 +**Returns**: Object - The default config object.

- lando.utils.config.loadFiles()

+ lando.utils.config.loadFiles(files) ⇒ Object
Merge in config file if it exists **Since**: 3.0.0 + +| Param | Type | Description | +| --- | --- | --- | +| files | Array | An array of files to try loading | + +**Returns**: Object - An object of config merged from file sources

- lando.utils.config.loadEnvs()

+ lando.utils.config.loadEnvs(prefix) ⇒ Object
-Grab envvars and map to config +Filter process.env by a given prefix **Since**: 3.0.0 + +| Param | Type | Description | +| --- | --- | --- | +| prefix | String | The prefix by which to filter. Should be without the trailing `_` eg `LANDO` not `LANDO_` | + +**Returns**: Object - Object of things with camelCased keys @@ -752,7 +767,7 @@ lando.log.warning('Something is up with app %s in directory %s', appName, dir);

- lando.plugins.load(plugin, dirs, [inject]) ⇒ Promise

+ lando.plugins.load(plugin, dirs, [injected]) ⇒ Promise
Loads a plugin. @@ -766,7 +781,7 @@ For each directory scanned plugins can live in either the `plugins` or | --- | --- | --- | | plugin | String | The name of the plugin | | dirs | Array | The directories to scan for plugins. | -| [inject] | Object | An object to inject into the plugin. | +| [injected] | Object | An object to inject into the plugin. | **Returns**: Promise - A Promise. **Example** @@ -1042,37 +1057,49 @@ Get latest version info from github

- lando.user.getUid() ⇒ String

+ lando.user.getUid([username]) ⇒ String
-Returns the id of the user. +Returns the id of the current user or username. -Note that on Windows this value is more or less worthless. +Note that on Windows this value is more or less worthless and `username` has +has no effect **Since**: 3.0.0 + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| [username] | String | '$(whoami)' | The username to get the ID for | + **Returns**: String - The user ID. **Example** ```js // Get the id of the user. -var userId = lando.user.getEngineUserId(); +var userId = lando.user.getUid(); ```

- lando.user.getGid() ⇒ String

+ lando.user.getGid([username]) ⇒ String
-Returns the group id of the user. +Returns the id of the current user or username. -Note that on Windows this value is more or less worthless. +Note that on Windows this value is more or less worthless and `username` has +has no effect **Since**: 3.0.0 + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| [username] | String | '$(whoami)' | The username to get the ID for | + **Returns**: String - The group ID. **Example** ```js // Get the id of the user. -var groupId = lando.user.getEngineUserGid(); +var groupId = lando.user.getGid(); ``` @@ -1081,7 +1108,7 @@ var groupId = lando.user.getEngineUserGid(); lando.yaml.load(file) ⇒ Object
-Loads a yaml object from a file +Loads a yaml object from a file. **Since**: 3.0.0 @@ -1093,26 +1120,9 @@ Loads a yaml object from a file **Example** ```js // Add a string to the cache -var thing = lando.yaml.load('/tmp/myfile.yml'); +const thing = lando.yaml.load('/tmp/myfile.yml'); ``` - - -

- lando.yaml.dump(file, data) ⇒

-
- -Dumps an object to a YAML file - -**Since**: 3.0.0 - -| Param | Type | Description | -| --- | --- | --- | -| file | String | The path to the file to be loaded | -| data | Object | The object to dump | - -**Returns**: - Flename -

@@ -2125,7 +2135,7 @@ Gets the docker networks. }; // Get the networks - return lando.networks.get(opts) + return lando.engine.getNetworks(opts) // Filter out lando_default .filter(function(network) { @@ -2138,50 +2148,48 @@ Gets the docker networks. }); ``` - + -

- lando.engine.createNetwork(name, [opts]) ⇒ Promise

+

+ lando.engine.getNetwork(id) ⇒ Object

-Creates a Docker network +Gets a Docker network -**See**: [docker api network docs](https://docs.docker.com/engine/api/v1.35/#operation/NetworkCreate) for info on opts. **Since**: 3.0.0. | Param | Type | Description | | --- | --- | --- | -| name | String | The name of the networks | -| [opts] | Object | See API network docs above | +| id | String | The id of the network | -**Returns**: Promise - A Promise with inspect data. +**Returns**: Object - A Dockerode Network object . **Example** ```js -// Get the networks - return lando.networks.inspect('mynetwork') +// Get the network + return lando.engine.getNetwork('mynetwork') ``` - + -

- lando.engine.pruneNetworks([opts]) ⇒ Promise

+

+ lando.engine.createNetwork(name, [opts]) ⇒ Promise

-Prunes the docker networks. +Creates a Docker network -**See**: [docker api network docs](https://docs.docker.com/engine/api/v1.27/#operation/NetworkPrune) for info on filters option. -**Since**: 3.0.0 +**See**: [docker api network docs](https://docs.docker.com/engine/api/v1.35/#operation/NetworkCreate) for info on opts. +**Since**: 3.0.0. | Param | Type | Description | | --- | --- | --- | -| [opts] | Object | Options to pass into the docker networks call | -| [opts.filters] | Object | Filters options | +| name | String | The name of the networks | +| [opts] | Object | See API network docs above | -**Returns**: Promise - A Promise with teh status +**Returns**: Promise - A Promise with inspect data. **Example** ```js -// Prune the networks - return lando.networks.prune() +// Create the network + return ando.engine.createNetwork('mynetwork') ``` @@ -2192,7 +2200,8 @@ Prunes the docker networks. Translate a name for use by docker-compose eg strip `-` and `.` and -**Todo:**: possibly more than that +**Todo:**: Eventually we want to get rid of this since it should only happen once +on the appName itself **Since**: 3.0.0 @@ -2244,6 +2253,19 @@ Get an init method Add an init method to the registry +**Since**: 3.0.0 + + + +

+ lando.init.cloneRepo()

+
+ +Helper to return a performant git clone command + +This clones to /tmp and then moves to /app to avoid file sharing performance +hits + **Since**: 3.0.0 @@ -2376,74 +2398,100 @@ The core service builder **Since**: 3.0.0 - + -

- lando.utils.services.connectNet()

+

+ lando.services.healthcheck()

-Default networking +Does a healthcheck on a service **Since**: 3.0.0 - + -

- lando.utils.services.connectBridge()

+

+ lando.utils.services.addConfig()

-Default bridge network +Helper function to inject config **Since**: 3.0.0 - + -

- lando.utils.services.filterBuildSteps()

+

+ lando.utils.services.addScript()

-Return an object of build steps +Helper function to inject utility scripts **Since**: 3.0.0 - + -

- lando.utils.services.setEntrypoint()

+

+ lando.utils.services.buildVolume()

-Set the entrypoint with a local script +Helper to build a volumes +**Note:**: This seems weird, maybe written before we have more generic compose merging? +**Note:**: Once we have more testing can we switch this to use normalizePath? **Since**: 3.0.0 - + -

- lando.utils.services.buildVolume()

+

+ lando.utils.services.filterBuildSteps()

-Helper to build a volumes +Return an object of build steps -**Note:**: This seems weird, maybe written before we have more generic compose merging? **Since**: 3.0.0 - + -

- lando.utils.services.addConfig()

+

+ lando.utils.services.getHostPath(mount) ⇒ String

-Helper function to inject config +Helper method to get the host part of a volume **Since**: 3.0.0 + +| Param | Type | Description | +| --- | --- | --- | +| mount | String | The entire mount | + +**Returns**: String - The host part of the mount - + -

- lando.utils.services.addScript()

+

+ lando.utils.services.normalizePath(local, base, excludes) ⇒ String

-Helper function to inject utility scripts +Helper method to normalize a path so that Lando overrides can be used as though +the docker-compose files were in the app root. + +**Since**: 3.0.0 + +| Param | Type | Description | +| --- | --- | --- | +| local | String | The first part of the volume mount | +| base | String | The path that should be prefixed to any local deemed to be a relative path | +| excludes | Array | An array of locals to exclude, this is primarily for named volumes | + +**Returns**: String - Either local or local prefixed by base + + + +

+ lando.utils.services.setEntrypoint()

+
+ +Set the entrypoint with a local script **Since**: 3.0.0 @@ -2718,7 +2766,7 @@ app is uninstalled such as invalidating any cached data. ```js // Make sure we remove our build cache app.events.on('post-uninstall', function() { - lando.cache.remove(app.name + ':last_build'); + lando.cache.remove(app.name + '.last_build'); }); ``` @@ -2765,20 +2813,20 @@ app.events.on('post-start', function() { // Go through each service _.forEach(app.config.services, function(service, name) { - // If the service has extras let's loop through and run some commands - if (!_.isEmpty(service.extras)) { + // If the service has run steps let's loop through and run some commands + if (!_.isEmpty(service.run)) { // Normalize data for loopage - if (!_.isArray(service.extras)) { - service.extras = [service.extras]; + if (!_.isArray(service.run)) { + service.run = [service.run]; } // Run each command - _.forEach(service.extras, function(cmd) { + _.forEach(service.run, function(cmd) { // Build out the compose object var compose = { - id: [app.dockerName, name, '1'].join('_'), + id: [service, name, '1'].join('_'), cmd: cmd, opts: { mode: 'attach' @@ -3071,3 +3119,20 @@ started **Since**: 3.0.0 + + +

+ lando.yaml.dump(file, data) ⇒ String

+
+ +Dumps an object to a YAML file + +**Since**: 3.0.0 + +| Param | Type | Description | +| --- | --- | --- | +| file | String | The path to the file to be loaded | +| data | Object | The object to dump | + +**Returns**: String - Flename + diff --git a/docs/helpers/helpers.js b/docs/helpers/helpers.js index 56dbb03c9..04628d888 100644 --- a/docs/helpers/helpers.js +++ b/docs/helpers/helpers.js @@ -1,8 +1,4 @@ 'use strict'; const _ = require('lodash'); - -exports.escapedAnchor = function (anchor) { - if (typeof anchor !== 'string') return null; - return _.toLower(anchor.replace(/\W/g, '')); -}; +exports.escapedAnchor = anchor => (typeof anchor !== 'string') ? null : _.toLower(anchor.replace(/\W/g, '')); diff --git a/lib/cache.js b/lib/cache.js index a4f93a40d..2a4e40a83 100644 --- a/lib/cache.js +++ b/lib/cache.js @@ -11,9 +11,6 @@ const path = require('path'); /* * Creates a new Cache instance. - * - * @param {object} opts - * @return */ class Cache extends NodeCache { constructor({log = new Log(), cacheDir = path.join(os.tmpdir(), '.cache')} = {}) { @@ -30,7 +27,7 @@ class Cache extends NodeCache { * Sets an item in the cache * * @since 3.0.0 - * @alias 'lando.cache.set' + * @alias lando.cache.set * @param {String} key - The name of the key to store the data with. * @param {Any} data - The data to store in the cache. * @param {Object} [opts] - Options to pass into the cache @@ -54,7 +51,7 @@ class Cache extends NodeCache { illegalRe: /[\/\?<>\\:\*\|":]/g, reservedRe: /^\.+$/, windowsReservedRe: /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i, - windowsTrailingRe: /[\. ]+$/ + windowsTrailingRe: /[\. ]+$/, }; _.map(patterns, pattern => { if (key.match(pattern)) throw new Error('Invalid cache key'); @@ -63,10 +60,7 @@ class Cache extends NodeCache { // Try to set cache if (this.__set(key, data, ttl)) { this.log.debug('Cached %j with key %s for %j', data, key, {persist, ttl}); - } - - // Report failed cache set - else { + } else { this.log.debug('Failed to cache %j with key %s', data, key); } @@ -74,23 +68,21 @@ class Cache extends NodeCache { if (persist) { jsonfile.writeFileSync(path.join(this.cacheDir, key), data); } - }; /** * Gets an item in the cache * * @since 3.0.0 - * @alias 'lando.cache.get' + * @alias lando.cache.get * @param {String} key - The name of the key to retrieve the data. * @return {Any} The data stored in the cache if applicable. * @example * * // Get the data stored with key mykey - * var data = lando.cache.get('mykey'); + * const data = lando.cache.get('mykey'); */ get(key) { - // Get from cache const memResult = this.__get(key); @@ -98,26 +90,21 @@ class Cache extends NodeCache { if (memResult) { this.log.debug('Retrieved from memcache with key %s', key); return memResult; - } - - // Then try file cache - else { + } else { try { this.log.debug('Trying to retrieve from file cache with key %s', key); return jsonfile.readFileSync(path.join(this.cacheDir, key)); - } - catch (e) { + } catch (e) { this.log.debug('File cache miss with key %s', key); } } - }; /** * Manually remove an item from the cache. * * @since 3.0.0 - * @alias 'lando.cache.remove' + * @alias lando.cache.remove * @param {String} key - The name of the key to remove the data. * @example * @@ -125,7 +112,6 @@ class Cache extends NodeCache { * lando.cache.remove('mykey'); */ remove(key) { - // Try to get cache if (this.__del(key) === 1) { this.log.debug('Removed key %s from memcache.', key); @@ -134,11 +120,9 @@ class Cache extends NodeCache { // Also remove file if applicable try { fs.unlinkSync(path.join(this.cacheDir, key)); - } - catch (e) { + } catch (e) { this.log.debug('No file cache with key %s', key); } - }; }; diff --git a/lib/config.js b/lib/config.js index e472858cd..1505fcb9c 100644 --- a/lib/config.js +++ b/lib/config.js @@ -25,9 +25,9 @@ const isBrowser = () => _(process.versions) * Attempt to parse a JSON string to an objects * * @since 3.0.0 - * @alias 'lando.utils.config.tryConvertJson' + * @alias lando.utils.config.tryConvertJson * @param {String} value The string to convert - * @returns {Object} A parsed object or the inputted value + * @return {Object} A parsed object or the inputted value */ exports.tryConvertJson = value => { try { @@ -43,16 +43,14 @@ exports.tryConvertJson = value => { * * @see https://lodash.com/docs#mergeWith * @since 3.0.0 - * @alias 'lando.utils.config.merge' + * @alias lando.utils.config.merge * @param {Object} old object to be merged * @param {Object} fresh object to be merged - * @returns {Object} The new object + * @return {Object} The new object * @example * * // Take an object and write a docker compose file - * var newObject = _.mergeWith(a, b, lando.utils.merger); - * - * @returns {Object} Merged object or arrays + * const newObject = _.mergeWith(a, b, lando.utils.merger); */ exports.merge = (old, fresh) => _.mergeWith(old, fresh, (s, f) => { if (_.isArray(s)) return _.uniq(s.concat(f)); @@ -64,16 +62,15 @@ exports.merge = (old, fresh) => _.mergeWith(old, fresh, (s, f) => { * NOTE: this actually returns process.env not a NEW object cloned from process.env * * @since 3.0.0 - * @alias 'lando.utils.config.stripEnv' + * @alias lando.utils.config.stripEnv * @param {String} prefix - The prefix to strip - * @returns {Object} Updated process.env + * @return {Object} Updated process.env * @example * * // Reset the process.env without any DOCKER_ prefixed envvars * process.env = config.stripEnv('DOCKER_'); */ exports.stripEnv = prefix => { - // Strip it down _.each(process.env, (value, key) => { if (_.includes(key, prefix)) { @@ -83,18 +80,16 @@ exports.stripEnv = prefix => { // Return return process.env; - }; /** * Define default config * * @since 3.0.0 - * @alias 'lando.utils.config.defaults' - * @returns {Object} The default config object. + * @alias lando.utils.config.defaults + * @return {Object} The default config object. */ exports.defaults = () => { - // Grab version things const configFilename = 'config.yml'; const srcRoot = path.resolve(__dirname, '..'); @@ -115,24 +110,23 @@ exports.defaults = () => { type: os.type(), platform: os.platform(), release: os.release(), - arch: os.arch() + arch: os.arch(), }, pluginDirs: [srcRoot], product: 'lando', process: process.lando, srcRoot, - userConfRoot: path.join(os.homedir(), '.lando') + userConfRoot: path.join(os.homedir(), '.lando'), }; - }; /** * Merge in config file if it exists * * @since 3.0.0 - * @alias 'lando.utils.config.loadFiles' + * @alias lando.utils.config.loadFiles * @param {Array} files - An array of files to try loading - * @returns {Object} An object of config merged from file sources + * @return {Object} An object of config merged from file sources */ exports.loadFiles = files => _(files) // Filter if file exists @@ -144,11 +138,11 @@ exports.loadFiles = files => _(files) * Filter process.env by a given prefix * * @since 3.0.0 - * @alias 'lando.utils.config.loadEnvs' + * @alias lando.utils.config.loadEnvs * @param {String} prefix - The prefix by which to filter. Should be without the trailing `_` eg `LANDO` not `LANDO_` - * @returns {Object} Object of things with camelCased keys + * @return {Object} Object of things with camelCased keys */ -exports.loadEnvs = prefix => _(process.env) +exports.loadEnvs = prefix => _(process.env) // Only muck with prefix_ variables .pickBy((value, key) => _.includes(key, prefix)) // Prep the keys for consumption diff --git a/lib/events.js b/lib/events.js index b9ca5c9a4..52019e8f4 100644 --- a/lib/events.js +++ b/lib/events.js @@ -8,9 +8,6 @@ const Promise = require('./promise'); /* * Creates a new Events instance. - * - * @param {object} opts - * @return */ class AsyncEvents extends EventEmitter { constructor(log = new Log()) { @@ -27,11 +24,11 @@ class AsyncEvents extends EventEmitter { * This optionally allows a priority to be specified. Lower priorities run first. * * @since 3.0.0 - * @alias 'lando.events.on' - * @param {String} name - The name of the event - * @param {Integer} [priority=5] - The priority the event should run in. - * @param {Function} fn - The function to call. Should get the args specified in the corresponding `emit` declaration. - * @returns {Promise} A Promise + * @alias lando.events.on + * @param {String} name The name of the event + * @param {Integer} [priority=5] The priority the event should run in. + * @param {Function} fn The function to call. Should get the args specified in the corresponding `emit` declaration. + * @return {Promise} A Promise * @example * * // Print out all our apps as they get instantiated and do it before other `post-instantiate-app` events @@ -66,10 +63,10 @@ class AsyncEvents extends EventEmitter { * This makes events blocking and promisified. * * @since 3.0.0 - * @alias 'lando.events.emit' - * @param {String} name - The name of the event - * @param {...Any} [args] - Options args to pass. - * @returns {Promise} A Promise + * @alias lando.events.emit + * @param {String} name The name of the event + * @param {...Any} [args] Options args to pass. + * @return {Promise} A Promise * @example * * // Emits a global event with a config arg @@ -78,25 +75,19 @@ class AsyncEvents extends EventEmitter { * // Emits an app event with a config arg * return app.events.emit('sector001', config); */ - emit() { - - // @todo: this is very old kbox code, can we update it a bit? - + emit(...args) { /* * Helper function that will always return a promise even if function is * synchronous and doesn't return a promise. + * @todo: this is very old kbox code, can we update it a bit? */ - function handle() { - const args = _.toArray(arguments); + const handle = (...args) => { const fn = args.shift(); const result = fn.apply(this, args); return (result instanceof Promise) ? result : Promise.resolve(result); - } - + }; // Save for later const self = this; - // Get args. - const args = _.toArray(arguments); // Grab name of event from first argument. const name = args.shift(); @@ -117,7 +108,7 @@ class AsyncEvents extends EventEmitter { this.log.debug('Event %s has %s listeners', name, fns.length); // Make listener functions to a promise in series. - return Promise.each(fns, fn => { + return Promise.each(fns, fn => { // Clone function arguments. const fnArgs = args.slice(); // Add listener function to front of arguments. @@ -131,9 +122,7 @@ class AsyncEvents extends EventEmitter { // Return true if event had listeners just like the original emit function. .return(!!fns.length); - }; - }; /** @@ -141,7 +130,7 @@ class AsyncEvents extends EventEmitter { * * I don't think you want to ever really use this. Mentioned only for transparency. * - * @alias 'lando.events.__on' + * @alias lando.events.__on * @see https://nodejs.org/api/events.html */ AsyncEvents.prototype.__on = EventEmitter.prototype.on; @@ -151,7 +140,7 @@ AsyncEvents.prototype.__on = EventEmitter.prototype.on; * * I don't think you want to ever really use this. Mentioned only for transparency. * - * @alias 'lando.events.__emit' + * @alias lando.events.__emit * @see https://nodejs.org/api/events.html */ AsyncEvents.prototype.__emit = EventEmitter.prototype.emit; diff --git a/lib/plugins.js b/lib/plugins.js index b0e53d70e..3fb2a611a 100644 --- a/lib/plugins.js +++ b/lib/plugins.js @@ -56,15 +56,15 @@ class Plugins { return Promise.filter(searchPaths, fs.existsSync).all() // Grabs the last path so that we load things from SRC -> SYS -> USER -> OTHER - .then(plugins => { - // Get the correct path - const pluginPath = _.last(plugins); - - // If we have a path lets cache it and return it - if (pluginPath) { - return pluginPath; - } - }); + .then(plugins => { + // Get the correct path + const pluginPath = _.last(plugins); + + // If we have a path lets cache it and return it + if (pluginPath) { + return pluginPath; + } + }); }; diff --git a/lib/promise.js b/lib/promise.js index 4c33d41ec..d9632c306 100644 --- a/lib/promise.js +++ b/lib/promise.js @@ -7,87 +7,53 @@ * All functionality should be the same as bluebird except where indicated * below * + * Note that bluebird currently wants you to use scoped prototypes to extend + * it rather than the normal extend syntax so that is why this is using the "old" + * way + * * @member - * @alias 'lando.Promise' + * @alias lando.Promise * @see http://bluebirdjs.com/docs/api-reference.html + * @see https://github.com/petkaantonov/bluebird/issues/1397 */ -var Promise = require('bluebird'); +const Promise = require('bluebird'); // Use long stack traces. Promise.longStackTraces(); /* - * Retry the function fn up to opts.max times until it successfully completes - * without an error. Pause opts.backoff * retry miliseconds between tries. + * Retry the function fn up to max times until it successfully completes + * without an error. Pause backoff * retry miliseconds between tries. */ -function retry(promise, fn, opts) { - - // Piggy back off of previous promise. - return promise.then(function() { - - // Setup default options. - opts = opts || {}; - opts.max = opts.max || 5; - opts.backoff = opts.backoff || 500; - - // Recursive function. - var rec = function(counter) { - - // Call function fn within the context of a Promise. - return Promise.try(function() { - return fn(counter); - }) - // Handle errors. - .catch(function(err) { - - // If we haven't reached max retries, delay for a short while and - // then retry. - if (counter < opts.max) { - - return Promise.delay(opts.backoff * counter) - .then(function() { - return rec(counter + 1); - }); - - } else { - - // No retries left so wrap and throw the error. - throw new Error( - err, - 'Failed after %s retries. %s', - opts.max, - JSON.stringify(opts) - ); - - } - }); - - }; - - // Init recursive function. - return rec(1); - - }); - -} +const retry = (fn, {max = 5, backoff = 500} = {}) => Promise.resolve().then(() => { + const rec = counter => Promise.try(() => fn(counter) + .catch(err => { + if (counter < max) { + return Promise.delay(backoff * counter).then(() => rec(counter + 1)); + } else { + throw new Error(err, 'Failed after %s retries. %j', max, {backoff, max}); + } + })); + + // Init recursive function. + return rec(1); +}); /* * Adds a retry method to the bluebird Promise module. */ -Promise.retry = function(fn, opts) { - return retry(Promise.resolve(), fn, opts); -}; +Promise.retry = (fn, opts) => retry(fn, opts); /** * Adds a retry method to all Promise instances. * * @since 3.0.0 - * @alias 'lando.Promise.retry' - * @param {Function} fn - The function to retry. - * @param {Opts} [opts] - Options to specify how retry works. - * @param {Integer} [opts.max=5] - The amount of times to retry. - * @param {Integer} [opts.backoff=500] - The amount to wait between retries. In miliseconds and cumulative. - * @returns {Promise} A Promise + * @alias lando.Promise.retry + * @param {Function} fn The function to retry. + * @param {Opts} [opts] Options to specify how retry works. + * @param {Integer} [opts.max=5] The amount of times to retry. + * @param {Integer} [opts.backoff=500] The amount to wait between retries. In miliseconds and cumulative. + * @return {Promise} A Promise * @example * * // Start the deamon @@ -100,9 +66,7 @@ Promise.retry = function(fn, opts) { * }, {max: 25, backoff: 1000}); * */ -Promise.prototype.retry = function(fn, opts) { - return retry(this, fn, opts); -}; +Promise.prototype.retry = (fn, opts) => retry(fn, opts); // Export the promise object module.exports = Promise; diff --git a/lib/serializer.js b/lib/serializer.js index c9265a59a..326e0bf4c 100644 --- a/lib/serializer.js +++ b/lib/serializer.js @@ -4,7 +4,8 @@ const Promise = require('./promise'); /* - * Constructor. + * Creates a new Events instance. + * @todo: Document this better? */ class Serializer { constructor(opts = {}) { @@ -12,9 +13,6 @@ class Serializer { this.last = Promise.resolve(); }; - /* - * Add a function to the serialized queue. - */ enqueue(fn) { const self = this; // Create a new promise that resolves with callback. @@ -22,12 +20,14 @@ class Serializer { // Add another promise to the end of the promise chain. self.last = self.last.then(() => fn.call(self)) // Make sure errors don't stop the promise chain. - .catch(err => { cb(err); }) + .catch(err => { + cb(err); + }) // Nodeify .nodeify(cb); }); }; -} +}; /* * Export the constructor. diff --git a/lib/tasks.js b/lib/tasks.js index 817bf3451..c1f7a8d72 100644 --- a/lib/tasks.js +++ b/lib/tasks.js @@ -7,7 +7,7 @@ const _ = require('lodash'); * A singleton array that contains all the tasks that have been added. * * @since 3.0.0 - * @alias 'lando.tasks.tasks' + * @alias lando.tasks.tasks * @example * * // Gets all the tasks that have been loaded @@ -22,20 +22,21 @@ exports.tasks = []; * and [inquirer](https://github.com/sboudrias/Inquirer.js) with a little extra special sauce. * * @since 3.0.0 - * @alias 'lando.tasks.add' + * @alias lando.tasks.add * @see [yargs docs](http://yargs.js.org/docs/) * @see [inquirer docs](https://github.com/sboudrias/Inquirer.js) - * @param {String} name - The name of the task. - * @param {Object} task - A Lando task object - * @param {String} task.command - A [yargs formatted command](http://yargs.js.org/docs/#methods-commandmodule-positional-arguments) - * @param {String} task.description - A short description of the command - * @param {Object} task.options - A [yargs builder object](http://yargs.js.org/docs/#methods-commandmodule). Each builder also has an 'interactive' key which is an [inquirier question object](https://github.com/sboudrias/Inquirer.js#objects) - * @param {Function} task.run - The function to run when the task is invoked. - * @param {Object} task.run.options - The options selected by the user, available to the run function. + * @param {String} name The name of the task. + * @param {Object} task A Lando task object + * @param {String} task.command A [yargs formatted command](http://yargs.js.org/docs/#methods-commandmodule-positional-arguments) + * @param {String} task.description A short description of the command + * @param {Object} task.options A [yargs builder object](http://yargs.js.org/docs/#methods-commandmodule). Each builder also has an 'interactive' key which is an [inquirier question object](https://github.com/sboudrias/Inquirer.js#objects) + * @param {Function} task.run The function to run when the task is invoked. + * @param {Object} task.run.options The options selected by the user, available to the run function. + * @return {Array} The task object * @example * * // Define a task - * var task = { + * const task = { * command: 'destroy [appname]', * describe: 'Destroy app in current directory or [appname]', * options: { @@ -58,13 +59,13 @@ exports.tasks = []; * // Add the task to Lando * lando.tasks.add('destroy', task); */ -exports.add = (name, data) => { +exports.add = (name, task) => { // Merge task data 2together - const task = _.merge(data, {name: name}); + task = _.merge(task, {name: name}); // Minimal task validation, just checking that common properties exist. If not, throw error. if (!(_.has(task, 'name') && _.has(task, 'command') && _.has(task, 'describe') && _.has(task, 'run'))) { throw new Error('The task object is not valid, please see https://docs.devwithlando.io/api/api.html#landotasksadd'); } // Return - return this.tasks.push(task); + return exports.tasks.push(task); }; diff --git a/lib/updates.js b/lib/updates.js index 3525b8bfa..1ffd39401 100644 --- a/lib/updates.js +++ b/lib/updates.js @@ -7,6 +7,9 @@ const Promise = require('./promise'); const semver = require('semver'); module.exports = class UpdateManager { + /** + * Constructor + */ constructor() { this.githubApi = new GitHubApi({Promise: Promise}); }; @@ -16,14 +19,14 @@ module.exports = class UpdateManager { * Compares two versions and determines if an update is available or not * * @since 3.0.0 - * @alias 'lando.updates.updateAvailable' - * @param {String} version1 - The current version. - * @param {String} version2 - The potential update version + * @alias lando.updates.updateAvailable + * @param {String} version1 The current version. + * @param {String} version2 The potential update version * @return {Boolean} Whether an update is avaiable. * @example * * // Does our current version need to be updated? - * var updateAvailable = lando.updates.updateAvailable('1.0.0', '1.0.1'); + * const updateAvailable = lando.updates.updateAvailable('1.0.0', '1.0.1'); */ updateAvailable(version1, version2) { return semver.lt(version1, version2); @@ -34,7 +37,9 @@ module.exports = class UpdateManager { * Determines whether we need to fetch updatest or not * * @since 3.0.0 - * @alias 'lando.updates.fetch' + * @alias lando.updates.fetch + * @param {Object} data Cached update data + * @return {Boolean} Whether we need to ping GitHub for new data or not */ fetch(data) { // Return true immediately if update is undefined @@ -47,40 +52,40 @@ module.exports = class UpdateManager { * Get latest version info from github * * @since 3.0.0 - * @alias 'lando.updates.refresh' + * @alias lando.updates.refresh + * @param {String} version Lando version to use as a fallback + * @return {Object} Update data */ refresh(version) { - // GitHub repo config const landoRepoConfig = { owner: 'lando', repo: 'lando', page: 1, - 'per_page': 10, + per_page: 10, }; // This i promise you return this.githubApi.repos.getReleases(landoRepoConfig) - // Extract and return the metadata - // @todo: is there an es6 default option thing here that can make latestrelease less cray - .then(data => { - // Get the latest non-draft/non-prerelease version - const latestRelease = _.find(_.get(data, 'data', []), r => (r.draft === false && r.prerelease === false)); - // Return the update data - return { - version: _.trimStart(_.get(latestRelease, 'tag_name', version), 'v'), - url: _.get(latestRelease, 'html_url', ''), - expires: Math.floor(Date.now()) + 86400000 - }; - }) - - // Don't let an error here kill things - .catch(() => ({ - version: _.trimStart(version, 'v'), - url: '', - expires: Math.floor(Date.now()) + 86400000 - })); + // Extract and return the metadata + // @todo: is there an es6 default option thing here that can make latestrelease less cray + .then(data => { + // Get the latest non-draft/non-prerelease version + const latest = _.find(_.get(data, 'data', []), r => (r.draft === false && r.prerelease === false)); + // Return the update data + return { + version: _.trimStart(_.get(latest, 'tag_name', version), 'v'), + url: _.get(latest, 'html_url', ''), + expires: Math.floor(Date.now()) + 86400000, + }; + }) + // Don't let an error here kill things + .catch(() => ({ + version: _.trimStart(version, 'v'), + url: '', + expires: Math.floor(Date.now()) + 86400000, + })); }; }; diff --git a/lib/user.js b/lib/user.js index 902d3e013..35de18dbd 100644 --- a/lib/user.js +++ b/lib/user.js @@ -13,7 +13,7 @@ const getId = (cmd, username = '$(whoami)') => { // Username parsing and command appending cmd.push(username); // Attempt to grab the data - const data = shell(cmd.join(' '), {silent:true}); + const data = shell(cmd.join(' '), {silent: true}); // Throw if error if (data.status !== 0) throw new Error('Cant get data with ' + cmd); // Otherwise return @@ -27,13 +27,13 @@ const getId = (cmd, username = '$(whoami)') => { * has no effect * * @since 3.0.0 - * @alias 'lando.user.getUid' - * @param {String} [username='$(whoami)'] - The username to get the ID for - * @returns {String} The user ID. + * @alias lando.user.getUid + * @param {String} [username='$(whoami)'] The username to get the ID for + * @return {String} The user ID. * @example * * // Get the id of the user. - * var userId = lando.user.getUid(); + * const userId = lando.user.getUid(); */ exports.getUid = username => getId(['id', '-u'], username); @@ -44,12 +44,12 @@ exports.getUid = username => getId(['id', '-u'], username); * has no effect * * @since 3.0.0 - * @alias 'lando.user.getGid' - * @param {String} [username='$(whoami)'] - The username to get the ID for - * @returns {String} The group ID. + * @alias lando.user.getGid + * @param {String} [username='$(whoami)'] The username to get the ID for + * @return {String} The group ID. * @example * * // Get the id of the user. - * var groupId = lando.user.getGid(); + * const groupId = lando.user.getGid(); */ exports.getGid = username => getId(['id', '-g'], username); diff --git a/lib/yaml.js b/lib/yaml.js index 75da6309f..c62528bd5 100644 --- a/lib/yaml.js +++ b/lib/yaml.js @@ -7,26 +7,22 @@ const path = require('path'); const yaml = require('js-yaml'); module.exports = (log = new Log()) => { - /** - * Loads a yaml object from a file + * Loads a yaml object from a file. * * @since 3.0.0 - * @alias 'lando.yaml.load' - * @param {String} file - The path to the file to be loaded + * @alias lando.yaml.load + * @param {String} file The path to the file to be loaded * @return {Object} The loaded object * @example * * // Add a string to the cache - * var thing = lando.yaml.load('/tmp/myfile.yml'); + * const thing = lando.yaml.load('/tmp/myfile.yml'); */ const load = file => { - // Try to load the file try { return yaml.safeLoad(fs.readFileSync(file)); - } - // If not warn the user of some sort of parse error - catch (e) { + } catch (e) { log.error('Problem parsing %s with %s', file, e.message); } }; @@ -35,10 +31,10 @@ module.exports = (log = new Log()) => { * Dumps an object to a YAML file * * @since 3.0.0 - * @alias 'lando.yaml.dump' - * @param {String} file - The path to the file to be loaded - * @param {Object} data - The object to dump - * @return - Flename + * @alias lando.yaml.dump + * @param {String} file The path to the file to be loaded + * @param {Object} data The object to dump + * @return {String} Flename */ const dump = (file, data = {}) => { // Make sure we have a place to store these files @@ -53,5 +49,4 @@ module.exports = (log = new Log()) => { // Return return {dump, load}; - }; diff --git a/package.json b/package.json index bfab72ca2..5d3ac8d9d 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "scripts": { "coverage": "nyc report --reporter=text-lcov | coveralls", "docs": "node ./scripts/docs.js && gitbook install && gitbook build", - "lint": "eslint bin lib plugins test scripts", + "lint": "eslint bin docs lib scripts test && eslint --config .eslintrc.old.json plugins", "pkg:cli": "node ./scripts/pkg.js --stage=cli", "pkg:full": "node ./scripts/pkg.js --stage=full", "release:major": "node ./scripts/bump.js --stage=major", diff --git a/scripts/bump.js b/scripts/bump.js index 8278fcc4e..468063941 100755 --- a/scripts/bump.js +++ b/scripts/bump.js @@ -1,7 +1,8 @@ #!/usr/bin/env node + 'use strict'; -/** +/* * Constants */ const argv = require('yargs').argv; @@ -12,64 +13,47 @@ const currentBranch = util.execGitCmd( 'Getting current branch' ).trim(); -/** - * Functions - */ - -/** +/* * Bump the package.json version number and write it back to the file. - * - * @param {object} pkgJson package.json contents. - * @param {string} stage Semver stage identifier (prerelease, patch, minor, major). - * - * @return {object} Updated package.json data. */ -function bumpPkgJson(pkgJson, stage) { +const bumpPkgJson = (pkgJson, stage) => { pkgJson.version = util.setVersion(pkgJson, stage); return pkgJson; -} +}; -/** +/* * Converts an Git command from an array to a string. - * - * @param {array} cmd Git command as array. - * - * @returns {string} representation of Git command. */ -function expandGitCmd(cmd = []) { +const expandGitCmd = (cmd = []) => { return 'git ' + cmd.join(' '); -} +}; const pkgJson = JSON.parse(fs.readFileSync('./package.json', 'utf8')); const newJson = bumpPkgJson(pkgJson, argv.stage); -const commitCmd = ['commit', 'package.json', '-m', 'Release v' + newJson.version], - pushBranchCmd = ['push', 'origin', currentBranch], - pushTagCmd = ['push', 'origin', 'v' + newJson.version], - tagCmd = ['tag', '-a', 'v' + pkgJson.version, '-m', 'Version v' + newJson.version]; +const commitCmd = ['commit', 'package.json', '-m', 'Release v' + newJson.version]; +const pushBranchCmd = ['push', 'origin', currentBranch]; +const pushTagCmd = ['push', 'origin', 'v' + newJson.version]; +const tagCmd = ['tag', '-a', 'v' + pkgJson.version, '-m', 'Version v' + newJson.version]; -/** +/* * Do the stuff. */ if (argv.dryRun) { console.log('Dry-Run: Would have bumped version in package.json to: v' + newJson.version); - return [commitCmd, tagCmd, pushBranchCmd, pushTagCmd].map(function(cmd) { + return [commitCmd, tagCmd, pushBranchCmd, pushTagCmd].map(cmd => { return console.log('Dry-Run: Would have run: ' + expandGitCmd(cmd)); }); -} -else { - +} else { // Bump the version in package.json console.log('Bumping Lando to version ' + pkgJson.version); - fs.writeFile('./package.json', JSON.stringify(pkgJson, null, 2), 'utf8', function (err) { + fs.writeFile('./package.json', JSON.stringify(pkgJson, null, 2), 'utf8', err => { if (err) { throw err; } // Commit, Tag, Push! - [commitCmd, tagCmd, pushBranchCmd, pushTagCmd].map(function (cmd) { + [commitCmd, tagCmd, pushBranchCmd, pushTagCmd].map(cmd => { return util.execGitCmd(cmd, 'running ' + expandGitCmd(cmd)); }); - }); - } diff --git a/scripts/dev-version.js b/scripts/dev-version.js index 15cdc072d..0b0f4b065 100644 --- a/scripts/dev-version.js +++ b/scripts/dev-version.js @@ -1,4 +1,6 @@ -/** +#!/usr/bin/env node + +/* * This is a nifty cross platform script that will replace relevant versions * in json files with a "dev" version generated with `git describe` */ @@ -6,37 +8,34 @@ 'use strict'; // Grab needed modules -var _ = require('lodash'); -var fs = require('fs-extra'); -var path = require('path'); -var Promise = require('bluebird'); -var exec = require('child_process').exec; +const _ = require('lodash'); +const fs = require('fs-extra'); +const path = require('path'); +const Promise = require('bluebird'); +const exec = require('child_process').exec; // Get the location of the files we need to edit -var files = ['package.json']; +const files = ['package.json']; // Start our sacred promise -return new Promise(function(resolve, reject) { - exec('git describe --tags --always --abbrev=1', function(error, stdout, stderr) { +return new Promise((resolve, reject) => { + exec('git describe --tags --always --abbrev=1', (error, stdout, stderr) => { if (error) { reject(new Error('error: ' + error + 'err:' + stderr)); - } - else { + } else { resolve(stdout); } }); }) // Get the git describe result and parse it -.then(function(data) { - return _.trim(data.slice(1)); -}) +.then(data => _.trim(data.slice(1))) // Replace the version for our files -.then(function(newVersion) { - _.forEach(files, function(file) { - var location = path.join(process.cwd(), file); - var data = require(location); +.then(newVersion => { + _.forEach(files, file => { + const location = path.join(process.cwd(), file); + const data = require(location); data.version = newVersion; console.log('Updating %s to dev version %s', file, data.version); fs.writeFileSync(location, JSON.stringify(data, null, 2)); @@ -44,6 +43,6 @@ return new Promise(function(resolve, reject) { }) // Catch errors and do stuff so we can break builds when this fails -.catch(function(error) { +.catch(error => { process.exit(error.code || 1); }); diff --git a/scripts/docs.js b/scripts/docs.js index b26079e6b..788bb2dfc 100755 --- a/scripts/docs.js +++ b/scripts/docs.js @@ -35,48 +35,69 @@ const fileMap = [ './plugins/lando-services/*.js', './plugins/lando-services/**/*.js', './plugins/lando-tooling/*.js', - './plugins/lando-tooling/**/*.js' + './plugins/lando-tooling/**/*.js', ]; const helpers = [ - './docs/helpers/helpers.js' + './docs/helpers/helpers.js', ]; const partials = [ './docs/partials/header.hbs', - './docs/partials/body.hbs' + './docs/partials/body.hbs', ]; +const needsWrapping = s => !_.startsWith(s, '\'') && !_.endsWith(s, '\'') && _.includes(s, 'lando.'); + // Collect any errors // // @NOTE: this will save time so we can see ALL the errors at once instead // of one per CI build const errors = []; -// Render the things -return jsdoc2md.render({ - files: fileMap, +// Get the data so we can preprocess it +return jsdoc2md.getTemplateData({'files': fileMap, 'no-cache': true}) + +// Fix "aliases" and then render +.then(data => _.map(data, datum => { + // Enclose lando-y aliases in single quotes + if (_.has(datum, 'alias') && needsWrapping(datum.alias)) { + if (!_.startsWith(datum.alias, '\'lando.') && !_.endsWith(datum.alias, '\'')) { + datum.name = datum.alias; + datum.kind = 'function'; + datum.scope = 'global'; + delete datum.memberof; + } + } + return datum; +})) + +// Do the render +.then(data => jsdoc2md.render({ + 'data': data, 'global-index-format': 'none', - helper: helpers, - partial: partials -}) + 'helper': helpers, + 'partial': partials, +})) // Report and collect errors -.catch(function(error) { +.catch(error => { errors.push(error.message); console.log(chalk.red('ERROR: ' + error.message)); }) // Write the file if we have data -.then(function(data) { +.then(data => { if (data) { console.log('writing ' + dest + '...'); - return fs.outputFile(dest, data, function(error) { if (error) { throw error; } }); + return fs.outputFile(dest, data, error => { + if (error) throw error; + }); } }) // Do the final error throw if we can -.then(function() { +.then(() => { if (!_.isEmpty(errors)) { console.log(); console.log(chalk.red('API doc build failed! See above errors!!!')); diff --git a/scripts/pkg.js b/scripts/pkg.js index b111be796..f747273bd 100755 --- a/scripts/pkg.js +++ b/scripts/pkg.js @@ -6,7 +6,6 @@ const util = require('./util'); if (argv.stage === 'cli') { return pkg.pkgCli(); -} -else if (argv.stage === 'full') { +} else if (argv.stage === 'full') { return pkg.pkgFull(util.platform); } diff --git a/scripts/pkg/functions.js b/scripts/pkg/functions.js index 1db8dec5a..c076659bc 100644 --- a/scripts/pkg/functions.js +++ b/scripts/pkg/functions.js @@ -25,17 +25,17 @@ const files = { path.join('plugins', '**'), path.join('config.yml'), path.join('package.json'), - path.join('yarn.lock') + path.join('yarn.lock'), ], clean: { cli: { build: [path.join('build', 'cli', path.sep)], - dist: [path.join('dist', 'cli', path.sep)] + dist: [path.join('dist', 'cli', path.sep)], }, installer: { build: [path.join('build', 'installer', path.sep)], - dist: [path.join('dist', path.sep)] - } + dist: [path.join('dist', path.sep)], + }, }, // Our copy tasks copy: { @@ -44,9 +44,9 @@ const files = { src: path.join('build', 'cli', cliPkgName), dest: path.join('dist', 'cli', cliPkgName), options: { - mode: true - } - } + mode: true, + }, + }, }, installer: { build: { @@ -55,8 +55,8 @@ const files = { dest: path.join('build', 'installer', path.sep), expand: true, options: { - mode: true - } + mode: true, + }, }, dist: { cwd: path.join('build', 'installer', 'dist', path.sep), @@ -64,63 +64,51 @@ const files = { dest: path.join('dist', path.sep), expand: true, options: { - mode: true - } - } - } + mode: true, + }, + }, + }, }, }; module.exports = { - /** + /* * Helper function to clean multiple directories. - * - * @param {Array} directories */ - clean: function (directories) { - return directories.map(function(dir) { - dir.map(function(nestedDir) { + clean: directories => { + return directories.map(dir => { + dir.map(nestedDir => { return fs.emptyDirSync(nestedDir); }); }); }, - /** + /* * Package the CLI. - * - * @return {Promise} Chain of the packager followed by copy. */ pkgCli: function() { this.clean([files.clean.cli.build, files.clean.cli.dist]); - copy(files.build, path.join('build', 'cli'), {srcBase: '.'}, (err, files) => { if (err) { throw err; } }); + copy(files.build, path.join('build', 'cli'), {srcBase: '.'}, (err, files) => { + if (err) throw err; + }); const pkgCmd = this.cliPkgTask(); return util.shellExec(pkgCmd).then(result => fs.copy(files.copy.cli.dist.src, files.copy.cli.dist.dest, err => { - if (err) { throw err; } + if (err) throw err; })); }, - /** + /* * Build full installer - * @param platform - * @returns {Promise} */ - pkgInstaller: function(platform) { + pkgInstaller: platform => { const extension = (platform === 'win32') ? 'ps1' : 'sh'; const script = path.join('scripts', `build-${platform}.${extension}`); - - const task = function(extension) { - if (extension === 'ps1') { - return util.psTask(script); - } else { - return util.scriptTask(script); - } - }; - + const task = extension => (extension === 'ps1') ? util.psTask(script) : util.scriptTask(script); return util.shellExec(task(extension)); }, - /** + /* * Run the full packager */ pkgFull: function() { @@ -129,46 +117,48 @@ module.exports = { path.join('installer', util.platform, '**'), path.join('build', 'installer', path.sep), {mode: true, srcBase: path.join('installer', util.platform, path.sep)}, - (err, files) => { if (err) throw err; } + (err, files) => { + if (err) throw err; + } ); this.pkgCli().then(result => { this.pkgInstaller(util.platform).then(result => copy( - path.join('build', 'installer', 'dist', '**'), - path.join('dist'), - {mode: true, srcBase: path.join('build', 'installer', 'dist', path.sep)}, - (err, files) => { if (err) throw err; } - )); + path.join('build', 'installer', 'dist', '**'), + path.join('dist'), + {mode: true, srcBase: path.join('build', 'installer', 'dist', path.sep)}, + (err, files) => { + if (err) throw err; + } + )); }); }, /* * Constructs the CLI PKG task */ - cliPkgTask: function() { - + cliPkgTask: () => { // Path to the pkg command - var binDir = path.resolve(__dirname, '..', '..', 'node_modules', 'pkg'); - var pkg = path.join(binDir, 'lib-es5', 'bin.js'); + const binDir = path.resolve(__dirname, '..', '..', 'node_modules', 'pkg'); + const pkg = path.join(binDir, 'lib-es5', 'bin.js'); // Get target info - var node = 'node8'; - var os = process.platform; - var arch = 'x64'; + const node = 'node8'; + const os = process.platform; + const arch = 'x64'; // Rename the OS because i guess we want to be different than process.platform? if (process.platform === 'darwin') { os = 'macos'; - } - else if (process.platform === 'win32') { + } else if (process.platform === 'win32') { os = 'win'; } // Exec options - var pkgName = cliPkgName; - var configFile = path.join('package.json'); - var entrypoint = path.join('bin', 'lando.js'); - var target = [node, os, arch].join('-'); - var shellOpts = { + const pkgName = cliPkgName; + const configFile = path.join('package.json'); + const entrypoint = path.join('bin', 'lando.js'); + const target = [node, os, arch].join('-'); + const shellOpts = { execOptions: { stdout: true, stderr: true, @@ -177,22 +167,22 @@ module.exports = { stdinRawMode: false, preferLocal: true, maxBuffer: 20 * 1024 * 1024, - } + }, }; // Package command - var pkgCmd = [ + const pkgCmd = [ 'node', pkg, '--targets ' + target, '--config ' + configFile, '--output ' + pkgName, - entrypoint + entrypoint, ]; // Start to build the command - var cmd = []; - var cliBuild = path.join('build', 'cli', path.sep); + const cmd = []; + const cliBuild = path.join('build', 'cli', path.sep); cmd.push('cd ' + cliBuild); cmd.push('yarn --production'); cmd.push(pkgCmd.join(' ')); @@ -206,10 +196,8 @@ module.exports = { // Return the CLI build task return { options: shellOpts, - command: cmd.join(' && ') + command: cmd.join(' && '), }; - - } - + }, }; diff --git a/scripts/util.js b/scripts/util.js index cde919187..60b2f0e27 100644 --- a/scripts/util.js +++ b/scripts/util.js @@ -6,18 +6,18 @@ const semver = require('semver'); module.exports = { - /** + /* * Helper to run Git Comamnds * @see https://github.com/pankajladhar/run-git-command/blob/master/index.js * @param args * @param customMsg */ - execGitCmd: function(args, customMsg) { + execGitCmd: (args, customMsg) => { console.log(customMsg); return child.spawnSync('git', args, {stdio: [0, 'pipe', 'pipe'], encoding: 'utf8'}).stdout; }, - /** + /* * The platform normalize for pkg */ platform: (process.platform !== 'darwin') ? process.platform : 'osx', @@ -25,28 +25,21 @@ module.exports = { /* * Run a ps script */ - psTask: function(cmd) { - - // "Constants" - var shellOpts = {execOptions: {maxBuffer: 20 * 1024 * 1024}}; - var entrypoint = 'PowerShell -NoProfile -ExecutionPolicy Bypass -Command'; - - // Return our ps task + psTask: cmd => { return { - options: shellOpts, - command: [entrypoint, cmd, '&& EXIT /B %errorlevel%'].join(' ') + options: {execOptions: {maxBuffer: 20 * 1024 * 1024}}, + command: ['PowerShell -NoProfile -ExecutionPolicy Bypass -Command', cmd, '&& EXIT /B %errorlevel%'].join(' '), }; - }, - /** + /* * Bump the Version of a Package.json given a json object and stage. * * @param {Object} pkgJson Package.json file as a loaded object. * @param {String} stage The release stage. * @returns {String} New version number. */ - setVersion: function(pkgJson, stage) { + setVersion: (pkgJson, stage) => { const current = pkgJson.version; switch (stage) { case 'prerelease': @@ -65,20 +58,18 @@ module.exports = { /* * Run a default bash/sh/cmd script */ - scriptTask: function(cmd) { - - // "Constants" - var shellOpts = {execOptions: {maxBuffer: 20 * 1024 * 1024}}; - - // Return our shell task + scriptTask: cmd => { return { - options: shellOpts, - command: cmd + options: {execOptions: {maxBuffer: 20 * 1024 * 1024}}, + command: cmd, }; - }, - shellExec: function(data) { + /* + * This does something? + * @todo: Dustin? + */ + shellExec: data => { const opts = { stdout: true, stderr: true, @@ -87,19 +78,17 @@ module.exports = { stdinRawMode: false, preferLocal: true, execOptions: { - env: data.options.execOptions.env || process.env - } + env: data.options.execOptions.env || process.env, + }, }; const cmd = typeof data === 'string' ? data : data.command; - if (cmd === undefined) { - throw new Error('`command` required'); - } + if (cmd === undefined) throw new Error('`command` required'); opts.execOptions = Object.assign(data.options, opts.execOptions); - const promiseFromChild = function(child) { - return new Promise(function(resolve, reject) { + const promiseFromChild = child => { + return new Promise((resolve, reject) => { child.addListener('error', reject); child.addListener('exit', resolve); }); @@ -107,18 +96,18 @@ module.exports = { const cp = child.exec(cmd, opts.execOptions); - cp.stdout.on('data', function (data) { + cp.stdout.on('data', data => { console.log('stdout: ' + data); }); - cp.stderr.on('data', function (data) { + cp.stderr.on('data', data => { console.log('stderr: ' + data); }); - return promiseFromChild(cp).then(function (result) { + return promiseFromChild(cp) + .then(result => { console.log('promise complete: ' + result); - }, function (err) { + }, err => { console.log('promise rejected: ' + err); }); - - } + }, }; diff --git a/test/helpers/functional/cli.js b/test/helpers/functional/cli.js index 9c12f89f2..d11315ee4 100644 --- a/test/helpers/functional/cli.js +++ b/test/helpers/functional/cli.js @@ -12,13 +12,8 @@ const os = require('os'); * Class containing static methods to help with running tests */ class CliHelper { - - /** + /* * Execute a Lando Command using the entrypoint in codebase - * @param {array} args - arguments/options to pass to Lando - * @param {object} opts - options to pass to execFile - * @return {Promise} - A promise chain containing output of - * command execution */ static execCommand(args, options) { const cliTest = new CliTest(); @@ -35,7 +30,7 @@ class CliHelper { const appFolder = fs.mkdtempSync( path.join(os.tmpdir(), 'lando-php-test-'), (err, folder) => { - if (err) { throw err; } + if (err) throw err; return folder; } ); @@ -45,7 +40,9 @@ class CliHelper { `${appFolder}${path.sep}.lando.yml`, jsYaml.dump(app), 'utf8', - err => { if (err) { throw err; } } + err => { + if (err) throw err; + } ); return new Promise((resolve, reject) => { diff --git a/test/unit/cache.spec.js b/test/unit/cache.spec.js index a5429ec48..b4de101fc 100644 --- a/test/unit/cache.spec.js +++ b/test/unit/cache.spec.js @@ -16,7 +16,6 @@ chai.should(); const Cache = require('./../../lib/cache'); describe('cache', () => { - describe('#Cache', () => { it('returns a cache instance with correct default options', () => { const cache = new Cache(); @@ -117,7 +116,7 @@ describe('cache', () => { const cache = new Cache(); - cache.set('yyz', 'amazing', {ttl:1}); + cache.set('yyz', 'amazing', {ttl: 1}); expect(cache.get('yyz')).to.eql('amazing'); clock.tick(1500); @@ -155,7 +154,7 @@ describe('cache', () => { const cache = new Cache(); - cache.set('yyz', 'amazing', {ttl:1}); + cache.set('yyz', 'amazing', {ttl: 1}); expect(cache.get('yyz')).to.eql('amazing'); clock.tick(1500); diff --git a/test/unit/config.spec.js b/test/unit/config.spec.js index 0490207ad..32799481a 100644 --- a/test/unit/config.spec.js +++ b/test/unit/config.spec.js @@ -15,7 +15,6 @@ chai.should(); const config = require('./../../lib/config'); describe('config', () => { - describe('#tryConvertJson', () => { it('returns the unaltered input if input is not a parsable JSON string', () => { const input = 'obiwan'; @@ -35,7 +34,6 @@ describe('config', () => { const result = config.tryConvertJson(input); expect(result).to.be.an('array'); }); - }); describe('#merge', () => { @@ -47,7 +45,7 @@ describe('config', () => { const bands2 = { best: 'nickelback', worst: 'miley', - supreme: 'taylor' + supreme: 'taylor', }; const landoMerge = hasher(config.merge(bands1, bands2)); const lodashMerge = hasher(_.merge(bands1, bands2)); @@ -69,7 +67,6 @@ describe('config', () => { expect(ourfavs.favs).to.have.length(3); expect(hasher(ourfavs.favs)).to.equal(hasher(['nickelback', 'abba', 'britney'])); }); - }); describe('#stripEnvs', () => { @@ -149,7 +146,7 @@ describe('config', () => { it('gives priority to the last file loaded', () => { filesystem({ '/tmp/config1.yml': 'scoundrel: lando', - '/tmp/config2.yml': 'scoundrel: solo' + '/tmp/config2.yml': 'scoundrel: solo', }); const fileConfig = config.loadFiles(['/tmp/config1.yml', '/tmp/config2.yml']); expect(hasher(fileConfig)).to.equal(hasher({scoundrel: 'solo'})); @@ -166,5 +163,4 @@ describe('config', () => { expect(result.now).to.equal(process.env.DANCE_NOW); }); }); - }); diff --git a/test/unit/events.spec.js b/test/unit/events.spec.js index d791add0c..1ae609371 100644 --- a/test/unit/events.spec.js +++ b/test/unit/events.spec.js @@ -15,7 +15,6 @@ chai.should(); const AsyncEvents = require('../../lib/events'); describe('events', () => { - describe('#AsyncEvents', () => { it('returns an events instance with correct default options', () => { const events = new AsyncEvents(); diff --git a/test/unit/node.spec.js b/test/unit/node.spec.js index a04646b3b..f042cf42e 100644 --- a/test/unit/node.spec.js +++ b/test/unit/node.spec.js @@ -14,7 +14,6 @@ chai.should(); const node = require('./../../lib/node'); describe('node', () => { - describe('#node', () => { it('is a non-empty object', () => { expect(node).to.be.an('object'); @@ -34,5 +33,4 @@ describe('node', () => { }); }); }); - }); diff --git a/test/unit/plugins.spec.js b/test/unit/plugins.spec.js index 860a63682..ec989500d 100644 --- a/test/unit/plugins.spec.js +++ b/test/unit/plugins.spec.js @@ -28,7 +28,7 @@ describe('plugins', function() { it('should look for plugins in reverse order of passed dirs', function() { plugins.load('test-plugin-one', [ process.cwd() + '/test/fixtures', - process.cwd() + '/test/fixtures/test-app' + process.cwd() + '/test/fixtures/test-app', ]).then(function() { plugins.loadedModules .should diff --git a/test/unit/serializer.spec.js b/test/unit/serializer.spec.js index 42a5b4f62..ee66ba7d2 100644 --- a/test/unit/serializer.spec.js +++ b/test/unit/serializer.spec.js @@ -14,7 +14,6 @@ chai.should(); const Serializer = require('./../../lib/serializer'); describe('serializer', () => { - describe('#Serializer', () => { it('returns a serializer instance with correct default options', () => { const serializer = new Serializer(); @@ -53,5 +52,4 @@ describe('serializer', () => { }); }); }); - }); diff --git a/test/unit/shell.spec.js b/test/unit/shell.spec.js index bde95bdfc..dff60a140 100644 --- a/test/unit/shell.spec.js +++ b/test/unit/shell.spec.js @@ -23,7 +23,7 @@ describe('shell', () => { }); it('should reject on a non-zero exit', function() { - const stub = sinon.stub(_shell, 'exec').returns({code:1}); + const stub = sinon.stub(_shell, 'exec').returns({code: 1}); shell.exec('nonsense').should.eventually.be.rejectedWith(Error); stub.should.be.calledWith('nonsense'); stub.restore(); diff --git a/test/unit/tasks.spec.js b/test/unit/tasks.spec.js index 9fd1ed881..6f56d1d19 100644 --- a/test/unit/tasks.spec.js +++ b/test/unit/tasks.spec.js @@ -22,18 +22,17 @@ const elScorcho = { boolean: true, interactive: { type: 'confirm', - message: 'Are you sure you are jello?' - } - } + message: 'Are you sure you are jello?', + }, + }, }, run: function(options) { console.log(options); - } + }, }; describe('tasks', () => { - - describe('#add', () => { + describe('#add', () => { it('Adds tasks to tasks collection', () => { tasks.add('El Scorcho', elScorcho); tasks.tasks[0].should.have.property('name', 'El Scorcho'); diff --git a/test/unit/updates.spec.js b/test/unit/updates.spec.js index cd4702f20..f5bdb992f 100644 --- a/test/unit/updates.spec.js +++ b/test/unit/updates.spec.js @@ -18,8 +18,7 @@ const UpdateManager = require('./../../lib/updates'); const updates = new UpdateManager(); describe('updates', () => { - - describe('#updateAvailable', () => { + describe('#updateAvailable', () => { it('checks to see if version 1 is less than version 2', () => { updates.updateAvailable('3.0.0', '3.0.1').should.be.true; updates.updateAvailable('3.0.1', '3.0.1').should.be.false; @@ -50,14 +49,13 @@ describe('updates', () => { }); }); - describe('#refresh', function() { + describe('#refresh', () => { // We need a Github API Client to stub. const github = new Github({Promise: Promise}); // Use our stubbed Github API so we don't make a real HTTP request. updates.githubApi = github; - it('Does a Barrel Roll if there is an error', function() { - + it('Does a Barrel Roll if there is an error', () => { // Throw an error on purpose const stub = sinon.stub(updates.githubApi.repos, 'getReleases') .rejects('Whoops!'); @@ -70,33 +68,33 @@ describe('updates', () => { }); // @Todo: figure out why this passes no matter what value we pass - //it('filters out drafts/prereleases', function() { - //const stub = sinon.stub(updates.githubApi.repos, 'getReleases') - //.returns( - //new Promise(() => [ - //{ - //'tag_name': 'vbeta.1', - //'prerelease': false, - //'draft': false - //}, - //{ - //'tag_name': 'vbeta.2', - //'prerelease': true, - //'draft': false - //}, - //{ - //'tag_name': 'vbeta.3', - //'prerelease': false, - //'draft': true - //} - //] - //) - //); - - //updates.refresh('beta.2').should.eventually.be - //.an('object').with.property('version', 'beta.1'); - - //stub.restore(); - //}); + // it('filters out drafts/prereleases', function() { + // const stub = sinon.stub(updates.githubApi.repos, 'getReleases') + // .returns( + // new Promise(() => [ + // { + // 'tag_name': 'vbeta.1', + // 'prerelease': false, + // 'draft': false + // }, + // { + // 'tag_name': 'vbeta.2', + // 'prerelease': true, + // 'draft': false + // }, + // { + // 'tag_name': 'vbeta.3', + // 'prerelease': false, + // 'draft': true + // } + // ] + // ) + // ); + + // updates.refresh('beta.2').should.eventually.be + // .an('object').with.property('version', 'beta.1'); + + // stub.restore(); + // }); }); }); diff --git a/test/unit/user.spec.js b/test/unit/user.spec.js index 8ec9c69d7..27dff13d3 100644 --- a/test/unit/user.spec.js +++ b/test/unit/user.spec.js @@ -20,7 +20,6 @@ const resetPlatform = function() { const user = require('./../../lib/user'); describe('user', () => { - describe('#getUid', () => { it('returns user 1000 on Windows', () => { setPlatform('win32'); @@ -51,8 +50,7 @@ describe('user', () => { it('throws an error for a bogus user on POSIX', () => { if (process.platform === 'win32') { expect(() => user.getUid('gandalflandokenobi5000')).to.not.throw(Error); - } - else { + } else { expect(() => user.getUid('gandalflandokenobi5000')).to.throw(Error); } }); @@ -88,11 +86,9 @@ describe('user', () => { it('throws an error for a bogus user on POSIX', () => { if (process.platform === 'win32') { expect(() => user.getGid('gandalflandokenobi5000')).to.not.throw(Error); - } - else { + } else { expect(() => user.getGid('gandalflandokenobi5000')).to.throw(Error); } }); }); - }); diff --git a/test/unit/yaml.spec.js b/test/unit/yaml.spec.js index 7e03708ba..0f2026cab 100644 --- a/test/unit/yaml.spec.js +++ b/test/unit/yaml.spec.js @@ -14,10 +14,11 @@ const os = require('os'); const path = require('path'); chai.should(); -const yaml = require('./../../lib/yaml')({error: () => { throw Error(); }}); +const yaml = require('./../../lib/yaml')({error: () => { + throw Error(); +}}); describe('yaml', () => { - describe('#load', () => { it('returns data from a YAML file as an Object', () => { const content = ['obiwan: kenobi', 'qui:', '- gon', '- jinn'].join(os.EOL); @@ -60,5 +61,4 @@ describe('yaml', () => { filesystem.restore(); }); }); - });