cartodb/lib/build/branchFiles/modifiedFiles.js
2020-06-15 10:58:47 +08:00

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;