Vmeda.Online/gulp/task-push.js

174 lines
5.9 KiB
JavaScript
Raw Normal View History

// (C) Copyright 2015 Moodle Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
const gulp = require('gulp');
const inquirer = require('inquirer');
const DevConfig = require('./dev-config');
const Git = require('./git');
const Jira = require('./jira');
const Utils = require('./utils');
/**
* Task to push a git branch and update tracker issue.
*/
class PushTask {
/**
* Run the task.
*
* @param args Command line arguments.
* @param done Function to call when done.
*/
async run(args, done) {
try {
const remote = args.remote || DevConfig.get('upstreamRemote', 'origin');
let branch = args.branch;
const force = !!args.force;
if (!branch) {
branch = await Git.getCurrentBranch();
}
if (!branch) {
throw new Error('Cannot determine the current branch. Please make sure youu aren\'t in detached HEAD state');
} else if (branch == 'HEAD') {
throw new Error('Cannot push HEAD branch');
}
const keepRunning = await this.validateLastCommitMessage(branch);
if (!keepRunning) {
// Last commit not valid, stop.
console.log('Exiting...');
done();
return;
}
// Push the branch.
console.log(`Pushing branch ${branch} to remote ${remote}...`);
await Git.push(remote, branch, force);
// Update tracker info.
console.log(`Branch pushed, update tracker info...`);
await this.updateTrackerGitInfo(branch, remote);
} catch (error) {
console.error(error);
}
done();
}
/**
* Update git info in the tracker issue.
*
* @param branch Branch name.
* @param remote Remote used.
* @return Promise resolved when done.
*/
async updateTrackerGitInfo(branch, remote) {
// Parse the branch to get the project and issue number.
const branchData = Utils.parseBranch(branch);
// Get the repository data for the project.
let repositoryUrl = DevConfig.get(branchData.project + '.repositoryUrl');
let diffUrlTemplate = DevConfig.get(branchData.project + '.diffUrlTemplate', '');
let remoteUrl;
if (!repositoryUrl) {
// Calculate the repositoryUrl based on the remote URL.
remoteUrl = await Git.getRemoteUrl(remote);
repositoryUrl = remoteUrl.replace(/^https?:\/\//, 'git://');
if (!repositoryUrl.match(/\.git$/)) {
repositoryUrl += '.git';
}
}
if (!diffUrlTemplate) {
// Calculate the diffUrlTemplate based on the remote URL.
if (!remoteUrl) {
remoteUrl = await Git.getRemoteUrl(remoteUrl);
}
diffUrlTemplate = remoteUrl + '/compare/%headcommit%...%branch%';
}
// Search HEAD commit to put in the diff URL.
console.log ('Searching for head commit...');
let headCommit = await Git.getHeadCommit(branch, branchData);
if (!headCommit) {
throw new Error('Head commit not resolved, aborting update of tracker fields');
}
headCommit = headCommit.substr(0, 10);
console.log(`Head commit resolved to ${headCommit}`);
// Calculate last properties needed.
const diffUrl = diffUrlTemplate.replace('%branch%', branch).replace('%headcommit%', headCommit);
const fieldRepositoryUrl = DevConfig.get('tracker.fieldnames.repositoryurl', 'Pull from Repository');
const fieldBranch = DevConfig.get('tracker.fieldnames.branch', 'Pull Master Branch');
const fieldDiffUrl = DevConfig.get('tracker.fieldnames.diffurl', 'Pull Master Diff URL');
// Update tracker fields.
const updates = {};
updates[fieldRepositoryUrl] = repositoryUrl;
updates[fieldBranch] = branch;
updates[fieldDiffUrl] = diffUrl;
console.log('Setting tracker fields...');
await Jira.setCustomFields(branchData.issue, updates);
}
/**
* Validate last commit message comparing it with the branch name.
*
* @param branch Branch name.
* @return True if value is ok or the user wants to continue anyway, false to stop.
*/
async validateLastCommitMessage(branch) {
const branchData = Utils.parseBranch(branch);
const messages = await Git.messages(1);
const message = messages[0];
const issue = Utils.getIssueFromCommitMessage(message);
if (!issue || issue != branchData.issue) {
if (!issue) {
console.log('The issue number could not be found in the commit message.');
console.log(`Commit: ${message}`);
} else if (issue != branchData.issue) {
console.log('The issue number in the last commit does not match the branch being pushed to.');
console.log(`Branch: ${branchData.issue} vs. commit: ${issue}`);
}
const answer = await inquirer.prompt([
{
type: 'input',
name: 'confirm',
message: 'Are you sure you want to continue?',
default: 'n',
},
]);
return answer.confirm == 'y';
}
return true;
}
}
module.exports = PushTask;