diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 80716af9c10f..1d41847172f3 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,10 +1,33 @@ { - "name": "Docusaurus Dev Container", - "image": "mcr.microsoft.com/vscode/devcontainers/typescript-node:14-buster", + "image": "mcr.microsoft.com/vscode/devcontainers/base:ubuntu-20.04", "settings": { - "terminal.integrated.shell.linux": "/bin/bash" + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + }, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + }, + "[jsonc]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + } }, - "extensions": ["dbaeumer.vscode-eslint", "orta.vscode-jest"], + "extensions": [ + "dbaeumer.vscode-eslint", + "orta.vscode-jest", + "esbenp.prettier-vscode", + "streetsidesoftware.code-spell-checker" + ], "forwardPorts": [3000], - "postCreateCommand": "yarn install" + "containerUser": "vscode", + "postCreateCommand": "yarn install", + "waitFor": "postCreateCommand", // otherwise automated jest tests fail + "features": { + "node": { + "version": "14" + }, + "github-cli": "latest" + } } diff --git a/.eslintrc.js b/.eslintrc.js index 64f77872d6a1..d31aec2e0a19 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -49,6 +49,7 @@ module.exports = { curly: [WARNING, 'all'], 'global-require': WARNING, 'lines-between-class-members': OFF, + 'max-classes-per-file': OFF, 'max-len': [ WARNING, { diff --git a/jest.config.mjs b/jest.config.mjs index d973ca87d2de..f47278a1c449 100644 --- a/jest.config.mjs +++ b/jest.config.mjs @@ -7,6 +7,8 @@ import {fileURLToPath} from 'url'; +process.env.TZ = 'UTC'; + const ignorePatterns = [ '/node_modules/', '__fixtures__', diff --git a/package.json b/package.json index fb186a2b162a..ef21905e1d61 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "lint:spelling": "cspell \"**\" --no-progress", "lint:style": "stylelint \"**/*.css\"", "lerna": "lerna", - "test": "cross-env TZ=UTC jest", + "test": "jest", "test:build:website": "./admin/scripts/test-release.sh", "watch": "yarn lerna run --parallel watch", "clear": "(yarn workspace website clear || echo 'Failure while running docusaurus clear') && yarn lerna exec --ignore docusaurus yarn rimraf lib lib-next", diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index ab24aa34ab92..a19f55d641fd 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -247,7 +247,7 @@ async function processBlogSourceFile( }); return result.date; } catch (err) { - logger.error(err); + logger.warn(err); return (await fs.stat(blogSourceAbsolute)).birthtime; } } diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/lastUpdate.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/lastUpdate.test.ts index 61e27d9014bd..17cfaba48e9f 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/lastUpdate.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/lastUpdate.test.ts @@ -47,7 +47,7 @@ describe('getFileLastUpdate', () => { it('non-existing file', async () => { const consoleMock = jest - .spyOn(console, 'error') + .spyOn(console, 'warn') .mockImplementation(() => {}); const nonExistingFileName = '.nonExisting'; const nonExistingFilePath = path.join( @@ -65,10 +65,17 @@ describe('getFileLastUpdate', () => { consoleMock.mockRestore(); }); - it('temporary created file that has no git timestamp', async () => { + it('temporary created file that is not tracked by git', async () => { + const consoleMock = jest + .spyOn(console, 'warn') + .mockImplementation(() => {}); const tempFilePath = path.join(__dirname, '__fixtures__', '.temp'); await fs.writeFile(tempFilePath, 'Lorem ipsum :)'); await expect(getFileLastUpdate(tempFilePath)).resolves.toBeNull(); + expect(consoleMock).toHaveBeenCalledTimes(1); + expect(consoleMock).toHaveBeenLastCalledWith( + expect.stringMatching(/not tracked by git./), + ); await fs.unlink(tempFilePath); }); diff --git a/packages/docusaurus-plugin-content-docs/src/lastUpdate.ts b/packages/docusaurus-plugin-content-docs/src/lastUpdate.ts index e62cfe309360..ae12fb244b1d 100644 --- a/packages/docusaurus-plugin-content-docs/src/lastUpdate.ts +++ b/packages/docusaurus-plugin-content-docs/src/lastUpdate.ts @@ -6,11 +6,16 @@ */ import logger from '@docusaurus/logger'; -import {getFileCommitDate, GitNotFoundError} from '@docusaurus/utils'; +import { + getFileCommitDate, + FileNotTrackedError, + GitNotFoundError, +} from '@docusaurus/utils'; type FileLastUpdateData = {timestamp?: number; author?: string}; let showedGitRequirementError = false; +let showedFileNotTrackedError = false; export async function getFileLastUpdate( filePath?: string, @@ -31,8 +36,16 @@ export async function getFileLastUpdate( if (err instanceof GitNotFoundError && !showedGitRequirementError) { logger.warn('Sorry, the docs plugin last update options require Git.'); showedGitRequirementError = true; + } else if ( + err instanceof FileNotTrackedError && + !showedFileNotTrackedError + ) { + logger.warn( + 'Cannot infer the update date for some files, as they are not tracked by git.', + ); + showedFileNotTrackedError = true; } else { - logger.error(err); + logger.warn(err); } return null; } diff --git a/packages/docusaurus-utils/src/gitUtils.ts b/packages/docusaurus-utils/src/gitUtils.ts index 7325964b6dd4..204b3f564d88 100644 --- a/packages/docusaurus-utils/src/gitUtils.ts +++ b/packages/docusaurus-utils/src/gitUtils.ts @@ -10,6 +10,8 @@ import shell from 'shelljs'; export class GitNotFoundError extends Error {} +export class FileNotTrackedError extends Error {} + export const getFileCommitDate = ( file: string, { @@ -70,6 +72,13 @@ export const getFileCommitDate = ( } const output = result.stdout.trim(); + + if (!output) { + throw new FileNotTrackedError( + `Failed to retrieve the git history for file "${file}" because the file is not tracked by git.`, + ); + } + const match = output.match(regex); if ( diff --git a/packages/docusaurus-utils/src/index.ts b/packages/docusaurus-utils/src/index.ts index 26cb7ae65756..c3e246ce8d5c 100644 --- a/packages/docusaurus-utils/src/index.ts +++ b/packages/docusaurus-utils/src/index.ts @@ -21,7 +21,11 @@ export { WEBPACK_URL_LOADER_LIMIT, } from './constants'; export {generate, genChunkName, readOutputHTMLFile} from './emitUtils'; -export {getFileCommitDate, GitNotFoundError} from './gitUtils'; +export { + getFileCommitDate, + FileNotTrackedError, + GitNotFoundError, +} from './gitUtils'; export { mergeTranslations, updateTranslationFileMessages, diff --git a/project-words.txt b/project-words.txt index ae29fa0b5180..f71fab6a6ca2 100644 --- a/project-words.txt +++ b/project-words.txt @@ -53,11 +53,13 @@ customizability daishi datagit datas +dbaeumer décembre dedup deduplicated déja deps +devcontainers devspace devto dmitry @@ -78,6 +80,7 @@ endilie endiliey entrypoints errnametoolong +esbenp esbuild eslintcache evaluable @@ -98,8 +101,8 @@ globby goss goyal gtag -hardcoding hahaha +hardcoding héctor héllô heuristical @@ -184,6 +187,7 @@ opensearch opensearchdescription optimizt optind +orta overrideable pageview palenight @@ -296,6 +300,7 @@ typesense unflat unist unlocalized +unmatch unnormalized unoptimized unprefixed