Skip to content

Commit

Permalink
MRL enforces tilde not caret for internal deps (#464)
Browse files Browse the repository at this point in the history
* MRL enforces tilde not caret for internal deps

* Cleanup
  • Loading branch information
ericanderson authored Jul 15, 2024
1 parent 343de0a commit 577cbd6
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 32 deletions.
59 changes: 59 additions & 0 deletions .monorepolint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import {
alphabeticalDependencies,
alphabeticalScripts,
createRuleFactory,
fileContents,
packageEntry,
packageOrder,
Expand Down Expand Up @@ -75,6 +76,61 @@ const esmOnlyPackages = [
// "@osdk/examples.*", but they have their own config cause they are nonstandard
];

/**
* We don't want to allow `workspace:^` in our dependencies because our current release branch
* strategy only allows for patch changes in the release branch and minors elsewhere.
*
* If we were to allow `workspace:^`, then the follow scenario causes issues:
* - Suppose we have a Foo and a Bar package and Bar depends on Foo.
* - at T0 we cut a release/1.1.x branch and ship [email protected], [email protected]
* - at T1 we cut a release 1.2.x branch and ship [email protected]
*
* If we have `workspace:^` in our deps, a user that already has `[email protected]` in their package.json
* could update their dependencies without updating Bar (say via pnpm update) and Bar's dependency
* on Foo @ `^1.1.0` would be satisfied by the shipped `[email protected]`.
*
* Using `workspace:~` prevents this as `~` can only resolve patch changes.
*/
const disallowWorkspaceCaret = createRuleFactory({
name: "disallowWorkspaceCaret",
check: async (context) => {
const packageJson = context.getPackageJson();
const packageJsonPath = context.getPackageJsonPath();

for (const d of ["dependencies", "devDependencies", "peerDependencies"]) {
const deps = packageJson[d] ?? {};

for (const [dep, version] of Object.entries(deps)) {
if (version === "workspace:^") {
const message = `'workspace:^' not allowed (${d}['${dep}']).`;
context.addError({
message,
longMessage: `${message} Did you mean 'workspace:~'?`,
file: context.getPackageJsonPath(),
fixer: () => {
// always refetch in fixer since another fixer may have already changed the file
let packageJson = context.getPackageJson();
if (packageJson[d]?.[dep] === "workspace:^") {
packageJson[d] = Object.assign(
{},
packageJson[d],
{ [dep]: "workspace:~" },
);

context.host.writeJson(
context.getPackageJsonPath(),
packageJson,
);
}
},
});
}
}
}
},
validateOptions: () => {}, // no options right now
});

const cache = new Map();

/**
Expand Down Expand Up @@ -157,6 +213,7 @@ function getTsconfigOptions(baseTsconfigPath, opts) {
* skipTsconfigReferences?: boolean
* singlePackageName?: string
* }} options
* @returns {import("@monorepolint/config").RuleModule[]}
*/
function standardPackageRules(shared, options) {
if (options.esmOnly && options.legacy) {
Expand All @@ -171,6 +228,8 @@ function standardPackageRules(shared, options) {
.slice(0, -1); // drop trailing slash

return [
disallowWorkspaceCaret({ ...shared }),

standardTsconfig({
...shared,

Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
"@babel/preset-typescript": "^7.24.1",
"@changesets/changelog-git": "^0.2.0",
"@changesets/cli": "^2.27.3",
"@monorepolint/cli": "0.5.0-alpha.137",
"@monorepolint/config": "0.5.0-alpha.137",
"@monorepolint/core": "0.5.0-alpha.137",
"@monorepolint/rules": "0.5.0-alpha.137",
"@monorepolint/cli": "0.5.0-beta.10",
"@monorepolint/config": "0.5.0-beta.10",
"@monorepolint/core": "0.5.0-beta.10",
"@monorepolint/rules": "0.5.0-beta.10",
"@types/lint-staged": "^13.3.0",
"@typescript-eslint/parser": "^7.16.0",
"babel-plugin-dev-expression": "^0.2.3",
Expand Down
2 changes: 1 addition & 1 deletion packages/client.api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"devDependencies": {
"@microsoft/api-documenter": "^7.25.3",
"@microsoft/api-extractor": "^7.47.0",
"@osdk/api": "workspace:^",
"@osdk/api": "workspace:~",
"@osdk/api-extractor": "workspace:~",
"@osdk/internal.foundry": "workspace:~",
"@types/geojson": "^7946.0.14",
Expand Down
54 changes: 27 additions & 27 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 577cbd6

Please sign in to comment.