diff --git a/README.md b/README.md index 71b62aa0..3cec2a47 100755 --- a/README.md +++ b/README.md @@ -37,9 +37,6 @@ Commands: package Generate a package.xml file from local describe information retrieve Retrieve metadata specified in package.xml deploy Deploy metadata specified in a package.xml - deployTest DEPRECATED! Use `deploy -t` instead - validate DEPRECATED! Use `deploy -c` instead - validateTest DEPRECATED! Use `deploy -ct` instead test Execute unit tests changeset Create a changeset/deployment from a unified diff input or cli args query Execute a SOQL query returing JSON @@ -172,16 +169,56 @@ exported metadata container to config/deployments/undo-vat **Deploying metadata** ```console -$ force-dev-tool validate -$ force-dev-tool validateTest -$ force-dev-tool validateTest -d config/deployments/vat -$ force-dev-tool deploy -$ force-dev-tool deployTest -``` +$ force-dev-tool deploy --help +Usage: + force-dev-tool deploy [options] [] -Options: +Deploy metadata specified in a package.xml. - -d= Directory containing the metadata and package.xml [default: ./src]. +Options: + -c --checkOnly Perform a test deployment (validation). + -t --test Run local tests. + --runTests= Names of test classes (one argument, separated by whitespace). + --runAllTests Run all tests including tests of managed packages. + --purgeOnDelete Don't store deleted components in the recycle bin. + --noSinglePackage Allows to deploy multiple packages. + -d= Directory to be deployed [default: src]. + -f= Zip file to be deployed. + +Examples: + + Deploying the default directory to the default remote + $ force-dev-tool deploy + Running Deployment of directory src to remote mydev + Visit https://mynamespace.my.salesforce.com/changemgmt/monitorDeploymentsDetails.apexp?asyncId=REDACTED for more information. + + Deploying to another remote + $ force-dev-tool deploy myqa + + Deploying a specified directory + $ force-dev-tool deploy -d config/deployments/vat + + Perform a test deployment (validation) + $ force-dev-tool deploy --checkOnly + $ force-dev-tool deploy -c + + Deploying with running local tests + $ force-dev-tool deploy -t + $ force-dev-tool deploy --test + + Deploying with running specified test classes + $ force-dev-tool deploy --runTests 'Test_MockFoo Test_MockBar' + + Deploying with running test classes matching a pattern + $ force-dev-tool package grep 'ApexClass/Test_Mock*' \ + | cut -d '/' -f 2 \ + | xargs -0 force-dev-tool deploy --runTests + + Deploying with running only test classes being contained in a deployment + $ force-dev-tool package grep 'ApexClass/Test_*' --template config/deployments/mock \ + | cut -d '/' -f 2 \ + | xargs -0 force-dev-tool deploy -d config/deployments/mock --runTests +``` **Running unit tests** @@ -236,7 +273,7 @@ The following environment variables can be used to define a default remote envir * `SFDC_SERVER_URL` ```console -$ force-dev-tool validateTest env +$ force-dev-tool deploy -ct env ``` Note: You can also define named remotes using [Environment Variables](https://github.com/amtrack/force-dev-tool/wiki/Environment-Variables) (e.g. `SFDC_ci_USERNAME`, `SFDC_ci_PASSWORD`, `SFDC_ci_SERVER_URL`). diff --git a/bin/cli b/bin/cli index c400808e..2d19640b 100755 --- a/bin/cli +++ b/bin/cli @@ -29,9 +29,6 @@ var doc = "force-dev-tool.\n" + " package Generate a package.xml file from local describe information\n" + " retrieve Retrieve metadata specified in a package.xml\n" + " deploy Deploy metadata specified in a package.xml\n" + - " deployTest DEPRECATED! Use `deploy -t` instead\n" + - " validate DEPRECATED! Use `deploy -c` instead\n" + - " validateTest DEPRECATED! Use `deploy -ct` instead\n" + " test Execute unit tests\n" + " changeset Create a changeset/deployment from a unified diff input or cli args\n" + " query Execute a SOQL query returing JSON\n" + @@ -48,7 +45,7 @@ var opts = docopt(doc, { var command = opts['']; var args = opts['']; var topic = (args !== null && args.length > 0) ? args[0] : null; -var validCommands = ['remote', 'login', 'fetch', 'info', 'package', 'retrieve', 'test', 'validate', 'validateTest', 'deploy', 'deployTest', 'changeset', 'query', 'bulk', 'execute']; +var validCommands = ['remote', 'login', 'fetch', 'info', 'package', 'retrieve', 'test', 'deploy', 'changeset', 'query', 'bulk', 'execute']; var storagePath = process.cwd(); var storagePathBestGuess = findUp.sync(path.join('src', 'package.xml')); diff --git a/lib/cli/deployTest.js b/lib/cli/deployTest.js deleted file mode 100755 index 57e8ec54..00000000 --- a/lib/cli/deployTest.js +++ /dev/null @@ -1,31 +0,0 @@ -"use strict"; - -var DeployCommand = require('./deploy'); - -var doc = "Usage:\n" + - " force-dev-tool deployTest [options] []\n" + - "\n" + - "DEPRECATED! Use `deploy --test` (or short `deploy -t`) instead.\n" + - "\n" + - "Options:\n" + - " -c --checkOnly Perform a test deployment (validation).\n" + - " --runTests= Names of test classes (one argument, separated by whitespace).\n" + - " --runAllTests Run all tests including tests of managed packages.\n" + - " --purgeOnDelete Don't store deleted components in the recycle bin.\n" + - " -d= Directory to be deployed [default: src].\n" + - " -f= Zip file to be deployed."; - -var SubCommand = module.exports = function(project) { - var self = this; - DeployCommand.call(self, project, doc); -}; - -SubCommand.prototype = Object.create(DeployCommand.prototype); -SubCommand.prototype.constructor = SubCommand; - -SubCommand.prototype.process = function(proc, callback) { - var self = this; - self.opts = self.docopt(); - self.opts['--test'] = true; - return DeployCommand.prototype.process.call(self, proc, callback); -}; diff --git a/lib/cli/validate.js b/lib/cli/validate.js deleted file mode 100755 index 418e32ef..00000000 --- a/lib/cli/validate.js +++ /dev/null @@ -1,31 +0,0 @@ -"use strict"; - -var DeployCommand = require('./deploy'); - -var doc = "Usage:\n" + - " force-dev-tool validate [options] []\n" + - "\n" + - "DEPRECATED! Use `deploy --checkOnly` (or short `deploy -c`) instead.\n" + - "\n" + - "Options:\n" + - " -t --test Run local tests.\n" + - " --runTests= Names of test classes (one argument, separated by whitespace).\n" + - " --runAllTests Run all tests including tests of managed packages.\n" + - " --purgeOnDelete Don't store deleted components in the recycle bin.\n" + - " -d= Directory to be deployed [default: src].\n" + - " -f= Zip file to be deployed."; - -var SubCommand = module.exports = function(project) { - var self = this; - DeployCommand.call(self, project, doc); -}; - -SubCommand.prototype = Object.create(DeployCommand.prototype); -SubCommand.prototype.constructor = SubCommand; - -SubCommand.prototype.process = function(proc, callback) { - var self = this; - self.opts = self.docopt(); - self.opts['--checkOnly'] = true; - return DeployCommand.prototype.process.call(self, proc, callback); -}; diff --git a/lib/cli/validateTest.js b/lib/cli/validateTest.js deleted file mode 100755 index 78173739..00000000 --- a/lib/cli/validateTest.js +++ /dev/null @@ -1,31 +0,0 @@ -"use strict"; - -var DeployCommand = require('./deploy'); - -var doc = "Usage:\n" + - " force-dev-tool validateTest [options] []\n" + - "\n" + - "DEPRECATED! Use `deploy --checkOnly --test` (or short `deploy -ct`) instead.\n" + - "\n" + - "Options:\n" + - " --runTests= Names of test classes (one argument, separated by whitespace).\n" + - " --runAllTests Run all tests including tests of managed packages.\n" + - " --purgeOnDelete Don't store deleted components in the recycle bin.\n" + - " -d= Directory to be deployed [default: src].\n" + - " -f= Zip file to be deployed."; - -var SubCommand = module.exports = function(project) { - var self = this; - DeployCommand.call(self, project, doc); -}; - -SubCommand.prototype = Object.create(DeployCommand.prototype); -SubCommand.prototype.constructor = SubCommand; - -SubCommand.prototype.process = function(proc, callback) { - var self = this; - self.opts = self.docopt(); - self.opts['--checkOnly'] = true; - self.opts['--test'] = true; - return DeployCommand.prototype.process.call(self, proc, callback); -}; diff --git a/test-integration/deploy.js b/test-integration/deploy.js new file mode 100644 index 00000000..7812f373 --- /dev/null +++ b/test-integration/deploy.js @@ -0,0 +1,60 @@ +"use strict"; + +var assert = require("assert"); +var path = require("path"); +var child = require("child_process"); +var tmp = require("tmp"); +var Unzip = require('../lib/unzip'); + +describe('force-dev-tool deploy', function() { + var fdt = path.resolve(__dirname, '..', 'bin', 'cli'); + it('should simulate deploying a zip file containing a layout with umlauts in the filename', function() { + this.timeout(1000 * 60 * 10); + this.slow(1000 * 60 * 5); + var deployCmd = child.spawnSync("node", [fdt, 'deploy', '-c', '-f', path.resolve(__dirname, '..', 'test', 'data', 'unpackaged', 'layout-with-umlauts.zip')]); + assert.deepEqual(deployCmd.status, 0, deployCmd.stderr); + assert(/Running Validation of zip file/.test(deployCmd.stdout.toString())); + assert(/Visit https/.test(deployCmd.stdout.toString())); + }); + it('should simulate deploying a layout with umlauts in the filename', function(done) { + this.timeout(1000 * 60 * 10); + this.slow(1000 * 60 * 5); + var tmpDir = tmp.dirSync(); + var testZipPath = path.join(__dirname, '..', 'test', 'data', 'unpackaged', 'layout-with-umlauts.zip'); + var unzipDir = path.join(tmpDir.name, 'unzipped'); + new Unzip(testZipPath).target(unzipDir, function(err) { + if (err) { + return done(err); + } + var deployCmd = child.spawnSync("node", [fdt, 'deploy', '-c', '-d', unzipDir]); + assert.deepEqual(deployCmd.status, 0, deployCmd.stderr); + assert(/Running Validation of directory/.test(deployCmd.stdout.toString())); + assert(/Visit https/.test(deployCmd.stdout.toString())); + done(); + }); + }); + it('should simulate deploying a visualforce page', function() { + this.timeout(1000 * 60 * 10); + this.slow(1000 * 60 * 5); + var deployCmd = child.spawnSync("node", [fdt, 'deploy', '-c', '-t', '-d', path.resolve(__dirname, '..', 'test', 'data', 'metadata', 'visualforce')]); + assert.deepEqual(deployCmd.status, 0, deployCmd.stderr); + assert(/Running Validation with test execution of directory/.test(deployCmd.stdout.toString())); + assert(/Visit https/.test(deployCmd.stdout.toString())); + }); + it('should simulate deploying an apex class with a test class', function() { + this.timeout(1000 * 60 * 10); + this.slow(1000 * 60 * 5); + var deployCmd = child.spawnSync("node", [fdt, 'deploy', '-c', '-t', '-d', path.resolve(__dirname, '..', 'test', 'data', 'unpackaged', 'apex')]); + assert.deepEqual(deployCmd.status, 0, deployCmd.stderr); + assert(/Running Validation with test execution of directory/.test(deployCmd.stdout.toString())); + assert(/Visit https/.test(deployCmd.stdout.toString())); + }); + it('should simulate deploying an apex class with a failing test class', function() { + this.timeout(1000 * 60 * 10); + this.slow(1000 * 60 * 5); + var deployCmd = child.spawnSync("node", [fdt, 'deploy', '-c', '-t', '-d', path.resolve(__dirname, '..', 'test', 'data', 'unpackaged', 'apex-failing')]); + assert.deepEqual(deployCmd.status, 1); + assert(/Running Validation with test execution of directory/.test(deployCmd.stdout.toString())); + assert(/Error:.*failed\./.test(deployCmd.stderr.toString())); + }); +}); diff --git a/test-integration/validate.js b/test-integration/validate.js deleted file mode 100644 index 8d16ff93..00000000 --- a/test-integration/validate.js +++ /dev/null @@ -1,36 +0,0 @@ -"use strict"; - -var assert = require("assert"); -var path = require("path"); -var child = require("child_process"); -var tmp = require("tmp"); -var Unzip = require('../lib/unzip'); - -describe('force-dev-tool validate', function() { - var fdt = path.resolve(__dirname, '..', 'bin', 'cli'); - it('should simulate deploying a zip file containing a layout with umlauts in the filename', function() { - this.timeout(1000 * 60 * 10); - this.slow(1000 * 60 * 5); - var validateCmd = child.spawnSync("node", [fdt, 'validate', '-f', path.resolve(__dirname, '..', 'test', 'data', 'unpackaged', 'layout-with-umlauts.zip')]); - assert.deepEqual(validateCmd.status, 0, validateCmd.stderr); - assert(/Running Validation of zip file/.test(validateCmd.stdout.toString())); - assert(/Visit https/.test(validateCmd.stdout.toString())); - }); - it('should simulate deploying a layout with umlauts in the filename', function(done) { - this.timeout(1000 * 60 * 10); - this.slow(1000 * 60 * 5); - var tmpDir = tmp.dirSync(); - var testZipPath = path.join(__dirname, '..', 'test', 'data', 'unpackaged', 'layout-with-umlauts.zip'); - var unzipDir = path.join(tmpDir.name, 'unzipped'); - new Unzip(testZipPath).target(unzipDir, function(err) { - if (err) { - return done(err); - } - var validateCmd = child.spawnSync("node", [fdt, 'validate', '-d', unzipDir]); - assert.deepEqual(validateCmd.status, 0, validateCmd.stderr); - assert(/Running Validation of directory/.test(validateCmd.stdout.toString())); - assert(/Visit https/.test(validateCmd.stdout.toString())); - done(); - }); - }); -}); diff --git a/test-integration/validateTest.js b/test-integration/validateTest.js deleted file mode 100644 index e886d969..00000000 --- a/test-integration/validateTest.js +++ /dev/null @@ -1,33 +0,0 @@ -"use strict"; - -var assert = require("assert"); -var path = require("path"); -var child = require("child_process"); - -describe('force-dev-tool validateTest', function() { - var fdt = path.resolve(__dirname, '..', 'bin', 'cli'); - it('should simulate deploying a visualforce page', function() { - this.timeout(1000 * 60 * 10); - this.slow(1000 * 60 * 5); - var validateTestCmd = child.spawnSync("node", [fdt, 'validateTest', '-d', path.resolve(__dirname, '..', 'test', 'data', 'metadata', 'visualforce')]); - assert.deepEqual(validateTestCmd.status, 0, validateTestCmd.stderr); - assert(/Running Validation with test execution of directory/.test(validateTestCmd.stdout.toString())); - assert(/Visit https/.test(validateTestCmd.stdout.toString())); - }); - it('should simulate deploying an apex class with a test class', function() { - this.timeout(1000 * 60 * 10); - this.slow(1000 * 60 * 5); - var validateTestCmd = child.spawnSync("node", [fdt, 'validateTest', '-d', path.resolve(__dirname, '..', 'test', 'data', 'unpackaged', 'apex')]); - assert.deepEqual(validateTestCmd.status, 0, validateTestCmd.stderr); - assert(/Running Validation with test execution of directory/.test(validateTestCmd.stdout.toString())); - assert(/Visit https/.test(validateTestCmd.stdout.toString())); - }); - it('should simulate deploying an apex class with a failing test class', function() { - this.timeout(1000 * 60 * 10); - this.slow(1000 * 60 * 5); - var validateTestCmd = child.spawnSync("node", [fdt, 'validateTest', '-d', path.resolve(__dirname, '..', 'test', 'data', 'unpackaged', 'apex-failing')]); - assert.deepEqual(validateTestCmd.status, 1); - assert(/Running Validation with test execution of directory/.test(validateTestCmd.stdout.toString())); - assert(/Error:.*failed\./.test(validateTestCmd.stderr.toString())); - }); -});