Skip to content

feat: install git repositories that use pnpm #3618

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

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/integration-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,11 @@ jobs:
with:
node-version: ${{matrix.node}}.x

- name: 'Install pnpm'
run: |
npm i -g pnpm
shell: bash

- uses: actions/download-artifact@v2
with:
name: yarn-artifacts
Expand Down
33 changes: 33 additions & 0 deletions .yarn/versions/4d0fa20f.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
releases:
"@yarnpkg/cli": minor
"@yarnpkg/core": minor
"@yarnpkg/plugin-git": minor
"@yarnpkg/plugin-github": minor

declined:
- "@yarnpkg/plugin-compat"
- "@yarnpkg/plugin-constraints"
- "@yarnpkg/plugin-dlx"
- "@yarnpkg/plugin-essentials"
- "@yarnpkg/plugin-exec"
- "@yarnpkg/plugin-file"
- "@yarnpkg/plugin-http"
- "@yarnpkg/plugin-init"
- "@yarnpkg/plugin-interactive-tools"
- "@yarnpkg/plugin-link"
- "@yarnpkg/plugin-nm"
- "@yarnpkg/plugin-npm"
- "@yarnpkg/plugin-npm-cli"
- "@yarnpkg/plugin-pack"
- "@yarnpkg/plugin-patch"
- "@yarnpkg/plugin-pnp"
- "@yarnpkg/plugin-pnpm"
- "@yarnpkg/plugin-stage"
- "@yarnpkg/plugin-typescript"
- "@yarnpkg/plugin-version"
- "@yarnpkg/plugin-workspace-tools"
- "@yarnpkg/builder"
- "@yarnpkg/doctor"
- "@yarnpkg/nm"
- "@yarnpkg/pnpify"
- "@yarnpkg/sdks"
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Yarn now accepts sponsorships! Please give a look at our [OpenCollective](https:
### Installs

- The pnpm linker will now remove the `node_modules/.store` and `node_modules` folders if they are empty.
- Yarn can now install git repositories that use pnpm (workspaces are supported too if pnpm@>=6.x is installed on the system).

### Miscellaneous Features

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const mte = generatePkgDriver({
[`YARN_ENABLE_TIMERS`]: `false`,
[`YARN_ENABLE_PROGRESS_BARS`]: `false`,
// Otherwise the output wouldn't be the same on CI vs non-CI
[`YARN_ENABLE_INLINE_BUILDS`]: `false`,
[`YARN_ENABLE_INLINE_BUILDS`]: `true`,
[`YARN_PREFER_AGGREGATE_CACHE_INFO`]: `false`,
// Otherwise we would more often test the fallback rather than the real logic
[`YARN_PNP_FALLBACK_MODE`]: `none`,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ref: refs/heads/master
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[core]
repositoryformatversion = 0
filemode = true
bare = false
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Unnamed repository; edit this file 'description' to name the repository.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".

exec git update-server-info
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
57d05601ca0e00e0047b2ea8a0f30b0dc760e40b refs/heads/master
57d05601ca0e00e0047b2ea8a0f30b0dc760e40b refs/remotes/origin/HEAD
57d05601ca0e00e0047b2ea8a0f30b0dc760e40b refs/remotes/origin/master
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x5�1� �agNA:+���ۀv�(4-��b|���/�%h���T�d�!L(�6��s���d�%��3�ؿ�̑�<�CD��Y�,��N& 4�R���� �
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
xUͱ�0�ag���$��э�:8��j�
\��ֻV!�wG���W��V��a�x���c�3�PM�,�^ r��e���Eja�O�;eߦ4��s���Η�v��C7�}"�) fEv& �yt@�X�;��/'�6�
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# pack-refs with: peeled fully-peeled sorted
57d05601ca0e00e0047b2ea8a0f30b0dc760e40b refs/remotes/origin/master
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
57d05601ca0e00e0047b2ea8a0f30b0dc760e40b
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ref: refs/heads/master
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[core]
repositoryformatversion = 0
filemode = true
bare = false
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Unnamed repository; edit this file 'description' to name the repository.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".

exec git update-server-info
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
d16bc461ce9bd42690625105cd50ae5936ebce34 refs/heads/master
d16bc461ce9bd42690625105cd50ae5936ebce34 refs/remotes/origin/HEAD
d16bc461ce9bd42690625105cd50ae5936ebce34 refs/remotes/origin/master
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x�A� =�}51<�;�b�6���x��L6V�xlKU*Y*�܇h�@n��|� :��0&���鉍[�F��g�J�&�2sm
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
x��I��V���W��U��6HyQ�1f2f0;̌1��럓��J��k��kQQ�~# p��m�������Ri� }
��0$Ȕ�a��1E�0f���i̛��T�i�>���G���_�;,�Q��GH�'Y�p��؇~���6��l(2���É��S6���:�;7�� ��sq<B�T�b�y����r��O�ʂ�ٿ�F�H�-�B� >{Y�r |6-���ױz](�i7mGg=��{a�6Ө5*��|�5���F~{@���*x�*���7� ��q������F��_.�VtΑm�hk�/J��w��/{�0�Q������]�ﯝ�7"J��(+� ��..yB�P�NG� Y�+r������1�UENoC��ޙ$i-� �"P��gB�d�2���t�-c���,�i4C)?K ����ɷ�I���J1�j�t���g�+q;���뙐&�,ዾ�Fc���6Ju�(;{W�W��t2Q�\ �Vz��ٰ�^��b1����=6"ϵE�� c`/��+M�9�_]ò�s���m�͝q�D�.��>�C^J5);2��l��U?0��*.��p�r��wb�D��׋"N�%3��}�TB $�Χ�̨��<��n�PCth�
�~h~e7�zu[s���;%�u`n�/�r�1,}[����!b�-?�ӗ���D�e�e����yd�N˥��%g��+�uZ�%^�bG d���7{�)�;��F������+;#o*���Hb������ƾ;#��5��~�w=�_�O�
Expand Down
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# pack-refs with: peeled fully-peeled sorted
d16bc461ce9bd42690625105cd50ae5936ebce34 refs/remotes/origin/master
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
d16bc461ce9bd42690625105cd50ae5936ebce34
Original file line number Diff line number Diff line change
Expand Up @@ -185,5 +185,48 @@ describe(`Protocols`, () => {
),
45000,
);

test(
`it should use pnpm to setup pnpm repositories`,
makeTemporaryEnv(
{
dependencies: {
[`pnpm-project`]: startPackageServer().then(url => `${url}/repositories/pnpm-project.git`),
},
},
async ({path, run, source}) => {
await run(`install`);

await expect(source(`require('pnpm-project')`)).resolves.toMatch(/\bpnpm\/[0-9]+/);
},
),
45000,
);

test(
`it should support installing specific workspaces from pnpm repositories`,
makeTemporaryEnv(
{
dependencies: {
[`pkg-a`]: startPackageServer().then(url => `${url}/repositories/pnpm-workspaces.git#workspace=pkg-a`),
[`pkg-b`]: startPackageServer().then(url => `${url}/repositories/pnpm-workspaces.git#workspace=pkg-b`),
},
},
async ({path, run, source}) => {
await run(`install`);

await expect(source(`require('pkg-a/package.json')`)).resolves.toMatchObject({
name: `pkg-a`,
version: `1.0.0`,
});

await expect(source(`require('pkg-b/package.json')`)).resolves.toMatchObject({
name: `pkg-b`,
version: `1.0.0`,
});
},
),
45000,
);
});
});
2 changes: 1 addition & 1 deletion packages/gatsby/content/features/protocols.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ [email protected]:yarnpkg/berry.git#head=master

