From c8632297c74f0febd12fb5f7fab0b3be956ea166 Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Fri, 27 Nov 2015 10:29:38 -0500 Subject: [PATCH 01/23] FLUID-5799: Check existence of remote repo Will check that the specified remote actually exists, and throw an error if it doesn't. Also added options to specify the remote name. --- README.md | 22 ++++++++++++++++++++++ package.json | 4 +++- publish.js | 27 +++++++++++++++++++++++---- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d4e37cd..de615d6 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,17 @@ publish.standard(); "git status -s -uno" + + + checkRemoteCmd + + + The CLI to execute which determines if the remote repository exists. This prevents trying to push a version control tag to a repo that doesn't exist. + + + "git ls-remote --exit-code ${remote}" + + rawTimestampCmd @@ -298,6 +309,17 @@ publish.standard(); "dev" + + + remoteName + + + The remote repository to push version control tag to. + + + "upstream" + + diff --git a/package.json b/package.json index 3eda31c..fb0b11d 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ }, "defaultOptions": { "changesCmd": "git status -s -uno", + "checkRemoteCmd": "git ls-remote --exit-code ${remote}", "rawTimestampCmd": "git show -s --format=%ct HEAD", "revisionCmd": "git rev-parse --verify --short HEAD", "packCmd": "npm pack", @@ -48,9 +49,10 @@ "distTagCmd": "npm dist-tag add ${packageName}@${version} ${tag}", "cleanCmd": "git checkout -- package.json", "vcTagCmd": "git tag -a v${version} -m 'Tagging the ${version} release'", - "pushVCTagCmd": "git push upstream v${version}", + "pushVCTagCmd": "git push ${remote} v${version}", "devVersion": "${version}-${preRelease}.${timestamp}.${revision}", "devTag": "dev", + "remoteName": "upstream", "moduleRoot": "" } } diff --git a/publish.js b/publish.js index b93506c..4e527fc 100644 --- a/publish.js +++ b/publish.js @@ -138,7 +138,7 @@ publish.checkChanges = function (options) { }; /** - * Calls publish.execSync with a + * Calls publish.execSync with a command crafted from a template string. * If it is a test run, the command will be output to the console. * * @param cmdTemplate {String} - A string template of the command to execute. @@ -150,12 +150,25 @@ publish.checkChanges = function (options) { publish.execSyncFromTemplate = function (cmdTemplate, cmdValues, isTest) { var cmdStr = es6Template(cmdTemplate, cmdValues); if (isTest) { - publish.log("command: " + cmdStr); + publish.log("command: " + cmdStr + " \n"); } else { publish.execSync(cmdStr); } }; +/** + * Checks that the remote exists. If it does not exist an error is thrown. + * + * @param options {Object} - e.g. {"checkRemoteCmd": "git ls-remote --exit-code ${remote}", "remoteName": "upstream"} + */ +publish.checkRemote = function (options) { + var cmdTemplate = options.checkRemoteCmd || defaults.checkRemoteCmd; + + publish.execSyncFromTemplate(cmdTemplate, { + remote: options.remoteName || defaults.remoteName + }); +}; + /** * Updates the package.json version to the specified version * This does not commit the change, it will only modify the file. @@ -237,7 +250,7 @@ publish.tag = function (isTest, packageName, version, tag, options) { * * @param isTest {Boolean} - indicates if this is a test run or not * @param version {String} - a string indicating the version - * @param options {Object} - e.g. {"vcTagCmd": "git tag -a v${version} -m 'Tagging the ${version} release'", "pushVCTagCmd": "git push upstream v${version}"} + * @param options {Object} - e.g. {"vcTagCmd": "git tag -a v${version} -m 'Tagging the ${version} release'", "pushVCTagCmd": "git push ${remote} v${version}", "remoteName": "upstream"} */ publish.tagVC = function (isTest, version, options) { var cmdTemplates = [ @@ -245,9 +258,12 @@ publish.tagVC = function (isTest, version, options) { options.pushVCTagCmd || defaults.pushVCTagCmd ]; + var remote = options.remoteName || defaults.remoteName; + cmdTemplates.forEach(function (cmdTemplate) { publish.execSyncFromTemplate(cmdTemplate, { - version: version + version: version, + remote: remote }, isTest); }); }; @@ -329,6 +345,9 @@ publish.standard = function (isTest, options) { // Ensure no uncommitted changes publish.checkChanges(opts); + // Ensure that the specified remote repository exists + publish.checkRemote(opts); + // create version control tag publish.tagVC (isTest, modulePkg.version, opts); From d8bf7b2c35029bc34cc7cd1a2c8ceaef04cd06ce Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Fri, 27 Nov 2015 20:04:18 -0500 Subject: [PATCH 02/23] FLUID-5799: Refactored to log all exec commands --- publish.js | 94 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 56 insertions(+), 38 deletions(-) diff --git a/publish.js b/publish.js index 4e527fc..c795671 100644 --- a/publish.js +++ b/publish.js @@ -16,14 +16,16 @@ var publish = {}; var path = require("path"); var extend = require("extend"); +// TODO: The supported version of node.js does not yet support ES6 template strings +// When version node.js 4.x.x is supported this can be replaced by native support. +var es6Template = require("es6-template-strings"); + // execSync and log are added to the exported "publish" namespace so they can // be stubbed in the tests. publish.execSync = require("child_process").execSync; publish.log = console.log; -// TODO: The supported version of node.js does not yet support ES6 template strings -// When version node.js 4.x.x is supported this can be replaced by native support. -var es6Template = require("es6-template-strings"); + /** * Returns the contents of a package.json file as JSON object @@ -124,35 +126,50 @@ publish.convertToISO8601 = function (timestamp) { }; /** - * Throws an error if there are any uncommitted changes + * Retrieves the requested option, or a default value if the option does not exist. + * The default value comes from the default object read in from the package.json file's + * "defaultOptions" property. * - * @param options {Object} - e.g. {"changesCmd": "git status -s -uno"} - * @throws Error - An error object with a message containing a list of uncommitted changes. + * @param options {Object} - e.g. {"key": "value"} + * @param key {String} - the particular option to look up and return the value for. */ -publish.checkChanges = function (options) { - var cmdStr = options.changesCmd || defaults.changesCmd; - var changes = publish.execSync(cmdStr); - if (changes.length) { - throw new Error("You have uncommitted changes\n" + changes); - } +publish.getOpt = function (options, key) { + return options[key] || defaults[key]; }; /** * Calls publish.execSync with a command crafted from a template string. - * If it is a test run, the command will be output to the console. + * If it is a test run, the command will only be logged to the console. * * @param cmdTemplate {String} - A string template of the command to execute. * Can provide tokens in the form ${tokenName} * @param values {Object} - the tokens and their replacement. * e.g. {tokenName: "value to insert"} - * @param isTest {Boolean} - indicates if this is a test run or not + * @param isTest {Boolean} - indicates if this is a test run or not. If it is + * a test run, the command will be logged but not executed. */ publish.execSyncFromTemplate = function (cmdTemplate, cmdValues, isTest) { var cmdStr = es6Template(cmdTemplate, cmdValues); - if (isTest) { - publish.log("command: " + cmdStr + " \n"); - } else { - publish.execSync(cmdStr); + + publish.log("executing command: " + cmdStr + " \n"); + + if (!isTest) { + return publish.execSync(cmdStr); + } +}; + +/** + * Throws an error if there are any uncommitted changes + * + * @param options {Object} - e.g. {"changesCmd": "git status -s -uno"} + * @throws Error - An error object with a message containing a list of uncommitted changes. + */ +publish.checkChanges = function (options) { + var cmdTemplate = publish.getOpt(options, "changesCmd"); + var changes = publish.execSyncFromTemplate(cmdTemplate); + + if (changes.length) { + throw new Error("You have uncommitted changes\n" + changes); } }; @@ -162,7 +179,7 @@ publish.execSyncFromTemplate = function (cmdTemplate, cmdValues, isTest) { * @param options {Object} - e.g. {"checkRemoteCmd": "git ls-remote --exit-code ${remote}", "remoteName": "upstream"} */ publish.checkRemote = function (options) { - var cmdTemplate = options.checkRemoteCmd || defaults.checkRemoteCmd; + var cmdTemplate = publish.getOpt(options, "checkRemoteCmd"); publish.execSyncFromTemplate(cmdTemplate, { remote: options.remoteName || defaults.remoteName @@ -177,7 +194,7 @@ publish.checkRemote = function (options) { * @param options {Object} - e.g. {"versionCmd": "npm version --no-git-tag-version ${version}"} */ publish.setVersion = function (version, options) { - var cmdTemplate = options.versionCmd || defaults.versionCmd; + var cmdTemplate = publish.getOpt(options, "versionCmd"); publish.execSyncFromTemplate(cmdTemplate, { version: version @@ -192,11 +209,15 @@ publish.setVersion = function (version, options) { * @returns {String} - the current dev version number */ publish.getDevVersion = function (moduleVersion, options) { - var rawTimestamp = publish.execSync(options.rawTimestampCmd || defaults.rawTimestampCmd); + var rawTimestampCmdTemplate = publish.getOpt(options, "rawTimestampCmd"); + var revisionCmdTemplate = publish.getOpt(options, "revisionCmd"); + var devVersionTemplate = publish.getOpt(options, "devVersion"); + var preRelease = publish.getOpt(options, "devTag"); + + var rawTimestamp = publish.execSyncFromTemplate(rawTimestampCmdTemplate); var timestamp = publish.convertToISO8601(rawTimestamp); - var revision = publish.execSync(options.revisionCmd || defaults.revisionCmd); - var preRelease = options.devTag || defaults.devTag; - var devVersionTemplate = options.devVersion || defaults.devVersion; + var revision = publish.execSyncFromTemplate(revisionCmdTemplate); + var newStr = es6Template(devVersionTemplate, { version: moduleVersion, preRelease: preRelease, @@ -217,12 +238,12 @@ publish.getDevVersion = function (moduleVersion, options) { publish.pubImpl = function (isTest, options) { if (isTest) { // create a local tarball - var packCmd = options.packCmd || defaults.packCmd; - publish.execSync(packCmd); + var packCmdTemplate = publish.getOpt(options, "packCmd"); + publish.execSyncFromTemplate(packCmdTemplate); } else { // publish to npm - var publishCmd = options.publishCmd || defaults.publishCmd; - publish.execSync(publishCmd); + var publishCmdTemplate = publish.getOpt(options, "publishCmd"); + publish.execSyncFromTemplate(publishCmdTemplate); } }; @@ -236,7 +257,7 @@ publish.pubImpl = function (isTest, options) { * @param options {Object} - e.g. {"distTagCmd": "npm dist-tag add ${packageName}@${version} ${tag}"} */ publish.tag = function (isTest, packageName, version, tag, options) { - var cmdTemplate = options.distTagCmd || defaults.distTagCmd; + var cmdTemplate = publish.getOpt(options, "distTagCmd"); publish.execSyncFromTemplate(cmdTemplate, { packageName: packageName, @@ -253,14 +274,11 @@ publish.tag = function (isTest, packageName, version, tag, options) { * @param options {Object} - e.g. {"vcTagCmd": "git tag -a v${version} -m 'Tagging the ${version} release'", "pushVCTagCmd": "git push ${remote} v${version}", "remoteName": "upstream"} */ publish.tagVC = function (isTest, version, options) { - var cmdTemplates = [ - options.vcTagCmd || defaults.vcTagCmd, - options.pushVCTagCmd || defaults.pushVCTagCmd - ]; - - var remote = options.remoteName || defaults.remoteName; + var cmds = ["vcTagCmd", "pushVCTagCmd"]; + var remote = publish.getOpt(options, "remoteName"); - cmdTemplates.forEach(function (cmdTemplate) { + cmds.forEach(function (cmd) { + var cmdTemplate = publish.getOpt(options, cmd); publish.execSyncFromTemplate(cmdTemplate, { version: version, remote: remote @@ -277,14 +295,14 @@ publish.tagVC = function (isTest, version, options) { * @param options {Object} - e.g. {"cleanCmd": "git checkout -- package.json"} */ publish.clean = function (moduleRoot, options) { - var cmdStr = options.cleanCmd || defaults.cleanCmd; + var cmdTemplate = publish.getOpt(options, "cleanCmd"); var originalDir = process.cwd(); // change to the module root directory process.chdir(moduleRoot || "./"); // run the clean command - publish.execSync(cmdStr); + publish.execSyncFromTemplate(cmdTemplate); // restore the working directory process.chdir(originalDir); From a64ac5fd44a8a01f823c45447e997187a9ce1c30 Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Thu, 11 Aug 2016 11:01:43 -0400 Subject: [PATCH 03/23] FLUID-5799: Providing hints when errors occur. Updated the tests and README --- README.md | 66 ++++++++++++ package.json | 8 +- publish.js | 114 +++++++++------------ tests/publishTests.js | 227 ++++++++++++++++++++++++++++-------------- 4 files changed, 272 insertions(+), 143 deletions(-) diff --git a/README.md b/README.md index de615d6..9b2177d 100644 --- a/README.md +++ b/README.md @@ -320,6 +320,72 @@ publish.standard(); "upstream" + + + changesHint + + + A hint for addressing uncommitted changes. + + + "Address uncommitted changes: Commit \"git commit -a\", Stash \"git stash\" or Clean \"git reset --hard\"\n" + + + + + checkRemoteHint + + + A hint for addressing an issue where the remote repository cannot be found. + + + "Run \"git remote -v\" for a list of available remote repositories.\n" + + + + + publishHint + + + A hint for addressing an issue where publishing to the registry fails. + + + "Ensure that you have access to publish to the registry and that the current version does not already exist.\n" + + + + + distTagHint + + + A hint for addressing an issue where applying a distribution tag fails. + + + "If the tag already exists use a new tag name or run \"npm dist-tag rm ${packageName} ${tag}\" to remove the existing one.\nAlso ensure that the tag name is valid (i.e. doesn't conform to a valid semver range like v1.4 or 1.4).\n" + + + + + vcTagHint + + + A hint for addressing an issue where applying a version control tag fails. + + + "If the tag already exists, run \"git tag -d v${version}\" to remove the existing tag.\n" + + + + + pushVCTagHint + + + A hint for addressing an issue where pushing a version control tag to a remote repository fails. + + + "If the tag already exists, run \"git push ${remote} :refs/tags/v${version} to remove the existing tag.\n" + + diff --git a/package.json b/package.json index fb0b11d..58fb5da 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,12 @@ "devVersion": "${version}-${preRelease}.${timestamp}.${revision}", "devTag": "dev", "remoteName": "upstream", - "moduleRoot": "" + "moduleRoot": "", + "changesHint": "Address uncommitted changes: Commit \"git commit -a\", Stash \"git stash\" or Clean \"git reset --hard\"\n", + "checkRemoteHint": "Run \"git remote -v\" for a list of available remote repositories.\n", + "publishHint": "Ensure that you have access to publish to the registry and that the current version does not already exist.\n", + "distTagHint": "If the tag already exists use a new tag name or run \"npm dist-tag rm ${packageName} ${tag}\" to remove the existing one.\nAlso ensure that the tag name is valid (i.e. doesn't conform to a valid semver range like v1.4 or 1.4).\n", + "vcTagHint": "If the tag already exists, run \"git tag -d v${version}\" to remove the existing tag.\n", + "pushVCTagHint": "If the tag already exists, run \"git push ${remote} :refs/tags/v${version} to remove the existing tag.\n" } } diff --git a/publish.js b/publish.js index c795671..06051b6 100644 --- a/publish.js +++ b/publish.js @@ -1,7 +1,7 @@ #! /usr/bin/env node /* -Copyright 2015 OCAD University +Copyright 2015-2016 OCAD University Licensed under the New BSD license. You may not use this file except in compliance with this License. @@ -41,9 +41,6 @@ publish.getPkg = function (moduleRoot) { return require(modulePkgPath); }; -var pkg = publish.getPkg(__dirname); -var defaults = pkg.defaultOptions; - /** * Processes the argv command line arguments into an object * @@ -53,7 +50,7 @@ publish.getCLIOpts = function () { var opts = { options: {} }; - // print process.argv + process.argv.forEach(function(val, index) { if (index > 1) { var opt = val.split("="); @@ -125,18 +122,6 @@ publish.convertToISO8601 = function (timestamp) { return date.year + date.month + date.day + "T" + date.hours + date.minutes + date.seconds + "Z"; }; -/** - * Retrieves the requested option, or a default value if the option does not exist. - * The default value comes from the default object read in from the package.json file's - * "defaultOptions" property. - * - * @param options {Object} - e.g. {"key": "value"} - * @param key {String} - the particular option to look up and return the value for. - */ -publish.getOpt = function (options, key) { - return options[key] || defaults[key]; -}; - /** * Calls publish.execSync with a command crafted from a template string. * If it is a test run, the command will only be logged to the console. @@ -145,30 +130,37 @@ publish.getOpt = function (options, key) { * Can provide tokens in the form ${tokenName} * @param values {Object} - the tokens and their replacement. * e.g. {tokenName: "value to insert"} + * @param hint {String} - A string template of a hint for recovering from an error thrown by the executed command. + * Can provide tokens in the form ${tokenName} * @param isTest {Boolean} - indicates if this is a test run or not. If it is * a test run, the command will be logged but not executed. */ -publish.execSyncFromTemplate = function (cmdTemplate, cmdValues, isTest) { +publish.execSyncFromTemplate = function (cmdTemplate, cmdValues, hint, isTest) { var cmdStr = es6Template(cmdTemplate, cmdValues); - - publish.log("executing command: " + cmdStr + " \n"); + publish.log("Executing Command: " + cmdStr + "\n"); if (!isTest) { - return publish.execSync(cmdStr); + try { + return publish.execSync(cmdStr); + } catch (error) { + var hintStr = es6Template(hint, cmdValues); + publish.log("Hint: " + hintStr); + throw(error); + } } }; /** * Throws an error if there are any uncommitted changes * - * @param options {Object} - e.g. {"changesCmd": "git status -s -uno"} + * @param options {Object} - e.g. {"changesCmd": "git status -s -uno", "changesHint": "change hint"} * @throws Error - An error object with a message containing a list of uncommitted changes. */ publish.checkChanges = function (options) { - var cmdTemplate = publish.getOpt(options, "changesCmd"); - var changes = publish.execSyncFromTemplate(cmdTemplate); + var changes = publish.execSyncFromTemplate(options.changesCmd); if (changes.length) { + publish.log("Hint: " + options.changesHint); throw new Error("You have uncommitted changes\n" + changes); } }; @@ -176,14 +168,12 @@ publish.checkChanges = function (options) { /** * Checks that the remote exists. If it does not exist an error is thrown. * - * @param options {Object} - e.g. {"checkRemoteCmd": "git ls-remote --exit-code ${remote}", "remoteName": "upstream"} + * @param options {Object} - e.g. {"checkRemoteCmd": "git ls-remote --exit-code ${remote}", "remoteName": "upstream", "checkRemoteHint": "check remote hint"} */ publish.checkRemote = function (options) { - var cmdTemplate = publish.getOpt(options, "checkRemoteCmd"); - - publish.execSyncFromTemplate(cmdTemplate, { - remote: options.remoteName || defaults.remoteName - }); + publish.execSyncFromTemplate(options.checkRemoteCmd, { + remote: options.remoteName + }, options.checkRemoteHint); }; /** @@ -194,9 +184,7 @@ publish.checkRemote = function (options) { * @param options {Object} - e.g. {"versionCmd": "npm version --no-git-tag-version ${version}"} */ publish.setVersion = function (version, options) { - var cmdTemplate = publish.getOpt(options, "versionCmd"); - - publish.execSyncFromTemplate(cmdTemplate, { + publish.execSyncFromTemplate(options.versionCmd, { version: version }); }; @@ -209,20 +197,14 @@ publish.setVersion = function (version, options) { * @returns {String} - the current dev version number */ publish.getDevVersion = function (moduleVersion, options) { - var rawTimestampCmdTemplate = publish.getOpt(options, "rawTimestampCmd"); - var revisionCmdTemplate = publish.getOpt(options, "revisionCmd"); - var devVersionTemplate = publish.getOpt(options, "devVersion"); - var preRelease = publish.getOpt(options, "devTag"); - - var rawTimestamp = publish.execSyncFromTemplate(rawTimestampCmdTemplate); + var rawTimestamp = publish.execSyncFromTemplate(options.rawTimestampCmd); var timestamp = publish.convertToISO8601(rawTimestamp); - var revision = publish.execSyncFromTemplate(revisionCmdTemplate); + var revision = publish.execSyncFromTemplate(options.revisionCmd); - var newStr = es6Template(devVersionTemplate, { + var newStr = es6Template(options.devVersion, { version: moduleVersion, - preRelease: preRelease, + preRelease: options.devTag, timestamp: timestamp, - // ensure that there are no leading or trailing whitespace characters revision: revision.toString().trim() }); return newStr; @@ -233,17 +215,15 @@ publish.getDevVersion = function (moduleVersion, options) { * If isTest is specified, it will instead create a tarball in the local directory. * * @param isTest {Boolean} - indicates if this is a test run or not - * @param options {Object} - e.g. {"packCmd": "npm pack", "publishCmd": "npm publish"} + * @param options {Object} - e.g. {"packCmd": "npm pack", "publishCmd": "npm publish", "publishHint": "publish hint"} */ publish.pubImpl = function (isTest, options) { if (isTest) { // create a local tarball - var packCmdTemplate = publish.getOpt(options, "packCmd"); - publish.execSyncFromTemplate(packCmdTemplate); + publish.execSyncFromTemplate(options.packCmd); } else { // publish to npm - var publishCmdTemplate = publish.getOpt(options, "publishCmd"); - publish.execSyncFromTemplate(publishCmdTemplate); + publish.execSyncFromTemplate(options.publishCmd, {}, options.publishHint); } }; @@ -254,16 +234,14 @@ publish.pubImpl = function (isTest, options) { * @param isTest {Boolean} - indicates if this is a test run or not * @param version {String} - a string indicating which version to tag * @param tag {String} - the dist-tag to apply - * @param options {Object} - e.g. {"distTagCmd": "npm dist-tag add ${packageName}@${version} ${tag}"} + * @param options {Object} - e.g. {"distTagCmd": "npm dist-tag add ${packageName}@${version} ${tag}", "distTagHint": "dist tag hint"} */ publish.tag = function (isTest, packageName, version, tag, options) { - var cmdTemplate = publish.getOpt(options, "distTagCmd"); - - publish.execSyncFromTemplate(cmdTemplate, { + publish.execSyncFromTemplate(options.distTagCmd, { packageName: packageName, version: version, tag: tag - }, isTest); + }, options.distTagHint, isTest); }; /** @@ -271,19 +249,18 @@ publish.tag = function (isTest, packageName, version, tag, options) { * * @param isTest {Boolean} - indicates if this is a test run or not * @param version {String} - a string indicating the version - * @param options {Object} - e.g. {"vcTagCmd": "git tag -a v${version} -m 'Tagging the ${version} release'", "pushVCTagCmd": "git push ${remote} v${version}", "remoteName": "upstream"} + * @param options {Object} - e.g. {"vcTagCmd": "git tag -a v${version} -m 'Tagging the ${version} release'", "pushVCTagCmd": "git push ${remote} v${version}", "remoteName": "upstream", "vcTagHint": "vc tag hint", "pushVCTagHint": "push vc tag hint"} */ publish.tagVC = function (isTest, version, options) { - var cmds = ["vcTagCmd", "pushVCTagCmd"]; - var remote = publish.getOpt(options, "remoteName"); - - cmds.forEach(function (cmd) { - var cmdTemplate = publish.getOpt(options, cmd); - publish.execSyncFromTemplate(cmdTemplate, { - version: version, - remote: remote - }, isTest); - }); + publish.execSyncFromTemplate(options.vcTagCmd, { + version: version, + remote: options.remoteName + }, options.vcTagHint, isTest); + + publish.execSyncFromTemplate(options.pushVCTagCmd, { + version: version, + remote: options.remoteName + }, options.pushVCTagHint, isTest); }; /** @@ -295,14 +272,13 @@ publish.tagVC = function (isTest, version, options) { * @param options {Object} - e.g. {"cleanCmd": "git checkout -- package.json"} */ publish.clean = function (moduleRoot, options) { - var cmdTemplate = publish.getOpt(options, "cleanCmd"); var originalDir = process.cwd(); // change to the module root directory process.chdir(moduleRoot || "./"); // run the clean command - publish.execSyncFromTemplate(cmdTemplate); + publish.execSyncFromTemplate(options.cleanCmd); // restore the working directory process.chdir(originalDir); @@ -321,7 +297,8 @@ publish.clean = function (moduleRoot, options) { * @param options {Object} - see defaultOptions in package.json for possible values */ publish.dev = function (isTest, options) { - var opts = extend(true, {}, defaults, options); + var publishPkg = publish.getPkg(__dirname); + var opts = extend(true, {}, publishPkg.defaultOptions, options); // The package.json file of the top level package which is // running this module. @@ -354,7 +331,8 @@ publish.dev = function (isTest, options) { * @param options {Object} - see defaultOptions in package.json for possible values */ publish.standard = function (isTest, options) { - var opts = extend(true, {}, defaults, options); + var publishPkg = publish.getPkg(__dirname); + var opts = extend(true, {}, publishPkg.defaultOptions, options); // The package.json file of the top level package which is // running this module. diff --git a/tests/publishTests.js b/tests/publishTests.js index fea65ae..6d678a7 100644 --- a/tests/publishTests.js +++ b/tests/publishTests.js @@ -23,13 +23,21 @@ var createStubs = function (obj, methods) { return stubs; }; +var resetStubs = function (obj, methods) { + methods.forEach(function (method) { + obj[method].reset(); + }); +}; + var removeStubs = function (obj, methods) { methods.forEach(function (method) { obj[method].restore(); }); }; -// publish.getPkg +/****************** + * publish.getPkg * + ******************/ console.log("\n*** publish.getPkg ***"); var getPkgFixture = [{ @@ -48,7 +56,9 @@ getPkgFixture.forEach(function (fixture) { assert.deepEqual(result, fixture.expected, "Expected pkg: " + JSON.stringify(fixture.expected) + " actual: " + JSON.stringify(result)); }); -// publish.padZeros +/******************** + * publish.padZeros * + ********************/ console.log("\n*** publish.padZeros ***"); var padZerosFixture = { @@ -73,7 +83,9 @@ padZerosFixture.nums.forEach(function (num, numIdx) { }); }); -// publish.fromTimestamp +/************************* + * publish.fromTimestamp * + *************************/ console.log("\n*** publish.fromTimestamp ***"); var fromTimestampFixture = [{ @@ -95,7 +107,9 @@ fromTimestampFixture.forEach(function (fixture) { assert.deepEqual(result, fixture.expected, "Expected adjusted date object: " + JSON.stringify(fixture.expected) + " actual: " + JSON.stringify(result)); }); -// publish.convertToISO8601 +/**************************** + * publish.convertToISO8601 * + ****************************/ console.log("\n*** publish.convertToISO8601 ***"); var convertToISO6801Fixture = [{ @@ -110,38 +124,9 @@ convertToISO6801Fixture.forEach(function (fixture) { assert.equal(result, fixture.expected, "Expected ISO8601 timestamp: " + fixture.expected + " actual: " + result); }); -// publish.checkChanges -console.log("\n*** publish.checkChanges ***"); - -var checkChangesFixture = [{ - cmdStr: "test command string", - cmdReturn: "" -}, { - cmdStr: "test command string", - cmdReturn: "some changes", - errorMsg: "You have uncommitted changes\nsome changes" -}]; - -checkChangesFixture.forEach(function (fixture) { - console.log("checkChanges test - changes: " + fixture.cmdReturn); - - var exec = sinon.stub(publish, "execSync"); - exec.returns(fixture.cmdReturn); - - try { - publish.checkChanges({changesCmd: fixture.cmdStr}); - assert(exec.called, "execSync should have been called"); - assert(exec.calledWith(fixture.cmdStr), "execSync should have been called with: " + fixture.cmdStr); - - } catch (e) { - assert.equal(e.message, fixture.errorMsg, "The errorMsg should have been called correctly. expected: " + fixture.errorMsg + " actual: " + e.message); - } - - // remove execSync stub - publish.execSync.restore(); -}); - -// publish.execSyncFromTemplate +/******************************** + * publish.execSyncFromTemplate * + ********************************/ console.log("\n*** publish.execSyncFromTemplate ***"); var execSyncFromTemplateFixture = [{ @@ -149,39 +134,49 @@ var execSyncFromTemplateFixture = [{ values: { value1: "value one" }, + hint: "hint for single token template", + expectedHint: "Hint: hint for single token template", expected: "value one", - expectedLog: "command: value one" + expectedLog: "Executing Command: value one\n" }, { template: "${value1} and ${value2}", values: { value1: "value one", value2: "value two" }, + hint: "hint for multi-token template", + expectedHint: "Hint: hint for multi-token template", expected: "value one and value two", - expectedLog: "command: value one and value two" + expectedLog: "Executing Command: value one and value two\n" }, { template: "${value1} to ${value2} and back to ${value1}", values: { value1: "value one", value2: "value two" }, + hint: "hint for reused token template", + expectedHint: "Hint: hint for reused token template", expected: "value one to value two and back to value one", - expectedLog: "command: value one to value two and back to value one" + expectedLog: "Executing Command: value one to value two and back to value one\n" }, { template: "no value", values: { value1: "value one", value2: "value two" }, + hint: "hint for no value test", + expectedHint: "Hint: hint for no value test", expected: "no value", - expectedLog: "command: no value" + expectedLog: "Executing Command: no value\n" }, { template: "$ {noToken}", values: { noToken: "no token" }, + hint: "hint for no token test", + expectedHint: "Hint: hint for no token test", expected: "$ {noToken}", - expectedLog: "command: $ {noToken}" + expectedLog: "Executing Command: $ {noToken}\n" }]; execSyncFromTemplateFixture.forEach(function (fixture) { @@ -191,23 +186,75 @@ execSyncFromTemplateFixture.forEach(function (fixture) { console.log("execSyncFromTemplate test - template: " + fixture.template + " values: " + JSON.stringify(fixture.values) + " isTest: " + false); - publish.execSyncFromTemplate(fixture.template, fixture.values); + publish.execSyncFromTemplate(fixture.template, fixture.values, fixture.hint); + assert(stub.execSync.called, "execSync should have been called"); + assert(stub.execSync.calledWith(fixture.expected), "execSync should have been called with: " + fixture.expected); + assert(stub.log.calledOnce, "log should have been called only once"); + assert.equal(stub.log.args[0][0], fixture.expectedLog, "log should have been called with: " + fixture.expectedLog); + resetStubs(publish, toStub); + + console.log("execSyncFromTemplate test with exception - template: " + fixture.template + " values: " + JSON.stringify(fixture.values) + " isTest: " + false); + + stub.execSync.throws("Error message"); + assert.throws(function () {publish.execSyncFromTemplate(fixture.template, fixture.values, fixture.hint);}, Error); assert(stub.execSync.called, "execSync should have been called"); assert(stub.execSync.calledWith(fixture.expected), "execSync should have been called with: " + fixture.expected); - assert(!stub.log.called, "log should not have been called"); + assert(stub.log.calledTwice, "log should have been called twice"); + assert.equal(stub.log.args[0][0], fixture.expectedLog, "log should have been called with: " + fixture.expectedLog); + assert.equal(stub.log.args[1][0], fixture.expectedHint, "log should have been called with: " + fixture.expectedHint); + resetStubs(publish, toStub); console.log("execSyncFromTemplate test - template: " + fixture.template + " values: " + JSON.stringify(fixture.values) + " isTest: " + true); - publish.execSyncFromTemplate(fixture.template, fixture.values, true); - assert(stub.log.called, "log should have been called"); - assert(stub.log.calledWith(fixture.expectedLog), "log should have been called with: " + fixture.expectedLog); - // using calledOnce because exec should have been called in the previous execSyncFromTemplate call. - assert(stub.execSync.calledOnce, "execSync should not have been called"); + publish.execSyncFromTemplate(fixture.template, fixture.values, fixture.hint, true); + assert(stub.log.calledOnce, "log should have been called twice"); + assert.equal(stub.log.args[0][0], fixture.expectedLog, "log should have been called with: " + fixture.expectedLog); + assert.equal(stub.execSync.callCount, 0, "execSync should not have been called"); + // removes stubs removeStubs(publish, toStub); }); -// publish.setVersion +/************************ + * publish.checkChanges * + ************************/ +console.log("\n*** publish.checkChanges ***"); + +var checkChangesFixture = [{ + cmdStr: "test command string", + cmdReturn: "" +}, { + cmdStr: "test command string", + cmdReturn: "some changes", + errorMsg: "You have uncommitted changes\nsome changes", + hint: "hint" +}]; + +checkChangesFixture.forEach(function (fixture) { + console.log("checkChanges test - changes: " + fixture.cmdReturn); + + var toStub = ["execSync", "log"]; + var stub = createStubs(publish, toStub); + stub.execSync.returns(fixture.cmdReturn); + + try { + publish.checkChanges({changesCmd: fixture.cmdStr, changesHint: fixture.hint}); + assert(stub.execSync.called, "execSync should have been called"); + assert(stub.execSync.calledWith(fixture.cmdStr), "execSync should have been called with: " + fixture.cmdStr); + + } catch (e) { + var expectedHint = "Hint: " + fixture.hint; + assert(stub.log.calledWith(expectedHint), "log should have been called with: " + expectedHint); + assert.equal(e.message, fixture.errorMsg, "The errorMsg should have been called correctly. expected: " + fixture.errorMsg + " actual: " + e.message); + } + + removeStubs(publish, toStub); +}); + + +/********************** + * publish.setVersion * + **********************/ console.log("\n*** publish.setVersion ***"); var setVersionFixture = [{ @@ -229,7 +276,9 @@ setVersionFixture.forEach(function (fixture) { publish.execSync.restore(); }); -// publish.getDevVersion +/************************* + * publish.getDevVersion * + *************************/ console.log("\n*** publish.getDevVersion ***"); var getDevVersionFixture = [{ @@ -261,7 +310,9 @@ getDevVersionFixture.forEach(function (fixture) { publish.execSync.restore(); }); -// publish.pubImpl +/******************* + * publish.pubImpl * + *******************/ console.log("\n*** publish.pubImpl ***"); var pubImplFixture = [{ @@ -291,7 +342,9 @@ pubImplFixture.forEach(function (fixture) { publish.execSync.restore(); }); -// publish.tag +/*************** + * publish.tag * + ***************/ console.log("\n*** publish.tag ***"); var tagFixture = [{ @@ -300,7 +353,7 @@ var tagFixture = [{ version: "1.0.0", tag: "tag", distTagCmd: "add tag ${tag} to ${packageName} at ${version}", - expected: "command: add tag tag to test1 at 1.0.0" + expected: "add tag tag to test1 at 1.0.0" }, { isTest: false, packageName: "test2", @@ -319,27 +372,29 @@ var tagFixture = [{ tagFixture.forEach(function (fixture) { console.log("tag test - isTest: " + fixture.isTest + " packageName: " + fixture.packageName + " version: " + fixture.version + " tag: " + fixture.tag + " distTagCmd: " + fixture.distTagCmd); - var exec = sinon.stub(publish, "execSync"); - var log = sinon.stub(publish, "log"); + var toStub = ["execSync", "log"]; + var stub = createStubs(publish, toStub); + var expectedLog = "Executing Command: " + fixture.expected + "\n"; publish.tag(fixture.isTest, fixture.packageName, fixture.version, fixture.tag, fixture); + assert(stub.log.calledOnce, "console.log should have been called"); + assert(stub.log.calledWith(expectedLog), "console.log should have been called with: " + expectedLog); + if (fixture.isTest) { - assert(log.calledOnce, "console.log should have been called"); - assert(log.calledWith(fixture.expected), "console.log should have been called with: " + fixture.expected); - assert(!exec.called, "execSync should not have been called"); + assert(!stub.execSync.called, "execSync should not have been called"); } else { - assert(exec.calledOnce, "execSync should have been called"); - assert(exec.calledWith(fixture.expected), "execSync should have been called with: " + fixture.expected); - assert(!log.called, "console.log should not have been called"); + assert(stub.execSync.calledOnce, "execSync should have been called"); + assert(stub.execSync.calledWith(fixture.expected), "execSync should have been called with: " + fixture.expected); } - // remove execSync and log stubs - publish.execSync.restore(); - publish.log.restore(); + // remove stubs + removeStubs(publish, toStub); }); -// publish.clean +/***************** + * publish.clean * + *****************/ console.log("\n*** publish.clean ***"); var cleanFixture = [{ @@ -361,12 +416,15 @@ cleanFixture.forEach(function (fixture) { publish.execSync.restore(); }); -// publish tests +/***************** + * publish tests * + *****************/ var publishFixture = [{ isTest: true, options: { "changesCmd": "dry run get changes", + "checkRemoteCmd": "dry run check remote", "rawTimestampCmd": "dry run get rawTimestamp", "revisionCmd": "dry run get revision", "packCmd": "dry run pack", @@ -378,12 +436,20 @@ var publishFixture = [{ "pushVCTagCmd": "dry run push vc tag", "devVersion": "dry run ${version}-${preRelease}.${timestamp}.${revision}", "devTag": "dry run dev", - "moduleRoot": __dirname + "remoteName": "dry run remote", + "moduleRoot": __dirname, + "changesHint": "dry run changes hint\n", + "checkRemoteHint": "dry run check remote hint\n", + "publishHint": "dry run publish hint\n", + "distTagHint": "dry run dist tag hint\n", + "vcTagHint": "dry run vc tag hint\n", + "pushVCTagHint": "dry run push vc tag hint\n" } }, { isTest: false, options: { "changesCmd": "get changes", + "checkRemoteCmd": "check remote", "rawTimestampCmd": "get rawTimestamp", "revisionCmd": "get revision", "packCmd": "pack", @@ -391,15 +457,24 @@ var publishFixture = [{ "versionCmd": "version", "distTagCmd": "set tag", "cleanCmd": "clean", - "vcTagCmd": "dry run vc tag", - "pushVCTagCmd": "dry run push vc tag", + "vcTagCmd": "vc tag", + "pushVCTagCmd": "push vc tag", "devVersion": "${version}-${preRelease}.${timestamp}.${revision}", "devTag": "dev", - "moduleRoot": __dirname + "remoteName": "remote", + "moduleRoot": __dirname, + "changesHint": "changes hint\n", + "checkRemoteHint": "check remote hint\n", + "publishHint": "publish hint\n", + "distTagHint": "dist tag hint\n", + "vcTagHint": "vc tag hint\n", + "pushVCTagHint": "push vc tag hint\n" } }]; -// publish.dev +/*************** + * publish.dev * + ***************/ console.log("\n*** publish.dev ***"); publishFixture.forEach(function (fixture) { @@ -432,7 +507,9 @@ publishFixture.forEach(function (fixture) { removeStubs(publish, toStub); }); -// publish.standard +/******************** + * publish.standard * + ********************/ console.log("\n*** publish.standard ***"); publishFixture.forEach(function (fixture) { @@ -441,14 +518,16 @@ publishFixture.forEach(function (fixture) { var optsString = JSON.stringify(fixture.options || {}); console.log("release test - isTest: " + fixture.isTest, " options: " + optsString + "\n"); - var toStub = ["checkChanges", "tagVC", "pubImpl"]; + var toStub = ["checkChanges", "checkRemote", "tagVC", "pubImpl"]; var stub = createStubs(publish, toStub); publish.standard(fixture.isTest, fixture.options); assert(stub.checkChanges.calledOnce, "checkChanges should have been called"); + assert(stub.checkRemote.calledOnce, "checkRemote should have been called"); + assert(stub.checkRemote.calledWith(fixture.options), "checkRemote should have been called with: " + optsString); assert(stub.tagVC.calledOnce, "tagVC should have been called"); - assert(stub.tagVC.calledWith(fixture.isTest, modulePackage.version, fixture.options), "tagVC should have been called with: " + fixture.isTest + " ," + modulePackage.version + " ," + fixture.options); + assert(stub.tagVC.calledWith(fixture.isTest, modulePackage.version, fixture.options), "tagVC should have been called with: " + fixture.isTest + " ," + modulePackage.version + " ," + optsString); assert(stub.pubImpl.calledOnce, "pubImpl should have been called"); assert(stub.pubImpl.calledWith(fixture.isTest, fixture.options), "pubImpl should have been called with: " + fixture.isTest + ", " + optsString); From 4a37de5176e52a939b309bde1d4b19a6b491cee1 Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Thu, 11 Aug 2016 12:20:03 -0400 Subject: [PATCH 04/23] NOJIRA: Updated to ESLint and linted code --- .eslintignore | 0 .eslintrc.json | 79 +++++++++++++++++++++++++++++++++++++++++++ .jshintignore | 1 - .jshintrc | 28 --------------- Gruntfile.js | 21 +++++------- package.json | 8 ++--- publish.js | 4 ++- tests/publishTests.js | 7 ++-- 8 files changed, 98 insertions(+), 50 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc.json delete mode 100644 .jshintignore delete mode 100644 .jshintrc diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..e69de29 diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..2706caa --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,79 @@ +{ + "env": { + "browser": true, + "jquery": true + }, + "globals": { + "fluid_2_0_0": true + }, + "rules": { + "block-scoped-var": "error", + "comma-style": [ + "error", + "last" + ], + "curly": [ + "error", + "all" + ], + "dot-notation": [ + "error", + { + "allowKeywords": false + } + ], + "eol-last": "error", + "eqeqeq": [ + "error", + "allow-null" + ], + "indent": ["error", 4], + "new-cap": ["error", { "properties": false }], + "no-caller": "error", + "no-cond-assign": [ + "error", + "except-parens" + ], + "no-debugger": "error", + "no-empty": ["error", {"allowEmptyCatch": true}], + "no-eval": "error", + "no-extend-native": "error", + "no-irregular-whitespace": "error", + "no-iterator": "error", + "no-loop-func": "error", + "no-multi-str": "error", + "no-new": "error", + "no-proto": "error", + "no-script-url": "error", + "no-sequences": "error", + "no-trailing-spaces": "error", + "no-undef": "error", + "no-unused-vars": "error", + "no-with": "error", + "quotes": [ + "error", + "double" + ], + "semi": [ + "error", + "always" + ], + "space-before-blocks": ["error", "always"], + "space-before-function-paren": ["error", {"anonymous": "always", "named": "never"}], + "space-infix-ops": "error", + "space-unary-ops": [ + "error", { + "words": true, + "nonwords": false, + "overrides": { + "typeof": false + } + }], + "strict": ["error", "safe"], + "valid-typeof": "error", + "wrap-iife": [ + "error", + "inside" + ] + } +} diff --git a/.jshintignore b/.jshintignore deleted file mode 100644 index a860310..0000000 --- a/.jshintignore +++ /dev/null @@ -1 +0,0 @@ -node_modules/** diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index e1cb307..0000000 --- a/.jshintrc +++ /dev/null @@ -1,28 +0,0 @@ -{ - "bitwise": false, - "camelcase": false, - "curly": true, - "eqeqeq": true, - "es3": true, - "forin": false, - "freeze": true, - "immed": true, - "indent": 4, - "latedef": true, - "newcap": true, - "noarg": true, - "noempty": false, - "nonbsp": true, - "nonew": true, - "plusplus": false, - "quotmark": "double", - "undef": true, - "unused": true, - "strict": true, - "trailing": true, - "maxerr": 1000, - "node": true, - "globals": { - "JSON": false - } -} diff --git a/Gruntfile.js b/Gruntfile.js index 13247fa..1d63597 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,5 +1,5 @@ /* -Copyright 2015 OCAD University +Copyright 2015-2016 OCAD University Licensed under the New BSD license. You may not use this file except in compliance with this License. @@ -8,34 +8,29 @@ You may obtain a copy of the License at https://github.com/fluid-project/first-discovery-server/raw/master/LICENSE.txt */ -// Declare dependencies -/* global module */ +/* eslint-env node */ +"use strict"; module.exports = function (grunt) { - "use strict"; // Project configuration. grunt.initConfig({ // Project package file destination. pkg: grunt.file.readJSON("package.json"), - jshint: { - all: ["**/*.js"], - buildScripts: ["Gruntfile.js"], - options: { - jshintrc: true - } + eslint: { + all: ["**/*.js"] }, jsonlint: { - all: ["package.json", ".jshintrc"] + all: ["*.json", ".*.json", "tests/*.json"] } }); // Load the plugin(s): - grunt.loadNpmTasks("grunt-contrib-jshint"); + grunt.loadNpmTasks("fluid-grunt-eslint"); grunt.loadNpmTasks("grunt-jsonlint"); // Custom tasks: grunt.registerTask("default", ["lint"]); - grunt.registerTask("lint", "Apply jshint and jsonlint", ["jshint", "jsonlint"]); + grunt.registerTask("lint", "Apply eslint and jsonlint", ["eslint", "jsonlint"]); }; diff --git a/package.json b/package.json index 58fb5da..d47a072 100644 --- a/package.json +++ b/package.json @@ -30,13 +30,13 @@ "homepage": "http://fluidproject.org", "dependencies": { "es6-template-strings": "2.0.0", - "extend": "^3.0.0" + "extend": "3.0.0" }, "devDependencies": { - "grunt": "^0.4.5", - "grunt-contrib-jshint": "~0.9.0", + "grunt": "0.4.5", + "fluid-grunt-eslint": "18.1.1", "grunt-jsonlint": "1.0.4", - "sinon": "^1.17.1" + "sinon": "1.17.1" }, "defaultOptions": { "changesCmd": "git status -s -uno", diff --git a/publish.js b/publish.js index 06051b6..6823968 100644 --- a/publish.js +++ b/publish.js @@ -10,6 +10,8 @@ You may obtain a copy of the License at https://github.com/fluid-project/first-discovery-server/raw/master/LICENSE.txt */ +/* eslint-env node */ + "use strict"; var publish = {}; @@ -51,7 +53,7 @@ publish.getCLIOpts = function () { options: {} }; - process.argv.forEach(function(val, index) { + process.argv.forEach(function (val, index) { if (index > 1) { var opt = val.split("="); diff --git a/tests/publishTests.js b/tests/publishTests.js index 6d678a7..aa704dd 100644 --- a/tests/publishTests.js +++ b/tests/publishTests.js @@ -1,5 +1,5 @@ /* -Copyright 2015 OCAD University +Copyright 2015-2016 OCAD University Licensed under the New BSD license. You may not use this file except in compliance with this License. @@ -7,6 +7,7 @@ compliance with this License. You may obtain a copy of the License at https://github.com/fluid-project/first-discovery-server/raw/master/LICENSE.txt */ +/* eslint-env node */ "use strict"; @@ -195,8 +196,8 @@ execSyncFromTemplateFixture.forEach(function (fixture) { console.log("execSyncFromTemplate test with exception - template: " + fixture.template + " values: " + JSON.stringify(fixture.values) + " isTest: " + false); - stub.execSync.throws("Error message"); - assert.throws(function () {publish.execSyncFromTemplate(fixture.template, fixture.values, fixture.hint);}, Error); + stub.execSync["throws"]("Error message"); + assert["throws"](function () {publish.execSyncFromTemplate(fixture.template, fixture.values, fixture.hint);}, Error); assert(stub.execSync.called, "execSync should have been called"); assert(stub.execSync.calledWith(fixture.expected), "execSync should have been called with: " + fixture.expected); assert(stub.log.calledTwice, "log should have been called twice"); From 2edf5c83078fa2f6968815e6c20055bbcd7ab538 Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Thu, 11 Aug 2016 12:40:12 -0400 Subject: [PATCH 05/23] FLUID-5799: Version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d47a072..ea779ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fluid-publish", - "version": "1.1.0", + "version": "2.0.0", "description": "A command line tool and node module that can be used to simplify the process of publishing a module to NPM. This is particularly useful for creating development releases, e.g. nightly or continuous integration releases.", "main": "publish.js", "engines": { From bf764ca913af30767d98992beb5c364bab962d02 Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Wed, 24 Aug 2016 11:11:09 -0400 Subject: [PATCH 06/23] NOJIRA: Updated fluid-grunt-eslint to fix count of linted files --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ea779ac..823f1bd 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ }, "devDependencies": { "grunt": "0.4.5", - "fluid-grunt-eslint": "18.1.1", + "fluid-grunt-eslint": "18.1.2", "grunt-jsonlint": "1.0.4", "sinon": "1.17.1" }, From 140c2cd205d2b9bdde044834adefc7846463504f Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Tue, 30 Aug 2016 09:17:49 -0400 Subject: [PATCH 07/23] FLUID-5799: Bumping node requirement to 4.0.0 --- package.json | 2 +- publish.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 823f1bd..3f31501 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "A command line tool and node module that can be used to simplify the process of publishing a module to NPM. This is particularly useful for creating development releases, e.g. nightly or continuous integration releases.", "main": "publish.js", "engines": { - "node": ">=0.12.0" + "node": ">=4.0.0" }, "scripts": { "pub": "node publish.js", diff --git a/publish.js b/publish.js index 6823968..92e3b7a 100644 --- a/publish.js +++ b/publish.js @@ -18,8 +18,9 @@ var publish = {}; var path = require("path"); var extend = require("extend"); -// TODO: The supported version of node.js does not yet support ES6 template strings -// When version node.js 4.x.x is supported this can be replaced by native support. +// Using the es6-template-strings module instead of the native ES6 Template Literals +// because Template Literals require the template to be surrounded in "`", which are not +// accepted as valid JSON ( the defaults are stored in the package.json file ). var es6Template = require("es6-template-strings"); // execSync and log are added to the exported "publish" namespace so they can From 0a69275764cad39b8aa2c5e66764e355d37f533e Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Wed, 31 Aug 2016 08:46:39 -0400 Subject: [PATCH 08/23] NOJIRA: Updating Linting rules --- .eslintrc.json | 1 + publish.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index 2706caa..f9e0623 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -28,6 +28,7 @@ "allow-null" ], "indent": ["error", 4], + "keyword-spacing": "error", "new-cap": ["error", { "properties": false }], "no-caller": "error", "no-cond-assign": [ diff --git a/publish.js b/publish.js index 92e3b7a..d001a88 100644 --- a/publish.js +++ b/publish.js @@ -148,7 +148,7 @@ publish.execSyncFromTemplate = function (cmdTemplate, cmdValues, hint, isTest) { } catch (error) { var hintStr = es6Template(hint, cmdValues); publish.log("Hint: " + hintStr); - throw(error); + throw (error); } } }; From be3042874cb5b5596dd5aafe982183db84929b57 Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Thu, 22 Sep 2016 09:49:23 -0400 Subject: [PATCH 09/23] FLUID-5967: added an option to get the module's version programmatically and via a command line flag. --- README.md | 14 ++++++++++++++ publish.js | 10 +++++++++- tests/publishTests.js | 31 +++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9b2177d..fb8f7d7 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,20 @@ fluid-publish ./node_modules/.bin/fluid-publish ``` +#### --standard #### + +__value__: true (Boolean) + +Returns the current version of the Fluid-Publish module itself. No publishing +steps will occur when this flag is enabled. + +```bash +# returns the version of fluid-publish +fluid-publish --version +# fluid-publish 2.0.0 +``` + + #### --standard #### __value__: true (Boolean) diff --git a/publish.js b/publish.js index d001a88..39fe42a 100644 --- a/publish.js +++ b/publish.js @@ -287,6 +287,12 @@ publish.clean = function (moduleRoot, options) { process.chdir(originalDir); }; +publish.getPublishPkgVersion = function () { + var publishPkg = publish.getPkg(__dirname); + publish.log(publishPkg.name + " " + publishPkg.version); + return publishPkg.version; +}; + /** * Publishes a development build. * This creates a release named after the version, but with the build stamp @@ -362,7 +368,9 @@ if (require.main === module) { var isTest = opts["--test"]; var options = JSON.parse(opts["--options"] || "{}"); - if (opts["--standard"]) { + if (opts["--version"]) { + publish.getPublishPkgVersion(); + } else if (opts["--standard"]) { publish.standard(isTest, options); } else { publish.dev(isTest, options); diff --git a/tests/publishTests.js b/tests/publishTests.js index aa704dd..cdcbd39 100644 --- a/tests/publishTests.js +++ b/tests/publishTests.js @@ -417,6 +417,37 @@ cleanFixture.forEach(function (fixture) { publish.execSync.restore(); }); +/******************************** + * publish.getPublishPkgVersion * + ********************************/ +console.log("\n*** publish.getPublishPkgVersion ***"); + +var getPublishPkgVersionFixture = [{ + packageJson: { + name: "test-package", + version: "1.0.0" + }, + expectedLog: "test-package 1.0.0" +}]; + +getPublishPkgVersionFixture.forEach(function (fixture) { + console.log("getPublishPkgVersion test - version: " + fixture.expectedLog); + + var toStub = ["getPkg", "log"]; + var stub = createStubs(publish, toStub); + + stub.getPkg.returns(fixture.packageJson); + + var version = publish.getPublishPkgVersion(); + assert.equal(version, fixture.packageJson.version, "The version number " + fixture.packageJson.version + " should have been returned"); + assert(stub.log.calledOnce, "publish.log should have been called once"); + assert(stub.log.calledWith(fixture.expectedLog), "publish.log should have been called with: " + fixture.expectedLog); + + // remove stubs + removeStubs(publish, toStub); +}); + + /***************** * publish tests * *****************/ From 49e5978ed63abfbd37a27a21e44da24ed6d294b8 Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Tue, 27 Sep 2016 08:44:23 -0400 Subject: [PATCH 10/23] NOJIRA: Updating grunt dependency --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3f31501..e400170 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "extend": "3.0.0" }, "devDependencies": { - "grunt": "0.4.5", + "grunt": "1.0.1", "fluid-grunt-eslint": "18.1.2", "grunt-jsonlint": "1.0.4", "sinon": "1.17.1" From 36feebfe7d4edbcd4e1d33944e9999dcffb2b49c Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Mon, 3 Oct 2016 10:01:47 -0400 Subject: [PATCH 11/23] NOJIRA: Updated to sharable eslint config --- .eslintrc.json | 79 +------------------------------------------------- package.json | 1 + 2 files changed, 2 insertions(+), 78 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index f9e0623..3a45c54 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,80 +1,3 @@ { - "env": { - "browser": true, - "jquery": true - }, - "globals": { - "fluid_2_0_0": true - }, - "rules": { - "block-scoped-var": "error", - "comma-style": [ - "error", - "last" - ], - "curly": [ - "error", - "all" - ], - "dot-notation": [ - "error", - { - "allowKeywords": false - } - ], - "eol-last": "error", - "eqeqeq": [ - "error", - "allow-null" - ], - "indent": ["error", 4], - "keyword-spacing": "error", - "new-cap": ["error", { "properties": false }], - "no-caller": "error", - "no-cond-assign": [ - "error", - "except-parens" - ], - "no-debugger": "error", - "no-empty": ["error", {"allowEmptyCatch": true}], - "no-eval": "error", - "no-extend-native": "error", - "no-irregular-whitespace": "error", - "no-iterator": "error", - "no-loop-func": "error", - "no-multi-str": "error", - "no-new": "error", - "no-proto": "error", - "no-script-url": "error", - "no-sequences": "error", - "no-trailing-spaces": "error", - "no-undef": "error", - "no-unused-vars": "error", - "no-with": "error", - "quotes": [ - "error", - "double" - ], - "semi": [ - "error", - "always" - ], - "space-before-blocks": ["error", "always"], - "space-before-function-paren": ["error", {"anonymous": "always", "named": "never"}], - "space-infix-ops": "error", - "space-unary-ops": [ - "error", { - "words": true, - "nonwords": false, - "overrides": { - "typeof": false - } - }], - "strict": ["error", "safe"], - "valid-typeof": "error", - "wrap-iife": [ - "error", - "inside" - ] - } + "extends": "eslint-config-fluid" } diff --git a/package.json b/package.json index e400170..0a9800c 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ }, "devDependencies": { "grunt": "1.0.1", + "eslint-config-fluid": "1.0.0", "fluid-grunt-eslint": "18.1.2", "grunt-jsonlint": "1.0.4", "sinon": "1.17.1" From cd241fc8e2d381ee1b06400c1d8890d2959e01b9 Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Mon, 3 Oct 2016 10:21:27 -0400 Subject: [PATCH 12/23] FLUID-5799: Cleaning up README --- README.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index fb8f7d7..2dde9f2 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ npm install fluid-publish --save-dev ## Usage ## -### Command Line ### +### Command Line API ### Run these commands from the root directory of the module to be published. @@ -27,7 +27,7 @@ fluid-publish ./node_modules/.bin/fluid-publish ``` -#### --standard #### +#### --version #### __value__: true (Boolean) @@ -81,12 +81,10 @@ A stringified JSON object containing overrides to the default options used acros fluid-publish --options="{'devTag': 'nightly'}" ``` -### Node ### +### JavaScript API ### -##### parameters ##### +fluid.publish can also be accessed through standard JavaScript function calls in a [node](https://nodejs.org) app. - * isTest {Boolean} - Indicates if this is a test run, if true a tarball will be generated instead of publishing to NPM. - * options {Object} - The defaults can be found in publish.js's [package.json](package.json) file under the `defaultOptions` key. (See: [Options](#options)) #### `dev` #### @@ -97,10 +95,10 @@ var publish = require("fluid-publish"); publish.dev(); ``` -##### parameters ##### +##### arguments ##### -* isTest {Boolean} - Indicates if this is a test run, if true a tarball will be generated instead of publishing to NPM. -* options {Object} - The defaults can be found in publish.js's [package.json](package.json) file under the `defaultOptions` key. (See: [Options](#options)) + 1. isTest {Boolean} - Indicates if this is a test run, if true a tarball will be generated instead of publishing to NPM. + 2. options {Object} - The defaults can be found in publish.js's [package.json](package.json) file under the `defaultOptions` key. (See: [Options](#options)) #### `standard` #### @@ -111,6 +109,11 @@ var publish = require("fluid-publish"); publish.standard(); ``` +##### arguments ##### + + 1. isTest {Boolean} - Indicates if this is a test run, if true a tarball will be generated instead of publishing to NPM. + 2. options {Object} - The defaults can be found in publish.js's [package.json](package.json) file under the `defaultOptions` key. (See: [Options](#options)) + ## Options ## From cb85d8962c889cd7852e513d0ff8466b3c31312b Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Mon, 3 Oct 2016 10:43:23 -0400 Subject: [PATCH 13/23] FLUID-5799: Command line options refactored Instead of being passed in as a stringified options object, each individual option is now taken in as a key/value pair. --- README.md | 8 +++----- publish.js | 9 +++------ 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 2dde9f2..4f7f9e3 100644 --- a/README.md +++ b/README.md @@ -68,17 +68,15 @@ fluid-publish fluid-publish --standard ``` -#### --options ##### +#### options ##### -__value__: {String} stringified JSON object - -A stringified JSON object containing overrides to the default options used across the publish script. The defaults can be found in publish.js's [package.json](package.json) file under the `defaultOptions` key. +Optional key/value pairs, in the form `key=value`, to overide the default configuration used across the publish script. The defaults can be found in publish.js's [package.json](package.json) file under the `defaultOptions` key. (See: [Options](#options)) ```bash # publishes a dev build and applies the tag "nightly" to it -fluid-publish --options="{'devTag': 'nightly'}" +fluid-publish devTag="nightly" ``` ### JavaScript API ### diff --git a/publish.js b/publish.js index 39fe42a..87f21fb 100644 --- a/publish.js +++ b/publish.js @@ -50,9 +50,7 @@ publish.getPkg = function (moduleRoot) { * @returns {Object} - the CLI arguments as an options object */ publish.getCLIOpts = function () { - var opts = { - options: {} - }; + var opts = {}; process.argv.forEach(function (val, index) { if (index > 1) { @@ -366,14 +364,13 @@ if (require.main === module) { var opts = publish.getCLIOpts(); var isTest = opts["--test"]; - var options = JSON.parse(opts["--options"] || "{}"); if (opts["--version"]) { publish.getPublishPkgVersion(); } else if (opts["--standard"]) { - publish.standard(isTest, options); + publish.standard(isTest, opts); } else { - publish.dev(isTest, options); + publish.dev(isTest, opts); } } From 099f773b6c5ba35739f0dd7bb94f0f5913660891 Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Thu, 8 Dec 2016 16:21:19 -0500 Subject: [PATCH 14/23] FLUID-5799: Removed "\n" from log statement --- publish.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/publish.js b/publish.js index 87f21fb..466e481 100644 --- a/publish.js +++ b/publish.js @@ -138,7 +138,7 @@ publish.convertToISO8601 = function (timestamp) { */ publish.execSyncFromTemplate = function (cmdTemplate, cmdValues, hint, isTest) { var cmdStr = es6Template(cmdTemplate, cmdValues); - publish.log("Executing Command: " + cmdStr + "\n"); + publish.log("Executing Command: " + cmdStr); if (!isTest) { try { From 0e0d366bf7d09951aebceeac509eeff35e328028 Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Thu, 8 Dec 2016 16:29:46 -0500 Subject: [PATCH 15/23] FLUID-5799: Fixed unit tests --- tests/publishTests.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/publishTests.js b/tests/publishTests.js index cdcbd39..4a5d26c 100644 --- a/tests/publishTests.js +++ b/tests/publishTests.js @@ -138,7 +138,7 @@ var execSyncFromTemplateFixture = [{ hint: "hint for single token template", expectedHint: "Hint: hint for single token template", expected: "value one", - expectedLog: "Executing Command: value one\n" + expectedLog: "Executing Command: value one" }, { template: "${value1} and ${value2}", values: { @@ -148,7 +148,7 @@ var execSyncFromTemplateFixture = [{ hint: "hint for multi-token template", expectedHint: "Hint: hint for multi-token template", expected: "value one and value two", - expectedLog: "Executing Command: value one and value two\n" + expectedLog: "Executing Command: value one and value two" }, { template: "${value1} to ${value2} and back to ${value1}", values: { @@ -158,7 +158,7 @@ var execSyncFromTemplateFixture = [{ hint: "hint for reused token template", expectedHint: "Hint: hint for reused token template", expected: "value one to value two and back to value one", - expectedLog: "Executing Command: value one to value two and back to value one\n" + expectedLog: "Executing Command: value one to value two and back to value one" }, { template: "no value", values: { @@ -168,7 +168,7 @@ var execSyncFromTemplateFixture = [{ hint: "hint for no value test", expectedHint: "Hint: hint for no value test", expected: "no value", - expectedLog: "Executing Command: no value\n" + expectedLog: "Executing Command: no value" }, { template: "$ {noToken}", values: { @@ -177,7 +177,7 @@ var execSyncFromTemplateFixture = [{ hint: "hint for no token test", expectedHint: "Hint: hint for no token test", expected: "$ {noToken}", - expectedLog: "Executing Command: $ {noToken}\n" + expectedLog: "Executing Command: $ {noToken}" }]; execSyncFromTemplateFixture.forEach(function (fixture) { @@ -375,7 +375,7 @@ tagFixture.forEach(function (fixture) { var toStub = ["execSync", "log"]; var stub = createStubs(publish, toStub); - var expectedLog = "Executing Command: " + fixture.expected + "\n"; + var expectedLog = "Executing Command: " + fixture.expected; publish.tag(fixture.isTest, fixture.packageName, fixture.version, fixture.tag, fixture); From 7a4f85a718e3841449ee550cf2920f6adcc75fe2 Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Thu, 8 Dec 2016 16:33:02 -0500 Subject: [PATCH 16/23] FLUID-5799: Cleanup after updating version in dev builds The cleanup will happen even in cases where the publishing or tagging steps fail. This way the repo won't be left in a "dirty" state. --- publish.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/publish.js b/publish.js index 466e481..2b01767 100644 --- a/publish.js +++ b/publish.js @@ -319,12 +319,15 @@ publish.dev = function (isTest, options) { // set the version number publish.setVersion(devVersion, opts); - // publish - publish.pubImpl(isTest, opts); - publish.tag(isTest, modulePkg.name, devVersion, opts.devTag, opts); + try { + // publish + publish.pubImpl(isTest, opts); + publish.tag(isTest, modulePkg.name, devVersion, opts.devTag, opts); + } finally { + // cleanup changes + publish.clean(opts.moduleRoot, opts); + }; - // cleanup changes - publish.clean(opts.moduleRoot, opts); }; /** From 74478a146697b0408c9b0251be796d4bed745acd Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Thu, 8 Dec 2016 16:53:49 -0500 Subject: [PATCH 17/23] FLUID-5799: Refactoring getCLIOpts and updating related docs The getCLIOpts method now converts both "true" and "false" to their respective booleans. --- README.md | 6 ++++-- publish.js | 9 ++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4f7f9e3..101c458 100644 --- a/README.md +++ b/README.md @@ -70,9 +70,11 @@ fluid-publish --standard #### options ##### -Optional key/value pairs, in the form `key=value`, to overide the default configuration used across the publish script. The defaults can be found in publish.js's [package.json](package.json) file under the `defaultOptions` key. +Optional key/value pairs, in the form `key=value`, to override the default configuration used across the publish script. The defaults can be found in publish.js's [package.json](package.json) file under the `defaultOptions` key. -(See: [Options](#options)) +NOTE: If only a key is provided, the value is assumed to be true + +(See: [Options](#options), [process.argv](https://nodejs.org/docs/latest/api/process.html#process_process_argv)) ```bash # publishes a dev build and applies the tag "nightly" to it diff --git a/publish.js b/publish.js index 2b01767..c76236b 100644 --- a/publish.js +++ b/publish.js @@ -46,6 +46,11 @@ publish.getPkg = function (moduleRoot) { /** * Processes the argv command line arguments into an object + * Options are expected to be key/value pairs in the format of `key=value`. + * When only a key is provided, that is no "=" symbol is found, the value + * is set to true. + * + * see: https://nodejs.org/docs/latest/api/process.html#process_process_argv * * @returns {Object} - the CLI arguments as an options object */ @@ -56,9 +61,11 @@ publish.getCLIOpts = function () { if (index > 1) { var opt = val.split("="); - // convert "false" to boolean + // convert "true" and "false" to the respective boolean value if (opt[1] === "false") { opt[1] = false; + } else if (opt[1] === "true") { + opt[1] = true; } opts[opt[0]] = opt.length < 2 ? true : opt[1]; From 66d5a98091b9a38ac30eab8575488a21c571c0d7 Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Tue, 20 Dec 2016 09:41:21 -0500 Subject: [PATCH 18/23] FLUID-5799: Fixing bug with tagging dev releases --- README.md | 35 ++++--------- package.json | 4 +- publish.js | 30 +++-------- tests/publishTests.js | 117 ++++++++++++++++++------------------------ 4 files changed, 70 insertions(+), 116 deletions(-) diff --git a/README.md b/README.md index 101c458..66d7916 100644 --- a/README.md +++ b/README.md @@ -199,45 +199,30 @@ publish.standard(); diff --git a/package.json b/package.json index 0a9800c..d25cb19 100644 --- a/package.json +++ b/package.json @@ -46,8 +46,8 @@ "revisionCmd": "git rev-parse --verify --short HEAD", "packCmd": "npm pack", "publishCmd": "npm publish", + "publishDevCmd": "npm publish --tag ${devTag}", "versionCmd": "npm version --no-git-tag-version ${version}", - "distTagCmd": "npm dist-tag add ${packageName}@${version} ${tag}", "cleanCmd": "git checkout -- package.json", "vcTagCmd": "git tag -a v${version} -m 'Tagging the ${version} release'", "pushVCTagCmd": "git push ${remote} v${version}", @@ -58,7 +58,7 @@ "changesHint": "Address uncommitted changes: Commit \"git commit -a\", Stash \"git stash\" or Clean \"git reset --hard\"\n", "checkRemoteHint": "Run \"git remote -v\" for a list of available remote repositories.\n", "publishHint": "Ensure that you have access to publish to the registry and that the current version does not already exist.\n", - "distTagHint": "If the tag already exists use a new tag name or run \"npm dist-tag rm ${packageName} ${tag}\" to remove the existing one.\nAlso ensure that the tag name is valid (i.e. doesn't conform to a valid semver range like v1.4 or 1.4).\n", + "publishDevHint": "Ensure that you have access to publish to the registry and that the current version does not already exist.\nIf the tag already exists use a new tag name or run \"npm dist-tag rm ${packageName} ${tag}\" to remove the existing one.\nAlso ensure that the tag name is valid (i.e. doesn't conform to a valid semver range like v1.4 or 1.4).\n", "vcTagHint": "If the tag already exists, run \"git tag -d v${version}\" to remove the existing tag.\n", "pushVCTagHint": "If the tag already exists, run \"git push ${remote} :refs/tags/v${version} to remove the existing tag.\n" } diff --git a/publish.js b/publish.js index c76236b..2d33160 100644 --- a/publish.js +++ b/publish.js @@ -223,35 +223,20 @@ publish.getDevVersion = function (moduleVersion, options) { * If isTest is specified, it will instead create a tarball in the local directory. * * @param isTest {Boolean} - indicates if this is a test run or not - * @param options {Object} - e.g. {"packCmd": "npm pack", "publishCmd": "npm publish", "publishHint": "publish hint"} + * @param isDev {Boolean} - indicates if this is a development (true) or standard (false) release + * @param options {Object} - e.g. {"packCmd": "npm pack", "publishCmd": "npm publish", "publishDevCmd": "npm publish --tag", "publishHint": "publish hint", "publishDevHint": "publish dev hint", devTag: "dev"} */ -publish.pubImpl = function (isTest, options) { +publish.pubImpl = function (isTest, isDev, options) { if (isTest) { // create a local tarball publish.execSyncFromTemplate(options.packCmd); } else { // publish to npm - publish.execSyncFromTemplate(options.publishCmd, {}, options.publishHint); + var pubCmd = isDev ? options.publishDevCmd : options.publishCmd; + publish.execSyncFromTemplate(pubCmd, options, options.publishHint); } }; -/** - * Tags the specified version with the specified dist-tag - * If it is a test run, the tag command will be output to the console. - * - * @param isTest {Boolean} - indicates if this is a test run or not - * @param version {String} - a string indicating which version to tag - * @param tag {String} - the dist-tag to apply - * @param options {Object} - e.g. {"distTagCmd": "npm dist-tag add ${packageName}@${version} ${tag}", "distTagHint": "dist tag hint"} - */ -publish.tag = function (isTest, packageName, version, tag, options) { - publish.execSyncFromTemplate(options.distTagCmd, { - packageName: packageName, - version: version, - tag: tag - }, options.distTagHint, isTest); -}; - /** * Applies a version control tag to the latest commit * @@ -328,8 +313,7 @@ publish.dev = function (isTest, options) { try { // publish - publish.pubImpl(isTest, opts); - publish.tag(isTest, modulePkg.name, devVersion, opts.devTag, opts); + publish.pubImpl(isTest, true, opts); } finally { // cleanup changes publish.clean(opts.moduleRoot, opts); @@ -365,7 +349,7 @@ publish.standard = function (isTest, options) { publish.tagVC (isTest, modulePkg.version, opts); // publish - publish.pubImpl(isTest, opts); + publish.pubImpl(isTest, false, opts); }; module.exports = publish; diff --git a/tests/publishTests.js b/tests/publishTests.js index 4a5d26c..76e840d 100644 --- a/tests/publishTests.js +++ b/tests/publishTests.js @@ -318,24 +318,61 @@ console.log("\n*** publish.pubImpl ***"); var pubImplFixture = [{ isTest: true, + isDev: false, packCmd: "pack", - publishCmd: "shouldn't publish" + publishCmd: "shouldn't publish", + publishDevCmd: "shouldn't publish dev" }, { isTest: false, + isDev: false, packCmd: "shouldn't pack", - publishCmd: "publish" + publishCmd: "publish", + publishDevCmd: "shouldn't publish dev" }, { + isDev: false, packCmd: "shouldn't pack", - publishCmd: "publish" + publishCmd: "publish", + publishDevCmd: "shouldn't publish dev" +}, { + isDev: true, + packCmd: "shouldn't pack", + publishCmd: "shouldn't publish", + publishDevCmd: "publish dev" +}, { + isTest: false, + isDev: true, + packCmd: "pack", + publishCmd: "shouldn't publish", + publishDevCmd: "publish dev" +}, { + isTest: true, + isDev: true, + packCmd: "pack", + publishCmd: "shouldn't publish", + publishDevCmd: "shouldn't publish dev" +}, { + isTest: false, + packCmd: "shouldn't pack", + publishCmd: "publish", + publishDevCmd: "shouldn't publish dev" +}, { + isTest: true, + packCmd: "pack", + publishCmd: "shouldn't publish", + publishDevCmd: "shouldn't publish dev" +}, { + packCmd: "shouldn't pack", + publishCmd: "publish", + publishDevCmd: "shouldn't publish dev" }]; pubImplFixture.forEach(function (fixture) { - console.log("pubImpl test - isTest: " + fixture.isTest + " packCmd: " + fixture.packCmd + " publishCmd: " + fixture.publishCmd); + console.log("pubImpl test - isTest: " + fixture.isTest + "isDev: " + fixture.isDev + " packCmd: " + fixture.packCmd + " publishCmd: " + fixture.publishCmd + " publishDevCmd: " + fixture.publishDevCmd); var exec = sinon.stub(publish, "execSync"); - var expected = fixture[fixture.isTest ? "packCmd" : "publishCmd"]; + var expected = fixture.isTest ? fixture.packCmd : fixture[fixture.isDev ? "publishDevCmd" : "publishCmd"]; - publish.pubImpl(fixture.isTest, fixture); + publish.pubImpl(fixture.isTest, fixture.isDev, fixture); assert(exec.calledOnce, "execSync should have been called"); assert(exec.calledWith(expected), "execSync should have been called with: " + expected); @@ -343,56 +380,6 @@ pubImplFixture.forEach(function (fixture) { publish.execSync.restore(); }); -/*************** - * publish.tag * - ***************/ -console.log("\n*** publish.tag ***"); - -var tagFixture = [{ - isTest: true, - packageName: "test1", - version: "1.0.0", - tag: "tag", - distTagCmd: "add tag ${tag} to ${packageName} at ${version}", - expected: "add tag tag to test1 at 1.0.0" -}, { - isTest: false, - packageName: "test2", - version: "2.0.0", - tag: "tag2", - distTagCmd: "add tag ${tag} to ${packageName} at ${version}", - expected: "add tag tag2 to test2 at 2.0.0" -}, { - version: "3.0.0", - packageName: "test3", - tag: "tag3", - distTagCmd: "add tag ${tag} to ${packageName} at ${version}", - expected: "add tag tag3 to test3 at 3.0.0" -}]; - -tagFixture.forEach(function (fixture) { - console.log("tag test - isTest: " + fixture.isTest + " packageName: " + fixture.packageName + " version: " + fixture.version + " tag: " + fixture.tag + " distTagCmd: " + fixture.distTagCmd); - - var toStub = ["execSync", "log"]; - var stub = createStubs(publish, toStub); - var expectedLog = "Executing Command: " + fixture.expected; - - publish.tag(fixture.isTest, fixture.packageName, fixture.version, fixture.tag, fixture); - - assert(stub.log.calledOnce, "console.log should have been called"); - assert(stub.log.calledWith(expectedLog), "console.log should have been called with: " + expectedLog); - - if (fixture.isTest) { - assert(!stub.execSync.called, "execSync should not have been called"); - } else { - assert(stub.execSync.calledOnce, "execSync should have been called"); - assert(stub.execSync.calledWith(fixture.expected), "execSync should have been called with: " + fixture.expected); - } - - // remove stubs - removeStubs(publish, toStub); -}); - /***************** * publish.clean * *****************/ @@ -461,8 +448,8 @@ var publishFixture = [{ "revisionCmd": "dry run get revision", "packCmd": "dry run pack", "publishCmd": "dry run publish", + "publishDevCmd": "dry run npm publish dev", "versionCmd": "dry run version", - "distTagCmd": "dry run set tag", "cleanCmd": "dry run clean", "vcTagCmd": "dry run vc tag", "pushVCTagCmd": "dry run push vc tag", @@ -473,7 +460,7 @@ var publishFixture = [{ "changesHint": "dry run changes hint\n", "checkRemoteHint": "dry run check remote hint\n", "publishHint": "dry run publish hint\n", - "distTagHint": "dry run dist tag hint\n", + "publishDevHint": "dry run publish dev hint\n", "vcTagHint": "dry run vc tag hint\n", "pushVCTagHint": "dry run push vc tag hint\n" } @@ -486,8 +473,8 @@ var publishFixture = [{ "revisionCmd": "get revision", "packCmd": "pack", "publishCmd": "publish", + "publishDevCmd": "publish dev", "versionCmd": "version", - "distTagCmd": "set tag", "cleanCmd": "clean", "vcTagCmd": "vc tag", "pushVCTagCmd": "push vc tag", @@ -498,7 +485,7 @@ var publishFixture = [{ "changesHint": "changes hint\n", "checkRemoteHint": "check remote hint\n", "publishHint": "publish hint\n", - "distTagHint": "dist tag hint\n", + "publishDevHint": "publish dev hint\n", "vcTagHint": "vc tag hint\n", "pushVCTagHint": "push vc tag hint\n" } @@ -515,7 +502,7 @@ publishFixture.forEach(function (fixture) { var optsString = JSON.stringify(fixture.options || {}); console.log("dev test - isTest: " + fixture.isTest, " options: " + optsString + "\n"); - var toStub = ["checkChanges", "getDevVersion", "setVersion", "pubImpl", "tag", "clean"]; + var toStub = ["checkChanges", "getDevVersion", "setVersion", "pubImpl", "clean"]; var stub = createStubs(publish, toStub); var moduleVersion = modulePackage.version; var devVersion = moduleVersion + "-testVersion"; @@ -530,11 +517,9 @@ publishFixture.forEach(function (fixture) { assert(stub.setVersion.calledOnce, "setVersion should have been called"); assert(stub.setVersion.calledWith(devVersion, fixture.options), "setVersion should have been called with: " + devVersion + ", " + optsString); assert(stub.pubImpl.calledOnce, "pubImpl should have been called"); - assert(stub.pubImpl.calledWith(fixture.isTest, fixture.options), modulePackage); - assert(stub.tag.calledOnce, "tag should have been called"); - assert(stub.tag.calledWith(fixture.isTest, modulePackage.name, devVersion, fixture.options.devTag, fixture.options), "tag should have been called with: " + fixture.isTest + ", " + modulePackage.name + ", " + devVersion + ", " + fixture.options.devTag + ", " + optsString); + assert(stub.pubImpl.calledWith(fixture.isTest, true, fixture.options), modulePackage); assert(stub.clean.calledOnce, "clean should have been called"); - assert(stub.clean.calledWith(fixture.options.moduleRoot, fixture.options), "clean should have been called with: " + fixture.options.moduleRoot + ", " + optsString); + assert(stub.clean.calledWith(fixture.options.moduleRoot, fixture.options), "clean should have been called with: " + fixture.options.moduleRoot + ", true, " + optsString); removeStubs(publish, toStub); }); @@ -561,7 +546,7 @@ publishFixture.forEach(function (fixture) { assert(stub.tagVC.calledOnce, "tagVC should have been called"); assert(stub.tagVC.calledWith(fixture.isTest, modulePackage.version, fixture.options), "tagVC should have been called with: " + fixture.isTest + " ," + modulePackage.version + " ," + optsString); assert(stub.pubImpl.calledOnce, "pubImpl should have been called"); - assert(stub.pubImpl.calledWith(fixture.isTest, fixture.options), "pubImpl should have been called with: " + fixture.isTest + ", " + optsString); + assert(stub.pubImpl.calledWith(fixture.isTest, false, fixture.options), "pubImpl should have been called with: " + fixture.isTest + ", false, " + optsString); removeStubs(publish, toStub); }); From 2775e6ab788a05d11d36cf6999b1ad12d0c34c7b Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Thu, 12 Jan 2017 11:23:46 -0500 Subject: [PATCH 19/23] FLUID-5799: Updating hint descriptions --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 66d7916..2fcceef 100644 --- a/README.md +++ b/README.md @@ -349,7 +349,7 @@ publish.standard(); publishHint diff --git a/package.json b/package.json index d25cb19..2a18400 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "changesHint": "Address uncommitted changes: Commit \"git commit -a\", Stash \"git stash\" or Clean \"git reset --hard\"\n", "checkRemoteHint": "Run \"git remote -v\" for a list of available remote repositories.\n", "publishHint": "Ensure that you have access to publish to the registry and that the current version does not already exist.\n", - "publishDevHint": "Ensure that you have access to publish to the registry and that the current version does not already exist.\nIf the tag already exists use a new tag name or run \"npm dist-tag rm ${packageName} ${tag}\" to remove the existing one.\nAlso ensure that the tag name is valid (i.e. doesn't conform to a valid semver range like v1.4 or 1.4).\n", + "publishDevHint": "Ensure that you have access to publish to the registry and that the current version does not already exist.\nIf the tag already exists use a new tag name or run \"npm dist-tag rm ${packageName} ${tag}\" to remove the existing one.\nTags share a namespace with versions. To reduce confusion, tags that can be interpreted as semver values, will be rejected.\n", "vcTagHint": "If the tag already exists, run \"git tag -d v${version}\" to remove the existing tag.\n", "pushVCTagHint": "If the tag already exists, run \"git push ${remote} :refs/tags/v${version} to remove the existing tag.\n" } From e663e250aa99c7f9dec70ea8b9af8bd9fefae787 Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Thu, 12 Jan 2017 14:28:54 -0500 Subject: [PATCH 21/23] FLUID-5799: using publishDevHint for dev releases --- publish.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/publish.js b/publish.js index 2d33160..6401b93 100644 --- a/publish.js +++ b/publish.js @@ -233,7 +233,8 @@ publish.pubImpl = function (isTest, isDev, options) { } else { // publish to npm var pubCmd = isDev ? options.publishDevCmd : options.publishCmd; - publish.execSyncFromTemplate(pubCmd, options, options.publishHint); + var pubHint = isDev ? options.publishDevHint : options.publishHint; + publish.execSyncFromTemplate(pubCmd, options, pubHint); } }; From 35a2d3c475694a94ceea730c8154a5d664712374 Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Thu, 12 Jan 2017 15:17:33 -0500 Subject: [PATCH 22/23] FLUID-5799: Updated test comment --- tests/publishTests.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/publishTests.js b/tests/publishTests.js index 76e840d..e11d789 100644 --- a/tests/publishTests.js +++ b/tests/publishTests.js @@ -316,6 +316,9 @@ getDevVersionFixture.forEach(function (fixture) { *******************/ console.log("\n*** publish.pubImpl ***"); +// In the cases where commands should not execute, +// their entry in the structure has been filled with a +// placeholder string beginning with "shouldn't" var pubImplFixture = [{ isTest: true, isDev: false, From f7da24a3673216042b6220b90a7123b49997a125 Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Tue, 24 Jan 2017 12:12:08 -0500 Subject: [PATCH 23/23] FLUID-5799: More clarifications to the publishDevHint --- README.md | 4 +--- package.json | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7b75b21..22836bb 100644 --- a/README.md +++ b/README.md @@ -363,9 +363,7 @@ publish.standard(); A hint for addressing an issue where publishing a development (pre-release) to the registry fails. diff --git a/package.json b/package.json index 2a18400..3229c34 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "changesHint": "Address uncommitted changes: Commit \"git commit -a\", Stash \"git stash\" or Clean \"git reset --hard\"\n", "checkRemoteHint": "Run \"git remote -v\" for a list of available remote repositories.\n", "publishHint": "Ensure that you have access to publish to the registry and that the current version does not already exist.\n", - "publishDevHint": "Ensure that you have access to publish to the registry and that the current version does not already exist.\nIf the tag already exists use a new tag name or run \"npm dist-tag rm ${packageName} ${tag}\" to remove the existing one.\nTags share a namespace with versions. To reduce confusion, tags that can be interpreted as semver values, will be rejected.\n", + "publishDevHint": "Ensure that you have access to publish to the registry and that the current version does not already exist.\nIf the npm tag specified by --tag is recognizable as a valid semver version number, it will be rejected by npm. This is because version numbers and tags share a common namespace for npm packages.\n", "vcTagHint": "If the tag already exists, run \"git tag -d v${version}\" to remove the existing tag.\n", "pushVCTagHint": "If the tag already exists, run \"git push ${remote} :refs/tags/v${version} to remove the existing tag.\n" }
- versionCmd + publishDevCmd - The CLI to execute which sets the dev version to release under. -
    -
  • - ${version} will be substituted with the generated dev build version. -
  • -
+ The CLI to execute which publishes a development release to NPM. + Uses the value specified by the `devTag` option.
- "npm version --no-git-tag-version ${version}" -
-
-

- NOTE: This command will update the version in the package.json file, but will not commit the change. -

+ "npm publish --tag ${devTag}"
- distTagCmd + versionCmd - The CLI to execute which tags an NPM release. + The CLI to execute which sets the dev version to release under.
    -
  • - ${packageName} will be substituted with executing module's name. -
  • ${version} will be substituted with the generated dev build version.
  • -
  • - ${tag}will be substituted with the value from the devTag option. -
- "npm dist-tag add ${packageName}@${version} ${tag}" + "npm version --no-git-tag-version ${version}"

@@ -372,13 +357,13 @@ publish.standard();

- distTagHint + publishDevHint - A hint for addressing an issue where applying a distribution tag fails. + A hint for addressing an issue where publishing to the registry fails. - "If the tag already exists use a new tag name or run \"npm dist-tag rm ${packageName} ${tag}\" to remove the existing one.\nAlso ensure that the tag name is valid (i.e. doesn't conform to a valid semver range like v1.4 or 1.4).\n" + "Ensure that you have access to publish to the registry and that the current version does not already exist.\nIf the tag already exists use a new tag name or run \"npm dist-tag rm ${packageName} ${tag}\" to remove the existing one.\nAlso ensure that the tag name is valid (i.e. doesn't conform to a valid semver range like v1.4 or 1.4).\n"
- A hint for addressing an issue where publishing to the registry fails. + A hint for addressing an issue where publishing a standard release to the registry fails. "Ensure that you have access to publish to the registry and that the current version does not already exist.\n" @@ -360,7 +360,7 @@ publish.standard(); publishDevHint - A hint for addressing an issue where publishing to the registry fails. + A hint for addressing an issue where publishing a development (pre-release) to the registry fails. "Ensure that you have access to publish to the registry and that the current version does not already exist.\nIf the tag already exists use a new tag name or run \"npm dist-tag rm ${packageName} ${tag}\" to remove the existing one.\nAlso ensure that the tag name is valid (i.e. doesn't conform to a valid semver range like v1.4 or 1.4).\n" From 3ed2231e0591f111732a5cabefbac6ed510138f1 Mon Sep 17 00:00:00 2001 From: Justin Obara Date: Thu, 12 Jan 2017 11:51:51 -0500 Subject: [PATCH 20/23] FLUID-5799: Clarifying tag requirements for dev releases. --- README.md | 4 +++- package.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2fcceef..7b75b21 100644 --- a/README.md +++ b/README.md @@ -363,7 +363,9 @@ publish.standard(); A hint for addressing an issue where publishing a development (pre-release) to the registry fails. - "Ensure that you have access to publish to the registry and that the current version does not already exist.\nIf the tag already exists use a new tag name or run \"npm dist-tag rm ${packageName} ${tag}\" to remove the existing one.\nAlso ensure that the tag name is valid (i.e. doesn't conform to a valid semver range like v1.4 or 1.4).\n" + "Ensure that you have access to publish to the registry and that the current version does not already exist.\nIf the tag already exists use a new tag name or run \"npm dist-tag rm ${packageName} ${tag}\" to remove the existing one.\nTags share a namespace with versions. To reduce confusion, tags that can be interpreted as semver values, will be rejected.\n" + + Also ensure that the tag name is valid (i.e. doesn't conform to a valid semver range like v1.4 or 1.4).\n"
- "Ensure that you have access to publish to the registry and that the current version does not already exist.\nIf the tag already exists use a new tag name or run \"npm dist-tag rm ${packageName} ${tag}\" to remove the existing one.\nTags share a namespace with versions. To reduce confusion, tags that can be interpreted as semver values, will be rejected.\n" - - Also ensure that the tag name is valid (i.e. doesn't conform to a valid semver range like v1.4 or 1.4).\n" + "Ensure that you have access to publish to the registry and that the current version does not already exist.\nIf the npm tag specified by --tag is recognizable as a valid semver version number, it will be rejected by npm. This is because version numbers and tags share a common namespace for npm packages.\n"