ask-cli-x
Version:
Alexa Skills Kit (ASK) Command Line Interfaces
234 lines (233 loc) • 8.41 kB
JavaScript
"use strict";
const { execSync } = require("child_process");
const fs = require("fs-extra");
const path = require("path");
const CLiError = require("../exceptions/cli-error");
const Messenger = require("../view/messenger");
/**
* Class for git commands management
*/
module.exports = class GitClient {
/**
* Constructor for GitClient with projectPath and verbosity options
* @param {string} projectPath the path of a project
* @param {object} verbosityOptions | showOutput
* | showCommand
*/
constructor(projectPath, verbosityOptions) {
this.projectPath = projectPath;
this.verbosityOptions = verbosityOptions;
}
/**
* Execute git-init to create an empty Git repository or reinitialize an existing one
*/
init() {
const commands = [`git init "${this.projectPath}"${this.verbosityOptions.showOutput === false ? " --quiet" : ""}`];
const options = {
showStdOut: this.verbosityOptions.showOutput,
showStdErr: true,
showCmd: this.verbosityOptions.showCommand,
};
this._execCommands(commands, options);
}
/**
* Config local git credential helper with credentialHelperPath
* @param {string} credentialScriptExecution the command to execute the git-credential-helper
* @param {string} hostUrl the host url to apply to the credential helper
*/
configureCredentialHelper(credentialScriptExecution, hostUrl) {
const commands = [
`git config --local credential.${hostUrl}.helper ""`,
`git config --local --add credential.${hostUrl}.helper "!${credentialScriptExecution}"`,
`git config --local credential.${hostUrl}.UseHttpPath true`,
];
const options = {
showStdOut: this.verbosityOptions.showOutput,
showStdErr: true,
showCmd: this.verbosityOptions.showCommand,
workingDir: this.projectPath,
};
this._execCommands(commands, options);
}
/**
* Add a new remote in the directory your repository is stored at
* @param {String} repoUrl a remote url
*/
addOrigin(repoUrl) {
const commands = [`git remote add origin ${repoUrl}`];
const options = {
showStdOut: this.verbosityOptions.showOutput,
showStdErr: true,
showCmd: this.verbosityOptions.showCommand,
workingDir: this.projectPath,
};
this._execCommands(commands, options);
}
/**
* Execute git fetch to fetch all remotes
*/
fetchAll() {
const commands = [`git fetch --all${this.verbosityOptions.showOutput === false ? " --quiet" : ""}`];
const options = {
showStdOut: this.verbosityOptions.showOutput,
showStdErr: false,
showCmd: this.verbosityOptions.showCommand,
workingDir: this.projectPath,
};
this._execCommands(commands, options);
}
/**
* Execute git checkout to switch branch or restore working tree files
* @param {string} branch the branch name
*/
checkoutBranch(branch) {
const commands = [`git checkout ${branch}${this.verbosityOptions.showOutput === false ? " --quiet" : ""}`];
const options = {
showStdOut: this.verbosityOptions.showOutput,
showStdErr: true,
showCmd: this.verbosityOptions.showCommand,
workingDir: this.projectPath,
};
this._execCommands(commands, options);
}
/**
* Execute git clone to clone a repository into a new directory
* @param {string} cloneUrl the clone url
* @param {string} branch the branch name
* @param {string} folderName the directory folder name
*/
clone(cloneUrl, branch, folderName) {
const commands = [
`git clone --branch ${branch} ${cloneUrl} "${folderName}" ${this.verbosityOptions.showOutput === false ? " --quiet" : ""}`,
];
const options = {
showStdOut: this.verbosityOptions.showOutput,
showStdErr: true,
showCmd: this.verbosityOptions.showCommand,
};
this._execCommands(commands, options);
}
/**
* Set up or update a gitignore file
* @param {Array} filesToIgnore the list of files to ignore for git
*/
setupGitIgnore(filesToIgnore) {
const gitignorePath = path.join(this.projectPath, ".gitignore");
if (fs.existsSync(gitignorePath) === false) {
fs.writeFileSync(gitignorePath, `${filesToIgnore.join("\n")}`);
}
else {
const gitignoreFile = fs.readFileSync(gitignorePath).toString();
filesToIgnore.forEach((file) => {
if (gitignoreFile.indexOf(file) === -1) {
fs.appendFileSync(gitignorePath, `\n${file}`);
}
});
}
this.add(".gitignore");
}
/**
* Execute git add to add file contents to the index
* @param {string} file the file to add content from
*/
add(file) {
const commands = [`git add "${file}"`];
const options = {
showStdOut: this.verbosityOptions.showOutput,
showStdErr: true,
showCmd: this.verbosityOptions.showCommand,
workingDir: this.projectPath,
};
this._execCommands(commands, options);
}
/**
* Execute git delete to delete a local branch
* @param {string} file the file to add content from
*/
deleteBranch(branch) {
const commands = [`git branch -d ${branch}`];
const options = {
showStdOut: this.verbosityOptions.showOutput,
showStdErr: true,
showCmd: this.verbosityOptions.showCommand,
};
this._execCommands(commands, options);
}
/**
* Execute git merge to join two development histories together
* @param {String} branch the development branch
*/
merge(branch) {
const commands = [`git merge ${branch}`];
const options = {
showStdOut: this.verbosityOptions.showOutput,
showStdErr: true,
showCmd: this.verbosityOptions.showCommand,
};
this._execCommands(commands, options);
}
/**
* Execute git status to show the working tree status in short-format
* @param {callback} callback { error }
*/
shortStatus() {
const command = "git status -s";
const options = {
showStdOut: this.verbosityOptions.showOutput,
showStdErr: true,
showCmd: this.verbosityOptions.showCommand,
};
try {
return this._execChildProcessSync(command, options);
}
catch (ex) {
throw new CLiError(`${ex}`);
}
}
/**
* Execute git rev-list to count the list of commit objects
* @param {String} commit1 the first commit
* @param {String} commit2 the second commit
* @param {callback} callback { error }
*/
countCommitDifference(commit1, commit2) {
const command = `git rev-list --count ${commit1}...${commit2}`;
const options = {
showStdOut: this.verbosityOptions.showOutput,
showStdErr: true,
showCmd: this.verbosityOptions.showCommand,
workingDir: this.projectPath,
};
try {
return this._execChildProcessSync(command, options);
}
catch (ex) {
throw new CLiError(`${ex}`);
}
}
_execCommands(commands, options) {
for (const command of commands) {
try {
this._execChildProcessSync(command, options);
}
catch (ex) {
throw new CLiError(`${ex}`);
}
}
}
_execChildProcessSync(command, options) {
const { showOutput, showStdErr, showCommand, workingDir } = options;
const execOptions = {
stdio: [null, showOutput ? 1 : null, showStdErr ? 2 : null],
shell: true,
windowsHide: true,
};
if (workingDir) {
execOptions.cwd = options.workingDir;
}
if (showCommand) {
Messenger.getInstance().info(command);
}
return execSync(command, execOptions);
}
};