Resolve sitemap URLs in relation to full site path (#2423)
* 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
This commit is contained in:
parent
a32eee3900
commit
ebe414f05b
4 changed files with 41 additions and 2 deletions
5
.changeset/flat-countries-roll.md
Normal file
5
.changeset/flat-countries-roll.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"astro": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Resolve sitemap URLs in relation to full site path
|
|
@ -146,7 +146,7 @@ class AstroBuilder {
|
||||||
// Build your final sitemap.
|
// Build your final sitemap.
|
||||||
timer.sitemapStart = performance.now();
|
timer.sitemapStart = performance.now();
|
||||||
if (this.config.buildOptions.sitemap && this.config.buildOptions.site) {
|
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);
|
const sitemapPath = new URL('./sitemap.xml', this.config.dist);
|
||||||
await fs.promises.mkdir(new URL('./', sitemapPath), { recursive: true });
|
await fs.promises.mkdir(new URL('./', sitemapPath), { recursive: true });
|
||||||
await fs.promises.writeFile(sitemapPath, sitemap, 'utf8');
|
await fs.promises.writeFile(sitemapPath, sitemap, 'utf8');
|
||||||
|
|
|
@ -15,6 +15,8 @@ describe('Sitemaps', () => {
|
||||||
await fixture.build();
|
await fixture.build();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
after(() => fixture.clean());
|
||||||
|
|
||||||
describe('RSS Generation', () => {
|
describe('RSS Generation', () => {
|
||||||
it('generates RSS correctly', async () => {
|
it('generates RSS correctly', async () => {
|
||||||
const rss = await fixture.readFile('/custom/feed.xml');
|
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(
|
||||||
|
`<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><url><loc>https://astro.build/base-directory/episode/fazers/</loc></url><url><loc>https://astro.build/base-directory/episode/rap-snitch-knishes/</loc></url><url><loc>https://astro.build/base-directory/episode/rhymes-like-dimes/</loc></url><url><loc>https://astro.build/base-directory/episodes/</loc></url></urlset>\n`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -7,6 +7,7 @@ import dev from '../dist/core/dev/index.js';
|
||||||
import build from '../dist/core/build/index.js';
|
import build from '../dist/core/build/index.js';
|
||||||
import preview from '../dist/core/preview/index.js';
|
import preview from '../dist/core/preview/index.js';
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('node-fetch').Response} Response
|
* @typedef {import('node-fetch').Response} Response
|
||||||
* @typedef {import('../src/core/dev/index').DevServer} DevServer
|
* @typedef {import('../src/core/dev/index').DevServer} DevServer
|
||||||
|
@ -21,12 +22,13 @@ import os from 'os';
|
||||||
* @property {(path: string) => Promise<string[]>} readdir
|
* @property {(path: string) => Promise<string[]>} readdir
|
||||||
* @property {() => Promise<DevServer>} startDevServer
|
* @property {() => Promise<DevServer>} startDevServer
|
||||||
* @property {() => Promise<PreviewServer>} preview
|
* @property {() => Promise<PreviewServer>} preview
|
||||||
|
* @property {() => Promise<void>} clean
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load Astro fixture
|
* Load Astro fixture
|
||||||
* @param {AstroConfig} inlineConfig Astro config partial (note: must specify projectRoot)
|
* @param {AstroConfig} inlineConfig Astro config partial (note: must specify projectRoot)
|
||||||
* @returns {Fixture} The fixture. Has the following properties:
|
* @returns {Promise<Fixture>} The fixture. Has the following properties:
|
||||||
* .config - Returns the final config. Will be automatically passed to the methods below:
|
* .config - Returns the final config. Will be automatically passed to the methods below:
|
||||||
*
|
*
|
||||||
* Build
|
* Build
|
||||||
|
@ -39,6 +41,9 @@ import os from 'os';
|
||||||
*
|
*
|
||||||
* Preview
|
* 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
|
* .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) {
|
export async function loadFixture(inlineConfig) {
|
||||||
if (!inlineConfig || !inlineConfig.projectRoot) throw new Error("Must provide { projectRoot: './fixtures/...' }");
|
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'),
|
readFile: (filePath) => fs.promises.readFile(new URL(filePath.replace(/^\//, ''), config.dist), 'utf8'),
|
||||||
readdir: (fp) => fs.promises.readdir(new URL(fp.replace(/^\//, ''), config.dist)),
|
readdir: (fp) => fs.promises.readdir(new URL(fp.replace(/^\//, ''), config.dist)),
|
||||||
|
clean: () => fs.promises.rm(config.dist, { maxRetries: 10, recursive: true, force: true }),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue