mirror of
https://github.com/microsoft/vscode-extension-samples.git
synced 2026-04-27 16:55:44 +08:00
Merge pull request #1053 from mjbvz/ridiculous-carp
Add validation scripts
This commit is contained in:
14
.github/workflows/ci.yml
vendored
Normal file
14
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ $default-branch ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- run: node ./.scripts/validate.js
|
||||
@ -164,16 +164,14 @@ const samples = [
|
||||
{
|
||||
description: 'webpack-sample',
|
||||
path: 'webpack-sample',
|
||||
excludeFromReadme: true,
|
||||
guide: null,
|
||||
guide: '/api/working-with-extensions/bundling-extension',
|
||||
apis: [],
|
||||
contributions: []
|
||||
},
|
||||
{
|
||||
description: 'esbuild-sample',
|
||||
path: 'esbuild-sample',
|
||||
excludeFromReadme: true,
|
||||
guide: null,
|
||||
guide: '/api/working-with-extensions/bundling-extension',
|
||||
apis: [],
|
||||
contributions: []
|
||||
},
|
||||
@ -276,6 +274,20 @@ const samples = [
|
||||
apis: [],
|
||||
contributions: []
|
||||
},
|
||||
{
|
||||
description: 'Chat Sample',
|
||||
path: 'chat-sample',
|
||||
guide: null,
|
||||
apis: [],
|
||||
contributions: []
|
||||
},
|
||||
{
|
||||
description: 'Notifications Sample',
|
||||
path: 'notifications-sample',
|
||||
guide: null,
|
||||
apis: [],
|
||||
contributions: []
|
||||
},
|
||||
{ description: 'configuration-sample', excludeFromReadme: true, path: 'configuration-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'contentprovider-sample', excludeFromReadme: true, path: 'contentprovider-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'nodefs-provider-sample', excludeFromReadme: true, path: 'nodefs-provider-sample', guide: null, apis: [], contributions: [] },
|
||||
@ -285,10 +297,14 @@ const samples = [
|
||||
{ description: 'fsconsumer-sample', excludeFromReadme: true, path: 'fsconsumer-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'github-authentication-sample', excludeFromReadme: true, path: 'github-authentication-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'helloworld-sample', excludeFromReadme: true, path: 'helloworld-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'helloworld-minimal-sample', excludeFromReadme: true, path: 'helloworld-minimal-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'helloworld-test-sample', excludeFromReadme: true, path: 'helloworld-test-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'helloworld-web-sample', excludeFromReadme: true, path: 'helloworld-web-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'helloworld-test-cli-sample', excludeFromReadme: true, path: 'helloworld-test-cli-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'inline-completions', excludeFromReadme: true, path: 'inline-completions', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'notebook-renderer-react-sample', excludeFromReadme: true, path: 'notebook-renderer-react-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'notebook-format-code-action-sample', excludeFromReadme: true, path: 'notebook-format-code-action-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'notebook-serializer-sample', excludeFromReadme: true, path: 'notebook-serializer-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'proposed-api-sample', excludeFromReadme: true, path: 'proposed-api-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'virtual-document-sample', excludeFromReadme: true, path: 'virtual-document-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'welcome-view-content-sample', excludeFromReadme: true, path: 'welcome-view-content-sample', guide: null, apis: [], contributions: [] },
|
||||
@ -296,6 +312,10 @@ const samples = [
|
||||
{ description: 'drop-on-document', excludeFromReadme: true, path: 'drop-on-document', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'uri-handler-sample', excludeFromReadme: true, path: 'uri-handler-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'authenticationprovider-sample', excludeFromReadme: true, path: 'authenticationprovider-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'jupyter-kernel-execution-sample', excludeFromReadme: true, path: 'jupyter-kernel-execution-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'shell-integration-sample', excludeFromReadme: true, path: 'shell-integration-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'tabs-api-sample', excludeFromReadme: true, path: 'tabs-api-sample', guide: null, apis: [], contributions: [] },
|
||||
{ description: 'telemetry-sample', excludeFromReadme: true, path: 'telemetry-sample', guide: null, apis: [], contributions: [] },
|
||||
]
|
||||
|
||||
/** LSP specific samples */
|
||||
@ -344,6 +364,13 @@ const lspSamples = [
|
||||
apis: [],
|
||||
contributions: []
|
||||
},
|
||||
{
|
||||
description: 'LSP User Input Sample',
|
||||
path: 'lsp-user-input-sample',
|
||||
guide: null,
|
||||
apis: [],
|
||||
contributions: []
|
||||
},
|
||||
]
|
||||
/**
|
||||
* LSP specific samples
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// @ts-check
|
||||
const fs = require('fs')
|
||||
|
||||
const { samples, lspSamples } = require('./samples')
|
||||
|
||||
const TABLE_HEAD = `<!-- SAMPLES_BEGIN -->
|
||||
@ -12,46 +12,66 @@ const LSP_TABLE_HEAD = `<!-- LSP_SAMPLES_BEGIN -->
|
||||
const LSP_TABLE_END = `<!-- LSP_SAMPLES_END -->`
|
||||
|
||||
const getTableRow = sample => {
|
||||
const descriptionCell = `[${sample.description}](https://github.com/Microsoft/vscode-extension-samples/tree/main/${sample.path})`
|
||||
let guideCell
|
||||
if (!sample.guide) {
|
||||
guideCell = 'N/A'
|
||||
} else if (sample.guide && sample.guide.startsWith('http')) {
|
||||
guideCell = sample.guide
|
||||
} else {
|
||||
guideCell = `[${sample.guide}](https://code.visualstudio.com${sample.guide})`
|
||||
}
|
||||
const descriptionCell = `[${sample.description}](https://github.com/Microsoft/vscode-extension-samples/tree/main/${sample.path})`
|
||||
let guideCell
|
||||
if (!sample.guide) {
|
||||
guideCell = 'N/A'
|
||||
} else if (sample.guide && sample.guide.startsWith('http')) {
|
||||
guideCell = sample.guide
|
||||
} else {
|
||||
guideCell = `[${sample.guide}](https://code.visualstudio.com${sample.guide})`
|
||||
}
|
||||
|
||||
const apis = sample.apis.map(api => {
|
||||
return `[${api}](https://code.visualstudio.com/api/references/vscode-api#${api})`
|
||||
})
|
||||
const contributions = sample.contributions.map(c => {
|
||||
return `[contributes.${c}](https://code.visualstudio.com/api/references/contribution-points#contributes.${c})`
|
||||
})
|
||||
const apiAndContributionCell = apis.concat(contributions).join('<br>')
|
||||
const apis = sample.apis.map(api => {
|
||||
return `[${api}](https://code.visualstudio.com/api/references/vscode-api#${api})`
|
||||
})
|
||||
const contributions = sample.contributions.map(c => {
|
||||
return `[contributes.${c}](https://code.visualstudio.com/api/references/contribution-points#contributes.${c})`
|
||||
})
|
||||
const apiAndContributionCell = apis.concat(contributions).join('<br>')
|
||||
|
||||
return `| ${descriptionCell} | ${guideCell} | ${apiAndContributionCell} |`
|
||||
return `| ${descriptionCell} | ${guideCell} | ${apiAndContributionCell} |`
|
||||
}
|
||||
|
||||
const getSamplesTable = samples => {
|
||||
const samplesMd = samples.map(s => getTableRow(s)).join('\n')
|
||||
const samplesMd = samples.map(s => getTableRow(s)).join('\n')
|
||||
|
||||
return `${TABLE_HEAD.trim()}
|
||||
return `${TABLE_HEAD.trim()}
|
||||
${samplesMd}
|
||||
${TABLE_END.trim()}`
|
||||
}
|
||||
|
||||
const getLSPSamplesTable = samples => {
|
||||
const samplesMd = samples.map(s => getTableRow(s)).join('\n')
|
||||
const samplesMd = samples.map(s => getTableRow(s)).join('\n')
|
||||
|
||||
return `${LSP_TABLE_HEAD.trim()}
|
||||
return `${LSP_TABLE_HEAD.trim()}
|
||||
${samplesMd}
|
||||
${LSP_TABLE_END.trim()}`
|
||||
}
|
||||
|
||||
const readme = fs.readFileSync('README.md', 'utf-8')
|
||||
const newReadme = readme
|
||||
.replace(/<!-- SAMPLES_BEGIN -->(.|\n)*<!-- SAMPLES_END -->/gm, getSamplesTable(samples.filter(x => !x.excludeFromReadme)))
|
||||
.replace(/<!-- LSP_SAMPLES_BEGIN -->(.|\n)*<!-- LSP_SAMPLES_END -->/gm, getLSPSamplesTable(lspSamples))
|
||||
/**
|
||||
* Update the README with the latest samples.
|
||||
*
|
||||
* @returns {boolean} true if the README was updated, false otherwise.
|
||||
*/
|
||||
function updateReadme(dryRun = false) {
|
||||
const readme = fs.readFileSync('README.md', 'utf-8')
|
||||
const newReadme = readme
|
||||
.replace(/<!-- SAMPLES_BEGIN -->(.|\n)*<!-- SAMPLES_END -->/gm, getSamplesTable(samples.filter(x => !x.excludeFromReadme)))
|
||||
.replace(/<!-- LSP_SAMPLES_BEGIN -->(.|\n)*<!-- LSP_SAMPLES_END -->/gm, getLSPSamplesTable(lspSamples))
|
||||
|
||||
fs.writeFileSync('README.md', newReadme)
|
||||
if (readme !== newReadme) {
|
||||
if (!dryRun) {
|
||||
fs.writeFileSync('README.md', newReadme)
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
exports.updateReadme = updateReadme;
|
||||
|
||||
if (require.main === module) {
|
||||
updateReadme();
|
||||
}
|
||||
|
||||
43
.scripts/validate.js
Normal file
43
.scripts/validate.js
Normal file
@ -0,0 +1,43 @@
|
||||
// @ts-check
|
||||
const path = require('path');
|
||||
|
||||
const { samples, lspSamples } = require('./samples');
|
||||
const fs = require('fs');
|
||||
|
||||
const root = path.join(__dirname, '..');
|
||||
|
||||
/**
|
||||
* Validates that all samples are correctly listed in `.scripts/samples.js`.
|
||||
*/
|
||||
function validateSamplesAreListed() {
|
||||
const allSamples = samples.concat(lspSamples);
|
||||
|
||||
const samplesByPath = new Map();
|
||||
for (const sample of allSamples) {
|
||||
samplesByPath.set(sample.path, sample);
|
||||
}
|
||||
|
||||
for (const fileName of fs.readdirSync(root)) {
|
||||
if (!fileName.endsWith('-sample') || fileName.startsWith('.')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const sampleEntry = samplesByPath.get(fileName);
|
||||
if (!sampleEntry) {
|
||||
throw new Error(`Sample '${fileName}' is not listed in samples.js`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that all samples are correctly listed in `.scripts/samples.js`.
|
||||
*/
|
||||
function validateReadmeUpdated() {
|
||||
const { updateReadme } = require('./update-readme');
|
||||
if (updateReadme(true)) {
|
||||
throw new Error(`Readme not updated. Run 'node .scripts/update-readme.js' to update the readme.`);
|
||||
}
|
||||
}
|
||||
|
||||
validateSamplesAreListed();
|
||||
validateReadmeUpdated();
|
||||
@ -51,8 +51,8 @@ You need to have [node](https://nodejs.org/en/) and [npm](https://nodejs.org/en/
|
||||
| [Color Theme Sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/theme-sample) | [/api/extension-guides/color-theme](https://code.visualstudio.com/api/extension-guides/color-theme) | [contributes.themes](https://code.visualstudio.com/api/references/contribution-points#contributes.themes) |
|
||||
| [Product Icon Theme Sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/product-icon-theme-sample) | [/api/extension-guides/product-icon-theme](https://code.visualstudio.com/api/extension-guides/product-icon-theme) | [contributes.productIconThemes](https://code.visualstudio.com/api/references/contribution-points#contributes.productIconThemes) |
|
||||
| [Vim Sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/vim-sample) | N/A | [commands](https://code.visualstudio.com/api/references/vscode-api#commands)<br>[StatusBarItem](https://code.visualstudio.com/api/references/vscode-api#StatusBarItem)<br>[window.createStatusBarItem](https://code.visualstudio.com/api/references/vscode-api#window.createStatusBarItem)<br>[TextEditorCursorStyle](https://code.visualstudio.com/api/references/vscode-api#TextEditorCursorStyle)<br>[window.activeTextEditor](https://code.visualstudio.com/api/references/vscode-api#window.activeTextEditor)<br>[Position](https://code.visualstudio.com/api/references/vscode-api#Position)<br>[Range](https://code.visualstudio.com/api/references/vscode-api#Range)<br>[Selection](https://code.visualstudio.com/api/references/vscode-api#Selection)<br>[TextEditor](https://code.visualstudio.com/api/references/vscode-api#TextEditor)<br>[TextEditorRevealType](https://code.visualstudio.com/api/references/vscode-api#TextEditorRevealType)<br>[TextDocument](https://code.visualstudio.com/api/references/vscode-api#TextDocument) |
|
||||
| [webpack-sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/webpack-sample) | [api/working-with-extensions/bundling-extension](https://code.visualstudio.com/api/working-with-extensions/bundling-extension) | |
|
||||
| [esbuild-sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/esbuild-sample) | [api/working-with-extensions/bundling-extension](https://code.visualstudio.com/api/working-with-extensions/bundling-extension) | |
|
||||
| [webpack-sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/webpack-sample) | [/api/working-with-extensions/bundling-extension](https://code.visualstudio.com/api/working-with-extensions/bundling-extension) | |
|
||||
| [esbuild-sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/esbuild-sample) | [/api/working-with-extensions/bundling-extension](https://code.visualstudio.com/api/working-with-extensions/bundling-extension) | |
|
||||
| [Source Control Sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/source-control-sample) | [/api/extension-guides/scm-provider](https://code.visualstudio.com/api/extension-guides/scm-provider) | [workspace.workspaceFolders](https://code.visualstudio.com/api/references/vscode-api#workspace.workspaceFolders)<br>[SourceControl](https://code.visualstudio.com/api/references/vscode-api#SourceControl)<br>[SourceControlResourceGroup](https://code.visualstudio.com/api/references/vscode-api#SourceControlResourceGroup)<br>[scm.createSourceControl](https://code.visualstudio.com/api/references/vscode-api#scm.createSourceControl)<br>[TextDocumentContentProvider](https://code.visualstudio.com/api/references/vscode-api#TextDocumentContentProvider)<br>[contributes.menus](https://code.visualstudio.com/api/references/contribution-points#contributes.menus) |
|
||||
| [Commenting API Sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/comment-sample) | N/A | |
|
||||
| [Document Editing Sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/document-editing-sample) | N/A | [commands](https://code.visualstudio.com/api/references/vscode-api#commands) |
|
||||
@ -65,6 +65,9 @@ You need to have [node](https://nodejs.org/en/) and [npm](https://nodejs.org/en/
|
||||
| [Getting Started Sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/getting-started-sample) | N/A | |
|
||||
| [notebook-renderer-sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/notebook-renderer-sample) | [/api/extension-guides/notebook#notebook-renderer](https://code.visualstudio.com/api/extension-guides/notebook#notebook-renderer) | [contributes.notebookRenderer](https://code.visualstudio.com/api/references/contribution-points#contributes.notebookRenderer) |
|
||||
| [notebook-extend-markdown-renderer-sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/notebook-extend-markdown-renderer-sample) | [/api/extension-guides/notebook#notebook-renderer](https://code.visualstudio.com/api/extension-guides/notebook#notebook-renderer) | [contributes.notebookRenderer](https://code.visualstudio.com/api/references/contribution-points#contributes.notebookRenderer) |
|
||||
| [jupyter-server-provider-sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/jupyter-server-provider-sample) | N/A | |
|
||||
| [Chat Sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/chat-sample) | N/A | |
|
||||
| [Notifications Sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/notifications-sample) | N/A | |
|
||||
<!-- SAMPLES_END -->
|
||||
|
||||
### Language Server Protocol Samples
|
||||
@ -78,6 +81,7 @@ You need to have [node](https://nodejs.org/en/) and [npm](https://nodejs.org/en/
|
||||
| [LSP Log Streaming Sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/lsp-log-streaming-sample) | N/A | |
|
||||
| [LSP Multi Root Server Sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/lsp-multi-server-sample) | https://github.com/Microsoft/vscode/wiki/Extension-Authoring:-Adopting-Multi-Root-Workspace-APIs#language-client--language-server | |
|
||||
| [LSP Web Extension Sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/lsp-web-extension-sample) | [/api/language-extensions/language-server-extension-guide](https://code.visualstudio.com/api/language-extensions/language-server-extension-guide) | |
|
||||
| [LSP User Input Sample](https://github.com/Microsoft/vscode-extension-samples/tree/main/lsp-user-input-sample) | N/A | |
|
||||
<!-- LSP_SAMPLES_END -->
|
||||
|
||||
## License
|
||||
|
||||
Reference in New Issue
Block a user