midsummer-sol 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/sol.js +108 -31
package/package.json
CHANGED
package/sol.js
CHANGED
|
@@ -1630,6 +1630,28 @@ async function resolveRef(log, ref) {
|
|
|
1630
1630
|
const op = ops.find((o) => o.rootAfter.startsWith(bare) || (o.entryHash ?? "").startsWith(bare)) || die("unknown ref: " + ref);
|
|
1631
1631
|
return { head: op.rootAfter, op };
|
|
1632
1632
|
}
|
|
1633
|
+
async function resolveRefSoft(log, ref) {
|
|
1634
|
+
const ops = await log.history();
|
|
1635
|
+
if (!ref || ref === "head" || ref === "HEAD")
|
|
1636
|
+
return { head: await log.head() ?? "", op: ops[ops.length - 1] };
|
|
1637
|
+
if (existsSync6(refsPath())) {
|
|
1638
|
+
const refs = JSON.parse(readFileSync6(refsPath(), "utf8"));
|
|
1639
|
+
if (ref === refs.current) {
|
|
1640
|
+
const h = await log.head() ?? "";
|
|
1641
|
+
return { head: h, op: [...ops].reverse().find((o) => o.rootAfter === h) ?? ops[ops.length - 1] };
|
|
1642
|
+
}
|
|
1643
|
+
const named = refs.branches[ref]?.head ?? refs.tags[ref];
|
|
1644
|
+
if (named !== undefined)
|
|
1645
|
+
return { head: named, op: [...ops].reverse().find((o) => o.rootAfter === named) };
|
|
1646
|
+
}
|
|
1647
|
+
if (/^\d+$/.test(ref)) {
|
|
1648
|
+
const op2 = ops.find((o) => o.seq === Number(ref));
|
|
1649
|
+
return op2 ? { head: op2.rootAfter, op: op2 } : undefined;
|
|
1650
|
+
}
|
|
1651
|
+
const bare = ref.startsWith("h_") ? ref : "h_" + ref;
|
|
1652
|
+
const op = ops.find((o) => o.rootAfter.startsWith(bare) || (o.entryHash ?? "").startsWith(bare));
|
|
1653
|
+
return op ? { head: op.rootAfter, op } : undefined;
|
|
1654
|
+
}
|
|
1633
1655
|
function materialize(store, head, path) {
|
|
1634
1656
|
const blob = fileAt(store, head, path);
|
|
1635
1657
|
if (!blob)
|
|
@@ -1656,6 +1678,40 @@ function materialize(store, head, path) {
|
|
|
1656
1678
|
}
|
|
1657
1679
|
return true;
|
|
1658
1680
|
}
|
|
1681
|
+
function materializeInto(store, head, target, path) {
|
|
1682
|
+
const blob = fileAt(store, head, path);
|
|
1683
|
+
if (!blob)
|
|
1684
|
+
return false;
|
|
1685
|
+
const abs = resolve2(target, path);
|
|
1686
|
+
if (abs !== target && !abs.startsWith(target + sep2))
|
|
1687
|
+
return false;
|
|
1688
|
+
const mode = modeAt(store, head, path);
|
|
1689
|
+
mkdirSync5(dirname3(abs), { recursive: true });
|
|
1690
|
+
if (mode === SYMLINK_MODE2) {
|
|
1691
|
+
try {
|
|
1692
|
+
unlinkSync4(abs);
|
|
1693
|
+
} catch {}
|
|
1694
|
+
symlinkSync3(blob.content, abs);
|
|
1695
|
+
return true;
|
|
1696
|
+
}
|
|
1697
|
+
writeFileSync6(abs, blob.encoding === "base64" ? Buffer.from(blob.content, "base64") : blob.content);
|
|
1698
|
+
if (mode === EXEC_MODE2) {
|
|
1699
|
+
try {
|
|
1700
|
+
chmodSync3(abs, EXEC_MODE2);
|
|
1701
|
+
} catch {}
|
|
1702
|
+
}
|
|
1703
|
+
return true;
|
|
1704
|
+
}
|
|
1705
|
+
function writeWorkingIndexAt(targetSolDir, target, files) {
|
|
1706
|
+
const idx = {};
|
|
1707
|
+
for (const f of files) {
|
|
1708
|
+
try {
|
|
1709
|
+
const st = lstatSync3(join6(target, f));
|
|
1710
|
+
idx[f] = [st.mtimeMs, st.size, st.mode & 73 ? 1 : 0];
|
|
1711
|
+
} catch {}
|
|
1712
|
+
}
|
|
1713
|
+
writeFileSync6(join6(targetSolDir, "index.json"), JSON.stringify(idx));
|
|
1714
|
+
}
|
|
1659
1715
|
function materializeTree(store, head) {
|
|
1660
1716
|
const want = new Set(head ? listAll(store, head) : []);
|
|
1661
1717
|
let n = 0;
|
|
@@ -1809,13 +1865,17 @@ function workingChanges(store, head, index = loadWorkingIndex()) {
|
|
|
1809
1865
|
}
|
|
1810
1866
|
return { added: added.sort(), modified: modified.sort(), removed: removed.sort() };
|
|
1811
1867
|
}
|
|
1812
|
-
function printWorkingDiff(store, base) {
|
|
1868
|
+
function printWorkingDiff(store, base, only) {
|
|
1813
1869
|
const ch = workingChanges(store, base);
|
|
1814
|
-
|
|
1870
|
+
const keep = (f) => only === undefined || f === only;
|
|
1871
|
+
const added = ch.added.filter(keep);
|
|
1872
|
+
const removed = ch.removed.filter(keep);
|
|
1873
|
+
const modified = ch.modified.filter(keep);
|
|
1874
|
+
for (const f of added)
|
|
1815
1875
|
console.log(`+ added ${f}`);
|
|
1816
|
-
for (const f of
|
|
1876
|
+
for (const f of removed)
|
|
1817
1877
|
console.log(`- removed ${f}`);
|
|
1818
|
-
for (const f of
|
|
1878
|
+
for (const f of modified) {
|
|
1819
1879
|
console.log(`~ modified ${f}`);
|
|
1820
1880
|
const abs = join6(cwd2, f);
|
|
1821
1881
|
if (lstatSync3(abs).isSymbolicLink())
|
|
@@ -1827,8 +1887,16 @@ function printWorkingDiff(store, base) {
|
|
|
1827
1887
|
if (typeof stored === "string" && stored !== buf.toString("utf8"))
|
|
1828
1888
|
console.log(indent(lineHunks2(stored, buf.toString("utf8"))));
|
|
1829
1889
|
}
|
|
1830
|
-
if (!
|
|
1831
|
-
console.log("no working changes");
|
|
1890
|
+
if (!added.length && !removed.length && !modified.length)
|
|
1891
|
+
console.log(only ? `no working changes in ${only}` : "no working changes");
|
|
1892
|
+
}
|
|
1893
|
+
function isWorkingPath(store, head, arg) {
|
|
1894
|
+
const rel = repoRel(arg);
|
|
1895
|
+
if (lexists(join6(cwd2, rel)))
|
|
1896
|
+
return rel;
|
|
1897
|
+
if (head && listAll(store, head).includes(rel))
|
|
1898
|
+
return rel;
|
|
1899
|
+
return;
|
|
1832
1900
|
}
|
|
1833
1901
|
function blameFile(ops, store, path) {
|
|
1834
1902
|
let tagged = [];
|
|
@@ -2401,10 +2469,26 @@ async function main() {
|
|
|
2401
2469
|
case "diff": {
|
|
2402
2470
|
const { log } = open();
|
|
2403
2471
|
const store = loadStore();
|
|
2472
|
+
const head = await log.head() ?? "";
|
|
2404
2473
|
if (args.length >= 2) {
|
|
2405
2474
|
printTreeDiff(diffTrees(store, (await resolveRef(log, args[0])).head, (await resolveRef(log, args[1])).head));
|
|
2475
|
+
} else if (args.length === 1) {
|
|
2476
|
+
const resolved = await resolveRefSoft(log, args[0]);
|
|
2477
|
+
if (resolved) {
|
|
2478
|
+
printWorkingDiff(store, resolved.head);
|
|
2479
|
+
} else {
|
|
2480
|
+
const path = isWorkingPath(store, head, args[0]);
|
|
2481
|
+
if (path)
|
|
2482
|
+
printWorkingDiff(store, head, path);
|
|
2483
|
+
else
|
|
2484
|
+
die(`'${args[0]}' is neither a ref nor a working-tree path.
|
|
2485
|
+
usage: sol diff (working tree vs HEAD)
|
|
2486
|
+
sol diff <ref> (working tree vs a branch/commit)
|
|
2487
|
+
sol diff <ref> <ref> (tree vs tree)
|
|
2488
|
+
sol diff <path> (one file, working tree vs HEAD)`);
|
|
2489
|
+
}
|
|
2406
2490
|
} else {
|
|
2407
|
-
printWorkingDiff(store,
|
|
2491
|
+
printWorkingDiff(store, head);
|
|
2408
2492
|
}
|
|
2409
2493
|
break;
|
|
2410
2494
|
}
|
|
@@ -2872,17 +2956,11 @@ async function main() {
|
|
|
2872
2956
|
store.put(node);
|
|
2873
2957
|
let n = 0;
|
|
2874
2958
|
if (checkoutHead) {
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
if (
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
if (!blob)
|
|
2881
|
-
continue;
|
|
2882
|
-
mkdirSync7(dirname5(abs), { recursive: true });
|
|
2883
|
-
writeFileSync9(abs, blob.encoding === "base64" ? Buffer.from(blob.content, "base64") : blob.content);
|
|
2884
|
-
n++;
|
|
2885
|
-
}
|
|
2959
|
+
const files = listAll3(store, checkoutHead);
|
|
2960
|
+
for (const f of files)
|
|
2961
|
+
if (materializeInto(store, checkoutHead, target, f))
|
|
2962
|
+
n++;
|
|
2963
|
+
writeWorkingIndexAt(fdir, target, files);
|
|
2886
2964
|
}
|
|
2887
2965
|
console.log(`cloned ${repoName} -> ${rest[1] || repoName} (${bundle.ops.length} ops, ${Object.keys(cloneBranches).length} branch(es), ${n} files, on ${onBranch})`);
|
|
2888
2966
|
break;
|
|
@@ -2898,8 +2976,9 @@ async function main() {
|
|
|
2898
2976
|
const localRefs = existsSync9(refsPath()) ? JSON.parse(readFileSync9(refsPath(), "utf8")) : undefined;
|
|
2899
2977
|
const branch = localRefs?.current ?? "main";
|
|
2900
2978
|
const branchHead = await log.head() ?? "";
|
|
2979
|
+
const remoteWasEmpty = rh.seq === 0 && !rh.tip;
|
|
2901
2980
|
if (localSeq === rh.seq && localTip === rh.tip) {
|
|
2902
|
-
console.log("everything up to date");
|
|
2981
|
+
console.log(remoteWasEmpty ? "nothing to push \u2014 local repo is empty (commit something first)" : "everything up to date");
|
|
2903
2982
|
break;
|
|
2904
2983
|
}
|
|
2905
2984
|
if (rh.seq > 0) {
|
|
@@ -2936,7 +3015,11 @@ async function main() {
|
|
|
2936
3015
|
}
|
|
2937
3016
|
setOpLogHead(res.head ?? branchHead);
|
|
2938
3017
|
const prod = res.refs?.production;
|
|
2939
|
-
|
|
3018
|
+
if (remoteWasEmpty) {
|
|
3019
|
+
console.log(`created remote repo ${cfg.repo} \u2014 pushed ${res.applied} op(s) (branch ${branch} @ ${(res.head ?? "").slice(0, 12)})${prod ? `; production=${prod}` : ""}`);
|
|
3020
|
+
} else {
|
|
3021
|
+
console.log(`pushed ${res.applied} op(s) -> remote (branch ${branch} @ ${(res.head ?? "").slice(0, 12)})${prod ? `; production=${prod}` : ""}`);
|
|
3022
|
+
}
|
|
2940
3023
|
break;
|
|
2941
3024
|
}
|
|
2942
3025
|
case "pull": {
|
|
@@ -3108,17 +3191,11 @@ async function main() {
|
|
|
3108
3191
|
store.put(node);
|
|
3109
3192
|
let n = 0;
|
|
3110
3193
|
if (checkoutHead) {
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
if (
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
if (!blob)
|
|
3117
|
-
continue;
|
|
3118
|
-
mkdirSync7(dirname5(abs), { recursive: true });
|
|
3119
|
-
writeFileSync9(abs, blob.encoding === "base64" ? Buffer.from(blob.content, "base64") : blob.content);
|
|
3120
|
-
n++;
|
|
3121
|
-
}
|
|
3194
|
+
const files = listAll3(store, checkoutHead);
|
|
3195
|
+
for (const f of files)
|
|
3196
|
+
if (materializeInto(store, checkoutHead, target, f))
|
|
3197
|
+
n++;
|
|
3198
|
+
writeWorkingIndexAt(fdir, target, files);
|
|
3122
3199
|
}
|
|
3123
3200
|
console.log(`forked ${parent} -> ${newRepo} (your copy at ${args[3] || newRepo}: ${Object.keys(cloneBranches).length} branch(es), ${n} files; parent: ${parent})`);
|
|
3124
3201
|
break;
|