From b1364afbaed891f69f93f1750e781d412b26e758 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Mon, 7 Jun 2021 14:24:55 -0400 Subject: [PATCH] Prevent duplicate snowpack logs (#316) * Prevent duplicate snowpack logs * Fix test to wait on expected messages * Update the snowpack/plugin-vue * Add changeset * Debugging * Skip the logging test on windows :( * arg --- .changeset/cool-pots-double.md | 6 ++ packages/astro/package.json | 3 +- packages/astro/src/runtime.ts | 3 +- packages/astro/src/snowpack-logger.ts | 34 +++++++++ packages/astro/test/helpers.js | 6 ++ packages/astro/test/snowpack-log.test.js | 80 ++++++++++++++++++++ packages/renderers/renderer-vue/package.json | 2 +- yarn.lock | 10 +-- 8 files changed, 136 insertions(+), 8 deletions(-) create mode 100644 .changeset/cool-pots-double.md create mode 100644 packages/astro/src/snowpack-logger.ts create mode 100644 packages/astro/test/snowpack-log.test.js diff --git a/.changeset/cool-pots-double.md b/.changeset/cool-pots-double.md new file mode 100644 index 000000000..cb8c1dac1 --- /dev/null +++ b/.changeset/cool-pots-double.md @@ -0,0 +1,6 @@ +--- +'astro': patch +'@astrojs/renderer-vue': patch +--- + +Updates logging to display messages from Snowpack diff --git a/packages/astro/package.json b/packages/astro/package.json index 280755239..d6e72b63d 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -104,7 +104,8 @@ "@types/node": "^14.14.31", "@types/sass": "^1.16.0", "@types/yargs-parser": "^20.2.0", - "astro-scripts": "0.0.1" + "astro-scripts": "0.0.1", + "is-windows": "^1.0.2" }, "engines": { "node": ">=14.0.0", diff --git a/packages/astro/src/runtime.ts b/packages/astro/src/runtime.ts index 86a816556..9b7aebae1 100644 --- a/packages/astro/src/runtime.ts +++ b/packages/astro/src/runtime.ts @@ -12,6 +12,7 @@ import { CompileError } from 'astro-parser'; import { loadConfiguration, logger as snowpackLogger, startServer as startSnowpackServer } from 'snowpack'; import { canonicalURL, getSrcPath, stopTimer } from './build/util.js'; import { debug, info } from './logger.js'; +import { configureSnowpackLogger } from './snowpack-logger.js'; import { searchForPage } from './search.js'; import snowpackExternals from './external.js'; @@ -45,7 +46,7 @@ type LoadResultError = { statusCode: 500 } & ({ type: 'parse-error'; error: Comp export type LoadResult = (LoadResultSuccess | LoadResultNotFound | LoadResultRedirect | LoadResultError) & { collectionInfo?: CollectionInfo }; // Disable snowpack from writing to stdout/err. -snowpackLogger.level = process.argv.includes('--verbose') ? 'debug' : 'silent'; +configureSnowpackLogger(snowpackLogger); /** Pass a URL to Astro to resolve and build */ async function load(config: RuntimeConfig, rawPathname: string | undefined): Promise { diff --git a/packages/astro/src/snowpack-logger.ts b/packages/astro/src/snowpack-logger.ts new file mode 100644 index 000000000..0240e6c55 --- /dev/null +++ b/packages/astro/src/snowpack-logger.ts @@ -0,0 +1,34 @@ +import { logger as snowpackLogger } from 'snowpack'; + +function verboseLogging() { + return process.argv.includes('--verbose'); +} + +const onceMessages = [ + 'Ready!', + 'watching for file changes' +].map(str => new RegExp(`\\[snowpack\\](.*?)${str}`)); + +export function configureSnowpackLogger(logger: typeof snowpackLogger) { + const messageCache = new Set(); + + if(verboseLogging()) { + logger.level = 'debug'; + } + + logger.on('info', message => { + // Cache messages that should only be shown once. + // This is due to having 2 snowpack instances. Once that is removed we can + // get rid of this workaround. + if(messageCache.has(message)) { + return; + } + + const shouldBeCached = onceMessages.some(exp => exp.test(message)); + if(shouldBeCached) { + messageCache.add(message); + } + + console.log(message); + }); +} \ No newline at end of file diff --git a/packages/astro/test/helpers.js b/packages/astro/test/helpers.js index 904cb0345..637fd5b37 100644 --- a/packages/astro/test/helpers.js +++ b/packages/astro/test/helpers.js @@ -4,6 +4,7 @@ import { readFile } from 'fs/promises'; import { createRuntime } from '#astro/runtime'; import { loadConfig } from '#astro/config'; import execa from 'execa'; +import del from 'del'; const MAX_STARTUP_TIME = 7000; // max time startup may take const MAX_TEST_TIME = 10000; // max time an individual test may take @@ -93,3 +94,8 @@ export function runDevServer(root, additionalArgs = []) { const proc = execa('node', args); return proc; } + +export async function clearCache() { + const cacheDir = new URL('../../../node_modules/.cache', import.meta.url); + await del(fileURLToPath(cacheDir)); +} \ No newline at end of file diff --git a/packages/astro/test/snowpack-log.test.js b/packages/astro/test/snowpack-log.test.js new file mode 100644 index 000000000..9bde02b19 --- /dev/null +++ b/packages/astro/test/snowpack-log.test.js @@ -0,0 +1,80 @@ +import { suite } from 'uvu'; +import * as assert from 'uvu/assert'; +import { clearCache, runDevServer } from './helpers.js'; +import isWindows from 'is-windows'; + +// For some reason Windows isn't getting anything from stdout in this test, not sure why. +if(!isWindows()) { + const SnowpackLogging = suite('snowpack logging'); + const MAX_TEST_TIME = 10000; // max time this test suite may take + + function numberOfEntries(stdout, message) { + const exp = new RegExp(message, 'g'); + let count = 0; + let res; + while(res = exp.exec(stdout)) { + count++; + } + return count; + } + + const root = new URL('./fixtures/astro/basic/', import.meta.url); + const timers = {}; + let runError = null; + SnowpackLogging.before(async context => { + await clearCache(); + + let importantMessages = 0; + let stdout = ''; + try { + const process = runDevServer(root, []); + + process.stdout.setEncoding('utf8'); + for await (const chunk of process.stdout) { + stdout += chunk; + if (/Server started/.test(chunk)) { + importantMessages++; + } + if(/Ready/.test(chunk)) { + importantMessages++; + } + if(/watching for file changes/.test(chunk)) { + importantMessages++; + } + if(importantMessages === 3) { + break; + } + } + + context.stdout = stdout; + process.kill(); + } catch(err) { + console.error(err); + runError = runError; + } + }); + + SnowpackLogging.before.each(({ __test__ }) => { + timers[__test__] = setTimeout(() => { + throw new Error(`Test "${__test__}" did not finish within allowed time`); + }, MAX_TEST_TIME); + }); + + SnowpackLogging('dev server started up', () => { + assert.equal(runError, null); + }); + + SnowpackLogging('Logs Ready message once', async ({ stdout }) => { + assert.equal(numberOfEntries(stdout, 'Ready'), 1); + }); + + SnowpackLogging('Logs [waiting for file changes] once', ({ stdout }) => { + assert.equal(numberOfEntries(stdout, 'watching for file changes'), 1); + }) + + SnowpackLogging.after.each(({ __test__ }) => { + clearTimeout(timers[__test__]); + }); + + SnowpackLogging.run(); +} diff --git a/packages/renderers/renderer-vue/package.json b/packages/renderers/renderer-vue/package.json index a9486073a..e4545a58a 100644 --- a/packages/renderers/renderer-vue/package.json +++ b/packages/renderers/renderer-vue/package.json @@ -11,6 +11,6 @@ "dependencies": { "vue": "^3.0.10", "@vue/server-renderer": "^3.0.10", - "@snowpack/plugin-vue": "^2.6.0" + "@snowpack/plugin-vue": "^2.6.1" } } diff --git a/yarn.lock b/yarn.lock index 919e96315..1af5947c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1338,10 +1338,10 @@ svelte-hmr "^0.13.2" svelte-preprocess "^4.7.2" -"@snowpack/plugin-vue@^2.6.0": - version "2.6.0" - resolved "https://registry.yarnpkg.com/@snowpack/plugin-vue/-/plugin-vue-2.6.0.tgz#9e8ac6eeb15d5e17d3ca297364c140c96d88a667" - integrity sha512-kRjfSHMckf2wwPwpQdgDzxxX637rwC2MZIk9ib6GWlrvbFDAjLozeQMY883naQSu8RwZ4jUC0gW1OHzgz8lLPw== +"@snowpack/plugin-vue@^2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@snowpack/plugin-vue/-/plugin-vue-2.6.1.tgz#ef883dd0b666500d1f401c069d2623ea573ce8c4" + integrity sha512-UsnhuSDT7yzoKWBe4sKHmcA1hi9h66hF1Bds2aa6UUcYLPFYZiBozMCZecqQD4LEtHASuTydNET6BYqrmqoAaw== dependencies: "@rollup/plugin-replace" "^2.4.2" "@vue/compiler-sfc" "^3.0.10" @@ -5454,7 +5454,7 @@ is-whitespace@^0.3.0: resolved "https://registry.yarnpkg.com/is-whitespace/-/is-whitespace-0.3.0.tgz#1639ecb1be036aec69a54cbb401cfbed7114ab7f" integrity sha1-Fjnssb4DauxppUy7QBz77XEUq38= -is-windows@^1.0.0, is-windows@^1.0.1: +is-windows@^1.0.0, is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==