« get me outta code hell

data: Track.alwaysReferencedByDirectory flag & field - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2023-09-18 16:05:05 -0300
committer(quasar) nebula <qznebula@protonmail.com>2023-09-18 17:57:30 -0300
commitfdd8f355bfe0992fc340f800297df524276b1946 (patch)
treefa7444538d49edd1a4ac124a06c02c1102e71e6a
parentf3a855d772d51749c6f9d50632dc74792f902b29 (diff)
data: Track.alwaysReferencedByDirectory flag & field
-rw-r--r--src/data/things/track.js35
-rw-r--r--src/data/yaml.js2
-rw-r--r--src/find.js24
3 files changed, 49 insertions, 12 deletions
diff --git a/src/data/things/track.js b/src/data/things/track.js
index e176acb..14510d9 100644
--- a/src/data/things/track.js
+++ b/src/data/things/track.js
@@ -36,6 +36,41 @@ export class Track extends Thing {
     urls: Thing.common.urls(),
     dateFirstReleased: Thing.common.simpleDate(),
 
+    // Controls how find.track works - it'll never be matched by a reference
+    // just to the track's name, which means you don't have to always reference
+    // some *other* (much more commonly referenced) track by directory instead
+    // of more naturally by name.
+    alwaysReferenceByDirectory: {
+      flags: {update: true, expose: true},
+
+      // Deliberately defaults to null - this will fall back to false in most
+      // cases.
+      update: {validate: isBoolean, default: null},
+
+      expose: {
+        dependencies: ['name', 'originalReleaseTrackByRef', 'trackData'],
+
+        transform(value, {
+          name,
+          originalReleaseTrackByRef,
+          trackData,
+          [Track.instance]: thisTrack,
+        }) {
+          if (value !== null) return value;
+
+          const original =
+            find.track(
+              originalReleaseTrackByRef,
+              trackData.filter(track => track !== thisTrack),
+              {quiet: true});
+
+          if (!original) return false;
+
+          return name === original.name;
+        }
+      },
+    },
+
     artistContribsByRef: Thing.common.contribsByRef(),
     contributorContribsByRef: Thing.common.contribsByRef(),
     coverArtistContribsByRef: Thing.common.contribsByRef(),
diff --git a/src/data/yaml.js b/src/data/yaml.js
index 3594319..07e0a3d 100644
--- a/src/data/yaml.js
+++ b/src/data/yaml.js
@@ -338,6 +338,8 @@ export const processTrackDocument = makeProcessDocument(T.Track, {
     coverArtFileExtension: 'Cover Art File Extension',
     hasCoverArt: 'Has Cover Art',
 
+    alwaysReferenceByDirectory: 'Always Reference By Directory',
+
     lyrics: 'Lyrics',
     commentary: 'Commentary',
     additionalFiles: 'Additional Files',
diff --git a/src/find.js b/src/find.js
index b823080..966629e 100644
--- a/src/find.js
+++ b/src/find.js
@@ -80,17 +80,19 @@ function matchDirectory(ref, data) {
 }
 
 function matchName(ref, data, mode) {
-  const matches = data.filter(
-    ({name}) => name.toLowerCase() === ref.toLowerCase()
-  );
+  const matches =
+    data
+      .filter(({name}) => name.toLowerCase() === ref.toLowerCase())
+      .filter(thing =>
+        (Object.hasOwn(thing, 'alwaysReferenceByDirectory')
+          ? !thing.alwaysReferenceByDirectory
+          : true));
 
   if (matches.length > 1) {
-    return warnOrThrow(
-      mode,
+    return warnOrThrow(mode,
       `Multiple matches for reference "${ref}". Please resolve:\n` +
-        matches.map((match) => `- ${inspect(match)}\n`).join('') +
-        `Returning null for this reference.`
-    );
+      matches.map(match => `- ${inspect(match)}\n`).join('') +
+      `Returning null for this reference.`);
   }
 
   if (matches.length === 0) {
@@ -100,10 +102,8 @@ function matchName(ref, data, mode) {
   const thing = matches[0];
 
   if (ref !== thing.name) {
-    warnOrThrow(
-      mode,
-      `Bad capitalization: ${color.red(ref)} -> ${color.green(thing.name)}`
-    );
+    warnOrThrow(mode,
+      `Bad capitalization: ${color.red(ref)} -> ${color.green(thing.name)}`);
   }
 
   return thing;