@rness/cli 0.22.0 → 0.22.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/README.md +32 -0
- package/dist/bin/rness.js +2 -2
- package/dist/{chunk-AEL2W76O.js → chunk-A7NX55WK.js} +4 -4
- package/dist/chunk-A7NX55WK.js.map +1 -0
- package/dist/{chunk-XCO5ZT2H.js → chunk-DFGZWBBW.js} +202 -140
- package/dist/chunk-DFGZWBBW.js.map +1 -0
- package/dist/{chunk-S4NARIQP.js → chunk-H5E6FMP6.js} +89 -59
- package/dist/chunk-H5E6FMP6.js.map +1 -0
- package/dist/index.js +2 -2
- package/dist/{note-XSJ7ASXM.js → note-PANYS7DK.js} +3 -3
- package/dist/{summary-47SFWNSQ.js → summary-K5ETHXOX.js} +3 -3
- package/package.json +1 -1
- package/scaffold/README.md +3 -3
- package/scaffold/WORKSPACE.md +2 -2
- package/scaffold/adr/0000-template.md +5 -5
- package/dist/chunk-AEL2W76O.js.map +0 -1
- package/dist/chunk-S4NARIQP.js.map +0 -1
- package/dist/chunk-XCO5ZT2H.js.map +0 -1
- /package/dist/{note-XSJ7ASXM.js.map → note-PANYS7DK.js.map} +0 -0
- /package/dist/{summary-47SFWNSQ.js.map → summary-K5ETHXOX.js.map} +0 -0
|
@@ -1,50 +1,3 @@
|
|
|
1
|
-
// src/core/fs.ts
|
|
2
|
-
import {
|
|
3
|
-
access,
|
|
4
|
-
lstat,
|
|
5
|
-
readFile,
|
|
6
|
-
rename,
|
|
7
|
-
rm,
|
|
8
|
-
writeFile
|
|
9
|
-
} from "fs/promises";
|
|
10
|
-
import { basename, dirname, join } from "path";
|
|
11
|
-
async function exists(p) {
|
|
12
|
-
try {
|
|
13
|
-
await access(p);
|
|
14
|
-
return true;
|
|
15
|
-
} catch {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
async function isSymlink(p) {
|
|
20
|
-
try {
|
|
21
|
-
return (await lstat(p)).isSymbolicLink();
|
|
22
|
-
} catch (e) {
|
|
23
|
-
if (e.code === "ENOENT") return false;
|
|
24
|
-
throw e;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
async function readOrNull(p) {
|
|
28
|
-
try {
|
|
29
|
-
return await readFile(p, "utf8");
|
|
30
|
-
} catch (e) {
|
|
31
|
-
if (e.code === "ENOENT") return null;
|
|
32
|
-
throw e;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
var sequence = 0;
|
|
36
|
-
async function writeFileAtomic(p, text) {
|
|
37
|
-
sequence += 1;
|
|
38
|
-
const tmp = join(dirname(p), `.${basename(p)}.${process.pid}.${sequence}.tmp`);
|
|
39
|
-
await writeFile(tmp, text, "utf8");
|
|
40
|
-
try {
|
|
41
|
-
await rename(tmp, p);
|
|
42
|
-
} catch (e) {
|
|
43
|
-
await rm(tmp, { force: true }).catch(() => void 0);
|
|
44
|
-
throw e;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
1
|
// src/core/frontmatter.ts
|
|
49
2
|
import { parse } from "yaml";
|
|
50
3
|
var FRONT_MATTER = /^---\r?\n(?:([\s\S]*?)\r?\n)?---(?:\r?\n|$)/;
|
|
@@ -83,8 +36,8 @@ function extractTitle(source) {
|
|
|
83
36
|
}
|
|
84
37
|
|
|
85
38
|
// src/core/collect.ts
|
|
86
|
-
import { glob, readFile
|
|
87
|
-
import { join
|
|
39
|
+
import { glob, readFile } from "fs/promises";
|
|
40
|
+
import { join, posix, sep } from "path";
|
|
88
41
|
function toPosix(rel) {
|
|
89
42
|
return rel.split(sep).join(posix.sep);
|
|
90
43
|
}
|
|
@@ -111,8 +64,8 @@ async function collectMarkdown(dir) {
|
|
|
111
64
|
for await (const rel of glob("**/*.md", { cwd: dir })) rels.push(toPosix(rel));
|
|
112
65
|
const items = await Promise.all(
|
|
113
66
|
rels.map(async (rel) => {
|
|
114
|
-
const path =
|
|
115
|
-
return markdownItem(path, rel, await
|
|
67
|
+
const path = join(dir, ...rel.split(posix.sep));
|
|
68
|
+
return markdownItem(path, rel, await readFile(path, "utf8"));
|
|
116
69
|
})
|
|
117
70
|
);
|
|
118
71
|
return items.sort((a, b) => a.rel < b.rel ? -1 : a.rel > b.rel ? 1 : 0);
|
|
@@ -152,7 +105,7 @@ function scopeChain(manifest, scope) {
|
|
|
152
105
|
}
|
|
153
106
|
|
|
154
107
|
// src/core/context.ts
|
|
155
|
-
import { join as
|
|
108
|
+
import { join as join2 } from "path";
|
|
156
109
|
var COLLECTIONS = [
|
|
157
110
|
"standards",
|
|
158
111
|
"adr",
|
|
@@ -195,14 +148,14 @@ async function assembleContext({
|
|
|
195
148
|
const chain = scopeChain(manifest, scope);
|
|
196
149
|
const collections = await Promise.all(
|
|
197
150
|
COLLECTIONS.map(
|
|
198
|
-
(name) => assembleCollection(
|
|
151
|
+
(name) => assembleCollection(join2(rnessDir, name), name, chain)
|
|
199
152
|
)
|
|
200
153
|
);
|
|
201
154
|
return { scope, collections };
|
|
202
155
|
}
|
|
203
156
|
|
|
204
157
|
// src/core/contract.ts
|
|
205
|
-
import { join as
|
|
158
|
+
import { join as join3 } from "path";
|
|
206
159
|
|
|
207
160
|
// src/core/documents.ts
|
|
208
161
|
import { posix as posix2 } from "path";
|
|
@@ -217,7 +170,9 @@ function documentNumber(rel) {
|
|
|
217
170
|
}
|
|
218
171
|
function documentTitle(heading, number) {
|
|
219
172
|
if (number === null) return heading;
|
|
220
|
-
const rest = new RegExp(`^${number}\\s*[\u2014\u2013:-]\\s*(.+)$`).exec(
|
|
173
|
+
const rest = new RegExp(`^${number}\\s*[\u2014\u2013:-]\\s*(.+)$`).exec(
|
|
174
|
+
heading
|
|
175
|
+
)?.[1];
|
|
221
176
|
return rest ?? heading;
|
|
222
177
|
}
|
|
223
178
|
|
|
@@ -237,12 +192,12 @@ var STATUSES = {
|
|
|
237
192
|
var SKIP = /* @__PURE__ */ new Set(["adr/0000-template.md"]);
|
|
238
193
|
var PLACEMENT_KEYS = ["scopes", "scope"];
|
|
239
194
|
async function itemsOf(rnessDir, name, override) {
|
|
240
|
-
const items = await collectMarkdown(
|
|
195
|
+
const items = await collectMarkdown(join3(rnessDir, name));
|
|
241
196
|
const prefix = `${name}/`;
|
|
242
197
|
if (override === void 0 || !override.rel.startsWith(prefix)) return items;
|
|
243
198
|
const rel = override.rel.slice(prefix.length);
|
|
244
199
|
const item = markdownItem(
|
|
245
|
-
|
|
200
|
+
join3(rnessDir, ...override.rel.split("/")),
|
|
246
201
|
rel,
|
|
247
202
|
override.text
|
|
248
203
|
);
|
|
@@ -288,7 +243,7 @@ async function checkContract(rnessDir, override) {
|
|
|
288
243
|
for (const key of PLACEMENT_KEYS) {
|
|
289
244
|
if (Object.hasOwn(item.fields, key)) {
|
|
290
245
|
problems.push(
|
|
291
|
-
`${where}: front matter "${key}" is not supported
|
|
246
|
+
`${where}: front matter "${key}" is not supported: the directory decides the scope; move the file`
|
|
292
247
|
);
|
|
293
248
|
}
|
|
294
249
|
}
|
|
@@ -314,12 +269,12 @@ async function checkContract(rnessDir, override) {
|
|
|
314
269
|
|
|
315
270
|
// src/core/contained.ts
|
|
316
271
|
import { realpath } from "fs/promises";
|
|
317
|
-
import { isAbsolute, join as
|
|
272
|
+
import { isAbsolute, join as join4, relative } from "path";
|
|
318
273
|
var RNESS_PATH = /^[A-Za-z0-9_-][A-Za-z0-9._-]*(?:\/[A-Za-z0-9_-][A-Za-z0-9._-]*)*$/;
|
|
319
274
|
async function containedPath(root, rel) {
|
|
320
275
|
if (!RNESS_PATH.test(rel))
|
|
321
276
|
throw new Error(`${rel} is not a path within .rness`);
|
|
322
|
-
const path =
|
|
277
|
+
const path = join4(root, ...rel.split("/"));
|
|
323
278
|
const [realRoot, real] = await Promise.all([realpath(root), realpath(path)]);
|
|
324
279
|
const inside = relative(realRoot, real);
|
|
325
280
|
if (inside === "" || inside.startsWith("..") || isAbsolute(inside))
|
|
@@ -985,6 +940,53 @@ function parseBoard(name, value, knows = isPresetRevision) {
|
|
|
985
940
|
};
|
|
986
941
|
}
|
|
987
942
|
|
|
943
|
+
// src/core/fs.ts
|
|
944
|
+
import {
|
|
945
|
+
access,
|
|
946
|
+
lstat,
|
|
947
|
+
readFile as readFile2,
|
|
948
|
+
rename,
|
|
949
|
+
rm,
|
|
950
|
+
writeFile
|
|
951
|
+
} from "fs/promises";
|
|
952
|
+
import { basename, dirname, join as join5 } from "path";
|
|
953
|
+
async function exists(p) {
|
|
954
|
+
try {
|
|
955
|
+
await access(p);
|
|
956
|
+
return true;
|
|
957
|
+
} catch {
|
|
958
|
+
return false;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
async function isSymlink(p) {
|
|
962
|
+
try {
|
|
963
|
+
return (await lstat(p)).isSymbolicLink();
|
|
964
|
+
} catch (e) {
|
|
965
|
+
if (e.code === "ENOENT") return false;
|
|
966
|
+
throw e;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
async function readOrNull(p) {
|
|
970
|
+
try {
|
|
971
|
+
return await readFile2(p, "utf8");
|
|
972
|
+
} catch (e) {
|
|
973
|
+
if (e.code === "ENOENT") return null;
|
|
974
|
+
throw e;
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
var sequence = 0;
|
|
978
|
+
async function writeFileAtomic(p, text) {
|
|
979
|
+
sequence += 1;
|
|
980
|
+
const tmp = join5(dirname(p), `.${basename(p)}.${process.pid}.${sequence}.tmp`);
|
|
981
|
+
await writeFile(tmp, text, "utf8");
|
|
982
|
+
try {
|
|
983
|
+
await rename(tmp, p);
|
|
984
|
+
} catch (e) {
|
|
985
|
+
await rm(tmp, { force: true }).catch(() => void 0);
|
|
986
|
+
throw e;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
|
|
988
990
|
// src/core/git.ts
|
|
989
991
|
import { execFile } from "child_process";
|
|
990
992
|
import { dirname as dirname2, resolve } from "path";
|
|
@@ -1153,6 +1155,20 @@ var SSH_HOST = "git@github.com:";
|
|
|
1153
1155
|
function repoUrl(host, org, repo) {
|
|
1154
1156
|
return `${host}${org}/${repo}.git`;
|
|
1155
1157
|
}
|
|
1158
|
+
function remoteKey(url) {
|
|
1159
|
+
let rest = url.trim();
|
|
1160
|
+
const scp = /^[^@/:]+@([^/:]+):(.*)$/.exec(rest);
|
|
1161
|
+
if (scp !== null) rest = `${scp[1]}/${scp[2]}`;
|
|
1162
|
+
else {
|
|
1163
|
+
const full = /^[a-z][a-z0-9+.-]*:\/\/(?:[^@/]*@)?([^/]*)(.*)$/i.exec(rest);
|
|
1164
|
+
if (full !== null)
|
|
1165
|
+
rest = `${(full[1] ?? "").replace(/:\d+$/, "")}${full[2] ?? ""}`;
|
|
1166
|
+
}
|
|
1167
|
+
return rest.replace(/\/+$/, "").replace(/\.git$/i, "").replace(/\/+$/, "").toLowerCase();
|
|
1168
|
+
}
|
|
1169
|
+
function sameRemote(a, b) {
|
|
1170
|
+
return remoteKey(a) === remoteKey(b);
|
|
1171
|
+
}
|
|
1156
1172
|
var AUTH = [
|
|
1157
1173
|
/authentication failed/i,
|
|
1158
1174
|
/permission denied/i,
|
|
@@ -1508,14 +1524,15 @@ function parseRepoSpec(spec, org, host) {
|
|
|
1508
1524
|
);
|
|
1509
1525
|
}
|
|
1510
1526
|
const last = url.replace(/\/+$/, "").split(/[/:]/).at(-1) ?? "";
|
|
1511
|
-
const
|
|
1527
|
+
const typed = last.endsWith(".git") ? last.slice(0, -4) : last;
|
|
1528
|
+
const name = typed.toLowerCase();
|
|
1512
1529
|
if (!NAME.test(name))
|
|
1513
|
-
throw new Error(`repository name "${
|
|
1530
|
+
throw new Error(`repository name "${typed}" may only contain ${NAME_RULE}`);
|
|
1514
1531
|
return { name, url };
|
|
1515
1532
|
}
|
|
1516
1533
|
|
|
1517
1534
|
// src/version.ts
|
|
1518
|
-
var VERSION = "0.22.
|
|
1535
|
+
var VERSION = "0.22.2";
|
|
1519
1536
|
|
|
1520
1537
|
// src/core/pm.ts
|
|
1521
1538
|
import { execFile as execFile2 } from "child_process";
|
|
@@ -3878,7 +3895,7 @@ function desiredOf(board, collections, org, fronts = /* @__PURE__ */ new Map(),
|
|
|
3878
3895
|
}
|
|
3879
3896
|
return {
|
|
3880
3897
|
path: row.path,
|
|
3881
|
-
title: `${row.id}
|
|
3898
|
+
title: `${row.id} - ${row.title}`,
|
|
3882
3899
|
body: headerOf(row.path, org),
|
|
3883
3900
|
status: status2,
|
|
3884
3901
|
statusField: c.field,
|
|
@@ -4297,7 +4314,7 @@ var GitHubBoards = class {
|
|
|
4297
4314
|
if (there.layout !== LAYOUTS[view.layout] || view.layout === "board" && there.columnField !== view.columns) {
|
|
4298
4315
|
await deleteView(there.id, this.#o);
|
|
4299
4316
|
added.push(
|
|
4300
|
-
`view ${view.name} remade${view.layout === "board" ?
|
|
4317
|
+
`view ${view.name} remade${view.layout === "board" ? `, columns ${view.columns}` : ""}`
|
|
4301
4318
|
);
|
|
4302
4319
|
await create(view);
|
|
4303
4320
|
gone2(view.name);
|
|
@@ -4840,15 +4857,71 @@ async function githubProvider(apiBase, wait) {
|
|
|
4840
4857
|
});
|
|
4841
4858
|
}
|
|
4842
4859
|
|
|
4860
|
+
// src/core/workspace.ts
|
|
4861
|
+
import { readdir as readdir3 } from "fs/promises";
|
|
4862
|
+
import { dirname as dirname3, join as join10, parse as parse2, resolve as resolve2 } from "path";
|
|
4863
|
+
async function findWorkspace(startDir) {
|
|
4864
|
+
const start = resolve2(startDir);
|
|
4865
|
+
const { root: fsRoot } = parse2(start);
|
|
4866
|
+
const ancestors = [];
|
|
4867
|
+
for (let dir = start; ; dir = dirname3(dir)) {
|
|
4868
|
+
ancestors.push(dir);
|
|
4869
|
+
if (dir === fsRoot) break;
|
|
4870
|
+
}
|
|
4871
|
+
for (const dir of ancestors) {
|
|
4872
|
+
if (await exists(join10(dir, ".rness", "rness.json")))
|
|
4873
|
+
return { root: dir, rnessDir: join10(dir, ".rness") };
|
|
4874
|
+
}
|
|
4875
|
+
for (const dir of ancestors) {
|
|
4876
|
+
if (await exists(join10(dir, "rness.json")))
|
|
4877
|
+
return { root: dirname3(dir), rnessDir: dir };
|
|
4878
|
+
}
|
|
4879
|
+
throw new Error(`no rness workspace found above ${startDir}`);
|
|
4880
|
+
}
|
|
4881
|
+
async function entryFor(root, name) {
|
|
4882
|
+
let entries;
|
|
4883
|
+
try {
|
|
4884
|
+
entries = await readdir3(join10(root, "org"));
|
|
4885
|
+
} catch {
|
|
4886
|
+
return null;
|
|
4887
|
+
}
|
|
4888
|
+
if (entries.includes(name)) return name;
|
|
4889
|
+
const variants = entries.filter((e) => e.toLowerCase() === name).sort();
|
|
4890
|
+
if (variants.length > 1)
|
|
4891
|
+
throw new Error(
|
|
4892
|
+
`${variants.map((v) => `org/${v}`).join(" and ")} both differ from org/${name} only by case: keep one, then run rness add again`
|
|
4893
|
+
);
|
|
4894
|
+
return variants[0] ?? null;
|
|
4895
|
+
}
|
|
4896
|
+
async function orgDirs(root) {
|
|
4897
|
+
let dirs;
|
|
4898
|
+
try {
|
|
4899
|
+
const entries = await readdir3(join10(root, "org"), { withFileTypes: true });
|
|
4900
|
+
dirs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
4901
|
+
} catch {
|
|
4902
|
+
return { clones: /* @__PURE__ */ new Set(), unread: [] };
|
|
4903
|
+
}
|
|
4904
|
+
return {
|
|
4905
|
+
clones: new Set(dirs.filter(isWorkspaceClone)),
|
|
4906
|
+
unread: dirs.filter(
|
|
4907
|
+
(d) => !isWorkspaceClone(d) && !EXCLUDED_NAMES.has(d.toLowerCase())
|
|
4908
|
+
).sort()
|
|
4909
|
+
};
|
|
4910
|
+
}
|
|
4911
|
+
async function clonesIn(root) {
|
|
4912
|
+
return (await orgDirs(root)).clones;
|
|
4913
|
+
}
|
|
4914
|
+
|
|
4843
4915
|
// src/core/repos.ts
|
|
4844
|
-
import { glob as glob2, readFile as readFile6, rm as rm3 } from "fs/promises";
|
|
4845
|
-
import { isAbsolute as isAbsolute2, join as
|
|
4916
|
+
import { glob as glob2, readFile as readFile6, rename as rename2, rm as rm3 } from "fs/promises";
|
|
4917
|
+
import { isAbsolute as isAbsolute2, join as join11, posix as posix5, relative as relative2, resolve as resolve3, sep as sep2 } from "path";
|
|
4846
4918
|
async function addRepository(input) {
|
|
4847
4919
|
const { name, url } = parseRepoSpec(input.spec, input.org, input.host);
|
|
4848
|
-
const
|
|
4920
|
+
const orgDir = join11(input.root, "org");
|
|
4921
|
+
const dir = join11(orgDir, name);
|
|
4849
4922
|
const repoPath = `org/${name}`;
|
|
4850
4923
|
const current = input.manifest.scopes[name];
|
|
4851
|
-
if (current !== void 0 && current.path !== repoPath)
|
|
4924
|
+
if (current !== void 0 && current.path.toLowerCase() !== repoPath)
|
|
4852
4925
|
throw new Error(`scope "${name}" already points at ${current.path}`);
|
|
4853
4926
|
const scopes = {
|
|
4854
4927
|
...input.manifest.scopes,
|
|
@@ -4862,50 +4935,69 @@ async function addRepository(input) {
|
|
|
4862
4935
|
throw new Error(
|
|
4863
4936
|
`sub-scope "${clean}" must be a relative path inside the repository`
|
|
4864
4937
|
);
|
|
4865
|
-
const base = segments.at(-1) ?? "";
|
|
4938
|
+
const base = (segments.at(-1) ?? "").toLowerCase();
|
|
4866
4939
|
const path = `org/${name}/${clean}`;
|
|
4867
4940
|
if (!NAME.test(base))
|
|
4868
4941
|
throw new Error(
|
|
4869
4942
|
`the last segment of sub-scope "${clean}" may only contain ${NAME_RULE}`
|
|
4870
4943
|
);
|
|
4871
4944
|
const existing = scopes[base];
|
|
4872
|
-
if (existing !== void 0 && existing.path !== path)
|
|
4945
|
+
if (existing !== void 0 && existing.path.toLowerCase() !== path.toLowerCase())
|
|
4873
4946
|
throw new Error(`scope "${base}" already points at ${existing.path}`);
|
|
4874
4947
|
scopes[base] = { path, extends: [name] };
|
|
4875
|
-
subs.push({
|
|
4948
|
+
subs.push({ clean, base });
|
|
4876
4949
|
}
|
|
4950
|
+
const entry = await entryFor(input.root, name);
|
|
4877
4951
|
let action;
|
|
4878
|
-
if (
|
|
4879
|
-
const
|
|
4952
|
+
if (entry !== null) {
|
|
4953
|
+
const found = join11(orgDir, entry);
|
|
4954
|
+
const origin = await originUrl(found);
|
|
4880
4955
|
if (origin === null)
|
|
4881
|
-
throw new Error(`org/${
|
|
4882
|
-
if (origin
|
|
4883
|
-
throw new Error(`org/${
|
|
4956
|
+
throw new Error(`org/${entry} exists and is not a git clone`);
|
|
4957
|
+
if (!sameRemote(origin, url))
|
|
4958
|
+
throw new Error(`org/${entry} is a clone of ${origin}, not ${url}`);
|
|
4884
4959
|
action = "adopted";
|
|
4885
4960
|
} else {
|
|
4886
4961
|
await clone(url, dir, input.credentialsFor?.(url) ?? null);
|
|
4887
4962
|
action = "cloned";
|
|
4888
4963
|
}
|
|
4964
|
+
const holder = join11(orgDir, entry ?? name);
|
|
4889
4965
|
const declared = [name];
|
|
4890
|
-
for (const {
|
|
4891
|
-
if (!await exists(
|
|
4966
|
+
for (const { clean, base } of subs) {
|
|
4967
|
+
if (!await exists(join11(holder, ...clean.split("/")))) {
|
|
4892
4968
|
if (action === "cloned") await rm3(dir, { recursive: true, force: true });
|
|
4893
|
-
throw new Error(
|
|
4969
|
+
throw new Error(`org/${entry ?? name}/${clean} does not exist`);
|
|
4894
4970
|
}
|
|
4895
4971
|
declared.push(base);
|
|
4896
4972
|
}
|
|
4973
|
+
const renamed = entry !== null && entry !== name ? entry : null;
|
|
4974
|
+
if (renamed !== null) await renameCase(orgDir, renamed, name);
|
|
4897
4975
|
const manifest = {
|
|
4898
4976
|
...input.manifest,
|
|
4899
4977
|
repos: { ...input.manifest.repos, [name]: { url } },
|
|
4900
4978
|
scopes
|
|
4901
4979
|
};
|
|
4902
4980
|
await writeManifest(input.rnessDir, manifest);
|
|
4903
|
-
return { manifest, name, url, action, declared };
|
|
4981
|
+
return { manifest, name, url, action, renamed, declared };
|
|
4982
|
+
}
|
|
4983
|
+
async function renameCase(orgDir, from, to) {
|
|
4984
|
+
const step2 = `${from}.rness-rename`;
|
|
4985
|
+
if (await exists(join11(orgDir, step2)))
|
|
4986
|
+
throw new Error(
|
|
4987
|
+
`org/${step2} exists, left by an interrupted rename: move it back to org/${from}, then run rness add again`
|
|
4988
|
+
);
|
|
4989
|
+
await rename2(join11(orgDir, from), join11(orgDir, step2));
|
|
4990
|
+
try {
|
|
4991
|
+
await rename2(join11(orgDir, step2), join11(orgDir, to));
|
|
4992
|
+
} catch (e) {
|
|
4993
|
+
await rename2(join11(orgDir, step2), join11(orgDir, from));
|
|
4994
|
+
throw e;
|
|
4995
|
+
}
|
|
4904
4996
|
}
|
|
4905
4997
|
function cloneHolding(root, repos, dir) {
|
|
4906
4998
|
for (const [name, repo] of Object.entries(repos)) {
|
|
4907
|
-
const clone2 =
|
|
4908
|
-
const r = relative2(clone2,
|
|
4999
|
+
const clone2 = resolve3(root, "org", name);
|
|
5000
|
+
const r = relative2(clone2, resolve3(dir));
|
|
4909
5001
|
if (r === "" || !r.startsWith("..") && !isAbsolute2(r))
|
|
4910
5002
|
return { name, dir: clone2, url: repo.url };
|
|
4911
5003
|
}
|
|
@@ -4915,7 +5007,7 @@ async function workspaceDirs(repoDir) {
|
|
|
4915
5007
|
let patterns = [];
|
|
4916
5008
|
try {
|
|
4917
5009
|
const pkg = JSON.parse(
|
|
4918
|
-
await readFile6(
|
|
5010
|
+
await readFile6(join11(repoDir, "package.json"), "utf8")
|
|
4919
5011
|
);
|
|
4920
5012
|
const w = pkg.workspaces;
|
|
4921
5013
|
if (Array.isArray(w))
|
|
@@ -4932,7 +5024,7 @@ async function workspaceDirs(repoDir) {
|
|
|
4932
5024
|
for (const pattern of patterns) {
|
|
4933
5025
|
for await (const match of glob2(pattern, { cwd: repoDir })) {
|
|
4934
5026
|
const rel = match.split(sep2).join(posix5.sep);
|
|
4935
|
-
if (await exists(
|
|
5027
|
+
if (await exists(join11(repoDir, ...rel.split(posix5.sep), "package.json")))
|
|
4936
5028
|
dirs.add(rel);
|
|
4937
5029
|
}
|
|
4938
5030
|
}
|
|
@@ -4946,38 +5038,6 @@ var defaultTerminal = {
|
|
|
4946
5038
|
prompts: () => import("@clack/prompts")
|
|
4947
5039
|
};
|
|
4948
5040
|
|
|
4949
|
-
// src/core/workspace.ts
|
|
4950
|
-
import { readdir as readdir3 } from "fs/promises";
|
|
4951
|
-
import { dirname as dirname3, join as join11, parse as parse2, resolve as resolve3 } from "path";
|
|
4952
|
-
async function findWorkspace(startDir) {
|
|
4953
|
-
const start = resolve3(startDir);
|
|
4954
|
-
const { root: fsRoot } = parse2(start);
|
|
4955
|
-
const ancestors = [];
|
|
4956
|
-
for (let dir = start; ; dir = dirname3(dir)) {
|
|
4957
|
-
ancestors.push(dir);
|
|
4958
|
-
if (dir === fsRoot) break;
|
|
4959
|
-
}
|
|
4960
|
-
for (const dir of ancestors) {
|
|
4961
|
-
if (await exists(join11(dir, ".rness", "rness.json")))
|
|
4962
|
-
return { root: dir, rnessDir: join11(dir, ".rness") };
|
|
4963
|
-
}
|
|
4964
|
-
for (const dir of ancestors) {
|
|
4965
|
-
if (await exists(join11(dir, "rness.json")))
|
|
4966
|
-
return { root: dirname3(dir), rnessDir: dir };
|
|
4967
|
-
}
|
|
4968
|
-
throw new Error(`no rness workspace found above ${startDir}`);
|
|
4969
|
-
}
|
|
4970
|
-
async function clonesIn(root) {
|
|
4971
|
-
try {
|
|
4972
|
-
const entries = await readdir3(join11(root, "org"), { withFileTypes: true });
|
|
4973
|
-
return new Set(
|
|
4974
|
-
entries.filter((e) => e.isDirectory() && isWorkspaceClone(e.name)).map((e) => e.name)
|
|
4975
|
-
);
|
|
4976
|
-
} catch {
|
|
4977
|
-
return /* @__PURE__ */ new Set();
|
|
4978
|
-
}
|
|
4979
|
-
}
|
|
4980
|
-
|
|
4981
5041
|
// src/core/style.ts
|
|
4982
5042
|
import { styleText } from "util";
|
|
4983
5043
|
var FORMAT = {
|
|
@@ -5143,7 +5203,7 @@ var PROVIDERS = {
|
|
|
5143
5203
|
gitlab: { name: "gitlab", label: "GitLab", available: false },
|
|
5144
5204
|
atlassian: {
|
|
5145
5205
|
name: "atlassian",
|
|
5146
|
-
label: "Atlassian
|
|
5206
|
+
label: "Atlassian (Bitbucket + Jira)",
|
|
5147
5207
|
available: false
|
|
5148
5208
|
}
|
|
5149
5209
|
};
|
|
@@ -5364,7 +5424,7 @@ function sessionUi(p) {
|
|
|
5364
5424
|
spin.stop(line === null ? label : label_(line));
|
|
5365
5425
|
return result;
|
|
5366
5426
|
} catch (e) {
|
|
5367
|
-
spin.error(`${label}
|
|
5427
|
+
spin.error(`${label}: failed`);
|
|
5368
5428
|
throw e;
|
|
5369
5429
|
}
|
|
5370
5430
|
}
|
|
@@ -5498,7 +5558,7 @@ async function loginCommand(opts, deps = {}) {
|
|
|
5498
5558
|
}
|
|
5499
5559
|
|
|
5500
5560
|
// src/board/journal-state.ts
|
|
5501
|
-
import { mkdir as mkdir2, readFile as readFile7, rename as
|
|
5561
|
+
import { mkdir as mkdir2, readFile as readFile7, rename as rename3, rm as rm4, writeFile as writeFile2 } from "fs/promises";
|
|
5502
5562
|
import { dirname as dirname4, join as join12 } from "path";
|
|
5503
5563
|
var notedOf = (value) => {
|
|
5504
5564
|
const v = value;
|
|
@@ -5518,7 +5578,7 @@ async function writeJson(file, value) {
|
|
|
5518
5578
|
const temporary = `${file}.${process.pid}`;
|
|
5519
5579
|
await writeFile2(temporary, `${JSON.stringify(value, null, 2)}
|
|
5520
5580
|
`);
|
|
5521
|
-
await
|
|
5581
|
+
await rename3(temporary, file);
|
|
5522
5582
|
}
|
|
5523
5583
|
async function notesPosted(rnessDir, session, plan) {
|
|
5524
5584
|
const file = await gitPath(rnessDir, COUNTS);
|
|
@@ -5686,7 +5746,7 @@ async function oneSyncAtATime(key, work, options = {}) {
|
|
|
5686
5746
|
}
|
|
5687
5747
|
|
|
5688
5748
|
// src/board/noted.ts
|
|
5689
|
-
import { mkdir as mkdir4, readFile as readFile9, rename as
|
|
5749
|
+
import { mkdir as mkdir4, readFile as readFile9, rename as rename4, rm as rm6, writeFile as writeFile4 } from "fs/promises";
|
|
5690
5750
|
import { dirname as dirname5 } from "path";
|
|
5691
5751
|
var NAME2 = "rness/noted";
|
|
5692
5752
|
function notedFile(rnessDir) {
|
|
@@ -5717,7 +5777,7 @@ async function writeNoted(file, noted) {
|
|
|
5717
5777
|
`${JSON.stringify([...noted].sort(), null, 2)}
|
|
5718
5778
|
`
|
|
5719
5779
|
);
|
|
5720
|
-
await
|
|
5780
|
+
await rename4(temporary, file);
|
|
5721
5781
|
} catch {
|
|
5722
5782
|
}
|
|
5723
5783
|
}
|
|
@@ -5740,7 +5800,7 @@ async function onceSaid(rnessDir, board, lines) {
|
|
|
5740
5800
|
}
|
|
5741
5801
|
|
|
5742
5802
|
// src/board/opened.ts
|
|
5743
|
-
import { mkdir as mkdir5, readFile as readFile10, rename as
|
|
5803
|
+
import { mkdir as mkdir5, readFile as readFile10, rename as rename5, rm as rm7, writeFile as writeFile5 } from "fs/promises";
|
|
5744
5804
|
import { dirname as dirname6 } from "path";
|
|
5745
5805
|
var NAME3 = "rness/opened";
|
|
5746
5806
|
function openedFile(rnessDir) {
|
|
@@ -5778,7 +5838,7 @@ async function writeOpened(file, opened) {
|
|
|
5778
5838
|
`${JSON.stringify(Object.fromEntries(entries), null, 2)}
|
|
5779
5839
|
`
|
|
5780
5840
|
);
|
|
5781
|
-
await
|
|
5841
|
+
await rename5(temporary, file);
|
|
5782
5842
|
} catch {
|
|
5783
5843
|
}
|
|
5784
5844
|
}
|
|
@@ -6201,7 +6261,7 @@ async function context(opts, wait) {
|
|
|
6201
6261
|
};
|
|
6202
6262
|
}
|
|
6203
6263
|
var waitSaid = (opts, ui) => rateWait(async (ms) => {
|
|
6204
|
-
ui.line("waiting", `${Math.round(ms / 1e3)} s
|
|
6264
|
+
ui.line("waiting", `${Math.round(ms / 1e3)} s: GitHub's rate limit`);
|
|
6205
6265
|
await (opts.sleep ?? ((n) => delay3(n)))(ms);
|
|
6206
6266
|
});
|
|
6207
6267
|
async function missingAccess(provider) {
|
|
@@ -6232,7 +6292,7 @@ async function declarations(c, ui) {
|
|
|
6232
6292
|
if (still.length > 0) {
|
|
6233
6293
|
ui?.line(
|
|
6234
6294
|
"skipped",
|
|
6235
|
-
`${name}: ${still.join(", ")}, which rness.json declares now
|
|
6295
|
+
`${name}: ${still.join(", ")}, which rness.json declares now: rness sync moves it`
|
|
6236
6296
|
);
|
|
6237
6297
|
continue;
|
|
6238
6298
|
}
|
|
@@ -6247,7 +6307,7 @@ async function declarations(c, ui) {
|
|
|
6247
6307
|
}
|
|
6248
6308
|
function noBoard(c) {
|
|
6249
6309
|
return new Error(
|
|
6250
|
-
c.manifest.refused === void 0 ? 'no board declared
|
|
6310
|
+
c.manifest.refused === void 0 ? 'no board declared: declare one in .rness/rness.json, as "boards": { "pulse": "agent-pulse" }, then rness board push' : `no board rness.json declares is valid: ${c.manifest.refused.map((r) => r.reason).join("; ")}`
|
|
6251
6311
|
);
|
|
6252
6312
|
}
|
|
6253
6313
|
async function declaredBoards(c, ui) {
|
|
@@ -6495,7 +6555,7 @@ async function syncBoard(c, board, ui, sayLayout, scope) {
|
|
|
6495
6555
|
if (!(e instanceof RateLimitError)) throw e;
|
|
6496
6556
|
const total = changes + writes.length;
|
|
6497
6557
|
throw new Error(
|
|
6498
|
-
`${e.message}: ${total - made} of ${total} changes not made
|
|
6558
|
+
`${e.message}: ${total - made} of ${total} changes not made: the next rness board push makes them`,
|
|
6499
6559
|
{ cause: e }
|
|
6500
6560
|
);
|
|
6501
6561
|
}
|
|
@@ -6601,7 +6661,7 @@ async function createBoards(c, boards, opts, terminal, ui, wait) {
|
|
|
6601
6661
|
}
|
|
6602
6662
|
c = { ...c, manifest };
|
|
6603
6663
|
made.push(b.name);
|
|
6604
|
-
ui.line("created", `${title}
|
|
6664
|
+
ui.line("created", `${title} - ${board.url}`);
|
|
6605
6665
|
}
|
|
6606
6666
|
return { c, made, left: [] };
|
|
6607
6667
|
}
|
|
@@ -6636,12 +6696,12 @@ async function boardPushCommand(opts, deps = {}) {
|
|
|
6636
6696
|
if (made.length > 0)
|
|
6637
6697
|
ui.line(
|
|
6638
6698
|
"declared",
|
|
6639
|
-
`${made.join(", ")} in .rness/rness.json
|
|
6699
|
+
`${made.join(", ")} in .rness/rness.json - commit it: git -C .rness commit -am "chore: board ${made.join(", ")}"`
|
|
6640
6700
|
);
|
|
6641
6701
|
}
|
|
6642
6702
|
if (left.length > 0)
|
|
6643
6703
|
throw new Error(
|
|
6644
|
-
`not created: ${left.join(", ")}
|
|
6704
|
+
`not created: ${left.join(", ")} - rness board push in a terminal, or with --yes, creates ${left.length === 1 ? "it" : "them"}`
|
|
6645
6705
|
);
|
|
6646
6706
|
return 0;
|
|
6647
6707
|
} catch (e) {
|
|
@@ -6740,7 +6800,7 @@ async function run(opts, failures) {
|
|
|
6740
6800
|
if (event === "session-end") {
|
|
6741
6801
|
for (const d of acting("journal-summary"))
|
|
6742
6802
|
try {
|
|
6743
|
-
const { postSummary } = await import("./summary-
|
|
6803
|
+
const { postSummary } = await import("./summary-K5ETHXOX.js");
|
|
6744
6804
|
await postSummary({
|
|
6745
6805
|
c,
|
|
6746
6806
|
board: d,
|
|
@@ -6830,10 +6890,6 @@ async function pulseCreateCommand(collection, opts, deps = {}) {
|
|
|
6830
6890
|
}
|
|
6831
6891
|
|
|
6832
6892
|
export {
|
|
6833
|
-
exists,
|
|
6834
|
-
isSymlink,
|
|
6835
|
-
readOrNull,
|
|
6836
|
-
writeFileAtomic,
|
|
6837
6893
|
containedPath,
|
|
6838
6894
|
parseFrontMatter,
|
|
6839
6895
|
extractTitle,
|
|
@@ -6853,6 +6909,10 @@ export {
|
|
|
6853
6909
|
contractOf,
|
|
6854
6910
|
PULSE,
|
|
6855
6911
|
parseBoard,
|
|
6912
|
+
exists,
|
|
6913
|
+
isSymlink,
|
|
6914
|
+
readOrNull,
|
|
6915
|
+
writeFileAtomic,
|
|
6856
6916
|
clone,
|
|
6857
6917
|
isClean,
|
|
6858
6918
|
changedPaths,
|
|
@@ -6912,6 +6972,10 @@ export {
|
|
|
6912
6972
|
unsupportedProviderMessage,
|
|
6913
6973
|
openProvider,
|
|
6914
6974
|
openGitProvider,
|
|
6975
|
+
findWorkspace,
|
|
6976
|
+
entryFor,
|
|
6977
|
+
orgDirs,
|
|
6978
|
+
clonesIn,
|
|
6915
6979
|
addRepository,
|
|
6916
6980
|
cloneHolding,
|
|
6917
6981
|
workspaceDirs,
|
|
@@ -6928,8 +6992,6 @@ export {
|
|
|
6928
6992
|
banner,
|
|
6929
6993
|
plainUi,
|
|
6930
6994
|
makeUi,
|
|
6931
|
-
findWorkspace,
|
|
6932
|
-
clonesIn,
|
|
6933
6995
|
reportError,
|
|
6934
6996
|
declaredBoard,
|
|
6935
6997
|
readBoards,
|
|
@@ -6957,4 +7019,4 @@ export {
|
|
|
6957
7019
|
boardRunCommand,
|
|
6958
7020
|
pulseCreateCommand
|
|
6959
7021
|
};
|
|
6960
|
-
//# sourceMappingURL=chunk-
|
|
7022
|
+
//# sourceMappingURL=chunk-DFGZWBBW.js.map
|