From ec3eb645d565c583efbf8339c26ffb78f308ce3a Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 8 Jan 2024 10:16:48 -0400 Subject: upd8: --skip-file-sizes --- src/upd8.js | 192 +++++++++++++++++-------------- src/write/build-modes/live-dev-server.js | 4 + src/write/build-modes/static-build.js | 4 + 3 files changed, 115 insertions(+), 85 deletions(-) (limited to 'src') diff --git a/src/upd8.js b/src/upd8.js index 19a12de4..989d19bf 100755 --- a/src/upd8.js +++ b/src/upd8.js @@ -285,6 +285,11 @@ async function main() { type: 'flag', }, + 'skip-file-sizes': { + help: `Skips preloading file sizes for images and additional files, which will be left blank in the build`, + type: 'flag', + }, + 'skip-media-validation': { help: `Skips checking and reporting missing and misplaced media files, which isn't necessary if you aren't adding or removing data or updating directories`, type: 'flag', @@ -646,6 +651,15 @@ async function main() { }, }); + fallbackStep('preloadFileSizes', { + default: 'perform', + buildConfig: 'fileSizes', + cli: { + flag: 'skip-file-sizes', + negate: true, + }, + }); + fallbackStep('verifyImagePaths', { default: 'perform', buildConfig: 'skipMediaValidation', @@ -1614,101 +1628,109 @@ async function main() { } } - Object.assign(stepStatusSummary.preloadFileSizes, { - status: STATUS_STARTED_NOT_DONE, - timeStart: Date.now(), - }); + let getSizeOfAdditionalFile; + let getSizeOfImagePath; - const fileSizePreloader = new FileSizePreloader(); - - // File sizes of additional files need to be precalculated before we can - // actually reference 'em in site building, so get those loading right - // away. We actually need to keep track of two things here - the on-device - // file paths we're actually reading, and the corresponding on-site media - // paths that will be exposed in site build code. We'll build a mapping - // function between them so that when site code requests a site path, - // it'll get the size of the file at the corresponding device path. - const additionalFilePaths = [ - ...wikiData.albumData.flatMap((album) => - [ - ...(album.additionalFiles ?? []), - ...album.tracks.flatMap((track) => [ - ...(track.additionalFiles ?? []), - ...(track.sheetMusicFiles ?? []), - ...(track.midiProjectFiles ?? []), - ]), - ] - .flatMap((fileGroup) => fileGroup.files) - .map((file) => ({ - device: path.join( - mediaPath, - urls - .from('media.root') - .toDevice('media.albumAdditionalFile', album.directory, file) - ), - media: urls - .from('media.root') - .to('media.albumAdditionalFile', album.directory, file), - })) - ), - ]; - - // Same dealio for images. Since just about any image can be embedded and - // we can't super easily know which ones are referenced at runtime, just - // cheat and get file sizes for all images under media. (This includes - // additional files which are images.) - const imageFilePaths = - await traverse(mediaPath, { - pathStyle: 'device', - filterDir: dir => dir !== '.git', - filterFile: file => - ['.png', '.gif', '.jpg'].includes(path.extname(file)) && - !isThumb(file), - }).then(files => files - .map(file => ({ - device: file, - media: - urls - .from('media.root') - .to('media.path', path.relative(mediaPath, file).split(path.sep).join('/')), - }))); + if (stepStatusSummary.preloadFileSizes.status === STATUS_NOT_APPLICABLE) { + getSizeOfAdditionalFile = () => null; + getSizeOfImagePath = () => null; + } else if (stepStatusSummary.preloadFileSizes.status === STATUS_NOT_STARTED) { + Object.assign(stepStatusSummary.preloadFileSizes, { + status: STATUS_STARTED_NOT_DONE, + timeStart: Date.now(), + }); - const getSizeOfMediaFileHelper = paths => (mediaPath) => { - const pair = paths.find(({media}) => media === mediaPath); - if (!pair) return null; - return fileSizePreloader.getSizeOfPath(pair.device); - }; + const fileSizePreloader = new FileSizePreloader(); + + // File sizes of additional files need to be precalculated before we can + // actually reference 'em in site building, so get those loading right + // away. We actually need to keep track of two things here - the on-device + // file paths we're actually reading, and the corresponding on-site media + // paths that will be exposed in site build code. We'll build a mapping + // function between them so that when site code requests a site path, + // it'll get the size of the file at the corresponding device path. + const additionalFilePaths = [ + ...wikiData.albumData.flatMap((album) => + [ + ...(album.additionalFiles ?? []), + ...album.tracks.flatMap((track) => [ + ...(track.additionalFiles ?? []), + ...(track.sheetMusicFiles ?? []), + ...(track.midiProjectFiles ?? []), + ]), + ] + .flatMap((fileGroup) => fileGroup.files) + .map((file) => ({ + device: path.join( + mediaPath, + urls + .from('media.root') + .toDevice('media.albumAdditionalFile', album.directory, file) + ), + media: urls + .from('media.root') + .to('media.albumAdditionalFile', album.directory, file), + })) + ), + ]; + + // Same dealio for images. Since just about any image can be embedded and + // we can't super easily know which ones are referenced at runtime, just + // cheat and get file sizes for all images under media. (This includes + // additional files which are images.) + const imageFilePaths = + await traverse(mediaPath, { + pathStyle: 'device', + filterDir: dir => dir !== '.git', + filterFile: file => + ['.png', '.gif', '.jpg'].includes(path.extname(file)) && + !isThumb(file), + }).then(files => files + .map(file => ({ + device: file, + media: + urls + .from('media.root') + .to('media.path', path.relative(mediaPath, file).split(path.sep).join('/')), + }))); + + const getSizeOfMediaFileHelper = paths => (mediaPath) => { + const pair = paths.find(({media}) => media === mediaPath); + if (!pair) return null; + return fileSizePreloader.getSizeOfPath(pair.device); + }; - const getSizeOfAdditionalFile = getSizeOfMediaFileHelper(additionalFilePaths); - const getSizeOfImagePath = getSizeOfMediaFileHelper(imageFilePaths); + getSizeOfAdditionalFile = getSizeOfMediaFileHelper(additionalFilePaths); + getSizeOfImagePath = getSizeOfMediaFileHelper(imageFilePaths); - logInfo`Preloading filesizes for ${additionalFilePaths.length} additional files...`; + logInfo`Preloading filesizes for ${additionalFilePaths.length} additional files...`; - fileSizePreloader.loadPaths(...additionalFilePaths.map((path) => path.device)); - await fileSizePreloader.waitUntilDoneLoading(); + fileSizePreloader.loadPaths(...additionalFilePaths.map((path) => path.device)); + await fileSizePreloader.waitUntilDoneLoading(); - logInfo`Preloading filesizes for ${imageFilePaths.length} full-resolution images...`; + logInfo`Preloading filesizes for ${imageFilePaths.length} full-resolution images...`; - fileSizePreloader.loadPaths(...imageFilePaths.map((path) => path.device)); - await fileSizePreloader.waitUntilDoneLoading(); + fileSizePreloader.loadPaths(...imageFilePaths.map((path) => path.device)); + await fileSizePreloader.waitUntilDoneLoading(); - if (fileSizePreloader.hasErrored) { - logWarn`Some media files couldn't be read for preloading filesizes.`; - logWarn`This means the wiki won't display file sizes for these files.`; - logWarn`Investigate missing or unreadable files to get that fixed!`; + if (fileSizePreloader.hasErrored) { + logWarn`Some media files couldn't be read for preloading filesizes.`; + logWarn`This means the wiki won't display file sizes for these files.`; + logWarn`Investigate missing or unreadable files to get that fixed!`; - Object.assign(stepStatusSummary.preloadFileSizes, { - status: STATUS_HAS_WARNINGS, - annotation: `see log for details`, - timeEnd: Date.now(), - }); - } else { - logInfo`Done preloading filesizes without any errors - nice!`; + Object.assign(stepStatusSummary.preloadFileSizes, { + status: STATUS_HAS_WARNINGS, + annotation: `see log for details`, + timeEnd: Date.now(), + }); + } else { + logInfo`Done preloading filesizes without any errors - nice!`; - Object.assign(stepStatusSummary.preloadFileSizes, { - status: STATUS_DONE_CLEAN, - timeEnd: Date.now(), - }); + Object.assign(stepStatusSummary.preloadFileSizes, { + status: STATUS_DONE_CLEAN, + timeEnd: Date.now(), + }); + } } if (stepStatusSummary.performBuild.status === STATUS_NOT_APPLICABLE) { diff --git a/src/write/build-modes/live-dev-server.js b/src/write/build-modes/live-dev-server.js index 0d16911a..8de40e97 100644 --- a/src/write/build-modes/live-dev-server.js +++ b/src/write/build-modes/live-dev-server.js @@ -26,6 +26,10 @@ const defaultPort = 8002; export const description = `Hosts a local HTTP server which generates page content as it is requested, instead of all at once; reacts to changes in data files, so new reloads will be up-to-date with on-disk YAML data (<- not implemented yet, check back soon!)\n\nIntended for local development ONLY; this custom HTTP server is NOT rigorously tested and almost certainly has security flaws`; export const config = { + fileSizes: { + default: true, + }, + languageReloading: { default: true, }, diff --git a/src/write/build-modes/static-build.js b/src/write/build-modes/static-build.js index 65fea6f1..33eafeac 100644 --- a/src/write/build-modes/static-build.js +++ b/src/write/build-modes/static-build.js @@ -38,6 +38,10 @@ const pageFlags = Object.keys(pageSpecs); export const description = `Generates all page content in one build (according to the contents of data files at build time) and writes them to disk, preparing the output folder for upload and serving by any static web host\n\nIntended for any production or public-facing release of a wiki; serviceable for local development, but can be a bit unwieldy and time/CPU-expensive`; export const config = { + fileSizes: { + default: true, + }, + languageReloading: { applicable: false, }, -- cgit 1.3.0-6-gf8a5