Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add experimental use-inline-specifiers-lockfile-format #5091

Merged
merged 3 commits into from Jul 27, 2022

Conversation

gluxon
Copy link
Member

@gluxon gluxon commented Jul 25, 2022

Fixes #4725.

This experimental lockfile format reduces merge conflicts when dependencies on adjacent lines are updated in different commits. See linked issue for an in-depth description of the formatting changes in this PR and the motivation.

Toy Example

Suppose the following package.json and (partial) pnpm-lock.yaml

// packages/example/package.json
{
  "name": "example"
  "dependencies": {
    "bar": "^1.0.0",
    "baz": "^1.0.0",
    "qux": "^1.0.0"
  }
}
# pnpm-lock.yaml (partial)
importers:

  packages/example:
    specifiers:
      bar: ^1.0.0
      baz: ^1.0.0
      qux: ^1.0.0
    dependencies:
      bar: 1.0.0
      baz: 1.0.0
      qux: 1.0.0

If the following package.json changes were made in different commits, this would cause a merge conflict in pnpm-lock.yaml.

Commit A (Upgrades bar)
 {
   "name": "example"
   "dependencies": {
-    "bar": "^1.0.0",
+    "bar": "^2.0.0",
     "baz": "^1.0.0",
     "qux": "^1.0.0"
   }
 }
Commit B (Upgrades baz)
 {
   "name": "example"
   "dependencies": {
     "bar": "^1.0.0",
-    "baz": "^1.0.0",
+    "baz": "^2.0.0",
     "qux": "^1.0.0"
   }
}

This is because pnpm-lock.yaml serializes these dependency resolutions next to each other. The diffs are "touching".

 importers:
   specifiers:
-    bar: ^1.0.0 # Commit A
+    bar: ^2.0.0 # Commit A
-    baz: ^1.0.0 # Commit B
+    baz: ^2.0.0 # Commit B
     qux: ^1.0.0
   dependencies:
-    bar: 1.0.0 # Commit A
+    bar: 2.0.0 # Commit A
-    baz: 1.0.0 # Commit B
+    baz: 2.0.0 # Commit B
     qux: 1.0.0

With use-inline-specifiers-lockfile-format set, the changes are no longer happening on adjacent lines. In the example below, the diff changes multiple lines, but the grouped line changes are from different commits.

 importers:
   dependencies:
     bar:
-      specifier: ^1.0.0 # Commit A
+      specifier: ^2.0.0 # Commit A
-      version: 1.0.0 # Commit A
+      version: 2.0.0 # Commit A
     baz:
-      specifier: ^1.0.0 # Commit B
+      specifier: ^2.0.0 # Commit B
-      version: 1.0.0 # Commit B
+      version: 2.0.0 # Commit B
     qux:
       specifier: ^1.0.0
       version: 1.0.0

Astute observers may notice that the package.json file in this example would probably merge conflict. One option to prevent that would be pnpm/rfcs#1.

Real World Example

Here's pnpm-lock.yaml on commit eb2426c with use-inline-specifiers-lockfile-format = true set in .npmrc.

Lockfile itself: https://gist.github.com/gluxon/7bb61624023bbdbdff3da4f917eccd0f
Diff of lockfile: https://gist.github.com/gluxon/a64f0bdc74ca9d99c1fc0723ed6f74fb

Existing Problems

The specifiers block still appears in the serialized pnpm-lock.yaml due to the normalizeLockfile function running after the converters.

specifiers: importer.specifiers ?? {},

This could be addressed by making normalizeLockfile aware of the feature flag, but that feels architecturally strange. I think this is a non-issue since this is a feature-flagged change, but wanted to call it out in case that's incorrect.

