spec-up-t 1.2.3 → 1.2.5
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/.sonarlint/connectedMode.json +5 -0
- package/assets/compiled/body.js +35 -32
- package/assets/compiled/head.css +7 -5
- package/assets/compiled/head.js +3 -3
- package/assets/css/add-bootstrap-classes-to-images.css +34 -0
- package/assets/css/adjust-font-size.css +6 -11
- package/assets/css/backToTop.css +0 -1
- package/assets/css/image-full-size.css +44 -0
- package/assets/css/index.css +1 -2
- package/assets/css/pdf-styles.css +23 -27
- package/assets/css/repo-issues.css +0 -6
- package/assets/css/search.css +0 -1
- package/assets/css/sidebar-toc.css +13 -12
- package/assets/css/terms-and-definitions.css +43 -37
- package/assets/js/add-bootstrap-classes-to-images.js +98 -0
- package/assets/js/add-href-to-snapshot-link.js +2 -1
- package/assets/js/addAnchorsToTerms.js +0 -1
- package/assets/js/adjust-font-size.js +0 -9
- package/assets/js/create-alphabet-index.js +12 -3
- package/assets/js/create-term-filter.js +12 -0
- package/assets/js/custom-elements.js +13 -18
- package/assets/js/declare-markdown-it.js +1 -1
- package/assets/js/hide-show-utility-container.js +17 -0
- package/assets/js/highlightMenuItems.js +3 -3
- package/assets/js/image-full-size.js +76 -0
- package/assets/js/index.js +1 -5
- package/assets/js/insert-trefs.js +2 -2
- package/assets/js/modal.js +3 -3
- package/assets/js/search.js +15 -3
- package/assets/js/utils.js +2 -3
- package/index.js +7 -17
- package/package.json +2 -2
- package/src/README.md +3 -3
- package/src/add-remove-xref-source.js +0 -2
- package/src/asset-map.json +5 -0
- package/src/collect-external-references.js +187 -179
- package/src/collectExternalReferences/fetchTermsFromIndex.js +2 -1
- package/src/config/paths.js +2 -2
- package/src/create-external-specs-list.js +1 -1
- package/src/create-term-index.js +126 -22
- package/src/fix-markdown-files.js +152 -90
- package/src/health-check/external-specs-checker.js +173 -94
- package/src/health-check/output-gitignore-checker.js +327 -191
- package/src/health-check/specs-configuration-checker.js +288 -210
- package/src/health-check/term-references-checker.js +200 -123
- package/src/health-check/tref-term-checker.js +264 -179
- package/src/health-check.js +52 -36
- package/src/init.js +1 -4
- package/src/insert-term-index.js +5 -5
- package/src/install-from-boilerplate/add-scripts-keys.js +3 -1
- package/src/install-from-boilerplate/boilerplate/gitignore +2 -1
- package/src/install-from-boilerplate/config-system-files.js +9 -1
- package/src/install-from-boilerplate/copy-system-files.js +1 -1
- package/src/markdown-it-extensions.js +199 -106
- package/src/references.js +1 -2
- package/src/utils/doesUrlExist.js +7 -5
- package/src/utils/fetch.js +14 -14
- package/templates/template.html +1 -2
- package/assets/js/insert-xrefs.js +0 -370
- package/src/create-term-relations.js +0 -131
- package/src/prepare-tref.js +0 -174
|
@@ -15,11 +15,11 @@ function extractTrefInfo(firstLine) {
|
|
|
15
15
|
try {
|
|
16
16
|
// Extract content between [[tref: and ]]
|
|
17
17
|
const trefMatch = firstLine.match(/\[\[tref:([^\]]+)\]\]/);
|
|
18
|
-
if (!trefMatch
|
|
18
|
+
if (!trefMatch?.length) {
|
|
19
19
|
return null;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const trefContent = trefMatch[1]
|
|
22
|
+
const trefContent = trefMatch[1]?.trim();
|
|
23
23
|
|
|
24
24
|
// Split by the first comma
|
|
25
25
|
const parts = trefContent.split(',');
|
|
@@ -75,7 +75,7 @@ function termExistsInRepo(filePath, term) {
|
|
|
75
75
|
const cacheData = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
76
76
|
|
|
77
77
|
// Check if the file has a terms array
|
|
78
|
-
if (!cacheData
|
|
78
|
+
if (!cacheData?.terms?.length) {
|
|
79
79
|
console.log(`Warning: Cache file ${filePath} has no terms array`);
|
|
80
80
|
return false;
|
|
81
81
|
}
|
|
@@ -86,7 +86,7 @@ function termExistsInRepo(filePath, term) {
|
|
|
86
86
|
// Check each term in the terms array
|
|
87
87
|
for (const termObj of cacheData.terms) {
|
|
88
88
|
// First check the 'term' property if it exists
|
|
89
|
-
if (termObj.term
|
|
89
|
+
if (termObj.term?.toLowerCase() === termLower) {
|
|
90
90
|
return true;
|
|
91
91
|
}
|
|
92
92
|
|
|
@@ -94,7 +94,7 @@ function termExistsInRepo(filePath, term) {
|
|
|
94
94
|
if (termObj.definition) {
|
|
95
95
|
// Look for patterns like [[def: term]] or similar
|
|
96
96
|
const defMatch = termObj.definition.match(/\[\[def:\s*([^\],]+)/i);
|
|
97
|
-
if (defMatch
|
|
97
|
+
if (defMatch?.[1]?.trim().toLowerCase() === termLower) {
|
|
98
98
|
return true;
|
|
99
99
|
}
|
|
100
100
|
}
|
|
@@ -117,7 +117,7 @@ function findRepoForCacheFile(filePath, externalSpecs) {
|
|
|
117
117
|
try {
|
|
118
118
|
const cacheData = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
119
119
|
|
|
120
|
-
if (!cacheData
|
|
120
|
+
if (!cacheData?.repository) {
|
|
121
121
|
return null;
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -129,15 +129,16 @@ function findRepoForCacheFile(filePath, externalSpecs) {
|
|
|
129
129
|
if (!spec.url) continue;
|
|
130
130
|
|
|
131
131
|
// Extract owner/repo from the URL
|
|
132
|
-
const match = spec.url.match(/github\.com\/([
|
|
133
|
-
if (match
|
|
132
|
+
const match = spec.url.match(/github\.com\/([^/]+\/[^/]+)/i);
|
|
133
|
+
if (match?.[1] && repoPath.includes(match[1])) {
|
|
134
134
|
return spec.external_spec;
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
return null;
|
|
139
139
|
} catch (error) {
|
|
140
|
-
|
|
140
|
+
console.error(`Error finding repository for cache file ${filePath}:`, error);
|
|
141
|
+
return null; // Could not determine repository due to error reading or parsing cache file
|
|
141
142
|
}
|
|
142
143
|
}
|
|
143
144
|
|
|
@@ -180,14 +181,14 @@ function findTermInOtherRepos(cacheDir, externalSpecs, currentRepo, term) {
|
|
|
180
181
|
* @returns {string|null} - Path to the cache file or null
|
|
181
182
|
*/
|
|
182
183
|
function findCacheFileForRepo(cacheDir, specConfig) {
|
|
183
|
-
if (!fs.existsSync(cacheDir) || !specConfig
|
|
184
|
+
if (!fs.existsSync(cacheDir) || !specConfig?.url) {
|
|
184
185
|
return null;
|
|
185
186
|
}
|
|
186
187
|
|
|
187
188
|
try {
|
|
188
189
|
// Extract owner and repo from URL
|
|
189
|
-
const match = specConfig.url.match(/github\.com\/([
|
|
190
|
-
if (!match
|
|
190
|
+
const match = specConfig.url.match(/github\.com\/([^/]+)\/([^/]+)/i);
|
|
191
|
+
if (!match?.[1] || !match?.[2]) {
|
|
191
192
|
return null;
|
|
192
193
|
}
|
|
193
194
|
|
|
@@ -203,8 +204,8 @@ function findCacheFileForRepo(cacheDir, specConfig) {
|
|
|
203
204
|
}))
|
|
204
205
|
// Sort by timestamp descending (assuming timestamp is at the beginning of filename)
|
|
205
206
|
.sort((a, b) => {
|
|
206
|
-
const timestampA = parseInt(a.name.split('-')[0]
|
|
207
|
-
const timestampB = parseInt(b.name.split('-')[0]
|
|
207
|
+
const timestampA = parseInt(a.name.split('-')[0] ?? '0', 10);
|
|
208
|
+
const timestampB = parseInt(b.name.split('-')[0] ?? '0', 10);
|
|
208
209
|
return timestampB - timestampA;
|
|
209
210
|
});
|
|
210
211
|
|
|
@@ -223,121 +224,276 @@ function findCacheFileForRepo(cacheDir, specConfig) {
|
|
|
223
224
|
}
|
|
224
225
|
|
|
225
226
|
/**
|
|
226
|
-
*
|
|
227
|
+
* Get configuration and setup data from specs.json
|
|
227
228
|
* @param {string} projectRoot - Root directory of the project
|
|
228
|
-
* @returns {
|
|
229
|
+
* @returns {Object} - Object containing results, specs data, external specs and spec directories
|
|
229
230
|
*/
|
|
230
|
-
async function
|
|
231
|
+
async function getProjectConfiguration(projectRoot) {
|
|
231
232
|
const results = [];
|
|
232
233
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
234
|
+
// Path to the project's specs.json
|
|
235
|
+
const specsPath = path.join(projectRoot, 'specs.json');
|
|
236
|
+
|
|
237
|
+
// Check if specs.json exists
|
|
238
|
+
if (!fs.existsSync(specsPath)) {
|
|
239
|
+
return {
|
|
240
|
+
results: [{
|
|
240
241
|
name: 'Find specs.json file',
|
|
241
242
|
success: false,
|
|
242
243
|
details: 'specs.json file not found in project root'
|
|
243
|
-
}]
|
|
244
|
+
}],
|
|
245
|
+
valid: false
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
results.push({
|
|
250
|
+
name: 'Find specs.json file',
|
|
251
|
+
success: true,
|
|
252
|
+
details: 'specs.json file found'
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// Read specs.json to get the spec directory
|
|
256
|
+
const specsContent = fs.readFileSync(specsPath, 'utf8');
|
|
257
|
+
const specs = JSON.parse(specsContent);
|
|
258
|
+
|
|
259
|
+
// Get the external specs
|
|
260
|
+
if (!specs.specs?.length) {
|
|
261
|
+
results.push({
|
|
262
|
+
name: 'Find specs configuration',
|
|
263
|
+
success: false,
|
|
264
|
+
details: 'specs array not found in specs.json'
|
|
265
|
+
});
|
|
266
|
+
return { results, valid: false };
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Collect all external specs and spec directories
|
|
270
|
+
const externalSpecs = [];
|
|
271
|
+
const specDirs = [];
|
|
272
|
+
|
|
273
|
+
specs.specs.forEach(spec => {
|
|
274
|
+
if (spec.external_specs?.length) {
|
|
275
|
+
externalSpecs.push(...spec.external_specs);
|
|
244
276
|
}
|
|
245
277
|
|
|
278
|
+
if (spec.spec_directory && spec.spec_terms_directory) {
|
|
279
|
+
const termsDir = path.join(
|
|
280
|
+
projectRoot,
|
|
281
|
+
spec.spec_directory,
|
|
282
|
+
spec.spec_terms_directory
|
|
283
|
+
);
|
|
284
|
+
specDirs.push(termsDir);
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
if (externalSpecs.length === 0) {
|
|
289
|
+
results.push({
|
|
290
|
+
name: 'Find external specs',
|
|
291
|
+
success: false,
|
|
292
|
+
details: 'No external specs found in specs.json'
|
|
293
|
+
});
|
|
294
|
+
return { results, valid: false };
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
results.push({
|
|
298
|
+
name: 'Find external specs',
|
|
299
|
+
success: true,
|
|
300
|
+
details: `Found ${externalSpecs.length} external specs`
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
if (specDirs.length === 0) {
|
|
304
|
+
results.push({
|
|
305
|
+
name: 'Find spec terms directories',
|
|
306
|
+
success: false,
|
|
307
|
+
details: 'No spec terms directories found'
|
|
308
|
+
});
|
|
309
|
+
return { results, valid: false };
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
results.push({
|
|
313
|
+
name: 'Find spec terms directories',
|
|
314
|
+
success: true,
|
|
315
|
+
details: `Found ${specDirs.length} spec terms directories`
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
return {
|
|
319
|
+
results,
|
|
320
|
+
specs,
|
|
321
|
+
externalSpecs,
|
|
322
|
+
specDirs,
|
|
323
|
+
valid: true,
|
|
324
|
+
githubCacheDir: path.join(projectRoot, '.cache', 'github-cache')
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Verify if a term exists in the specified repository
|
|
330
|
+
* @param {Object} options - Options for verification
|
|
331
|
+
* @param {string} options.githubCacheDir - Path to GitHub cache directory
|
|
332
|
+
* @param {string} options.repo - Repository to check
|
|
333
|
+
* @param {string} options.term - Term to find
|
|
334
|
+
* @param {string} options.file - File name for reporting
|
|
335
|
+
* @param {Array} options.externalSpecs - List of external specs
|
|
336
|
+
* @returns {Object} - Object containing results and status
|
|
337
|
+
*/
|
|
338
|
+
function verifyTermInRepo(options) {
|
|
339
|
+
const { githubCacheDir, repo, term, file, externalSpecs } = options;
|
|
340
|
+
const results = [];
|
|
341
|
+
|
|
342
|
+
// Check if the referenced repo exists in external_specs
|
|
343
|
+
const specConfig = externalSpecs.find(spec => spec.external_spec === repo);
|
|
344
|
+
if (!specConfig) {
|
|
345
|
+
results.push({
|
|
346
|
+
name: `Check repo reference in ${file}`,
|
|
347
|
+
success: false,
|
|
348
|
+
details: `Referenced repo "${repo}" is not defined in external_specs`
|
|
349
|
+
});
|
|
350
|
+
return { results, status: 'invalid_repo' };
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Find the cache file for this repo
|
|
354
|
+
const cacheFile = findCacheFileForRepo(githubCacheDir, specConfig);
|
|
355
|
+
|
|
356
|
+
if (!cacheFile) {
|
|
357
|
+
results.push({
|
|
358
|
+
name: `Find cache for repo "${repo}" referenced in ${file}`,
|
|
359
|
+
success: false,
|
|
360
|
+
details: `No cache file found for repo "${repo}". Unable to verify if term "${term}" exists.`
|
|
361
|
+
});
|
|
362
|
+
return { results, status: 'no_cache' };
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// Check if the term exists in the repo
|
|
366
|
+
const termExists = termExistsInRepo(cacheFile, term);
|
|
367
|
+
|
|
368
|
+
if (termExists) {
|
|
246
369
|
results.push({
|
|
247
|
-
name:
|
|
370
|
+
name: `Term "${term}" in repo "${repo}" (${file})`,
|
|
248
371
|
success: true,
|
|
249
|
-
details:
|
|
372
|
+
details: `Term "${term}" found in repo "${repo}"`
|
|
373
|
+
});
|
|
374
|
+
return { results, status: 'found' };
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Check if the term exists in other repos
|
|
378
|
+
const otherRepos = findTermInOtherRepos(githubCacheDir, externalSpecs, repo, term);
|
|
379
|
+
|
|
380
|
+
if (otherRepos.length > 0) {
|
|
381
|
+
// Show as warning (partial success) instead of failure
|
|
382
|
+
results.push({
|
|
383
|
+
name: `Term "${term}" in repo "${repo}" (${file})`,
|
|
384
|
+
success: 'partial', // Use 'partial' to indicate a warning
|
|
385
|
+
details: `Warning: Term <code>${term}</code> NOT found in repo ${repo} but found in these repos: <code>${otherRepos.join(', ')}</code>. Consider updating the reference.`
|
|
250
386
|
});
|
|
387
|
+
return { results, status: 'found_elsewhere' };
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
results.push({
|
|
391
|
+
name: `Term "${term}" in repo "${repo}" (${file})`,
|
|
392
|
+
success: false,
|
|
393
|
+
details: `Term <code>${term}</code> NOT found in repo <code>${repo}</code> and not found in any other external repos`
|
|
394
|
+
});
|
|
395
|
+
return { results, status: 'not_found' };
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Process a single markdown file to check for tref tags
|
|
400
|
+
* @param {Object} options - Processing options
|
|
401
|
+
* @param {string} options.filePath - Path to markdown file
|
|
402
|
+
* @param {string} options.githubCacheDir - Path to GitHub cache directory
|
|
403
|
+
* @param {Array} options.externalSpecs - List of external specs
|
|
404
|
+
* @returns {Object} - Object containing results and counts
|
|
405
|
+
*/
|
|
406
|
+
function processMarkdownFile(options) {
|
|
407
|
+
const { filePath, githubCacheDir, externalSpecs } = options;
|
|
408
|
+
const file = path.basename(filePath);
|
|
409
|
+
const results = [];
|
|
410
|
+
const counts = {
|
|
411
|
+
filesWithTref: 0,
|
|
412
|
+
validTerms: 0,
|
|
413
|
+
invalidTerms: 0,
|
|
414
|
+
termsFoundInOtherRepos: 0
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
try {
|
|
418
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
419
|
+
const lines = content.split('\n');
|
|
420
|
+
const firstLine = lines[0];
|
|
421
|
+
|
|
422
|
+
if (!firstLine.includes('[[tref:')) {
|
|
423
|
+
return { results, counts };
|
|
424
|
+
}
|
|
251
425
|
|
|
252
|
-
|
|
253
|
-
const specsContent = fs.readFileSync(specsPath, 'utf8');
|
|
254
|
-
const specs = JSON.parse(specsContent);
|
|
426
|
+
counts.filesWithTref = 1;
|
|
255
427
|
|
|
256
|
-
//
|
|
257
|
-
|
|
428
|
+
// Extract repo and term information
|
|
429
|
+
const trefInfo = extractTrefInfo(firstLine);
|
|
430
|
+
if (!trefInfo) {
|
|
258
431
|
results.push({
|
|
259
|
-
name:
|
|
432
|
+
name: `Parse tref in ${file}`,
|
|
260
433
|
success: false,
|
|
261
|
-
details:
|
|
434
|
+
details: `Could not parse tref information from first line: "${firstLine}"`
|
|
262
435
|
});
|
|
263
|
-
return results;
|
|
436
|
+
return { results, counts };
|
|
264
437
|
}
|
|
265
438
|
|
|
266
|
-
|
|
267
|
-
const externalSpecs = [];
|
|
268
|
-
const specDirs = [];
|
|
439
|
+
const { repo, term } = trefInfo;
|
|
269
440
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
projectRoot,
|
|
278
|
-
spec.spec_directory,
|
|
279
|
-
spec.spec_terms_directory
|
|
280
|
-
);
|
|
281
|
-
specDirs.push(termsDir);
|
|
282
|
-
}
|
|
441
|
+
// Verify the term
|
|
442
|
+
const verification = verifyTermInRepo({
|
|
443
|
+
githubCacheDir,
|
|
444
|
+
repo,
|
|
445
|
+
term,
|
|
446
|
+
file,
|
|
447
|
+
externalSpecs
|
|
283
448
|
});
|
|
284
449
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
450
|
+
results.push(...verification.results);
|
|
451
|
+
|
|
452
|
+
// Update counts based on verification status
|
|
453
|
+
if (verification.status === 'found') {
|
|
454
|
+
counts.validTerms = 1;
|
|
455
|
+
} else if (verification.status === 'found_elsewhere') {
|
|
456
|
+
counts.termsFoundInOtherRepos = 1;
|
|
457
|
+
} else if (verification.status === 'not_found') {
|
|
458
|
+
counts.invalidTerms = 1;
|
|
292
459
|
}
|
|
293
460
|
|
|
461
|
+
} catch (error) {
|
|
294
462
|
results.push({
|
|
295
|
-
name:
|
|
296
|
-
success:
|
|
297
|
-
details: `
|
|
463
|
+
name: `Process file ${file}`,
|
|
464
|
+
success: false,
|
|
465
|
+
details: `Error processing file: ${error.message}`
|
|
298
466
|
});
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
return { results, counts };
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Check if terms referenced via tref tags exist in the corresponding external repos
|
|
474
|
+
* @param {string} projectRoot - Root directory of the project
|
|
475
|
+
* @returns {Promise<Array>} - Array of check results
|
|
476
|
+
*/
|
|
477
|
+
async function checkTrefTerms(projectRoot) {
|
|
478
|
+
try {
|
|
479
|
+
// Get project configuration
|
|
480
|
+
const config = await getProjectConfiguration(projectRoot);
|
|
299
481
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
success: false,
|
|
304
|
-
details: 'No spec terms directories found'
|
|
305
|
-
});
|
|
306
|
-
return results;
|
|
482
|
+
// If configuration is invalid, return early with errors
|
|
483
|
+
if (!config.valid) {
|
|
484
|
+
return config.results;
|
|
307
485
|
}
|
|
308
486
|
|
|
309
|
-
results
|
|
310
|
-
name: 'Find spec terms directories',
|
|
311
|
-
success: true,
|
|
312
|
-
details: `Found ${specDirs.length} spec terms directories`
|
|
313
|
-
});
|
|
487
|
+
const { results, specDirs, externalSpecs, githubCacheDir } = config;
|
|
314
488
|
|
|
315
|
-
//
|
|
316
|
-
// // Path to the GitHub cache directory
|
|
317
|
-
// const githubCacheDir = path.join(projectRoot, 'output', 'github-cache');
|
|
318
|
-
|
|
319
|
-
// if (!fs.existsSync(githubCacheDir)) {
|
|
320
|
-
// results.push({
|
|
321
|
-
// name: 'Find GitHub cache directory',
|
|
322
|
-
// success: false,
|
|
323
|
-
// details: 'GitHub cache directory not found at output/github-cache. Terms in external repos cannot be verified.'
|
|
324
|
-
// });
|
|
325
|
-
// return results;
|
|
326
|
-
// }
|
|
327
|
-
|
|
328
|
-
// results.push({
|
|
329
|
-
// name: 'Find GitHub cache directory',
|
|
330
|
-
// success: true,
|
|
331
|
-
// details: 'GitHub cache directory found'
|
|
332
|
-
// });
|
|
333
|
-
|
|
334
|
-
// Find and check all markdown files in all spec directories
|
|
489
|
+
// Initialize counters
|
|
335
490
|
let totalFiles = 0;
|
|
336
491
|
let filesWithTref = 0;
|
|
337
492
|
let validTerms = 0;
|
|
338
493
|
let invalidTerms = 0;
|
|
339
494
|
let termsFoundInOtherRepos = 0;
|
|
340
495
|
|
|
496
|
+
// Process each spec directory
|
|
341
497
|
for (const specDir of specDirs) {
|
|
342
498
|
if (!fs.existsSync(specDir)) {
|
|
343
499
|
continue;
|
|
@@ -349,98 +505,27 @@ async function checkTrefTerms(projectRoot) {
|
|
|
349
505
|
|
|
350
506
|
totalFiles += markdownFiles.length;
|
|
351
507
|
|
|
508
|
+
// Process each markdown file
|
|
352
509
|
for (const file of markdownFiles) {
|
|
353
510
|
const filePath = path.join(specDir, file);
|
|
511
|
+
const fileResult = processMarkdownFile({
|
|
512
|
+
filePath,
|
|
513
|
+
githubCacheDir,
|
|
514
|
+
externalSpecs
|
|
515
|
+
});
|
|
354
516
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
filesWithTref++;
|
|
365
|
-
|
|
366
|
-
// Extract repo and term information
|
|
367
|
-
const trefInfo = extractTrefInfo(firstLine);
|
|
368
|
-
if (!trefInfo) {
|
|
369
|
-
results.push({
|
|
370
|
-
name: `Parse tref in ${file}`,
|
|
371
|
-
success: false,
|
|
372
|
-
details: `Could not parse tref information from first line: "${firstLine}"`
|
|
373
|
-
});
|
|
374
|
-
continue;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
const { repo, term } = trefInfo;
|
|
378
|
-
|
|
379
|
-
// Check if the referenced repo exists in external_specs
|
|
380
|
-
const specConfig = externalSpecs.find(spec => spec.external_spec === repo);
|
|
381
|
-
if (!specConfig) {
|
|
382
|
-
results.push({
|
|
383
|
-
name: `Check repo reference in ${file}`,
|
|
384
|
-
success: false,
|
|
385
|
-
details: `Referenced repo "${repo}" is not defined in external_specs`
|
|
386
|
-
});
|
|
387
|
-
continue;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
// Find the cache file for this repo
|
|
391
|
-
const cacheFile = findCacheFileForRepo(githubCacheDir, specConfig);
|
|
392
|
-
|
|
393
|
-
if (!cacheFile) {
|
|
394
|
-
results.push({
|
|
395
|
-
name: `Find cache for repo "${repo}" referenced in ${file}`,
|
|
396
|
-
success: false,
|
|
397
|
-
details: `No cache file found for repo "${repo}". Unable to verify if term "${term}" exists.`
|
|
398
|
-
});
|
|
399
|
-
continue;
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
// Check if the term exists in the repo
|
|
403
|
-
const termExists = termExistsInRepo(cacheFile, term);
|
|
404
|
-
|
|
405
|
-
if (termExists) {
|
|
406
|
-
validTerms++;
|
|
407
|
-
results.push({
|
|
408
|
-
name: `Term "${term}" in repo "${repo}" (${file})`,
|
|
409
|
-
success: true,
|
|
410
|
-
details: `Term "${term}" found in repo "${repo}"`
|
|
411
|
-
});
|
|
412
|
-
} else {
|
|
413
|
-
// Check if the term exists in other repos
|
|
414
|
-
const otherRepos = findTermInOtherRepos(githubCacheDir, externalSpecs, repo, term);
|
|
415
|
-
|
|
416
|
-
if (otherRepos.length > 0) {
|
|
417
|
-
// Change: Show as warning (partial success) instead of failure
|
|
418
|
-
termsFoundInOtherRepos++;
|
|
419
|
-
results.push({
|
|
420
|
-
name: `Term "${term}" in repo "${repo}" (${file})`,
|
|
421
|
-
success: 'partial', // Use 'partial' to indicate a warning
|
|
422
|
-
details: `Warning: Term <code>${term}</code> NOT found in repo ${repo} but found in these repos: <code>${otherRepos.join(', ')}</code>. Consider updating the reference.`
|
|
423
|
-
});
|
|
424
|
-
} else {
|
|
425
|
-
invalidTerms++;
|
|
426
|
-
results.push({
|
|
427
|
-
name: `Term "${term}" in repo "${repo}" (${file})`,
|
|
428
|
-
success: false,
|
|
429
|
-
details: `Term <code>${term}</code> NOT found in repo <code>${repo}</code> and not found in any other external repos`
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
} catch (error) {
|
|
434
|
-
results.push({
|
|
435
|
-
name: `Process file ${file}`,
|
|
436
|
-
success: false,
|
|
437
|
-
details: `Error processing file: ${error.message}`
|
|
438
|
-
});
|
|
439
|
-
}
|
|
517
|
+
// Add results
|
|
518
|
+
results.push(...fileResult.results);
|
|
519
|
+
|
|
520
|
+
// Update counters
|
|
521
|
+
filesWithTref += fileResult.counts.filesWithTref;
|
|
522
|
+
validTerms += fileResult.counts.validTerms;
|
|
523
|
+
invalidTerms += fileResult.counts.invalidTerms;
|
|
524
|
+
termsFoundInOtherRepos += fileResult.counts.termsFoundInOtherRepos;
|
|
440
525
|
}
|
|
441
526
|
}
|
|
442
527
|
|
|
443
|
-
// Add summary results
|
|
528
|
+
// Add summary results
|
|
444
529
|
results.push({
|
|
445
530
|
name: 'Term reference validation summary',
|
|
446
531
|
success: invalidTerms === 0,
|