2019-05-14 18:25:46 -04:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
const resolve = require("path").resolve;
|
|
|
|
const spawn = require("child_process").spawn;
|
|
|
|
|
|
|
|
const semver = require("semver");
|
|
|
|
|
|
|
|
const { run } = require("./build");
|
|
|
|
const { loadPackage } = require("./local");
|
|
|
|
|
|
|
|
function git(args) {
|
|
|
|
return run("git", args);
|
|
|
|
}
|
|
|
|
|
|
|
|
function getStatus(filename) {
|
|
|
|
return git([ "status", "-s", resolve(__dirname, "..", filename) ]).then((result) => {
|
|
|
|
result = result.trim();
|
|
|
|
if (result === "") { return "unmodified"; }
|
|
|
|
switch (result.substring(0, 2)) {
|
|
|
|
case 'M ': return "modified";
|
|
|
|
case 'A ': return "added";
|
|
|
|
case 'D ': return "deleted";
|
|
|
|
case 'R ': return "renamed";
|
|
|
|
case 'C ': return "copied";
|
|
|
|
case 'U ': return "updated";
|
|
|
|
case '??': return "untracked";
|
|
|
|
}
|
|
|
|
console.log(result);
|
|
|
|
return "unknown";
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
async function getChanges(latest) {
|
|
|
|
let diff = await git(["diff", "--name-only", latest ]);
|
|
|
|
|
|
|
|
// Map dirname => { dist: [ ], src: [ ] }
|
|
|
|
let changes = { "_": { filename: "_", dist: [], src: [] } };
|
|
|
|
|
|
|
|
diff.split("\n").forEach((line) => {
|
|
|
|
// e.g. packages/constants/index.d.ts
|
|
|
|
let comps = line.trim().split("/");
|
|
|
|
|
|
|
|
// Track non-packages as dist
|
|
|
|
if (comps.length < 2 || comps[0] !== "packages") {
|
|
|
|
let filename = comps.join("/").trim();
|
|
|
|
if (filename === "") { return; }
|
|
|
|
changes._.dist.push(filename);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let name = loadPackage(comps[1]).name;
|
|
|
|
|
|
|
|
let change = changes[name];
|
|
|
|
if (!change) {
|
|
|
|
change = { filename: comps[1], dist: [ ], src: [ ] }
|
|
|
|
changes[name] = change;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Split changes into source changes (src.ts/) or dist changes (output of TypeScript)
|
|
|
|
if (comps[2] === "src.ts") {
|
|
|
|
change.src.push(comps.join("/"));
|
|
|
|
} else {
|
|
|
|
change.dist.push(comps.join("/"));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return changes;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getLatestTag() {
|
|
|
|
let seq = Promise.resolve();
|
|
|
|
|
|
|
|
// @TODO: Pull
|
|
|
|
if (false) {
|
|
|
|
seq = seq.then(() => {
|
|
|
|
console.log("Pulling remote changes...");
|
|
|
|
return git([ "pull" ]);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
seq = seq.then(() => {
|
|
|
|
return git([ "tag" ]).then((tags) => {
|
|
|
|
tags = tags.split("\n").filter(tag => (tag.match(/^v[0-9]+\.[0-9]+\.[0-9]+\-/)));
|
|
|
|
tags.sort(semver.compare)
|
|
|
|
return tags.pop();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
return seq;
|
|
|
|
}
|
|
|
|
|
|
|
|
function findChanges(latest) {
|
|
|
|
let seq = Promise.resolve();
|
|
|
|
|
|
|
|
seq = seq.then(() => {
|
|
|
|
return git(["diff", "--name-only", latest, "HEAD" ]).then((result) => {
|
|
|
|
let filenames = { };
|
|
|
|
result.split("\n").forEach((line) => {
|
|
|
|
// e.g. packages/constants/index.d.ts
|
|
|
|
let comps = line.trim().split("/");
|
|
|
|
if (comps.length < 2) { return; }
|
|
|
|
filenames[comps[1]] = true;
|
|
|
|
});
|
|
|
|
return Object.keys(filenames);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
seq = seq.then((filenames) => {
|
|
|
|
return filenames.map((filename) => {
|
|
|
|
let name = packages[filename].name;
|
|
|
|
return {
|
|
|
|
filename: filename,
|
|
|
|
name: name,
|
|
|
|
localVersion: getLocalVersion(name),
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
seq = seq.then((packages) => {
|
|
|
|
let seq = Promise.resolve();
|
|
|
|
packages.forEach((p) => {
|
|
|
|
seq = seq.then(() => {
|
|
|
|
return getNpmVersion(p.name).then((version) => {
|
|
|
|
p.npmVersion = version;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
return seq.then(() => packages);
|
|
|
|
});
|
|
|
|
return seq;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function getGitTag(filename) {
|
|
|
|
let result = await git([ "log", "-n", "1", "--", filename ]);
|
|
|
|
result = result.trim();
|
|
|
|
if (!result) { return null; }
|
|
|
|
result = result.match(/^commit\s+([0-9a-f]{40})\n/i);
|
|
|
|
if (!result) { return null; }
|
|
|
|
return result[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
async function getDiff(filename, tag, nameOnly) {
|
|
|
|
if (tag == null) { tag = "HEAD"; }
|
|
|
|
let cmd = [ "diff", "--name-only", tag, "--", filename ]
|
|
|
|
if (!nameOnly) { cmd.splice(1, 1); }
|
2019-05-14 21:23:27 -04:00
|
|
|
try {
|
|
|
|
let result = await git(cmd);
|
|
|
|
result = result.trim();
|
|
|
|
if (result === "") { return [ ]; }
|
|
|
|
return result.split("\n");
|
|
|
|
} catch (error) {
|
|
|
|
// This tag does not exist, so compare against beginning of time
|
|
|
|
// This happens when there is a new history (like an orphan branch)
|
|
|
|
if (error.stderr.trim().match(/^fatal: bad object/)) {
|
|
|
|
console.log("Could not find history; showing all");
|
|
|
|
let cmd = [ "rev-list", "--max-parents=0", "HEAD" ];
|
|
|
|
let tag = await git(cmd);
|
|
|
|
return getDiff(filename, tag.trim(), nameOnly);
|
|
|
|
}
|
|
|
|
|
|
|
|
throw error;
|
|
|
|
}
|
2019-05-14 18:25:46 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
async function getUntracked(filename) {
|
|
|
|
let cmd = [ "ls-files", "-o", "--exclude-standard"];
|
|
|
|
if (filename) {
|
|
|
|
cmd.push("--");
|
|
|
|
cmd.push(filename);
|
|
|
|
}
|
|
|
|
let result = await git(cmd);
|
|
|
|
result = result.trim();
|
|
|
|
if (result === "") { return [ ]; }
|
|
|
|
return result.split("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
findChanges: findChanges,
|
|
|
|
getChanges: getChanges,
|
|
|
|
getDiff: getDiff,
|
|
|
|
getGitTag: getGitTag,
|
|
|
|
getLatestTag: getLatestTag,
|
|
|
|
getStatus: getStatus,
|
|
|
|
getUntracked: getUntracked,
|
|
|
|
run: git,
|
|
|
|
}
|