dotmd-cli 0.14.5 → 0.14.7
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/src/rename.mjs +13 -59
- package/src/render.mjs +6 -2
package/package.json
CHANGED
package/src/rename.mjs
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { extractFrontmatter, parseSimpleFrontmatter, replaceFrontmatter } from './frontmatter.mjs';
|
|
4
3
|
import { toRepoPath, resolveDocPath, die, warn } from './util.mjs';
|
|
5
4
|
import { collectDocFiles } from './index.mjs';
|
|
6
5
|
import { gitMv } from './git.mjs';
|
|
7
|
-
import { green, dim
|
|
6
|
+
import { green, dim } from './color.mjs';
|
|
8
7
|
import { isInteractive, promptText } from './prompt.mjs';
|
|
9
8
|
|
|
10
9
|
export async function runRename(argv, config, opts = {}) {
|
|
@@ -60,53 +59,25 @@ export async function runRename(argv, config, opts = {}) {
|
|
|
60
59
|
|
|
61
60
|
// Scan for references in other docs
|
|
62
61
|
const allFiles = collectDocFiles(config);
|
|
63
|
-
const
|
|
64
|
-
...(config.referenceFields.bidirectional || []),
|
|
65
|
-
...(config.referenceFields.unidirectional || []),
|
|
66
|
-
];
|
|
67
|
-
const refUpdates = [];
|
|
68
|
-
const bodyWarnings = [];
|
|
62
|
+
const filesToUpdate = [];
|
|
69
63
|
|
|
70
64
|
for (const filePath of allFiles) {
|
|
71
65
|
if (filePath === oldPath) continue;
|
|
72
66
|
const raw = readFileSync(filePath, 'utf8');
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
// Check frontmatter reference fields for old basename
|
|
77
|
-
let hasRef = false;
|
|
78
|
-
for (const line of frontmatter.split('\n')) {
|
|
79
|
-
if (line.includes(oldBasename)) {
|
|
80
|
-
hasRef = true;
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (hasRef) {
|
|
86
|
-
refUpdates.push(filePath);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Check body for markdown links containing old basename
|
|
90
|
-
if (body && body.includes(oldBasename)) {
|
|
91
|
-
bodyWarnings.push(toRepoPath(filePath, config.repoRoot));
|
|
67
|
+
if (raw.includes(oldBasename)) {
|
|
68
|
+
filesToUpdate.push(filePath);
|
|
92
69
|
}
|
|
93
70
|
}
|
|
94
71
|
|
|
95
72
|
if (dryRun) {
|
|
96
73
|
const prefix = dim('[dry-run]');
|
|
97
74
|
process.stdout.write(`${prefix} Would rename: ${oldRepoPath} → ${newRepoPath}\n`);
|
|
98
|
-
if (
|
|
99
|
-
process.stdout.write(`${prefix} Would update references in ${
|
|
100
|
-
for (const f of
|
|
75
|
+
if (filesToUpdate.length > 0) {
|
|
76
|
+
process.stdout.write(`${prefix} Would update references in ${filesToUpdate.length} file(s):\n`);
|
|
77
|
+
for (const f of filesToUpdate) {
|
|
101
78
|
process.stdout.write(`${prefix} ${toRepoPath(f, config.repoRoot)}\n`);
|
|
102
79
|
}
|
|
103
80
|
}
|
|
104
|
-
if (bodyWarnings.length > 0) {
|
|
105
|
-
process.stdout.write(`\n${yellow('Body links referencing old name')} (manual update needed):\n`);
|
|
106
|
-
for (const p of bodyWarnings) {
|
|
107
|
-
process.stdout.write(` ${p}\n`);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
81
|
return;
|
|
111
82
|
}
|
|
112
83
|
|
|
@@ -116,23 +87,13 @@ export async function runRename(argv, config, opts = {}) {
|
|
|
116
87
|
die(result.stderr || 'git mv failed.');
|
|
117
88
|
}
|
|
118
89
|
|
|
119
|
-
// Update references
|
|
90
|
+
// Update all references (frontmatter + body) in other docs
|
|
120
91
|
let updatedCount = 0;
|
|
121
|
-
for (const filePath of
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
if (
|
|
125
|
-
|
|
126
|
-
const newFm = fm.split('\n').map(line => {
|
|
127
|
-
if (line.includes(oldBasename)) {
|
|
128
|
-
return line.split(oldBasename).join(newBasename);
|
|
129
|
-
}
|
|
130
|
-
return line;
|
|
131
|
-
}).join('\n');
|
|
132
|
-
|
|
133
|
-
if (newFm !== fm) {
|
|
134
|
-
raw = replaceFrontmatter(raw, newFm);
|
|
135
|
-
writeFileSync(filePath, raw, 'utf8');
|
|
92
|
+
for (const filePath of filesToUpdate) {
|
|
93
|
+
const raw = readFileSync(filePath, 'utf8');
|
|
94
|
+
const updated = raw.split(oldBasename).join(newBasename);
|
|
95
|
+
if (updated !== raw) {
|
|
96
|
+
writeFileSync(filePath, updated, 'utf8');
|
|
136
97
|
updatedCount++;
|
|
137
98
|
}
|
|
138
99
|
}
|
|
@@ -142,12 +103,5 @@ export async function runRename(argv, config, opts = {}) {
|
|
|
142
103
|
process.stdout.write(`Updated references in ${updatedCount} file(s).\n`);
|
|
143
104
|
}
|
|
144
105
|
|
|
145
|
-
if (bodyWarnings.length > 0) {
|
|
146
|
-
process.stdout.write(`\n${yellow('Body links referencing old name')} (manual update needed):\n`);
|
|
147
|
-
for (const p of bodyWarnings) {
|
|
148
|
-
process.stdout.write(` ${p}\n`);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
106
|
try { config.hooks.onRename?.({ oldPath: oldRepoPath, newPath: newRepoPath, referencesUpdated: updatedCount }); } catch (err) { warn(`Hook 'onRename' threw: ${err.message}`); }
|
|
153
107
|
}
|
package/src/render.mjs
CHANGED
|
@@ -17,8 +17,10 @@ export function renderCompactList(index, config) {
|
|
|
17
17
|
function _renderCompactList(index, config) {
|
|
18
18
|
const lines = ['Index', ''];
|
|
19
19
|
const maxWidth = config.display.lineWidth || process.stdout.columns || 120;
|
|
20
|
+
const hidden = config.lifecycle.archiveStatuses;
|
|
20
21
|
|
|
21
22
|
for (const status of config.statusOrder) {
|
|
23
|
+
if (hidden.has(status)) continue;
|
|
22
24
|
const docs = index.docs.filter(d => d.status === status);
|
|
23
25
|
if (!docs.length) continue;
|
|
24
26
|
|
|
@@ -43,7 +45,7 @@ function _renderCompactList(index, config) {
|
|
|
43
45
|
|
|
44
46
|
// Render docs with statuses not in statusOrder
|
|
45
47
|
const knownStatuses = new Set(config.statusOrder);
|
|
46
|
-
const otherStatuses = [...new Set(index.docs.filter(d => d.status && !knownStatuses.has(d.status)).map(d => d.status))].sort();
|
|
48
|
+
const otherStatuses = [...new Set(index.docs.filter(d => d.status && !knownStatuses.has(d.status) && !hidden.has(d.status)).map(d => d.status))].sort();
|
|
47
49
|
for (const status of otherStatuses) {
|
|
48
50
|
const docs = index.docs.filter(d => d.status === status);
|
|
49
51
|
if (!docs.length) continue;
|
|
@@ -72,8 +74,10 @@ function _renderCompactList(index, config) {
|
|
|
72
74
|
|
|
73
75
|
export function renderVerboseList(index, config) {
|
|
74
76
|
const lines = ['Index', ''];
|
|
77
|
+
const hidden = config.lifecycle.archiveStatuses;
|
|
75
78
|
|
|
76
79
|
for (const status of config.statusOrder) {
|
|
80
|
+
if (hidden.has(status)) continue;
|
|
77
81
|
const docs = index.docs.filter(doc => doc.status === status);
|
|
78
82
|
if (docs.length === 0) continue;
|
|
79
83
|
|
|
@@ -90,7 +94,7 @@ export function renderVerboseList(index, config) {
|
|
|
90
94
|
|
|
91
95
|
// Render docs with statuses not in statusOrder
|
|
92
96
|
const knownStatuses = new Set(config.statusOrder);
|
|
93
|
-
const otherStatuses = [...new Set(index.docs.filter(d => d.status && !knownStatuses.has(d.status)).map(d => d.status))].sort();
|
|
97
|
+
const otherStatuses = [...new Set(index.docs.filter(d => d.status && !knownStatuses.has(d.status) && !hidden.has(d.status)).map(d => d.status))].sort();
|
|
94
98
|
for (const status of otherStatuses) {
|
|
95
99
|
const docs = index.docs.filter(doc => doc.status === status);
|
|
96
100
|
if (docs.length === 0) continue;
|