feat(DEP0164): handle non-integer codes passed to process.exit & process.exitCode#413
Conversation
process.exit & process.exitCode
|
Given the mere moments between opening this PR and your #405 (comment), it's fairly clear this was fully AI-generated. Could you please confirm what you used to generate it, how much of it, and which specific pieces you reviewed of the generated code. |
|
Thanks for calling this out, yes, I used AI assistance (GitHub Copilot Chat in VS Code) to speed up drafting. What was AI-assisted: What I manually reviewed and adjusted: You are right that I should have disclosed this in the PR description from the start. |
|
aslo for you info you have to use this structure of testing Codemod leverages a
Use the Single-file fixtures option. |
|
AugustinMauroy
left a comment
There was a problem hiding this comment.
Better but still something to improve
| function coerceBoolean(expressionText: string, mode: ExitMode): string { | ||
| if (mode === 'exit') return `${expressionText} ? 1 : 0`; | ||
| return `${expressionText} ? 0 : 1`; | ||
| } |
There was a problem hiding this comment.
I think we can just coerce booleans with Numberto be more simple and consistent.
- process.exit(true)
+ process.exit(Number(true))| ): string { | ||
| if (mode !== 'exitCode') return '1'; | ||
|
|
||
| const codeValue = getObjectCodeValue(objectNode); |
There was a problem hiding this comment.
inline it
| const codeValue = getObjectCodeValue(objectNode); | |
| const pair = objectNode.find({ | |
| rule: { | |
| kind: 'pair', | |
| has: { | |
| kind: 'property_identifier', | |
| field: 'key', | |
| regex: 'code', | |
| }, | |
| }, | |
| }); | |
| const valueValue = pair?.field('value') || null; |
| function getObjectCodeValue(objectNode: SgNode<JS>): SgNode<JS> | null { | ||
| const pairs = objectNode.findAll({ | ||
| rule: { | ||
| kind: 'pair', | ||
| }, | ||
| }); | ||
|
|
||
| for (const pair of pairs) { | ||
| const key = pair.field('key'); | ||
| const value = pair.field('value'); | ||
| if (!key || !value) continue; | ||
| if (key.text() === 'code') return value; | ||
| } | ||
|
|
||
| return null; | ||
| } |
There was a problem hiding this comment.
it can be simplified, and doing that I think just make it inline is better, so replace the functions/implementation by the suggestion on the next comment
| function getObjectCodeValue(objectNode: SgNode<JS>): SgNode<JS> | null { | |
| const pairs = objectNode.findAll({ | |
| rule: { | |
| kind: 'pair', | |
| }, | |
| }); | |
| for (const pair of pairs) { | |
| const key = pair.field('key'); | |
| const value = pair.field('value'); | |
| if (!key || !value) continue; | |
| if (key.text() === 'code') return value; | |
| } | |
| return null; | |
| } |
| if (inferredKind === 'boolean_true' || inferredKind === 'boolean_false') { | ||
| return mode === 'exit' | ||
| ? inferredKind === 'boolean_true' | ||
| ? '1' | ||
| : '0' | ||
| : inferredKind === 'boolean_true' | ||
| ? '0' | ||
| : '1'; | ||
| } |
There was a problem hiding this comment.
why inferredKind need to be compared with same value so many times? this code is quite confusing to me, could you explain why it is necessary or maybe refactor it a bit?
| const declarators = rootNode.findAll({ | ||
| rule: { | ||
| kind: 'variable_declarator', | ||
| }, | ||
| }); |
There was a problem hiding this comment.
this will look for all variable_declarators in the source code I think it not really needed.
https://docs.codemod.com/jssg/semantic-analysis#node-definition-options
LSP.goToDefinition is supported by jssg try use it instead
|
|
||
| proc.exit(0); | ||
| exit(Math.floor(2.3)); | ||
| proc.exitCode = 0; |
There was a problem hiding this comment.
Why process.exitCode = true becomes process.exitCode = 0? It not need to be 1 instead?
Summary
This PR adds a new codemod recipe to handle DEP0164 by coercing unsupported values passed to process.exit(code) and assigned to process.exitCode into integer-compatible values.
Closes #405.
What this adds
Transformation behavior
The codemod applies explicit and safe coercions aligned with the issue requirements:
Safety and scope
Tests
Added fixture coverage for the 10 scenarios from the issue plus additional edge cases:
Validation run: