Describe the bug
In both npm and yarn legacy, when running a script named xxx, if a script named prexxx exists it would be run beforehand. Likewise, a script named postxxx would be run afterwards.
In yarn berry, this is no longer the case; prestart, poststart no longer work for custom script names.
To Reproduce
{
"name": "test-package",
"scripts": {
"prestart": "echo prestart",
"start": "echo start"
}
}
Screenshots
npm and yarn 1 work correctly:

yarn berry works incorrectly:

Sherlock repro
js repro
await packageJsonAndInstall({
"scripts": {
"prestart": "echo prestart",
"start": "echo start"
}
});
await expect(await yarn(`start`)).toContain(`prestart`);
This issue reproduces on master:
Error: expect(received).toContain(expected) // indexOf
Expected substring: "prestart"
Received string: "start
"
at module.exports (evalmachine.<anonymous>:8:35)
at processTicksAndRejections (internal/process/task_queues.js:94:5)
at async /github/workspace/.yarn/cache/@arcanis-sherlock-npm-1.0.38-d4f5e2dbf3-2.zip/node_modules/@arcanis/sherlock/lib/executeRepro.js:56:13
at async executeInTempDirectory (/github/workspace/.yarn/cache/@arcanis-sherlock-npm-1.0.38-d4f5e2dbf3-2.zip/node_modules/@arcanis/sherlock/lib/executeRepro.js:17:16)
at async Object.executeRepro (/github/workspace/.yarn/cache/@arcanis-sherlock-npm-1.0.38-d4f5e2dbf3-2.zip/node_modules/@arcanis/sherlock/lib/executeRepro.js:24:12)
at async ExecCommand.execute (/github/workspace/.yarn/cache/@arcanis-sherlock-npm-1.0.38-d4f5e2dbf3-2.zip/node_modules/@arcanis/sherlock/lib/commands/exec.js:25:38)
at async ExecCommand.validateAndExecute (/github/workspace/.yarn/cache/clipanion-npm-2.0.0-rc.16-b9444aaf89-2.zip/node_modules/clipanion/lib/advanced/Command.js:161:26)
at async Cli.run (/github/workspace/.yarn/cache/clipanion-npm-2.0.0-rc.16-b9444aaf89-2.zip/node_modules/clipanion/lib/advanced/Cli.js:74:24)
at async Cli.runExit (/github/workspace/.yarn/cache/clipanion-npm-2.0.0-rc.16-b9444aaf89-2.zip/node_modules/clipanion/lib/advanced/Cli.js:83:28)
This issue reproduces on master:
Error: expect(received).toContain(expected) // indexOf
Expected substring: "prestart"
Received string: "start
"
at module.exports (evalmachine.<anonymous>:8:35)
at processTicksAndRejections (internal/process/task_queues.js:94:5)
at async /github/workspace/.yarn/cache/@arcanis-sherlock-npm-1.0.38-d4f5e2dbf3-2.zip/node_modules/@arcanis/sherlock/lib/executeRepro.js:56:13
at async executeInTempDirectory (/github/workspace/.yarn/cache/@arcanis-sherlock-npm-1.0.38-d4f5e2dbf3-2.zip/node_modules/@arcanis/sherlock/lib/executeRepro.js:17:16)
at async Object.executeRepro (/github/workspace/.yarn/cache/@arcanis-sherlock-npm-1.0.38-d4f5e2dbf3-2.zip/node_modules/@arcanis/sherlock/lib/executeRepro.js:24:12)
at async ExecCommand.execute (/github/workspace/.yarn/cache/@arcanis-sherlock-npm-1.0.38-d4f5e2dbf3-2.zip/node_modules/@arcanis/sherlock/lib/commands/exec.js:25:38)
at async ExecCommand.validateAndExecute (/github/workspace/.yarn/cache/clipanion-npm-2.0.0-rc.16-b9444aaf89-2.zip/node_modules/clipanion/lib/advanced/Command.js:161:26)
at async Cli.run (/github/workspace/.yarn/cache/clipanion-npm-2.0.0-rc.16-b9444aaf89-2.zip/node_modules/clipanion/lib/advanced/Cli.js:74:24)
at async Cli.runExit (/github/workspace/.yarn/cache/clipanion-npm-2.0.0-rc.16-b9444aaf89-2.zip/node_modules/clipanion/lib/advanced/Cli.js:83:28)
This issue reproduces on master:
Error: expect(received).toContain(expected) // indexOf
Expected substring: "prestart"
Received string: "start
"
at module.exports (evalmachine.<anonymous>:8:35)
at processTicksAndRejections (internal/process/task_queues.js:94:5)
at async /github/workspace/.yarn/cache/@arcanis-sherlock-npm-1.0.38-d4f5e2dbf3-2.zip/node_modules/@arcanis/sherlock/lib/executeRepro.js:56:13
at async executeInTempDirectory (/github/workspace/.yarn/cache/@arcanis-sherlock-npm-1.0.38-d4f5e2dbf3-2.zip/node_modules/@arcanis/sherlock/lib/executeRepro.js:17:16)
at async Object.executeRepro (/github/workspace/.yarn/cache/@arcanis-sherlock-npm-1.0.38-d4f5e2dbf3-2.zip/node_modules/@arcanis/sherlock/lib/executeRepro.js:24:12)
at async ExecCommand.execute (/github/workspace/.yarn/cache/@arcanis-sherlock-npm-1.0.38-d4f5e2dbf3-2.zip/node_modules/@arcanis/sherlock/lib/commands/exec.js:25:38)
at async ExecCommand.validateAndExecute (/github/workspace/.yarn/cache/clipanion-npm-2.0.0-rc.16-b9444aaf89-2.zip/node_modules/clipanion/lib/advanced/Command.js:161:26)
at async Cli.run (/github/workspace/.yarn/cache/clipanion-npm-2.0.0-rc.16-b9444aaf89-2.zip/node_modules/clipanion/lib/advanced/Cli.js:74:24)
at async Cli.runExit (/github/workspace/.yarn/cache/clipanion-npm-2.0.0-rc.16-b9444aaf89-2.zip/node_modules/clipanion/lib/advanced/Cli.js:83:28)
We should add a note to https://yarnpkg.com/advanced/lifecycle-scripts about this - the gist is that pre and post scripts have been deliberately deprecated.
The reason for this is that they make the code execution implicit rather than explicit (so just looking at the script entry isn't enough to know what's getting executed), and that they cause awkward executions in other circumstances (for example, a script named serve will also cause preserve to be executed). Finally, they had inconsistent timing issues.
Note that this is purely about user scripts - we still support some pre and post scripts as long as they have a clearly defined semantic, such as preinstall / postinstall, or prepack and postpack.
This should also be specified in the migration guide, as it is an incredibly large difference from how things used to work, and will break many user scripts.
Now documented as of #1002