142 lines
4.0 KiB
JavaScript
142 lines
4.0 KiB
JavaScript
var child = require('child_process');
|
|
var path = require('path');
|
|
var fs = require('fs');
|
|
var recursive = require('recursive-readdir');
|
|
var _ = require('underscore');
|
|
|
|
/**
|
|
* getCurrentBranchName
|
|
*
|
|
* @returns {string} The name of the current git branch
|
|
*/
|
|
function getCurrentBranchName () {
|
|
var promise = new Promise(function (resolve, reject) {
|
|
child.exec('git rev-parse --abbrev-ref HEAD', function (error, stdout, stderr) {
|
|
if (!error) {
|
|
resolve(stdout.replace(/(\r\n|\n|\r)/gm, ''));
|
|
}
|
|
});
|
|
});
|
|
|
|
return promise;
|
|
}
|
|
|
|
/**
|
|
* getFilesModifiedInBranch
|
|
*
|
|
* @param {string} branchName The branch name to get the list of modified file list from.
|
|
* @returns {Promise} result.
|
|
* @resolves {string[]} The list of modified files in the given branch.
|
|
*/
|
|
function getFilesModifiedInBranch (branchName) {
|
|
var promise = new Promise(function (resolve, reject) {
|
|
var files;
|
|
var command = 'git diff --name-only ' + branchName + ' `git merge-base ' + branchName + ' master`';
|
|
|
|
child.exec(command, function (error, stdout, stderr) {
|
|
if (!error) {
|
|
var newLine = /(\r\n|\n|\r)/;
|
|
files = stdout.split(newLine).filter(function (file) {
|
|
return file.trim().length > 0;
|
|
});
|
|
files = files.map(function (file) {
|
|
return path.resolve('.', file);
|
|
});
|
|
resolve(files);
|
|
}
|
|
});
|
|
});
|
|
|
|
return promise;
|
|
}
|
|
|
|
var notNodeModules = function (file, stats) {
|
|
return stats.isDirectory() && file.toLowerCase().indexOf('node_modules') > -1;
|
|
};
|
|
|
|
/**
|
|
* getFilesInStatus
|
|
*
|
|
* @returns {Promise} result.
|
|
* @resolves {string[]} The list of working tree files as shown by `git status --short` but without status codes.
|
|
*/
|
|
function getFilesInStatus () {
|
|
var promise = new Promise(function (resolve, reject) {
|
|
child.exec('git status --short', function (error, stdout, stderr) {
|
|
if (!error) {
|
|
var newLine = /\n/;
|
|
var files = stdout.split(newLine);
|
|
var promises = files.reduce(function (acc, file) {
|
|
if (file.trim().length > 0) {
|
|
var name = file.slice(3);
|
|
var resolvedPath = path.resolve('.', name);
|
|
|
|
try {
|
|
var stats = fs.statSync(resolvedPath);
|
|
if (stats.isFile()) {
|
|
acc.push(Promise.resolve(resolvedPath));
|
|
return acc;
|
|
} else if (stats.isDirectory()) {
|
|
acc.push(new Promise(function (resolve, reject) {
|
|
recursive(resolvedPath, [notNodeModules], function (err, files) {
|
|
if (err) {
|
|
reject(err);
|
|
}
|
|
|
|
resolve(files);
|
|
});
|
|
}));
|
|
return acc;
|
|
}
|
|
} catch (err) {
|
|
if (err.code === 'ENOENT') {
|
|
acc.push(Promise.resolve(resolvedPath));
|
|
return acc;
|
|
} else {
|
|
throw new Error(err);
|
|
}
|
|
}
|
|
} else {
|
|
return acc;
|
|
}
|
|
}, []);
|
|
|
|
Promise.all(promises)
|
|
.then(function (fileList) {
|
|
resolve(_.uniq(_.compact(_.flatten(fileList))));
|
|
});
|
|
}
|
|
});
|
|
});
|
|
return promise;
|
|
}
|
|
|
|
/**
|
|
* getModifiedFiles
|
|
*
|
|
* @returns {Promise} result.
|
|
* @resolves {string[]} The list of all modified files of the working branch compared to master. It includes already committed files and the ones unstaged.
|
|
*/
|
|
var getModifiedFiles = function () {
|
|
var files = [];
|
|
|
|
var promise = new Promise(function (resolve, reject) {
|
|
getCurrentBranchName()
|
|
.then(function (branchName) {
|
|
return getFilesModifiedInBranch(branchName);
|
|
})
|
|
.then(function (modifiedFiles) {
|
|
files = files.concat(modifiedFiles);
|
|
return getFilesInStatus();
|
|
})
|
|
.then(function (filesInStatus) {
|
|
files = _.uniq(files.concat(filesInStatus));
|
|
resolve(files);
|
|
});
|
|
});
|
|
|
|
return promise;
|
|
};
|
|
|
|
module.exports = getModifiedFiles;
|