Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ describe('transformLinks plugin', () => {
expect(result).toMatchInlineSnapshot(`"[file](dir/file.zip)"`);
});

it('transforms json file links inside a directory with ".json" in its name', async () => {
const result = await processContent(`[json](../dir.json/data.json)`);
// The ".raw" extension swap must only apply to the file extension,
// not to the first ".json" occurrence (here, the directory name)
expect(result).toContain('require("./../dir.json/data.raw!=!');
expect(result).toContain('!./../dir.json/data.json").default');
});

it('does not transform existing dotted directory links to asset requires', async () => {
const result = await processContent(
`[directory](../dotted-directory.whatever)`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,10 @@ async function toAssetRequireNode(

const requireString = `${
// A hack to stop Webpack from using its built-in loader to parse JSON
// Note: only replace the file extension at the end of the path:
// the ".json" string can also appear in directory/file names
path.extname(relativeAssetPath) === '.json'
? `${relativeAssetPath.replace('.json', '.raw')}!=`
? `${relativeAssetPath.replace(/\.json$/, '.raw')}!=`
: ''
}${context.inlineMarkdownLinkFileLoader}${
escapePath(relativeAssetPath) + search
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ function AlternateLangHeaders(): ReactNode {
// using underscores instead of dashes.
// See https://ogp.me/#optional
// See https://en.wikipedia.org/wiki/IETF_language_tag)
// Note: BCP 47 tags can have multiple subtags (e.g. zh-Hans-CN),
// so all dashes must be replaced, not just the first one
const bcp47ToOpenGraphLocale = (code: string): string =>
code.replace('-', '_');
code.replaceAll('-', '_');

// Note: it is fine to use both "x-default" and "en" to target the same url
// See https://www.searchviu.com/en/multiple-hreflang-tags-one-url/
Expand Down
43 changes: 43 additions & 0 deletions packages/docusaurus-utils/src/vcs/__tests__/gitUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,49 @@ describe('commit info APIs', () => {
);
});

it('returns files info for author names containing commas', async () => {
const {repoDir, git} = await createGitRepoEmpty();
await git.commitFile('test.txt', {
commitDate: '2020-06-19',
commitAuthor: 'Doe, John <john.doe@example.com>',
});

const filesInfo = await getGitRepositoryFilesInfo(repoDir);
expect(filesInfo.get('test.txt')).toEqual({
creation: {
author: 'Doe, John',
timestamp: new Date('2020-06-19').getTime(),
},
lastUpdate: {
author: 'Doe, John',
timestamp: new Date('2020-06-19').getTime(),
},
});
});

it('returns files info for non-ASCII file paths', async () => {
const {repoDir, git} = await createGitRepoEmpty();
// Write the file and use "git add ." to avoid shell encoding issues
await fs.outputFile(
path.join(repoDir, 'docs', 'café.md'),
'Some content',
);
await git.addAll();
await git.commit('Add doc', '2020-06-19', 'Seb <seb@example.com>');

const filesInfo = await getGitRepositoryFilesInfo(repoDir);
expect(filesInfo.get('docs/café.md')).toEqual({
creation: {
author: 'Seb',
timestamp: new Date('2020-06-19').getTime(),
},
lastUpdate: {
author: 'Seb',
timestamp: new Date('2020-06-19').getTime(),
},
});
});

it('returns files info', async () => {
const repoDir = await repoDirPromise;

Expand Down
19 changes: 11 additions & 8 deletions packages/docusaurus-utils/src/vcs/gitUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,11 @@ export async function getGitRepositoryFilesInfo(
// See https://github.com/facebook/docusaurus/pull/10022
'-c',
'log.showSignature=false',
// Do not quote/escape non-ASCII file paths in the --name-status output
// Otherwise paths like "docs/café.md" are emitted as
// "\"docs/caf\\303\\251.md\"" and can't be matched to real file paths
'-c',
'core.quotepath=false',
// The git command we want to run
'log',
// Format each history entry as t:<seconds since epoch>
Expand Down Expand Up @@ -485,14 +490,12 @@ The command exited with code ${result.exitCode}: ${result.stderr}`,
const runningMap: GitFileInfoMap = new Map();

for (const logLine of logLines) {
if (logLine.startsWith('t:')) {
// t:<timestamp>,a:<author name>
const [timestampStr, authorStr] = logLine.split(',') as [string, string];
const timestamp = Number.parseInt(timestampStr.slice(2), 10) * 1000;
const author = authorStr.slice(2);

runningDate = timestamp;
runningAuthor = author;
// t:<timestamp>,a:<author name>
// Note: the author name can contain commas, so we can't just split(',')
const entryMatch = logLine.match(/^t:(?<timestamp>\d+),a:(?<author>.*)$/);
if (entryMatch) {
runningDate = Number.parseInt(entryMatch.groups!.timestamp!, 10) * 1000;
runningAuthor = entryMatch.groups!.author!;
}

// TODO the code below doesn't handle delete/move/rename operations properly
Expand Down