« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/upd8.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/upd8.js')
-rwxr-xr-xsrc/upd8.js113
1 files changed, 85 insertions, 28 deletions
diff --git a/src/upd8.js b/src/upd8.js
index a9929154..ae072d5a 100755
--- a/src/upd8.js
+++ b/src/upd8.js
@@ -42,8 +42,9 @@ import wrap from 'word-wrap';
 
 import {mapAggregate, openAggregate, showAggregate} from '#aggregate';
 import CacheableObject from '#cacheable-object';
-import {stringifyCache} from '#cli';
+import {formatDuration, stringifyCache} from '#cli';
 import {displayCompositeCacheAnalysis} from '#composite';
+import * as html from '#html';
 import find, {bindFind, getAllFindSpecs} from '#find';
 import {processLanguageFile, watchLanguageFile, internalDefaultStringsFile}
   from '#language';
@@ -68,8 +69,9 @@ import {
 
 import {
   filterReferenceErrors,
-  reportDirectoryErrors,
   reportContentTextErrors,
+  reportDirectoryErrors,
+  reportOrphanedArtworks,
 } from '#data-checks';
 
 import {
@@ -116,7 +118,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
 let COMMIT;
 try {
   COMMIT = execSync('git log --format="%h %B" -n 1 HEAD', {cwd: __dirname}).toString().trim();
-} catch (error) {
+} catch {
   COMMIT = '(failed to detect)';
 }
 
@@ -175,6 +177,10 @@ async function main() {
       {...defaultStepStatus, name: `report directory errors`,
         for: ['verify']},
 
+    reportOrphanedArtworks:
+      {...defaultStepStatus, name: `report orphaned artworks`,
+        for: ['verify']},
+
     filterReferenceErrors:
       {...defaultStepStatus, name: `filter reference errors`,
         for: ['verify']},
@@ -399,6 +405,11 @@ async function main() {
       type: 'flag',
     },
 
+    'skip-orphaned-artwork-validation': {
+      help: `Skips checking for internally orphaned artworks, which is a bad idea, unless you're debugging those in particular`,
+      type: 'flag',
+    },
+
     'skip-reference-validation': {
       help: `Skips checking and reporting reference errors, which speeds up the build but may silently allow erroneous data to pass through`,
       type: 'flag',
@@ -508,6 +519,11 @@ async function main() {
       type: 'flag',
     },
 
+    'skip-self-diagnosis': {
+      help: `Disable some runtime validation for the wiki's own code, which speeds up long builds, but may allow unpredicted corner cases to fail strangely and silently`,
+      type: 'flag',
+    },
+
     'queue-size': {
       help: `Process more or fewer disk files at once to optimize performance or avoid I/O errors, unlimited if set to 0 (between 500 and 700 is usually a safe range for building HSMusic on Windows machines)\nDefaults to ${defaultQueueSize}`,
       type: 'value',
@@ -646,7 +662,8 @@ async function main() {
   const thumbsOnly = cliOptions['thumbs-only'] ?? false;
   const noInput = cliOptions['no-input'] ?? false;
 
-  const showAggregateTraces = cliOptions['show-traces'] ?? false;
+  const skipSelfDiagnosis = cliOptions['skip-self-diagnosis'] ?? false;
+  const showTraces = cliOptions['show-traces'] ?? false;
 
   const precacheMode = cliOptions['precache-mode'] ?? 'common';
 
@@ -843,6 +860,16 @@ async function main() {
       },
     });
 
+    fallbackStep('reportOrphanedArtworks', {
+      default: 'perform',
+      cli: {
+        flag: 'skip-orphaned-artwork-validation',
+        negate: true,
+        warn:
+          `Skipping orphaned artwork validation. Hopefully you're debugging!`,
+      },
+    });
+
     fallbackStep('filterReferenceErrors', {
       default: 'perform',
       cli: {
@@ -1136,6 +1163,18 @@ async function main() {
     return false;
   }
 
+  if (skipSelfDiagnosis) {
+    logWarn`${'Skipping code self-diagnosis.'} (--skip-self-diagnosis provided)`;
+    logWarn`This build should run substantially faster, but corner cases`;
+    logWarn`not previously predicted may fail strangely and silently.`;
+
+    html.disableSlotValidation();
+  }
+
+  if (!showTraces) {
+    html.disableTagTracing();
+  }
+
   Object.assign(stepStatusSummary.determineMediaCachePath, {
     status: STATUS_STARTED_NOT_DONE,
     timeStart: Date.now(),
@@ -1314,7 +1353,7 @@ async function main() {
 
   const niceShowAggregate = (error, ...opts) => {
     showAggregate(error, {
-      showTraces: showAggregateTraces,
+      showTraces,
       pathToFileURL: (f) => path.relative(__dirname, fileURLToPath(f)),
       ...opts,
     });
@@ -1736,8 +1775,8 @@ async function main() {
     });
   }
 
-  // Filter out any things with duplicate directories throughout the data,
-  // warning about them too.
+  // Check for things with duplicate directories throughout the data,
+  // and halt if any are found.
 
   if (stepStatusSummary.reportDirectoryErrors.status === STATUS_NOT_STARTED) {
     Object.assign(stepStatusSummary.reportDirectoryErrors, {
@@ -1778,8 +1817,42 @@ async function main() {
     }
   }
 
-  // Filter out any reference errors throughout the data, warning about them
-  // too.
+  // Check for artwork objects which have been orphaned from their things,
+  // and halt if any are found.
+
+  if (stepStatusSummary.reportOrphanedArtworks.status === STATUS_NOT_STARTED) {
+    Object.assign(stepStatusSummary.reportOrphanedArtworks, {
+      status: STATUS_STARTED_NOT_DONE,
+      timeStart: Date.now(),
+    });
+
+    try {
+      reportOrphanedArtworks(wikiData, {getAllFindSpecs});
+
+      Object.assign(stepStatusSummary.reportOrphanedArtworks, {
+        status: STATUS_DONE_CLEAN,
+        timeEnd: Date.now(),
+        memory: process.memoryUsage(),
+      });
+    } catch (aggregate) {
+      if (!paragraph) console.log('');
+      niceShowAggregate(aggregate);
+
+      logError`Failed to initialize artwork data connections properly.`;
+      fileIssue();
+
+      Object.assign(stepStatusSummary.reportOrphanedArtworks, {
+        status: STATUS_FATAL_ERROR,
+        annotation: `orphaned artworks found`,
+        timeEnd: Date.now(),
+        memory: process.memoryUsage(),
+      });
+
+      return false;
+    }
+  }
+
+  // Filter out any reference errors throughout the data, warning about these.
 
   if (stepStatusSummary.filterReferenceErrors.status === STATUS_NOT_STARTED) {
     Object.assign(stepStatusSummary.filterReferenceErrors, {
@@ -2365,7 +2438,7 @@ async function main() {
       });
 
       internalDefaultLanguage = internalDefaultLanguageWatcher.language;
-    } catch (_error) {
+    } catch {
       // No need to display the error here - it's already printed by
       // watchLanguageFile.
       errorLoadingInternalDefaultLanguage = true;
@@ -3153,6 +3226,7 @@ async function main() {
     developersComment,
     languages,
     missingImagePaths,
+    niceShowAggregate,
     thumbsCache,
     urlSpec,
     urls,
@@ -3215,7 +3289,7 @@ async function main() {
 }
 
 // TODO: isMain detection isn't consistent across platforms here
-/* eslint-disable-next-line no-constant-condition */
+// eslint-disable-next-line no-constant-binary-expression
 if (true || isMain(import.meta.url) || path.basename(process.argv[1]) === 'hsmusic') {
   (async () => {
     let result;
@@ -3309,23 +3383,6 @@ if (true || isMain(import.meta.url) || path.basename(process.argv[1]) === 'hsmus
   })();
 }
 
-function formatDuration(timeDelta) {
-  const seconds = timeDelta / 1000;
-
-  if (seconds > 90) {
-    const modSeconds = Math.floor(seconds % 60);
-    const minutes = Math.floor(seconds - seconds % 60) / 60;
-    return `${minutes}m${modSeconds}s`;
-  }
-
-  if (seconds < 0.1) {
-    return 'instant';
-  }
-
-  const precision = (seconds > 1 ? 3 : 2);
-  return `${seconds.toPrecision(precision)}s`;
-}
-
 function showStepStatusSummary() {
   const longestNameLength =
     Math.max(...