- Yarn will use either of Yarn, npm, or pnpm to pack the repository, based on the repository style (ie we'll use Yarn if there's a `yarn.lock`, npm if there's a `package-lock.json`, or pnpm if there's a `pnpm-lock.yaml`)

- Workspaces can be cloned as long as the remote repository uses Yarn or npm (npm@>=7.x has to be installed on the system); we can't support pnpm because it doesn't have equivalent for the [`workspace` command](/cli/workspace). Just reference the workspace by name in your range (you can optionally enforce the tag as well):
- Workspaces can be cloned as long as the remote repository uses Yarn, npm (npm@>=7.x has to be installed on the system), or pnpm (pnpm@>=6.x has to be installed on the system). Just reference the workspace by name in your range (you can optionally enforce the tag as well):

```
[email protected]:yarnpkg/berry.git#workspace=@yarnpkg/shell&tag=@yarnpkg/shell/2.1.0
Expand Down
35 changes: 34 additions & 1 deletion packages/yarnpkg-core/sources/scriptUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,11 +348,44 @@ export async function prepareExternalProject(cwd: PortablePath, outputPath: Port

return 0;
}],

[PackageManager.Pnpm, async () => {
const install = await execUtils.pipevp(`pnpm`, [`install`], {cwd, env, stdin, stdout, stderr, end: execUtils.EndStrategy.ErrorCode});
if (install.code !== 0)
return install.code;

const packStream = new PassThrough();
const packPromise = miscUtils.bufferStream(packStream);

packStream.pipe(stdout);

// It seems that pnpm doesn't support specifying the pack output path,
// so we have to extract the stdout on top of forking it to the logs.

// - `pnpm pack` doesn't support the `--filter` flag so we have to use `pnpm exec`
// - We have to use the `--pack-destination` flag because otherwise pnpm generates the tarball inside the workspace cwd
Comment on lines +362 to +366
Copy link
Member

@merceyz merceyz Oct 22, 2021

Choose a reason for hiding this comment

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

Could we point --pack-destination to an empty temp folder and then just read its contents thus avoiding the parsing of stdout?

Copy link
Member Author

Choose a reason for hiding this comment

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

We could, but after a bit more research it looks like only pnpm@>=6.x supports --pack-destination. Because of this, I'd prefer to only pass the --pack-destination option when packing a workspace so that pnpm 5 can be used to install regular packages too.

// - Only pnpm@>=6.x supports the `--pack-destination` flag (and previous versions throw an error)
const packArgs = workspace !== null
? [`--filter`, workspace, `exec`, `pnpm`, `pack`, `--pack-destination`, npath.fromPortablePath(cwd)]
: [`pack`];

const pack = await execUtils.pipevp(`pnpm`, packArgs, {cwd, env, stdin, stdout: packStream, stderr});
Copy link
Member

@merceyz merceyz Apr 27, 2022

Choose a reason for hiding this comment

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

Just to make sure we don't forget; this needs to apply the same fix as #4403

if (pack.code !== 0)
return pack.code;

const packOutput = (await packPromise).toString().trim().replace(/^.*\n/s, ``);
const packTarget = ppath.resolve(cwd, npath.toPortablePath(packOutput));

// Only then can we move the pack to its rightful location
await xfs.renamePromise(packTarget, outputPath);

return 0;
}],
]);

const workflow = workflows.get(effectivePackageManager);
if (typeof workflow === `undefined`)
throw new Error(`Assertion failed: Unsupported workflow`);
throw new Error(`Assertion failed: Unsupported workflow: "${effectivePackageManager}"`);

const code = await workflow();
if (code === 0 || typeof code === `undefined`)
Expand Down