qforce
Version:
Commands to help with salesforce development.
139 lines (138 loc) • 7.27 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const command_1 = require("@oclif/command");
const cli_ux_1 = require("cli-ux");
const utility_1 = require("../../helper/utility");
const sfdx = require('sfdx-node');
const execa = require('execa');
const YAML = require('yaml');
const path = require('path');
const fs = require('fs');
const _ = require('lodash');
class DevDeploy extends command_1.Command {
async run() {
cli_ux_1.default.action.start('Deploying feature ');
const { args, flags } = this.parse(DevDeploy);
let settings, sfdxConfig;
if (fs.existsSync(utility_1.getAbsolutePath('.qforce/settings.json'))) {
settings = JSON.parse(fs.readFileSync(utility_1.getAbsolutePath('.qforce/settings.json')));
}
if (fs.existsSync(path.join(process.cwd(), '.sfdx', 'sfdx-config.json'))) {
sfdxConfig = JSON.parse(fs.readFileSync(path.join(process.cwd(), '.sfdx', 'sfdx-config.json')));
}
if (fs.existsSync(utility_1.getAbsolutePath('.qforce/deploy'))) {
utility_1.deleteFolderRecursive('.qforce/deploy');
}
const targetusername = flags.username || settings.targetusername || sfdxConfig.defaultusername;
if (flags.file) {
let retrieveYAML;
let filePath = flags.file || 'feature.yml';
if (!fs.existsSync(utility_1.getAbsolutePath(filePath))) {
filePath = settings.retrieveBasePath + '/' + filePath;
}
if (!fs.existsSync(utility_1.getAbsolutePath(filePath))) {
cli_ux_1.default.action.stop('File not found');
}
retrieveYAML = YAML.parse(fs.readFileSync(filePath, 'utf-8'));
for (let metadataType in retrieveYAML) {
if (retrieveYAML[metadataType]) {
for (let metadataName of retrieveYAML[metadataType]) {
let command = `sfdx force:source:deploy -m ${metadataType}:${metadataName} -u ${targetusername}`;
let result = execa.commandSync(command);
this.log(JSON.stringify(result, null, 4));
}
}
else {
let command = `sfdx force:source:deploy -m ${metadataType} -u ${targetusername}`;
let result = execa.commandSync(command);
this.log(JSON.stringify(result, null, 4));
}
}
cli_ux_1.default.action.stop();
return;
}
const featureBranch = args.featureBranch || flags.lastDeployCommit || settings.lastDeployCommit;
const developBranch = args.developBranch || flags.diff ? 'HEAD' : settings.developBranch;
let diffFilesList = [];
if (flags.diff) {
let diff = await execa('git', ['diff', '--name-only', featureBranch, developBranch]);
diffFilesList = diff.stdout.split('\n');
}
else if (flags.isCommit) {
let commitFiles = 'git diff-tree --no-commit-id --name-only -r ' + featureBranch;
let diff = await execa.command(commitFiles);
diffFilesList = _.union(diffFilesList, diff.stdout.split('\n'));
//this.log('diff original:\n' + diff.stdout)
if (diff.stdout === "") {
//this.log('Looks like a merge commit. Will calculate diff with parents.')
let getParents = `git rev-list --parents -n 1 ${featureBranch}`;
let parents = await execa.command(getParents);
let parentList = parents.stdout.split(' ');
if (parentList.length < 3) {
this.log('Could not calculate diff. Will abort.');
return;
}
else {
for (let i = 1; i < parentList.length; i++) {
let getDiff = `git diff-tree --no-commit-id --name-only -r ${featureBranch} ${parentList[i]}`;
let diff = await execa.command(getDiff);
diffFilesList = _.union(diffFilesList, diff.stdout.split('\n'));
}
}
}
}
else {
const mergeBase = await execa('git', ['merge-base', featureBranch, developBranch]);
const baseCommit = mergeBase.stdout;
let diff = await execa('git', ['diff', '--name-only', baseCommit, featureBranch]);
diffFilesList = diff.stdout.split('\n');
}
//this.log(diffFilesList[0])
for (let sourceFilePath of diffFilesList) {
//this.log(sourceFilePath)
if (!fs.existsSync(sourceFilePath))
continue;
let deployFilePath = '.qforce/deploy/' + sourceFilePath;
if (!fs.existsSync(path.dirname(deployFilePath))) {
fs.mkdirSync(path.dirname(deployFilePath), { recursive: true });
}
fs.copyFileSync(sourceFilePath, deployFilePath);
if (sourceFilePath.includes('classes/')
|| sourceFilePath.includes('email/')
|| sourceFilePath.includes('pages/')
|| sourceFilePath.includes('scontrols/')
|| sourceFilePath.includes('siteDotComSites/')
|| sourceFilePath.includes('triggers/')
|| sourceFilePath.includes('components/')) {
if (sourceFilePath.includes('meta.xml'))
continue;
fs.copyFileSync(sourceFilePath + '-meta.xml', deployFilePath + '-meta.xml');
}
else if (sourceFilePath.includes('documents/')) {
fs.copyFileSync(sourceFilePath.replace(/\..*$/, '.document-meta.xml'), deployFilePath.replace(/\..*$/, '.document-meta.xml'));
}
else if (sourceFilePath.includes('lwc/')
|| sourceFilePath.includes('aura/')) {
fs.readdirSync(path.dirname(sourceFilePath)).forEach((file, index) => {
if (fs.lstatSync(path.dirname(sourceFilePath) + '/' + file).isFile()) {
fs.copyFileSync(path.dirname(sourceFilePath) + '/' + file, path.dirname(deployFilePath) + '/' + file);
}
});
}
}
let deployCommand = 'sfdx force:source:deploy -p .qforce/deploy -u ' + targetusername;
execa.command(deployCommand).stdout.pipe(process.stdout);
}
}
exports.default = DevDeploy;
DevDeploy.description = 'Deploy source components included in a feature branch.';
DevDeploy.aliases = ['deploy', 'dev:deploy'];
DevDeploy.flags = {
help: command_1.flags.help({ char: 'h' }),
username: command_1.flags.string({ char: 'u' }),
file: command_1.flags.string({ char: 'f', description: 'Relative path of YAML file in unix format.' }),
diff: command_1.flags.boolean({ char: 'd', description: 'Set to true if passing commit hash.' }),
isCommit: command_1.flags.boolean({ char: 'c', description: 'Set to true if deploying a single commit.' }),
lastDeployCommit: command_1.flags.string({ description: 'Commit hash of the last commit.' }),
};
DevDeploy.args = [{ name: 'featureBranch' }, { name: 'developBranch' }];