Skip to content

Commit

Permalink
Add a pre-commit hook to check whether API docs are updated (#18820)
Browse files Browse the repository at this point in the history
  • Loading branch information
nosolosw authored Dec 19, 2019
1 parent 4c178b8 commit e60b9c4
Show file tree
Hide file tree
Showing 9 changed files with 176 additions and 99 deletions.
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

# Tooling
/bin @ntwb @nerrad @ajitbohra
/bin/update-readmes.js @ntwb @nerrad @ajitbohra @nosolosw
/bin/api-docs @ntwb @nerrad @ajitbohra @nosolosw
/docs/tool @youknowriad @chrisvanpatten @ajitbohra @nosolosw
/packages/babel-plugin-import-jsx-pragma @gziolo @ntwb @nerrad @ajitbohra
/packages/babel-plugin-makepot @ntwb @nerrad @ajitbohra
Expand Down
28 changes: 28 additions & 0 deletions bin/api-docs/are-readmes-unstaged.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env node

/**
* Node dependencies.
*/
const { join } = require( 'path' );
const chalk = require( 'chalk' );
const execSync = require( 'child_process' ).execSync;

/**
* Local dependencies.
*/
const getPackages = require( './packages' );

const getUnstagedFiles = () => execSync( 'git diff --name-only', { encoding: 'utf8' } ).split( '\n' ).filter( ( element ) => '' !== element );
const readmeFiles = getPackages().map( ( [ packageName ] ) => join( 'packages', packageName, 'README.md' ) );
const unstagedReadmes = getUnstagedFiles().filter( ( element ) => readmeFiles.includes( element ) );

if ( unstagedReadmes.length > 0 ) {
process.exitCode = 1;
process.stdout.write( chalk.red(
'\n',
'Some API docs may be out of date:',
unstagedReadmes.toString(),
'Either stage them or continue with --no-verify.',
'\n'
) );
}
44 changes: 44 additions & 0 deletions bin/api-docs/packages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const packages = [
'a11y',
'autop',
'blob',
'block-editor',
'block-library',
'block-serialization-default-parser',
'blocks',
'compose',
[ 'core-data', {
'Autogenerated actions': 'src/actions.js',
'Autogenerated selectors': 'src/selectors.js',
} ],
'data',
'data-controls',
'date',
'deprecated',
'dom',
'dom-ready',
'e2e-test-utils',
'edit-post',
'element',
'escape-html',
'html-entities',
'i18n',
'keycodes',
'plugins',
'priority-queue',
'redux-routine',
'rich-text',
'shortcode',
'url',
'viewport',
'wordcount',
];

module.exports = function() {
return packages.map( ( entry ) => {
if ( ! Array.isArray( entry ) ) {
entry = [ entry, { 'Autogenerated API docs': 'src/index.js' } ];
}
return entry;
} );
};
35 changes: 35 additions & 0 deletions bin/api-docs/update-readmes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Node dependencies.
*/
const { join } = require( 'path' );
const spawnSync = require( 'child_process' ).spawnSync;

/**
* Local dependencies.
*/
const getPackages = require( './packages' );

getPackages().forEach( ( entry ) => {
const [ packageName, targetFiles ] = entry;

Object.entries( targetFiles ).forEach( ( [ token, path ] ) => {
// Each target operates over the same file, so it needs to be processed synchronously,
// as to make sure the processes don't overwrite each other.
const { status, stderr } = spawnSync(
join( __dirname, '..', '..', 'node_modules', '.bin', 'docgen' ).replace( / /g, '\\ ' ),
[
join( 'packages', packageName, path ),
`--output packages/${ packageName }/README.md`,
'--to-token',
`--use-token "${ token }"`,
'--ignore "/unstable|experimental/i"',
],
{ shell: true },
);

if ( status !== 0 ) {
process.stderr.write( `${ packageName } ${ stderr.toString() }\n` );
process.exit( 1 );
}
} );
} );
70 changes: 0 additions & 70 deletions bin/update-readmes.js

This file was deleted.

27 changes: 27 additions & 0 deletions docs/tool/are-data-files-unstaged.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env node

/**
* Node dependencies.
*/
const chalk = require( 'chalk' );
const execSync = require( 'child_process' ).execSync;

/**
* Local dependencies.
*/
const getPackages = require( './packages' );

const getUnstagedFiles = () => execSync( 'git diff --name-only', { encoding: 'utf8' } ).split( '\n' ).filter( ( element ) => '' !== element );
const readmeFiles = getPackages().map( ( [ packageName ] ) => `docs/designers-developers/developers/data/data-${ packageName.replace( '/', '-' ) }.md` );
const unstagedReadmes = getUnstagedFiles().filter( ( element ) => readmeFiles.includes( element ) );

if ( unstagedReadmes.length > 0 ) {
process.exitCode = 1;
process.stdout.write( chalk.red(
'\n',
'Some API docs may be out of date:',
unstagedReadmes.toString(),
'Either stage them or continue with --no-verify.',
'\n'
) );
}
26 changes: 26 additions & 0 deletions docs/tool/packages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const packages = [
[ 'core', {
'Autogenerated actions': 'packages/core-data/src/actions.js',
'Autogenerated selectors': 'packages/core-data/src/selectors.js',
} ],
'core/annotations',
'core/blocks',
'core/block-editor',
'core/editor',
'core/edit-post',
'core/notices',
'core/nux',
'core/viewport',
];

module.exports = function() {
return packages.map( ( entry ) => {
if ( ! Array.isArray( entry ) ) {
entry = [ entry, {
'Autogenerated actions': `packages/${ entry.replace( 'core/', '' ) }/src/store/actions.js`,
'Autogenerated selectors': `packages/${ entry.replace( 'core/', '' ) }/src/store/selectors.js`,
} ];
}
return entry;
} );
};
35 changes: 10 additions & 25 deletions docs/tool/update-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,23 @@
const { join } = require( 'path' );
const spawnSync = require( 'child_process' ).spawnSync;

const modules = [
[ 'core', {
'Autogenerated actions': 'packages/core-data/src/actions.js',
'Autogenerated selectors': 'packages/core-data/src/selectors.js',
} ],
'core/annotations',
'core/blocks',
'core/block-editor',
'core/editor',
'core/edit-post',
'core/notices',
'core/nux',
'core/viewport',
];
/**
* Local dependencies.
*/
const getPackages = require( './packages' );

modules.forEach( ( entry ) => {
if ( ! Array.isArray( entry ) ) {
entry = [ entry, {
'Autogenerated actions': `packages/${ entry.replace( 'core/', '' ) }/src/store/actions.js`,
'Autogenerated selectors': `packages/${ entry.replace( 'core/', '' ) }/src/store/selectors.js`,
} ];
}
const [ namespace, targets ] = entry;
getPackages().forEach( ( entry ) => {
const [ packageName, targetFiles ] = entry;

Object.entries( targets ).forEach( ( [ token, target ] ) => {
Object.entries( targetFiles ).forEach( ( [ token, target ] ) => {
// Note that this needs to be a sync process for each output file that is updated:
// until docgen provides a way to update many tokens at once, we need to make sure
// the output file is updated before starting the second pass for the next token.
const { status, stderr } = spawnSync(
join( __dirname, '..', '..', 'node_modules', '.bin', 'docgen' ).replace( / /g, '\\ ' ),
[
target,
`--output docs/designers-developers/developers/data/data-${ namespace.replace( '/', '-' ) }.md`,
`--output docs/designers-developers/developers/data/data-${ packageName.replace( '/', '-' ) }.md`,
'--to-token',
`--use-token "${ token }"`,
'--ignore "/unstable|experimental/i"',
Expand All @@ -45,7 +29,8 @@ modules.forEach( ( entry ) => {
);

if ( status !== 0 ) {
throw stderr.toString();
process.stderr.write( `${ packageName } ${ stderr.toString() }\n` );
process.exit( 1 );
}
} );
} );
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@
"predev": "npm run check-engines",
"dev": "npm run build:packages && concurrently \"wp-scripts start\" \"npm run dev:packages\"",
"dev:packages": "node ./bin/packages/watch.js",
"docs:build": "node ./docs/tool/index.js && node ./bin/update-readmes.js",
"docs:build": "node ./docs/tool/index.js && node ./bin/api-docs/update-readmes.js",
"fixtures:clean": "rimraf \"packages/e2e-tests/fixtures/blocks/*.+(json|serialized.html)\"",
"fixtures:server-registered": "npm run wp-env run tests-wordpress-phpunit './bin/get-server-blocks.php > test/integration/full-content/server-registered.json'",
"fixtures:generate": "npm run fixtures:server-registered && cross-env GENERATE_MISSING_FIXTURES=y npm run test-unit",
Expand Down Expand Up @@ -233,10 +233,12 @@
"wp-scripts lint-js"
],
"{docs/{toc.json,tool/*.js},packages/{*/README.md,*/src/{actions,selectors}.js,components/src/*/**/README.md}}": [
"node ./docs/tool/index.js"
"node ./docs/tool/index.js",
"node ./docs/tool/are-data-files-unstaged.js"
],
"packages/**/*.js": [
"node ./bin/update-readmes.js"
"node ./bin/api-docs/update-readmes.js",
"node ./bin/api-docs/are-readmes-unstaged.js"
]
},
"wp-env": {
Expand Down

0 comments on commit e60b9c4

Please sign in to comment.