@gluxon gluxon force-pushed the experiment-lockfile-project-deps-by-name branch from 0dbf792 to e81b281 Compare July 25, 2022 04:19
@@ -157,6 +157,9 @@ export interface Config {
changedFilesIgnorePattern?: string[]
rootProjectManifest?: ProjectManifest
userConfig: Record<string, string>

// feature flags for experimental testing
useInlineSpecifiersLockfileFormat?: boolean // For https://github.com/pnpm/pnpm/issues/4725
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea behind the naming here was that "specifiers" are now "inlined" next to their resolved version instead of in their own block.

I think this naming is awful, but can't think of any better ones at the moment.

// Check for one of the dep type fields that were moved to the root instead.
const someDepFieldIsOnRoot = DEPENDENCIES_FIELDS.some(depType => lockfileFile[depType] != null)

if (specifiersFieldIsOnRoot || someDepFieldIsOnRoot) {
Copy link
Member Author

@gluxon gluxon Jul 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the shared lockfile format is used, specifiers, dependencies, devDependencies, and optionalDependencies may appear as keys on the root of the lockfile. At the moment this logic only checks for the specifiers key to guess whether the lockfile was serialized using the shared lockfile format.

After the changes in this PR, we unfortunately can't rely on the presence of specifiers on the root to detect the shared lockfile format since the "inline specifiers" format removes specifiers. We're now checking for one of the other fields. This patch is only change not gated behind the feature flag. Assuming the logic is correct, it should not change runtime behavior when the flag is off though.

If that's not okay, I can revert the change to this function and have convertToInlineSpecifiersFormat write out an empty specifiers: {} block. The thinking was that we'll have to remove the check for specifiers here if we end up adopting the changes in this feature flag, so I might as well commit this planned change and have it up for review.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't you just check the existence of "importers" field instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that seems much better. Thanks for the suggestion.

@@ -0,0 +1,8 @@
---
"@pnpm/config": minor
Copy link
Member Author

@gluxon gluxon Jul 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is minor the right semver change for a flagged feature? This didn't feel like a patch, but I could be wrong.

@gluxon
Copy link
Member Author

gluxon commented Jul 25, 2022

Is there potentially a bad cache on the windows-latest / Node.js 14.6 check? The check passes on a forked repo for the same commit: https://github.com/gluxon/pnpm/actions/runs/2729853189

It looks like TypeScript is attempting to compile make-dedicated-lockfile before compiling lockfile-file? tsc --build relies on timestamps. My guess is there might be something weird going on with preserving timestamps on Windows with @actions/cache.

@gluxon gluxon marked this pull request as ready for review July 25, 2022 04:48
@gluxon gluxon requested a review from zkochan as a code owner July 25, 2022 04:48
const { specifiers } = projectSnapshot
return {
dependencies: projectSnapshot.dependencies != null
? convertResolvedDependenciesToInlineSpecifiersFormat(projectSnapshot.dependencies, { specifiers })
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it will be shorter if you add specifiers as the first argument and then make a new function. like

const _convertResolvedDependenciesToInlineSpecifiersFormat = convertResolvedDependenciesToInlineSpecifiersFormat.bind(null, { specifiers })

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or you may use a loop

for (const depField of DEPENDENCIES_FIELDS) {
  newImporter[depField] = projectSnapshot[depField]......
}

Copy link
Member Author

@gluxon gluxon Jul 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree this could have been much shorter. How does the functional approach that was just pushed look?

const convertBlock = (block?: ResolvedDependencies) =>
block != null
? convertResolvedDependenciesToInlineSpecifiersFormat(block, { specifiers })
: block
return {
...rest,
dependencies: convertBlock(projectSnapshot.dependencies),
optionalDependencies: convertBlock(projectSnapshot.optionalDependencies),
devDependencies: convertBlock(projectSnapshot.devDependencies),
}

// Check for one of the dep type fields that were moved to the root instead.
const someDepFieldIsOnRoot = DEPENDENCIES_FIELDS.some(depType => lockfileFile[depType] != null)

if (specifiersFieldIsOnRoot || someDepFieldIsOnRoot) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't you just check the existence of "importers" field instead?

packages/lockfile-file/src/sortLockfileKeys.ts Outdated Show resolved Hide resolved
@gluxon
Copy link
Member Author

gluxon commented Jul 25, 2022

Thanks for the suggestions! I'm away from my keyboard for a few more hours, but will update the PR once I get back in ~3 hours.

gluxon added a commit to gluxon/pnpm that referenced this pull request Jul 26, 2022
The `convertFromLockfileFileMutable` function reverts changes from
`normalizeLockfile` when not using the shared lockfile format.

  - The non-shared lockfile format puts fields like `specifiers`,
    `dependencies`, `devDependencies`, `optionalDependencies`, and
    `dependenciesMeta` on the root of the lockfile. This is typically
    the case for a repo not using pnpm workspaces.
  - The shared lockfile format puts these under a `importers` block
    scoped by a path.

The `use-inline-specifiers-lockfile-format` feature flag removes the
`specifiers` block in favor of putting each specifier next to the
resolved version within each `dependencies`, `devDependencies`, etc
block.

This means the `convertFromLockfileFileMutable` function can no longer
check for `specifiers` to detect the whether the "shared" format is
used. @zkochan suggested checking for `importers` instead, which should
have the same effect.
pnpm#5091 (comment)
gluxon added a commit to gluxon/pnpm that referenced this pull request Jul 26, 2022
The `convertFromLockfileFileMutable` function reverts changes from
`normalizeLockfile` when not using the shared lockfile format.

  - The non-shared lockfile format puts fields like `specifiers`,
    `dependencies`, `devDependencies`, `optionalDependencies`, and
    `dependenciesMeta` on the root of the lockfile. This is typically
    the case for a repo not using pnpm workspaces.
  - The shared lockfile format puts these under a `importers` block
    scoped by a path.

The `use-inline-specifiers-lockfile-format` feature flag removes the
`specifiers` block in favor of putting each specifier next to the
resolved version within each `dependencies`, `devDependencies`, etc
block.

This means the `convertFromLockfileFileMutable` function can no longer
check for `specifiers` to detect the whether the "shared" format is
used. @zkochan suggested checking for `importers` instead, which should
have the same effect.
pnpm#5091 (comment)
gluxon added a commit to gluxon/pnpm that referenced this pull request Jul 26, 2022
The `convertFromLockfileFileMutable` function reverts changes from
`normalizeLockfile` when not using the shared lockfile format.

  - The non-shared lockfile format puts fields like `specifiers`,
    `dependencies`, `devDependencies`, `optionalDependencies`, and
    `dependenciesMeta` on the root of the lockfile. This is typically
    the case for a repo not using pnpm workspaces.
  - The shared lockfile format puts these under a `importers` block
    scoped by a path.

The `use-inline-specifiers-lockfile-format` feature flag removes the
`specifiers` block in favor of putting each specifier next to the
resolved version within each `dependencies`, `devDependencies`, etc
block.

This means the `convertFromLockfileFileMutable` function can no longer
check for `specifiers` to detect the whether the "shared" format is
used. @zkochan suggested checking for `importers` instead, which should
have the same effect.
pnpm#5091 (comment)
gluxon added a commit to gluxon/pnpm that referenced this pull request Jul 26, 2022
The `convertFromLockfileFileMutable` function reverts changes from
`normalizeLockfile` when not using the shared lockfile format.

  - The non-shared lockfile format puts fields like `specifiers`,
    `dependencies`, `devDependencies`, `optionalDependencies`, and
    `dependenciesMeta` on the root of the lockfile. This is typically
    the case for a repo not using pnpm workspaces.
  - The shared lockfile format puts these under a `importers` block
    scoped by a path.

The `use-inline-specifiers-lockfile-format` feature flag removes the
`specifiers` block in favor of putting each specifier next to the
resolved version within each `dependencies`, `devDependencies`, etc
block.

This means the `convertFromLockfileFileMutable` function can no longer
check for `specifiers` to detect the whether the "shared" format is
used. @zkochan suggested checking for `importers` instead, which should
have the same effect.
pnpm#5091 (comment)
gluxon added a commit to gluxon/pnpm that referenced this pull request Jul 26, 2022
The `convertFromLockfileFileMutable` function reverts changes from
`normalizeLockfile` when not using the shared lockfile format.

  - The non-shared lockfile format puts fields like `specifiers`,
    `dependencies`, `devDependencies`, `optionalDependencies`, and
    `dependenciesMeta` on the root of the lockfile. This is typically
    the case for a repo not using pnpm workspaces.
  - The shared lockfile format puts these under a `importers` block
    scoped by a path.

The `use-inline-specifiers-lockfile-format` feature flag removes the
`specifiers` block in favor of putting each specifier next to the
resolved version within each `dependencies`, `devDependencies`, etc
block.

This means the `convertFromLockfileFileMutable` function can no longer
check for `specifiers` to detect the whether the "shared" format is
used. @zkochan suggested checking for `importers` instead, which should
have the same effect.
pnpm#5091 (comment)
gluxon added a commit to gluxon/pnpm that referenced this pull request Jul 26, 2022
The `convertFromLockfileFileMutable` function reverts changes from
`normalizeLockfile` when not using the shared lockfile format.

  - The non-shared lockfile format puts fields like `specifiers`,
    `dependencies`, `devDependencies`, `optionalDependencies`, and
    `dependenciesMeta` on the root of the lockfile. This is typically
    the case for a repo not using pnpm workspaces.
  - The shared lockfile format puts these under a `importers` block
    scoped by a path.

The `use-inline-specifiers-lockfile-format` feature flag removes the
`specifiers` block in favor of putting each specifier next to the
resolved version within each `dependencies`, `devDependencies`, etc
block.

This means the `convertFromLockfileFileMutable` function can no longer
check for `specifiers` to detect the whether the "shared" format is
used. @zkochan suggested checking for `importers` instead, which should
have the same effect.
pnpm#5091 (comment)
The `convertFromLockfileFileMutable` function reverts changes from
`normalizeLockfile` when not using the shared lockfile format.

  - The non-shared lockfile format puts fields like `specifiers`,
    `dependencies`, `devDependencies`, `optionalDependencies`, and
    `dependenciesMeta` on the root of the lockfile. This is typically
    the case for a repo not using pnpm workspaces.
  - The shared lockfile format puts these under a `importers` block
    scoped by a path.

The `use-inline-specifiers-lockfile-format` feature flag removes the
`specifiers` block in favor of putting each specifier next to the
resolved version within each `dependencies`, `devDependencies`, etc
block.

This means the `convertFromLockfileFileMutable` function can no longer
check for `specifiers` to detect the whether the "shared" format is
used. @zkochan suggested checking for `importers` instead, which should
have the same effect.
pnpm#5091 (comment)
@gluxon gluxon force-pushed the experiment-lockfile-project-deps-by-name branch from e81b281 to 3cd2784 Compare July 26, 2022 03:48
@gluxon
Copy link
Member Author

gluxon commented Jul 26, 2022

Latest force push should:

  • Address initial feedback.
  • I added a bit more to the changelog cautioning pnpm min version constraints in case anyone discovers this feature and decides to use it.
  • I caught that convertResolvedDependenciesToInlineSpecifiersFormat could also be simplified with mapValues and rewrote that.

@zkochan zkochan merged commit 4fa1091 into pnpm:main Jul 27, 2022
@zkochan
Copy link
Member

zkochan commented Jul 27, 2022

I have tried this setting.

Now the lockfile has this:

  packages/audit:
    specifiers: {}
    dependencies:
      '@pnpm/error':
        specifier: workspace:*
        version: link:../error

I guess the specifiers field shouldn't be there

@zkochan zkochan added this to the v7.7 milestone Jul 27, 2022
@gluxon gluxon deleted the experiment-lockfile-project-deps-by-name branch July 27, 2022 16:52
@gluxon
Copy link
Member Author

gluxon commented Jul 27, 2022

Thanks for testing @zkochan. I mentioned this briefly under "Existing Problems" in the PR description. Would it make sense to just pass a useInlineSpecifiersFormat flag into normalizeLockfile?

Was originally worried about the change leaking out of the converter functions, but making normalizeLockfile aware of this flag is probably okay.

@zkochan
Copy link
Member

zkochan commented Jul 27, 2022

Or alternatively you can duplicate the normalise function for the new format

@zkochan
Copy link
Member

zkochan commented Jul 28, 2022

I am doing it

#5110

@gluxon
Copy link
Member Author

gluxon commented Jul 28, 2022

Thanks!

kodiakhq bot pushed a commit to mheob/config that referenced this pull request Aug 13, 2022
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [pnpm](https://pnpm.io) ([source](https://togithub.com/pnpm/pnpm)) | [`7.6.0` -> `7.9.0`](https://renovatebot.com/diffs/npm/pnpm/7.6.0/7.9.0) | [![age](https://badges.renovateapi.com/packages/npm/pnpm/7.9.0/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/npm/pnpm/7.9.0/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/npm/pnpm/7.9.0/compatibility-slim/7.6.0)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/npm/pnpm/7.9.0/confidence-slim/7.6.0)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>pnpm/pnpm</summary>

### [`v7.9.0`](https://togithub.com/pnpm/pnpm/releases/tag/v7.9.0)

[Compare Source](https://togithub.com/pnpm/pnpm/compare/v7.8.0...v7.9.0)

#### Minor Changes

-   When `ignore-dep-scripts` is `true`, ignore scripts of dependencies but run the scripts of the project.
-   When `ignore-compatibility-db` is set to `true`, the [compatibility database](https://togithub.com/yarnpkg/berry/blob/master/packages/yarnpkg-extensions/sources/index.ts) will not be used to patch dependencies [#&#8203;5132](https://togithub.com/pnpm/pnpm/issues/5132).
-   Print the versions of packages in peer dependency warnings and errors.
-   Support a new hook for passing a custom package importer to the store controller.

#### Patch Changes

-   Don't print the same deprecation warning multiple times.
-   On POSIX `pnpm setup` should suggest users to source the config instead of restarting the terminal.
-   Installing a package with `bin` that points to an `.exe` file on Windows [#&#8203;5159](https://togithub.com/pnpm/pnpm/issues/5159).
-   Fix bug where the package manifest was not resolved if `verify-store-integrity` is set to `false`.
-   Fix sorting of keys in lockfile to make it more deterministic and prevent unnecessary churn in the lockfile [#&#8203;5151](https://togithub.com/pnpm/pnpm/pull/5151).
-   Don't create a separate bundle for pnpx.

#### Our Gold Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle">
        <a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/bit.svg" width="80"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://nhost.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/nhost.svg" width="180"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://novu.co/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/novu.svg" width="180"></a>
      </td>
    </tr>
  </tbody>
</table>
#### Our Silver Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle">
        <a href="https://prisma.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/prisma.svg" width="180"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://leniolabs.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/leniolabs.jpg" width="80"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://vercel.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/vercel.svg" width="180"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://www.takeshape.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/takeshape.svg" width="280"></a>
      </td>
    </tr>
  </tbody>
</table>

### [`v7.8.0`](https://togithub.com/pnpm/pnpm/releases/tag/v7.8.0)

[Compare Source](https://togithub.com/pnpm/pnpm/compare/v7.7.1...v7.8.0)

#### Minor Changes

-   When `publishConfig.directory` is set, only symlink it to other workspace projects if `publishConfig.linkDirectory` is set to `true`. Otherwise, only use it for publishing [#&#8203;5115](https://togithub.com/pnpm/pnpm/issues/5115).

#### Patch Changes

-   Don't incorrectly identify a lockfile out-of-date when the package has a publishConfig.directory field [#&#8203;5124](https://togithub.com/pnpm/pnpm/issues/5124).
-   Don't crash when a config file contains a setting with an env variable that doesn't exist [#&#8203;5093](https://togithub.com/pnpm/pnpm/issues/5093).

#### Our Gold Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle">
        <a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/bit.svg" width="80"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://nhost.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/nhost.svg" width="180"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://novu.co/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/novu.svg" width="180"></a>
      </td>
    </tr>
  </tbody>
</table>
#### Our Silver Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle">
        <a href="https://prisma.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/prisma.svg" width="180"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://leniolabs.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/leniolabs.jpg" width="80"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://vercel.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/vercel.svg" width="180"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://www.takeshape.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/takeshape.svg" width="280"></a>
      </td>
    </tr>
  </tbody>
</table>
#### What's Changed
* fix: don't incorrectly identify a lockfile out-of-date by @&#8203;zkochan in pnpm/pnpm#5126
* feat: publishConfig.linkDirectory by @&#8203;zkochan in pnpm/pnpm#5125
* fix: don't crash on a .npmrc with missing env var by @&#8203;zkochan in pnpm/pnpm#5127
* chore: fix typo by @&#8203;LuciNyan in pnpm/pnpm#5128
#### New Contributors
* @&#8203;LuciNyan made their first contribution in pnpm/pnpm#5128

**Full Changelog**: pnpm/pnpm@v7.7.1...v7.8.0

### [`v7.7.1`](https://togithub.com/pnpm/pnpm/releases/tag/v7.7.1)

[Compare Source](https://togithub.com/pnpm/pnpm/compare/v7.7.0...v7.7.1)

#### Patch Changes

-   pnpm should not consider a lockfile out-of-date if `auto-install-peers` is set to `true` and the peer dependency is in `devDependencies` or `optionalDependencies` [#&#8203;5080](https://togithub.com/pnpm/pnpm/issues/5080).
-   Don't incorrectly consider a lockfile out-of-date when `workspace:^` or `workspace:~` version specs are used in a workspace.

#### Our Gold Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle">
        <a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/bit.svg" width="80"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://nhost.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/nhost.svg" width="180"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://novu.co/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/novu.svg" width="180"></a>
      </td>
    </tr>
  </tbody>
</table>
#### Our Silver Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle">
        <a href="https://prisma.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/prisma.svg" width="180"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://leniolabs.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/leniolabs.jpg" width="80"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://vercel.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/vercel.svg" width="180"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://www.takeshape.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/takeshape.svg" width="280"></a>
      </td>
    </tr>
  </tbody>
</table>
#### What's Changed
* fix: frozen install in a project with peer deps and `auto-install-peers=true` by @&#8203;zkochan in pnpm/pnpm#5120
* fix: don't incorrectly consider a lockfile to be out-of-date by @&#8203;zkochan in pnpm/pnpm#5121

**Full Changelog**: pnpm/pnpm@v7.7.0...v7.7.1

### [`v7.7.0`](https://togithub.com/pnpm/pnpm/releases/tag/v7.7.0)

[Compare Source](https://togithub.com/pnpm/pnpm/compare/v7.6.0...v7.7.0)

#### Minor Changes

-   Add experimental lockfile format that should merge conflict less in the `importers` section. Enabled by setting the `use-inline-specifiers-lockfile-format = true` feature flag in `.npmrc`.

    If this feature flag is committed to a repo, we recommend setting the minimum allowed version of pnpm to this release in the `package.json` `engines` field. Once this is set, older pnpm versions will throw on invalid lockfile versions.

-   Add `publishDirectory` field to the lockfile and relink the project when it changes.

-   `verify-store-integrity=false` makes pnpm skip checking the integrities of files in the global content-addressable store.

-   Allow to set `only-built-dependencies[]` through `.npmrc`.

#### Patch Changes

-   It should be possible to publish a package with local dependencies from a custom publish directory (set via `publishConfig.directory`) [#&#8203;3901](https://togithub.com/pnpm/pnpm/issues/3901#issuecomment-1194156886).
-   `pnpm deploy` should inject local dependencies of all types (dependencies, optionalDependencies, devDependencies) [#&#8203;5078](https://togithub.com/pnpm/pnpm/issues/5078).
-   When a project in a workspace has a `publishConfig.directory` set, dependent projects should install the project from that directory [#&#8203;3901](https://togithub.com/pnpm/pnpm/issues/3901)
-   **pnpm deploy**: accept absolute paths and use cwd instead of workspaceDir for deploy target directory [#&#8203;4980](https://togithub.com/pnpm/pnpm/issues/4980).
-   **pnpm setup** should update `.zshrc` in the right directory when a `$ZDOTDIR` is set.

#### Our Gold Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle">
        <a href="https://bit.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/bit.svg" width="80"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://nhost.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/nhost.svg" width="180"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://novu.co/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/novu.svg" width="180"></a>
      </td>
    </tr>
  </tbody>
</table>
#### Our Silver Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle">
        <a href="https://prisma.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/prisma.svg" width="180"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://leniolabs.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/leniolabs.jpg" width="80"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://vercel.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/vercel.svg" width="180"></a>
      </td>
      <td align="center" valign="middle">
        <a href="https://www.takeshape.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://raw.githubusercontent.com/pnpm/pnpm.github.io/main/static/img/users/takeshape.svg" width="280"></a>
      </td>
    </tr>
  </tbody>
</table>
#### What's Changed
* fix(deploy): inject all types of deps by @&#8203;zkochan in pnpm/pnpm#5084
* fix(make-dedicated-lockfile): prepublishOnly script is automatically … by @&#8203;zkochan in pnpm/pnpm#5083
* fix: symlink a workspace pkg correctly, when it has a custom publish dir by @&#8203;zkochan in pnpm/pnpm#5089
* feat: add experimental use-inline-specifiers-lockfile-format  by @&#8203;gluxon in pnpm/pnpm#5091
* fix: plugin-commands-deploy use path resolve on deploy target dir by @&#8203;AWare in pnpm/pnpm#5026
* fix: relink the project when its publish directory changes by @&#8203;zkochan in pnpm/pnpm#5109
* fix: don't include specifiers field in new experimental lockfile format by @&#8203;zkochan in pnpm/pnpm#5110
* feat: verify-store-integrity by @&#8203;zkochan in pnpm/pnpm#5112
#### New Contributors
* @&#8203;AWare made their first contribution in pnpm/pnpm#5026

**Full Changelog**: pnpm/pnpm@v7.6.0...v7.7.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "before 5am on Wednesday" in timezone Europe/Berlin, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] If you want to rebase/retry this PR, click this checkbox.

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://app.renovatebot.com/dashboard#github/mheob/config).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants