index.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. var spawn = require("child_process").spawn;
  2. var fs = require("fs");
  3. var sgf = function(filter, callback) {
  4. if (typeof filter == "function") {
  5. callback = filter;
  6. filter = "ACDMRTUXB";
  7. }
  8. sgf.getHead(function(err, head) {
  9. if (err) {
  10. callback(err);
  11. } else {
  12. var command = "git diff-index --cached --name-status -M --diff-filter=" + filter + " " + head;
  13. run(command, function(err, stdout, stderr) {
  14. if (err || stderr) {
  15. callback(err || new Error(stderr));
  16. } else {
  17. callback(null, stdoutToResultsObject(stdout));
  18. }
  19. });
  20. }
  21. });
  22. }
  23. sgf.cwd = process.cwd();
  24. sgf.debug = false;
  25. sgf.includeContent = false;
  26. sgf.firstHead = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
  27. sgf.getHead = function(callback) {
  28. run("git rev-parse --verify HEAD", function(err, stdout, stderr) {
  29. if (err && err.message.indexOf("fatal: Needed a single revision")!==-1) {
  30. callback(null, sgf.firstHead);
  31. } else if (err || stderr) {
  32. callback(err || new Error("STDERR: " + stderr));
  33. } else {
  34. stdout = stdout.replace("\n", "");
  35. callback(null, stdout);
  36. }
  37. });
  38. }
  39. sgf.readFile = function(filename, options, callback) {
  40. fs.readFile(sgf.cwd + "/" + filename, options, callback);
  41. }
  42. module.exports = sgf;
  43. /** ======================================== HELPERS ======================================== **/
  44. var run = function(command, callback) {
  45. if (sgf.debug) {
  46. console.log("RUNNING: " + command);
  47. }
  48. // var exec = require("child_process").exec;
  49. // exec("cd '" + module.exports.cwd + "' && " + command, callback);
  50. var bits = command.split(" ");
  51. var args = bits.slice(1);
  52. var cmd = spawn(bits[0], args, {
  53. cwd: module.exports.cwd
  54. });
  55. var stdout = "";
  56. var stderr = "";
  57. cmd.stdout.on('data', function(data){
  58. stdout+=data.toString();
  59. });
  60. cmd.stderr.on('data', function(data){
  61. stderr+=data.toString();
  62. });
  63. cmd.on("close", function(code){
  64. var err = null;
  65. if(code!==0){
  66. err = new Error(stderr);
  67. }
  68. callback(err,stdout,stderr);
  69. });
  70. }
  71. var codeToStatus = function(code) {
  72. /* ===============================================================================================================================
  73. ** PER docs at https://git-scm.com/docs/git-diff-index
  74. ** Possible status letters are:
  75. ** A: addition of a file
  76. ** C: copy of a file into a new one
  77. ** D: deletion of a file
  78. ** M: modification of the contents or mode of a file
  79. ** R: renaming of a file
  80. ** T: change in the type of the file
  81. ** U: file is unmerged (you must complete the merge before it can be committed)
  82. ** X: "unknown" change type (most probably a bug, please report it)
  83. **
  84. ** Status letters C and R are always followed by a score (denoting the percentage of similarity between the source and target of the move or copy).
  85. ** Status letter M may be followed by a score (denoting the percentage of dissimilarity) for file rewrites.
  86. ** ============================================================================================================================ */
  87. var map = {
  88. "A": "Added",
  89. "C": "Copied",
  90. "D": "Deleted",
  91. "M": "Modified",
  92. "R": "Renamed",
  93. "T": "Type-Change",
  94. "U": "Unmerged",
  95. "X": "Unknown",
  96. "B": "Broken"
  97. }
  98. return map[code.charAt(0)];
  99. }
  100. var stdoutToResultsObject = function(stdout) {
  101. var results = [];
  102. var lines = stdout.split("\n");
  103. var iLines = lines.length;
  104. var files_with_errors = 0;
  105. while (iLines--) {
  106. var line = lines[iLines];
  107. if (line != "") {
  108. var parts = line.split("\t");
  109. var result = {
  110. filename: parts[2] || parts[1],
  111. status: codeToStatus(parts[0])
  112. }
  113. if (sgf.includeContent) {
  114. try {
  115. result.content = fs.readFileSync(sgf.cwd + "/" + result.filename, {
  116. encoding: "utf8"
  117. });
  118. } catch (err) {
  119. result.err = err;
  120. }
  121. }
  122. results.push(result);
  123. }
  124. }
  125. return results;
  126. }