yarramate 0.3.0 → 0.3.1
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.
|
@@ -4,7 +4,7 @@ import { resolve } from 'node:path';
|
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
5
|
import { createHash, randomUUID } from 'node:crypto';
|
|
6
6
|
import Ajv2020Module from 'ajv/dist/2020.js';
|
|
7
|
-
import { isSeq, parseDocument } from 'yaml';
|
|
7
|
+
import { isMap, isSeq, parseDocument } from 'yaml';
|
|
8
8
|
import { isMainModule, resolveCliWorkspaceSources, } from '../cli-support.js';
|
|
9
9
|
import { compileWorkspace } from '../compiler.js';
|
|
10
10
|
import { adapterMappingLocation, loadAdapterMapping, validateAdapterMapping, } from '../adapter-mapping.js';
|
|
@@ -73,7 +73,7 @@ const publishFiles = (files) => {
|
|
|
73
73
|
}
|
|
74
74
|
};
|
|
75
75
|
const usage = 'Usage:\n' +
|
|
76
|
-
' yarramate-likec4 map --sync <mapping.yaml> <workspace-or-source...>\n' +
|
|
76
|
+
' yarramate-likec4 map --sync [--prune] <mapping.yaml> <workspace-or-source...>\n' +
|
|
77
77
|
' yarramate-likec4 check <projection.yaml> <mapping.yaml> [--json] [--kinds <kind-mapping.yaml>] [--compare <from-state> <to-state>] <workspace-or-source...>\n' +
|
|
78
78
|
' yarramate-likec4 check <likec4-project.yaml> [--json] <workspace-or-source...>\n' +
|
|
79
79
|
' yarramate-likec4 export <projection.yaml> <mapping.yaml> [--kinds <kind-mapping.yaml>] [--compare <from-state> <to-state>] <workspace-or-source...>\n' +
|
|
@@ -91,7 +91,10 @@ const checkJson = (ok, diagnostics) => `${JSON.stringify({
|
|
|
91
91
|
const sameJson = (left, right) => JSON.stringify(left) === JSON.stringify(right);
|
|
92
92
|
const lowerCamel = (value) => value.replaceAll(/-([a-z0-9])/g, (_, character) => character.toUpperCase());
|
|
93
93
|
const runLikeC4MapSync = (args, cwd) => {
|
|
94
|
-
const
|
|
94
|
+
const sync = args[0];
|
|
95
|
+
const prune = args[1] === '--prune';
|
|
96
|
+
const mappingPath = args[prune ? 2 : 1];
|
|
97
|
+
const sourcePaths = args.slice(prune ? 3 : 2);
|
|
95
98
|
if (sync !== '--sync' ||
|
|
96
99
|
mappingPath === undefined ||
|
|
97
100
|
mappingPath.startsWith('-') ||
|
|
@@ -145,16 +148,23 @@ const runLikeC4MapSync = (args, cwd) => {
|
|
|
145
148
|
stderr: '',
|
|
146
149
|
};
|
|
147
150
|
}
|
|
151
|
+
const graphSubjects = new Set(compilation.graph.subjects.map(({ id }) => id));
|
|
152
|
+
const staleCount = loaded.mapping.mappings.filter(({ native }) => !graphSubjects.has(native)).length;
|
|
148
153
|
const validation = validateAdapterMapping(compilation.graph, loaded.mapping);
|
|
149
|
-
|
|
154
|
+
const blockingDiagnostics = validation.ok
|
|
155
|
+
? []
|
|
156
|
+
: validation.diagnostics.filter(({ code }) => code !== 'YM601');
|
|
157
|
+
if (blockingDiagnostics.length > 0) {
|
|
150
158
|
return {
|
|
151
159
|
exitCode: 1,
|
|
152
|
-
stdout: diagnosticJson(
|
|
160
|
+
stdout: diagnosticJson(blockingDiagnostics),
|
|
153
161
|
stderr: '',
|
|
154
162
|
};
|
|
155
163
|
}
|
|
156
164
|
const mapped = new Set(loaded.mapping.mappings.map(({ native }) => native));
|
|
157
|
-
const claimedExternal = new Set(loaded.mapping.mappings
|
|
165
|
+
const claimedExternal = new Set(loaded.mapping.mappings
|
|
166
|
+
.filter(({ native }) => !prune || graphSubjects.has(native))
|
|
167
|
+
.map(({ external }) => external));
|
|
158
168
|
const architectureStates = new Set(compilation.graph.claims
|
|
159
169
|
.filter(({ predicate }) => predicate === 'yarramate/state/type')
|
|
160
170
|
.map(({ subject }) => subject));
|
|
@@ -180,18 +190,29 @@ const runLikeC4MapSync = (args, cwd) => {
|
|
|
180
190
|
type: subject.type,
|
|
181
191
|
};
|
|
182
192
|
});
|
|
183
|
-
if (additions.length === 0) {
|
|
193
|
+
if (additions.length === 0 && (!prune || staleCount === 0)) {
|
|
184
194
|
return {
|
|
185
195
|
exitCode: 0,
|
|
186
|
-
stdout:
|
|
196
|
+
stdout: staleCount === 0
|
|
197
|
+
? `LikeC4 mapping ${mappingPath} is already synchronized\n`
|
|
198
|
+
: `LikeC4 mapping ${mappingPath} has ${staleCount} stale ${staleCount === 1 ? 'mapping' : 'mappings'} (use --prune)\n`,
|
|
187
199
|
stderr: '',
|
|
188
200
|
};
|
|
189
201
|
}
|
|
190
202
|
const document = parseDocument(original);
|
|
203
|
+
const mappings = document.getIn(['mappings'], true);
|
|
204
|
+
if (prune && isSeq(mappings)) {
|
|
205
|
+
const firstMappingWasPruned = mappings.items.length > 0 &&
|
|
206
|
+
isMap(mappings.items[0]) &&
|
|
207
|
+
!graphSubjects.has(String(mappings.items[0].get('native')));
|
|
208
|
+
mappings.items = mappings.items.filter((item) => !isMap(item) ||
|
|
209
|
+
graphSubjects.has(String(item.get('native'))));
|
|
210
|
+
if (firstMappingWasPruned)
|
|
211
|
+
mappings.commentBefore = undefined;
|
|
212
|
+
}
|
|
191
213
|
for (const addition of additions) {
|
|
192
214
|
document.addIn(['mappings'], addition);
|
|
193
215
|
}
|
|
194
|
-
const mappings = document.getIn(['mappings'], true);
|
|
195
216
|
if (isSeq(mappings))
|
|
196
217
|
mappings.flow = false;
|
|
197
218
|
const candidate = document.toString({ lineWidth: 0 });
|
|
@@ -207,10 +228,13 @@ const runLikeC4MapSync = (args, cwd) => {
|
|
|
207
228
|
};
|
|
208
229
|
}
|
|
209
230
|
const candidateValidation = validateAdapterMapping(compilation.graph, candidateMapping.mapping);
|
|
210
|
-
|
|
231
|
+
const candidateBlockingDiagnostics = candidateValidation.ok
|
|
232
|
+
? []
|
|
233
|
+
: candidateValidation.diagnostics.filter(({ code }) => prune || code !== 'YM601');
|
|
234
|
+
if (candidateBlockingDiagnostics.length > 0) {
|
|
211
235
|
return {
|
|
212
236
|
exitCode: 1,
|
|
213
|
-
stdout: diagnosticJson(
|
|
237
|
+
stdout: diagnosticJson(candidateBlockingDiagnostics),
|
|
214
238
|
stderr: '',
|
|
215
239
|
};
|
|
216
240
|
}
|
|
@@ -223,7 +247,14 @@ const runLikeC4MapSync = (args, cwd) => {
|
|
|
223
247
|
}
|
|
224
248
|
return {
|
|
225
249
|
exitCode: 0,
|
|
226
|
-
stdout:
|
|
250
|
+
stdout: prune
|
|
251
|
+
? additions.length > 0
|
|
252
|
+
? `Added ${additions.length} and pruned ${staleCount} stale LikeC4 ${staleCount === 1 ? 'mapping' : 'mappings'} in ${mappingPath}\n`
|
|
253
|
+
: `Pruned ${staleCount} stale LikeC4 ${staleCount === 1 ? 'mapping' : 'mappings'} from ${mappingPath}\n`
|
|
254
|
+
: `Added ${additions.length} LikeC4 ${additions.length === 1 ? 'mapping' : 'mappings'} to ${mappingPath}` +
|
|
255
|
+
(staleCount === 0
|
|
256
|
+
? '\n'
|
|
257
|
+
: `; left ${staleCount} stale ${staleCount === 1 ? 'mapping' : 'mappings'} (use --prune)\n`),
|
|
227
258
|
stderr: '',
|
|
228
259
|
};
|
|
229
260
|
}
|
package/package.json
CHANGED
|
@@ -195,5 +195,15 @@ yarramate-likec4 map --sync \
|
|
|
195
195
|
.yarramate/workspace.yaml
|
|
196
196
|
```
|
|
197
197
|
|
|
198
|
+
Sync preserves and reports mappings for native subjects that no longer exist.
|
|
199
|
+
After confirming that those subjects were intentionally removed or renamed,
|
|
200
|
+
delete the stale entries while adding missing mappings with:
|
|
201
|
+
|
|
202
|
+
```sh
|
|
203
|
+
yarramate-likec4 map --sync --prune \
|
|
204
|
+
.yarramate/integrations/likec4/subject-mapping.yaml \
|
|
205
|
+
.yarramate/workspace.yaml
|
|
206
|
+
```
|
|
207
|
+
|
|
198
208
|
Treat exit `0` as successful execution, `1` as correctness diagnostics, and
|
|
199
209
|
`2` as invocation or file failure.
|