diff options
Diffstat (limited to 'src/data')
-rw-r--r-- | src/data/checks.js | 156 | ||||
-rw-r--r-- | src/data/composite/things/track/withMainRelease.js | 6 | ||||
-rw-r--r-- | src/data/composite/things/track/withMainReleaseTrack.js | 14 | ||||
-rw-r--r-- | src/data/composite/things/track/withPropertyFromMainRelease.js | 2 | ||||
-rw-r--r-- | src/data/things/track.js | 4 |
5 files changed, 137 insertions, 45 deletions
diff --git a/src/data/checks.js b/src/data/checks.js index b7a237ad..e68b2ed0 100644 --- a/src/data/checks.js +++ b/src/data/checks.js @@ -11,6 +11,7 @@ import Thing from '#thing'; import thingConstructors from '#things'; import { + annotateError, annotateErrorWithIndex, conditionallySuppressError, decorateErrorWithIndex, @@ -165,6 +166,69 @@ function getFieldPropertyMessage(yamlDocumentSpec, property) { return fieldPropertyMessage; } +function decoAnnotateFindErrors(findFn) { + function annotateMultipleNameMatchesIncludingUnfortunatelyUnsecondary(error) { + const matches = error[Symbol.for('hsmusic.find.multipleNameMatches')]; + if (!matches) return; + + const notSoSecondary = + matches + .map(match => match.thing ?? match) + .filter(match => + match.isTrack && + match.isMainRelease && + CacheableObject.getUpdateValue(match, 'mainRelease')); + + if (empty(notSoSecondary)) return; + + let {message} = error; + message += (message.includes('\n') ? '\n\n' : '\n'); + message += colors.bright(colors.yellow('<!>')) + ' '; + message += colors.yellow(`Some of these tracks are meant to be secondary releases,`) + '\n'; + message += ' '.repeat(4); + message += colors.yellow(`but another error is keeping that from processing correctly!`) + '\n'; + message += ' '.repeat(4); + message += colors.yellow(`Probably look for an error to do with "Main Release", first.`); + Object.assign(error, {message}); + } + + return (...args) => { + try { + return findFn(...args); + } catch (caughtError) { + throw annotateError(caughtError, ...[ + annotateMultipleNameMatchesIncludingUnfortunatelyUnsecondary, + ]); + } + }; +} + +function decoSuppressFindErrors(findFn, {property}) { + void property; + + return conditionallySuppressError(_error => { + // We're not suppressing any errors at the moment. + // An old suppression is kept below for reference. + + /* + if (property === 'sampledTracks') { + // Suppress "didn't match anything" errors in particular, just for samples. + // In hsmusic-data we have a lot of "stub" sample data which don't have + // corresponding tracks yet, so it won't be useful to report such reference + // errors until we take the time to address that. But other errors, like + // malformed reference strings or miscapitalized existing tracks, should + // still be reported, as samples of existing tracks *do* display on the + // website! + if (error.message.includes(`Didn't match anything`)) { + return true; + } + } + */ + + return false; + }, findFn); +} + // Warn about references across data which don't match anything. This involves // using the find() functions on all references, setting it to 'error' mode, and // collecting everything in a structured logged (which gets logged if there are @@ -353,7 +417,12 @@ export function filterReferenceErrors(wikiData, { if (ref === 'same name single') { // Accessing the current thing here. try { - return boundFind.albumSinglesOnly(thing.name); + return boundFind.albumSinglesOnly(thing.name, { + fuzz: { + capitalization: true, + kebab: true, + }, + }); } catch (caughtError) { throw new Error( `Didn't match a single with the same name`, @@ -400,11 +469,20 @@ export function filterReferenceErrors(wikiData, { // gets refactored, there might be trouble here... if (thing.mainReleaseTrack === null) { - throw new Error( - `Matched album for reference "${ref}":\n` + - `- ` + inspect(album) + `\n` + - `...but none of its tracks automatically match this secondary release.\n` + - `Please resolve by specifying the track here, instead of the album.`); + if (album === thing.album) { + throw new Error( + `Matched album for reference "${ref}":\n` + + `- ` + inspect(album) + `\n` + + `...but this is the album that includes this secondary release, itself.\n` + + `Please resolve by pointing to aonther album here, or by removing this\n` + + `Main Release field, if this track is meant to be the main release.`); + } else { + throw new Error( + `Matched album for reference "${ref}":\n` + + `- ` + inspect(album) + `\n` + + `...but none of its tracks automatically match this secondary release.\n` + + `Please resolve by specifying the track here, instead of the album.`); + } } else { return album; } @@ -428,9 +506,16 @@ export function filterReferenceErrors(wikiData, { case '_trackMainReleasesOnly': findFn = trackRef => { - const track = boundFind.track(trackRef); - const mainRef = track && CacheableObject.getUpdateValue(track, 'mainRelease'); + let track = boundFind.trackMainReleasesOnly(trackRef, {mode: 'quiet'}); + if (track) { + return track; + } + // Will error normally, if this can't unambiguously resolve + // or doesn't match any track. + track = boundFind.track(trackRef); + + const mainRef = CacheableObject.getUpdateValue(track, 'mainRelease'); if (mainRef) { // It's possible for the main release to not actually exist, in this case. // It should still be reported since the 'Main Release' field was present. @@ -461,27 +546,8 @@ export function filterReferenceErrors(wikiData, { break; } - const suppress = fn => conditionallySuppressError(_error => { - // We're not suppressing any errors at the moment. - // An old suppression is kept below for reference. - - /* - if (property === 'sampledTracks') { - // Suppress "didn't match anything" errors in particular, just for samples. - // In hsmusic-data we have a lot of "stub" sample data which don't have - // corresponding tracks yet, so it won't be useful to report such reference - // errors until we take the time to address that. But other errors, like - // malformed reference strings or miscapitalized existing tracks, should - // still be reported, as samples of existing tracks *do* display on the - // website! - if (error.message.includes(`Didn't match anything`)) { - return true; - } - } - */ - - return false; - }, fn); + findFn = decoSuppressFindErrors(findFn, {property}); + findFn = decoAnnotateFindErrors(findFn); const fieldPropertyMessage = getFieldPropertyMessage( @@ -537,10 +603,10 @@ export function filterReferenceErrors(wikiData, { value, {message: errorMessage}, decorateErrorWithIndex(refs => (refs.length === 1 - ? suppress(findFn)(refs[0]) + ? findFn(refs[0]) : filterAggregate( refs, {message: `Errors in entry's artist references`}, - decorateErrorWithIndex(suppress(findFn))) + decorateErrorWithIndex(findFn)) .aggregate .close()))); @@ -552,19 +618,18 @@ export function filterReferenceErrors(wikiData, { if (Array.isArray(value)) { newPropertyValue = filter( value, {message: errorMessage}, - decorateErrorWithIndex(suppress(findFn))); + decorateErrorWithIndex(findFn)); break determineNewPropertyValue; } - nest({message: errorMessage}, - suppress(({call}) => { - try { - call(findFn, value); - } catch (error) { - newPropertyValue = null; - throw error; - } - })); + nest({message: errorMessage}, ({call}) => { + try { + call(findFn, value); + } catch (error) { + newPropertyValue = null; + throw error; + } + }); } if (writeProperty) { @@ -588,7 +653,11 @@ export class ContentNodeError extends Error { message, }) { const headingLine = - `(${where}) ${message}`; + (message.includes('\n\n') + ? `(${where})\n\n` + message + '\n' + : message.includes('\n') + ? `(${where})\n` + message + : `(${where}) ${message}`); const textUpToNode = containingLine.slice(0, columnNumber); @@ -762,6 +831,9 @@ export function reportContentTextErrors(wikiData, { break; } + findFn = decoSuppressFindErrors(findFn, {property: null}); + findFn = decoAnnotateFindErrors(findFn); + const findRef = (replacerKeyImplied ? replacerValue diff --git a/src/data/composite/things/track/withMainRelease.js b/src/data/composite/things/track/withMainRelease.js index f1b0841a..67a312ae 100644 --- a/src/data/composite/things/track/withMainRelease.js +++ b/src/data/composite/things/track/withMainRelease.js @@ -67,6 +67,12 @@ export default templateCompositeFrom({ withResolvedReference({ ref: '#sameNameSingleReference', find: soupyFind.input('albumSinglesOnly'), + findOptions: input.value({ + fuzz: { + capitalization: true, + kebab: true, + }, + }), }).outputs({ '#resolvedReference': '#sameNameSingle', }), diff --git a/src/data/composite/things/track/withMainReleaseTrack.js b/src/data/composite/things/track/withMainReleaseTrack.js index 871eba7d..e498582d 100644 --- a/src/data/composite/things/track/withMainReleaseTrack.js +++ b/src/data/composite/things/track/withMainReleaseTrack.js @@ -203,5 +203,19 @@ export default templateCompositeFrom({ null, }), }, + + { + dependencies: ['#mainReleaseTrack', input.myself()], + + compute: (continuation, { + ['#mainReleaseTrack']: mainReleaseTrack, + [input.myself()]: thisTrack, + }) => continuation({ + ['#mainReleaseTrack']: + (mainReleaseTrack === thisTrack + ? null + : mainReleaseTrack), + }), + }, ], }); diff --git a/src/data/composite/things/track/withPropertyFromMainRelease.js b/src/data/composite/things/track/withPropertyFromMainRelease.js index 3e1b6d19..c6f65653 100644 --- a/src/data/composite/things/track/withPropertyFromMainRelease.js +++ b/src/data/composite/things/track/withPropertyFromMainRelease.js @@ -13,7 +13,7 @@ import {withPropertyFromObject} from '#composite/data'; import withMainReleaseTrack from './withMainReleaseTrack.js'; export default templateCompositeFrom({ - annotation: `inheritFromMainRelease`, + annotation: `withPropertyFromMainRelease`, inputs: { property: input({type: 'string'}), diff --git a/src/data/things/track.js b/src/data/things/track.js index 110769e0..1871e86b 100644 --- a/src/data/things/track.js +++ b/src/data/things/track.js @@ -398,7 +398,7 @@ export class Track extends Thing { referenceList({ class: input.value(Track), - find: soupyFind.input('track'), + find: soupyFind.input('trackMainReleasesOnly'), }), ], @@ -409,7 +409,7 @@ export class Track extends Thing { referenceList({ class: input.value(Track), - find: soupyFind.input('track'), + find: soupyFind.input('trackMainReleasesOnly'), }), ], |