Analyzer CLI: Add other schemas to scan (#33220)

* Add schema

* update to new filepath

* test

* Revert "test"

This reverts commit d05a731a46.

* remove unused import

* add products and orders scanning

* escape slashes

* save

* save

* save

* test

* save

* save

* better descriptions

* moar tests

* Revert "moar tests"

This reverts commit ad552db45b.

* remove test

* better doc blocks

* check port first

* stop wp-env after operation is done

* remove ProductAttributesLookup
This commit is contained in:
Paul Sealock 2022-06-08 15:11:55 +12:00 committed by GitHub
parent 62313708aa
commit be15a35038
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 223 additions and 26 deletions

View File

@ -20,6 +20,7 @@ import {
getFilename,
getPatches,
getHookName,
areSchemasEqual,
} from '../../utils';
import { generatePatch, generateSchemaDiff } from '../../git';
@ -95,7 +96,7 @@ export default class Analyzer extends Command {
flags.output === 'console' &&
flags.source === 'woocommerce/woocommerce'
) {
const schemaDiff = generateSchemaDiff(
const schemaDiff = await generateSchemaDiff(
flags.source,
args.compare,
flags.base,
@ -106,15 +107,10 @@ export default class Analyzer extends Command {
patchContent,
pluginData[ 0 ],
flags.output,
schemaDiff[ 0 ] === schemaDiff[ 1 ]
schemaDiff
);
} else {
this.scanChanges(
patchContent,
pluginData[ 0 ],
flags.output,
true
);
this.scanChanges( patchContent, pluginData[ 0 ], flags.output );
}
}
@ -201,7 +197,14 @@ export default class Analyzer extends Command {
content: string,
version: string,
output: string,
schemaEquality: boolean
schemaDiff: {
[ key: string ]: {
description: string;
base: string;
compare: string;
areEqual: boolean;
};
} | void
): void {
const templates = this.scanTemplates( content, version );
const hooks = this.scanHooks( content, version, output );
@ -226,9 +229,12 @@ export default class Analyzer extends Command {
this.log( 'No new hooks found' );
}
if ( ! schemaEquality ) {
printSchemaChange( version, output, ( s: string ): void =>
this.log( s )
if ( ! areSchemasEqual( schemaDiff ) ) {
printSchemaChange(
schemaDiff,
version,
output,
( s: string ): void => this.log( s )
);
} else {
this.log( 'No new schema changes found' );

View File

@ -7,6 +7,11 @@ import { join } from 'path';
import { tmpdir } from 'os';
import { readFileSync } from 'fs';
/**
* Internal dependencies
*/
import { startWPEnv, stopWPEnv } from './utils';
/**
* Fetch branches from origin.
*
@ -85,23 +90,35 @@ export const generatePatch = (
return content;
};
/**
* Get all schema strings found in WooCommerce.
*
* @param {string} branch branch being compared.
* @param {Function} error Error logging function.
* @return {Object} Object of schema strings.
*/
export const getSchema = (
branch: string,
error: ( s: string ) => void
): string | undefined => {
): {
schema: string;
OrdersTableDataStore: string;
} | void => {
// Save the current branch for later.
const currentBranch = execSync( 'git rev-parse --abbrev-ref HEAD' );
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
// Get the WooCommerce schema from wp cli
const schema = execSync(
`wp-env run cli "wp eval-file '${ getSchemaPath }'"`,
{
@ -109,12 +126,26 @@ export const getSchema = (
encoding: 'utf-8',
}
);
// Get the OrdersTableDataStore schema.
const OrdersTableDataStore = execSync(
'wp-env run cli "wp eval \'echo (new Automattic\\WooCommerce\\Internal\\DataStores\\Orders\\OrdersTableDataStore)->get_database_schema();\'"',
{
cwd: 'plugins/woocommerce',
encoding: 'utf-8',
}
);
// Return to the current branch.
execSync( `git checkout ${ currentBranch }` );
CliUx.ux.action.stop();
return schema;
return {
schema,
OrdersTableDataStore,
};
} catch ( e ) {
// Return to the current branch.
execSync( `git checkout ${ currentBranch }` );
error( `Unable to get schema for branch ${ branch }. \n${ e }` );
}
};
@ -126,15 +157,46 @@ export const getSchema = (
* @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.
* @return {Object|void} diff object.
*/
export const generateSchemaDiff = (
export const generateSchemaDiff = async (
source: string,
compare: string,
base: string,
error: ( s: string ) => void
): Array< string | undefined > => {
): Promise< {
[ key: string ]: {
description: string;
base: string;
compare: string;
areEqual: boolean;
};
} | void > => {
// Be sure the wp-env engine is started.
await startWPEnv( error );
const baseSchema = getSchema( base, error );
const compareSchema = getSchema( compare, error );
return [ baseSchema, compareSchema ];
stopWPEnv( error );
if ( ! baseSchema || ! compareSchema ) {
return;
}
return {
schema: {
description: 'WooCommerce Base Schema',
base: baseSchema.schema,
compare: compareSchema.schema,
areEqual: baseSchema.schema === compareSchema.schema,
},
OrdersTableDataStore: {
description: 'OrdersTableDataStore Schema',
base: baseSchema.OrdersTableDataStore,
compare: compareSchema.OrdersTableDataStore,
areEqual:
baseSchema.OrdersTableDataStore ===
compareSchema.OrdersTableDataStore,
},
};
};

View File

@ -93,22 +93,41 @@ export const printHookResults = (
/**
* Print Schema change results.
*
* @param {string} version Version change was introduced.
* @param {string} output Output style.
* @param {Function} log Print method.
* @param {Object} schemaDiff Schema diff object
* @param {string} version Version change was introduced.
* @param {string} output Output style.
* @param {Function} log Print method.
*/
export const printSchemaChange = (
schemaDiff: {
[ key: string ]: {
description: string;
base: string;
compare: string;
areEqual: boolean;
};
} | void,
version: string,
output: string,
log: ( s: string ) => void
): void => {
if ( ! schemaDiff ) {
return;
}
if ( output === 'github' ) {
// Add Github output here.
} else {
log( '\n## SCHEMA CHANGES' );
log( '---------------------------------------------------' );
log( ` NOTICE | Schema changes detected in ${ version }` );
log( '---------------------------------------------------' );
Object.keys( schemaDiff ).forEach( ( key ) => {
if ( ! schemaDiff[ key ].areEqual ) {
log(
` NOTICE | Schema changes detected in ${ schemaDiff[ key ].description } as of ${ version }`
);
log( '---------------------------------------------------' );
}
} );
}
};

View File

@ -1,3 +1,9 @@
/**
* External dependencies
*/
import { createServer, Server } from 'net';
import { execSync } from 'child_process';
/**
* Format version string for regex.
*
@ -60,3 +66,107 @@ export const getHookName = ( name: string ): string => {
return name.replace( /(\'|\")/g, '' ).trim();
};
/**
* Determine if schema diff object contains schemas that are equal.
*
* @param {Object} schemaDiff
* @return {boolean|void} If the schema diff describes schemas that are equal.
*/
export const areSchemasEqual = (
schemaDiff: {
[ key: string ]: {
description: string;
base: string;
compare: string;
areEqual: boolean;
};
} | void
): boolean => {
if ( ! schemaDiff ) {
return false;
}
return ! Object.keys( schemaDiff ).some(
( d: string ) => schemaDiff[ d ].areEqual === false
);
};
/**
* Determine if the default port for wp-env is already taken. If so, see
* https://developer.wordpress.org/block-editor/reference-guides/packages/packages-env/#2-check-the-port-number
* for alternatives.
*
* @return {Promise<boolean>} if the port is being currently used.
*/
export const isWPEnvPortTaken = () => {
return new Promise< boolean >( ( resolve, reject ) => {
const test: Server = createServer()
.once( 'error', ( err: { code: string } ) => {
return err.code === 'EADDRINUSE'
? resolve( true )
: reject( err );
} )
.once( 'listening', () => {
return test.once( 'close', () => resolve( false ) ).close();
} )
.listen( '8888' );
} );
};
/**
* Start wp-engine.
*
* @param {Function} error error print method.
* @return {boolean} if starting the container succeeded.
*/
export const startWPEnv = async ( error: ( s: string ) => void ) => {
try {
// Stop wp-env if its already running.
execSync( 'wp-env stop', {
cwd: 'plugins/woocommerce',
encoding: 'utf-8',
} );
if ( await isWPEnvPortTaken() ) {
throw new Error(
'Unable to start wp-env. Make sure port 8888 is available or specify port number WP_ENV_PORT in .wp-env.override.json'
);
}
execSync( 'wp-env start', {
cwd: 'plugins/woocommerce',
encoding: 'utf-8',
} );
return true;
} catch ( e ) {
let message = '';
if ( e instanceof Error ) {
message = e.message;
error( message );
}
return false;
}
};
/**
* Stop wp-engine.
*
* @param {Function} error error print method.
* @return {boolean} if stopping the container succeeded.
*/
export const stopWPEnv = ( error: ( s: string ) => void ): boolean => {
try {
execSync( 'wp-env stop', {
cwd: 'plugins/woocommerce',
encoding: 'utf-8',
} );
return true;
} catch ( e ) {
let message = '';
if ( e instanceof Error ) {
message = e.message;
error( message );
}
return false;
}
};