Analyzer CLI: Add Database scanning (#33084)
This commit is contained in:
parent
66633dfe1a
commit
37905dd178
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: dev
|
||||
|
||||
Add script for accessing database schema via CLI
|
|
@ -9,14 +9,19 @@ import { readFileSync } from 'fs';
|
|||
* Internal dependencies
|
||||
*/
|
||||
import { MONOREPO_ROOT } from '../../const';
|
||||
import { printTemplateResults, printHookResults } from '../../print';
|
||||
import {
|
||||
printTemplateResults,
|
||||
printHookResults,
|
||||
printSchemaChange,
|
||||
printDatabaseUpdates,
|
||||
} from '../../print';
|
||||
import {
|
||||
getVersionRegex,
|
||||
getFilename,
|
||||
getPatches,
|
||||
getHookName,
|
||||
} from '../../utils';
|
||||
import { generatePatch } from '../../git';
|
||||
import { generatePatch, generateSchemaDiff } from '../../git';
|
||||
|
||||
/**
|
||||
* Analyzer class
|
||||
|
@ -85,7 +90,32 @@ export default class Analyzer extends Command {
|
|||
const pluginData = this.getPluginData( flags.plugin );
|
||||
this.log( `${ pluginData[ 1 ] } Version: ${ pluginData[ 0 ] }` );
|
||||
|
||||
this.scanChanges( patchContent, pluginData[ 0 ], flags.output );
|
||||
// Avoid running this on CI for now, and only run schema diffs in the monorepo.
|
||||
if (
|
||||
flags.output === 'console' &&
|
||||
flags.source === 'woocommerce/woocommerce'
|
||||
) {
|
||||
const schemaDiff = generateSchemaDiff(
|
||||
flags.source,
|
||||
args.compare,
|
||||
flags.base,
|
||||
( e: string ): void => this.error( e )
|
||||
);
|
||||
|
||||
this.scanChanges(
|
||||
patchContent,
|
||||
pluginData[ 0 ],
|
||||
flags.output,
|
||||
schemaDiff[ 0 ] === schemaDiff[ 1 ]
|
||||
);
|
||||
} else {
|
||||
this.scanChanges(
|
||||
patchContent,
|
||||
pluginData[ 0 ],
|
||||
flags.output,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -162,17 +192,20 @@ export default class Analyzer extends Command {
|
|||
/**
|
||||
* Scan patches for changes in templates, hooks and database schema
|
||||
*
|
||||
* @param {string} content Patch content.
|
||||
* @param {string} version Current product version.
|
||||
* @param {string} output Output style.
|
||||
* @param {string} content Patch content.
|
||||
* @param {string} version Current product version.
|
||||
* @param {string} output Output style.
|
||||
* @param {boolean} schemaEquality if schemas are equal between branches.
|
||||
*/
|
||||
private scanChanges(
|
||||
content: string,
|
||||
version: string,
|
||||
output: string
|
||||
output: string,
|
||||
schemaEquality: boolean
|
||||
): void {
|
||||
const templates = this.scanTemplates( content, version );
|
||||
const hooks = this.scanHooks( content, version, output );
|
||||
const databaseUpdates = this.scanDatabases( content );
|
||||
|
||||
if ( templates.size ) {
|
||||
printTemplateResults(
|
||||
|
@ -192,6 +225,59 @@ export default class Analyzer extends Command {
|
|||
} else {
|
||||
this.log( 'No new hooks found' );
|
||||
}
|
||||
|
||||
if ( ! schemaEquality ) {
|
||||
printSchemaChange( version, output, ( s: string ): void =>
|
||||
this.log( s )
|
||||
);
|
||||
} else {
|
||||
this.log( 'No new schema changes found' );
|
||||
}
|
||||
|
||||
if ( databaseUpdates ) {
|
||||
printDatabaseUpdates(
|
||||
databaseUpdates,
|
||||
output,
|
||||
( s: string ): void => this.log( s )
|
||||
);
|
||||
} else {
|
||||
this.log( 'No database updates found' );
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Scan patches for changes in the database
|
||||
*
|
||||
* @param {string} content Patch content.
|
||||
* @param {string} version Current product version.
|
||||
* @param {string} output Output style.
|
||||
* @return {object|null}
|
||||
*/
|
||||
private scanDatabases(
|
||||
content: string
|
||||
): { updateFunctionName: string; updateFunctionVersion: string } | null {
|
||||
CliUx.ux.action.start( 'Scanning database changes' );
|
||||
const matchPatches = /^a\/(.+).php/g;
|
||||
const patches = getPatches( content, matchPatches );
|
||||
const databaseUpdatePatch = patches.find( ( patch ) => {
|
||||
const lines = patch.split( '\n' );
|
||||
const filepath = getFilename( lines[ 0 ] );
|
||||
return filepath.includes( 'class-wc-install.php' );
|
||||
} );
|
||||
|
||||
if ( ! databaseUpdatePatch ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const updateFunctionRegex = /\+{1,2}\s*'(\d.\d.\d)' => array\(\n\+{1,2}\s*'(.*)',\n\+{1,2}\s*\),/m;
|
||||
const match = databaseUpdatePatch.match( updateFunctionRegex );
|
||||
|
||||
if ( ! match ) {
|
||||
return null;
|
||||
}
|
||||
const updateFunctionVersion = match[ 1 ];
|
||||
const updateFunctionName = match[ 2 ];
|
||||
CliUx.ux.action.stop();
|
||||
return { updateFunctionName, updateFunctionVersion };
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -84,3 +84,57 @@ export const generatePatch = (
|
|||
CliUx.ux.action.stop();
|
||||
return content;
|
||||
};
|
||||
|
||||
export const getSchema = (
|
||||
branch: string,
|
||||
error: ( s: string ) => void
|
||||
): string | undefined => {
|
||||
try {
|
||||
// Make sure the branch is available.
|
||||
fetchBranch( branch, error );
|
||||
// Start spinner.
|
||||
CliUx.ux.action.start( `Gathering schema from ${ branch }` );
|
||||
// Save the current branch for later.
|
||||
const currentBranch = execSync( 'git rev-parse --abbrev-ref HEAD' );
|
||||
// Checkout branch to compare
|
||||
execSync( `git checkout ${ branch }` );
|
||||
|
||||
const getSchemaPath =
|
||||
'wp-content/plugins/woocommerce/bin/wc-get-schema.php';
|
||||
// Get the schema from wp cli
|
||||
const schema = execSync(
|
||||
`wp-env run cli "wp eval-file '${ getSchemaPath }'"`,
|
||||
{
|
||||
cwd: 'plugins/woocommerce',
|
||||
encoding: 'utf-8',
|
||||
}
|
||||
);
|
||||
// Return to the current branch.
|
||||
execSync( `git checkout ${ currentBranch }` );
|
||||
|
||||
CliUx.ux.action.stop();
|
||||
return schema;
|
||||
} catch ( e ) {
|
||||
error( `Unable to get schema for branch ${ branch }. \n${ e }` );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a schema for each branch being compared.
|
||||
*
|
||||
* @param {string} source The GitHub repository.
|
||||
* @param {string} compare Branch/commit hash to compare against the base.
|
||||
* @param {string} base Base branch/commit hash.
|
||||
* @param {Function} error error print method.
|
||||
* @return {Array<string|undefined>} patch string.
|
||||
*/
|
||||
export const generateSchemaDiff = (
|
||||
source: string,
|
||||
compare: string,
|
||||
base: string,
|
||||
error: ( s: string ) => void
|
||||
): Array< string | undefined > => {
|
||||
const baseSchema = getSchema( base, error );
|
||||
const compareSchema = getSchema( compare, error );
|
||||
return [ baseSchema, compareSchema ];
|
||||
};
|
||||
|
|
|
@ -89,3 +89,53 @@ export const printHookResults = (
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Print Schema change results.
|
||||
*
|
||||
* @param {string} version Version change was introduced.
|
||||
* @param {string} output Output style.
|
||||
* @param {Function} log Print method.
|
||||
*/
|
||||
export const printSchemaChange = (
|
||||
version: string,
|
||||
output: string,
|
||||
log: ( s: string ) => void
|
||||
): void => {
|
||||
if ( output === 'github' ) {
|
||||
// Add Github output here.
|
||||
} else {
|
||||
log( '\n## SCHEMA CHANGES' );
|
||||
log( '---------------------------------------------------' );
|
||||
log( ` NOTICE | Schema changes detected in ${ version }` );
|
||||
log( '---------------------------------------------------' );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Object} databaseUpdates Database update info.
|
||||
* @param {string} databaseUpdates.updateFunctionName Database upodate function name.
|
||||
* @param {string} databaseUpdates.updateFunctionVersion Database update version.
|
||||
* @param {string} output Output style.
|
||||
* @param {Function} log Print method.
|
||||
*/
|
||||
export const printDatabaseUpdates = (
|
||||
{
|
||||
updateFunctionName,
|
||||
updateFunctionVersion,
|
||||
}: { updateFunctionName: string; updateFunctionVersion: string },
|
||||
output: string,
|
||||
log: ( s: string ) => void
|
||||
): void => {
|
||||
if ( output === 'github' ) {
|
||||
// Add Github output here.
|
||||
} else {
|
||||
log( '\n## DATABASE UPDATES' );
|
||||
log( '---------------------------------------------------' );
|
||||
log(
|
||||
` NOTICE | Database update found | ${ updateFunctionName } introduced in ${ updateFunctionVersion }`
|
||||
);
|
||||
log( '---------------------------------------------------' );
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue