From ebe414f05b69d50de4aab64358cd4a31c254f7e6 Mon Sep 17 00:00:00 2001 From: Chris Swithinbank Date: Fri, 21 Jan 2022 01:27:47 +0100 Subject: [PATCH] Resolve sitemap URLs in relation to full site path (#2423) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Resolve sitemap URLs in relation to full site path Fixes #2422 * Test generated sitemap contains base directory in URLs * Add changeset * test: Add `clean` helper to loaded fixture API Adds a method that when called will remove the loaded fixture’s dist directory using `rimraf`. * test: Clean up between sitemap/RSS tests * See if letting rimraf retry more helps… * Add logging to double check nothing’s running in parallel * Remove logging & double check clean up actually succeeds * Try using basic Node.js to clean up dist * Remove logging/checks * Remove stray unnecessary `async` keyword --- .changeset/flat-countries-roll.md | 5 ++++ packages/astro/src/core/build/index.ts | 2 +- packages/astro/test/astro-sitemap-rss.test.js | 28 +++++++++++++++++++ packages/astro/test/test-utils.js | 8 +++++- 4 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 .changeset/flat-countries-roll.md diff --git a/.changeset/flat-countries-roll.md b/.changeset/flat-countries-roll.md new file mode 100644 index 000000000..7c8598861 --- /dev/null +++ b/.changeset/flat-countries-roll.md @@ -0,0 +1,5 @@ +--- +"astro": patch +--- + +Resolve sitemap URLs in relation to full site path diff --git a/packages/astro/src/core/build/index.ts b/packages/astro/src/core/build/index.ts index f6b379942..a93b1f81b 100644 --- a/packages/astro/src/core/build/index.ts +++ b/packages/astro/src/core/build/index.ts @@ -146,7 +146,7 @@ class AstroBuilder { // Build your final sitemap. timer.sitemapStart = performance.now(); if (this.config.buildOptions.sitemap && this.config.buildOptions.site) { - const sitemap = generateSitemap(pageNames.map((pageName) => new URL(`/${pageName}`, this.config.buildOptions.site).href)); + const sitemap = generateSitemap(pageNames.map((pageName) => new URL(pageName, this.config.buildOptions.site).href)); const sitemapPath = new URL('./sitemap.xml', this.config.dist); await fs.promises.mkdir(new URL('./', sitemapPath), { recursive: true }); await fs.promises.writeFile(sitemapPath, sitemap, 'utf8'); diff --git a/packages/astro/test/astro-sitemap-rss.test.js b/packages/astro/test/astro-sitemap-rss.test.js index ca9f8d0db..f3ef8d220 100644 --- a/packages/astro/test/astro-sitemap-rss.test.js +++ b/packages/astro/test/astro-sitemap-rss.test.js @@ -15,6 +15,8 @@ describe('Sitemaps', () => { await fixture.build(); }); + after(() => fixture.clean()); + describe('RSS Generation', () => { it('generates RSS correctly', async () => { const rss = await fixture.readFile('/custom/feed.xml'); @@ -34,3 +36,29 @@ describe('Sitemaps', () => { }); }); }); + +describe('Sitemaps served from subdirectory', () => { + let fixture; + + before(async () => { + fixture = await loadFixture({ + projectRoot: './fixtures/astro-sitemap-rss/', + buildOptions: { + site: 'https://astro.build/base-directory/', + sitemap: true, + }, + }); + await fixture.build(); + }); + + after(() => fixture.clean()); + + describe('Sitemap Generation', () => { + it('Generates Sitemap correctly', async () => { + let sitemap = await fixture.readFile('/sitemap.xml'); + expect(sitemap).to.equal( + `https://astro.build/base-directory/episode/fazers/https://astro.build/base-directory/episode/rap-snitch-knishes/https://astro.build/base-directory/episode/rhymes-like-dimes/https://astro.build/base-directory/episodes/\n` + ); + }); + }); +}); diff --git a/packages/astro/test/test-utils.js b/packages/astro/test/test-utils.js index d503b0cfe..18c83d506 100644 --- a/packages/astro/test/test-utils.js +++ b/packages/astro/test/test-utils.js @@ -7,6 +7,7 @@ import dev from '../dist/core/dev/index.js'; import build from '../dist/core/build/index.js'; import preview from '../dist/core/preview/index.js'; import os from 'os'; + /** * @typedef {import('node-fetch').Response} Response * @typedef {import('../src/core/dev/index').DevServer} DevServer @@ -21,12 +22,13 @@ import os from 'os'; * @property {(path: string) => Promise} readdir * @property {() => Promise} startDevServer * @property {() => Promise} preview + * @property {() => Promise} clean */ /** * Load Astro fixture * @param {AstroConfig} inlineConfig Astro config partial (note: must specify projectRoot) - * @returns {Fixture} The fixture. Has the following properties: + * @returns {Promise} The fixture. Has the following properties: * .config - Returns the final config. Will be automatically passed to the methods below: * * Build @@ -39,6 +41,9 @@ import os from 'os'; * * Preview * .preview() - Async. Starts a preview server. Note this can’t be running in same fixture as .dev() as they share ports. Also, you must call `server.close()` before test exit + * + * Clean-up + * .clean() - Async. Removes the project’s dist folder. */ export async function loadFixture(inlineConfig) { if (!inlineConfig || !inlineConfig.projectRoot) throw new Error("Must provide { projectRoot: './fixtures/...' }"); @@ -77,6 +82,7 @@ export async function loadFixture(inlineConfig) { }, readFile: (filePath) => fs.promises.readFile(new URL(filePath.replace(/^\//, ''), config.dist), 'utf8'), readdir: (fp) => fs.promises.readdir(new URL(fp.replace(/^\//, ''), config.dist)), + clean: () => fs.promises.rm(config.dist, { maxRetries: 10, recursive: true, force: true }), }; }