-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor pre-commit code into separate files (and add --*=false optio…
- Loading branch information
Showing
5 changed files
with
231 additions
and
184 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// Copyright 2022-2024, University of Colorado Boulder | ||
|
||
// @author Michael Kauzmann (PhET Interactive Simulations) | ||
|
||
import buildLocal from '../../../../perennial-alias/js/common/buildLocal.js'; | ||
import getOption, { isOptionKeyProvided } from '../../../../perennial-alias/js/grunt/tasks/util/getOption.js'; | ||
|
||
const SUPPORTED_TASKS = [ 'lint', 'report-media', 'type-check', 'unit-test', 'phet-io-api' ]; | ||
|
||
/** | ||
* Parse options and build-local defaults to get the list of tasks to be run for pre-commit hooks. | ||
* @author Michael Kauzmann (PhET Interactive Simulations) | ||
* @author Sam Reid (PhET Interactive Simulations) | ||
* | ||
*/ | ||
const getPreCommitTasks = ( outputToConsole: boolean ): string[] => { | ||
|
||
|
||
// By default, run all tasks | ||
const OPT_OUT_ALL = '*'; // Key to opt out of all tasks | ||
let tasksToRun = isOptionKeyProvided( OPT_OUT_ALL ) && !getOption( OPT_OUT_ALL ) ? [] : [ ...SUPPORTED_TASKS ]; | ||
|
||
// check local preferences for overrides for which tasks to turn 'off' | ||
const hookPreCommit = buildLocal.hookPreCommit; | ||
if ( hookPreCommit && hookPreCommit[ OPT_OUT_ALL ] === false ) { | ||
outputToConsole && console.log( 'all tasks opted out from build-local.json' ); | ||
tasksToRun.length = 0; | ||
} | ||
|
||
SUPPORTED_TASKS.forEach( ( task: string ) => { | ||
|
||
// process the buildLocal preferences first | ||
if ( hookPreCommit && hookPreCommit[ task ] === false ) { | ||
outputToConsole && console.log( 'task opted out from build-local.json:', task ); | ||
tasksToRun = tasksToRun.filter( t => t !== task ); | ||
} | ||
|
||
// process the CLI overrides | ||
if ( isOptionKeyProvided( task ) ) { | ||
if ( getOption( task ) ) { | ||
if ( !tasksToRun.includes( task ) ) { | ||
outputToConsole && console.log( 'task added from CLI:', task ); | ||
tasksToRun.push( task ); | ||
} | ||
} | ||
else { | ||
outputToConsole && console.log( 'task removed from CLI:', task ); | ||
tasksToRun = tasksToRun.filter( t => t !== task ); | ||
} | ||
} | ||
} ); | ||
|
||
if ( getOption( 'allTasks' ) ) { | ||
outputToConsole && console.log( 'forcing all tasks to run' ); | ||
tasksToRun = [ ...SUPPORTED_TASKS ]; | ||
} | ||
return tasksToRun; | ||
}; | ||
|
||
export default getPreCommitTasks; |
31 changes: 16 additions & 15 deletions
31
js/common/pre-commit-main.ts → js/common/pre-commit/pre-commit-task.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// Copyright 2020-2024, University of Colorado Boulder | ||
|
||
|
||
import assert from 'assert'; | ||
import execute from '../../../../perennial-alias/js/common/execute.js'; | ||
import phetTimingLog from '../../../../perennial-alias/js/common/phetTimingLog.js'; | ||
import tsxCommand from '../../../../perennial-alias/js/common/tsxCommand.js'; | ||
import getOption from '../../../../perennial-alias/js/grunt/tasks/util/getOption.js'; | ||
import getPreCommitTasks from './getPreCommitTasks.js'; | ||
|
||
/** | ||
* Main logic of pre-commit responsible for launching pre-commit tasks in parallel for a given repo | ||
* | ||
* @author Sam Reid (PhET Interactive Simulations) | ||
* @author Michael Kauzmann (PhET Interactive Simulations) | ||
*/ | ||
|
||
export async function preCommitMain( repo: string, outputToConsole: boolean ): Promise<void> { | ||
const absolute = getOption( 'absolute' ); // Output paths that WebStorm External Tools can parse and hyperlink | ||
|
||
const tasksToRun = getPreCommitTasks( outputToConsole ); | ||
|
||
outputToConsole && console.log( 'tasks to run:', tasksToRun ); | ||
|
||
const precommitSuccess = await phetTimingLog.startAsync( `pre-commit repo="${repo}"`, async () => { | ||
|
||
outputToConsole && console.log( 'repo:', repo ); | ||
|
||
const taskResults = await Promise.allSettled( | ||
tasksToRun.map( task => { | ||
return phetTimingLog.startAsync( | ||
task, | ||
async () => { | ||
const results = await execute( | ||
tsxCommand, | ||
[ | ||
'../chipper/js/common/pre-commit/pre-commit-task.ts', | ||
`--command=${task}`, | ||
`--repo=${repo}`, | ||
outputToConsole ? '--console' : '', | ||
absolute ? '--absolute' : '' | ||
], | ||
'../chipper', | ||
{ | ||
errors: 'resolve' | ||
} | ||
); | ||
assert( typeof results !== 'string' ); | ||
results.stdout && results.stdout.trim().length > 0 && console.log( results.stdout ); | ||
results.stderr && results.stderr.trim().length > 0 && console.log( results.stderr ); | ||
|
||
if ( results.code === 0 ) { | ||
return { task: task, success: true }; | ||
} | ||
else { | ||
let message = 'Task failed: ' + task; | ||
if ( results.stdout && results.stdout.trim().length > 0 ) { | ||
message = message + ': ' + results.stdout; | ||
} | ||
if ( results.stderr && results.stderr.trim().length > 0 ) { | ||
message = message + ': ' + results.stderr; | ||
} | ||
return { task: task, success: false, message: message }; | ||
} | ||
}, | ||
{ | ||
depth: 1 | ||
} | ||
); | ||
} ) | ||
); | ||
|
||
taskResults.forEach( result => { | ||
if ( result.status === 'fulfilled' ) { | ||
if ( result.value.success ) { | ||
console.log( `Task ${result.value.task} succeeded` ); | ||
} | ||
else { | ||
console.error( result.value.message ); | ||
} | ||
} | ||
else { | ||
console.error( `Task ${result.reason.task} encountered an error: ${result.reason.message}` ); | ||
} | ||
} ); | ||
|
||
return taskResults.every( result => result.status === 'fulfilled' && result.value.success ); | ||
} ); | ||
|
||
// generatePhetioMacroAPI is preventing exit for unknown reasons, so manually exit here | ||
phetTimingLog.close( () => process.exit( precommitSuccess ? 0 : 1 ) ); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// Copyright 2022-2024, University of Colorado Boulder | ||
|
||
import path from 'path'; | ||
import { Repo } from '../../../../perennial-alias/js/browser-and-node/PerennialTypes.js'; | ||
import dirname from '../../../../perennial-alias/js/common/dirname.js'; | ||
import execute from '../../../../perennial-alias/js/common/execute.js'; | ||
import tsxCommand from '../../../../perennial-alias/js/common/tsxCommand.js'; | ||
|
||
/** | ||
* Spawns the same pre-commit process on each repo in the list | ||
* @author Michael Kauzmann (PhET Interactive Simulations) | ||
* @author Sam Reid (PhET Interactive Simulations) | ||
*/ | ||
export default async function preCommitOnRepos( repos: Repo[], outputToConsole: boolean ): Promise<boolean> { | ||
const startTime = Date.now(); | ||
|
||
let success = true; | ||
|
||
// This is done sequentially so we don't spawn a bunch of uncached type-check at once, but in the future we may want to optimize | ||
// to run one sequentially then the rest in parallel | ||
for ( let i = 0; i < repos.length; i++ ) { | ||
|
||
process.stdout.write( repos[ i ] + ': ' ); | ||
|
||
// get all argv, but drop out --all and --changed | ||
const args = process.argv.slice( 2 ).filter( arg => ![ '--all', '--changed' ].includes( arg ) ); | ||
outputToConsole && console.log( 'spawning pre-commit.ts with args:', args ); | ||
|
||
// @ts-expect-error | ||
const __dirname = dirname( import.meta.url ); | ||
|
||
// get the cwd to the repo, ../../../../repo | ||
const cwd = path.resolve( __dirname, '../../../../', repos[ i ] ); | ||
|
||
const result = await execute( tsxCommand, [ '../chipper/js/grunt/tasks/pre-commit.ts', ...args ], cwd, { | ||
|
||
// resolve errors so Promise.all doesn't fail on first repo that cannot pull/rebase | ||
errors: 'resolve' | ||
} ); | ||
outputToConsole && console.log( 'result:', result ); | ||
if ( result.code === 0 ) { | ||
console.log( 'Success' ); | ||
} | ||
else { | ||
console.log(); | ||
result.stdout.trim().length > 0 && console.log( result.stdout.trim() ); | ||
result.stderr.trim().length > 0 && console.log( result.stderr.trim() ); | ||
success = false; | ||
} | ||
} | ||
|
||
console.log( 'Done in ' + ( Date.now() - startTime ) + 'ms' ); | ||
return success; | ||
} |
Oops, something went wrong.