From 58ae45ee73426f04ec58dc3d3f483e278e43ffa9 Mon Sep 17 00:00:00 2001 From: John Gozde Date: Thu, 19 Oct 2017 17:54:57 -0600 Subject: [PATCH] fix(linker): use lockfileFolder when creating bin links (#4730) **Summary** Fixes #4706, fixes #4359, refs #4513. `this.config.cwd` was being used as the root for bin link paths, rather than `this.config.lockfileFolder`. **Test plan** - Added tests for `add` and `remove` commands (#4706) - Added test for `install` command (#4359) --- __tests__/commands/add.js | 29 ++++++ .../commands/install/workspaces-install.js | 33 ++++++- __tests__/commands/remove.js | 28 ++++++ .../install/workspaces-install-bin/file.js | 0 .../workspaces-install-bin/package.json | 12 +++ .../packages/workspace-1/bin.js | 0 .../packages/workspace-1/package.json | 8 ++ .../packages/workspace-2/package.json | 10 ++ .../install/workspaces-install-bin/yarn.lock | 90 ++++++++++++++++++ .../abbrev/-/abbrev-1.1.1.tgz.bin | Bin 0 -> 2998 bytes .../rimraf/-/rimraf-2.6.2.tgz.bin | Bin 0 -> 6231 bytes src/package-linker.js | 2 +- 12 files changed, 209 insertions(+), 3 deletions(-) create mode 100644 __tests__/fixtures/install/workspaces-install-bin/file.js create mode 100644 __tests__/fixtures/install/workspaces-install-bin/package.json create mode 100755 __tests__/fixtures/install/workspaces-install-bin/packages/workspace-1/bin.js create mode 100644 __tests__/fixtures/install/workspaces-install-bin/packages/workspace-1/package.json create mode 100644 __tests__/fixtures/install/workspaces-install-bin/packages/workspace-2/package.json create mode 100644 __tests__/fixtures/install/workspaces-install-bin/yarn.lock create mode 100644 __tests__/fixtures/request-cache/GET/registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz.bin create mode 100644 __tests__/fixtures/request-cache/GET/registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz.bin diff --git a/__tests__/commands/add.js b/__tests__/commands/add.js index 2182bad4c8..26890aec45 100644 --- a/__tests__/commands/add.js +++ b/__tests__/commands/add.js @@ -957,3 +957,32 @@ test.concurrent('installing with --pure-lockfile and then adding should keep bui expect(await fs.exists(path.join(config.cwd, 'node_modules', 'package-a', 'temp.txt'))).toBe(true); }); }); + +test.concurrent('preserves unaffected bin links after adding to workspace package', async () => { + await runInstall({binLinks: true}, 'workspaces-install-bin', async (config): Promise => { + const reporter = new ConsoleReporter({}); + + expect(await fs.exists(`${config.cwd}/node_modules/.bin/rimraf`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/node_modules/.bin/touch`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/node_modules/.bin/workspace-1`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/packages/workspace-2/node_modules/.bin/rimraf`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/packages/workspace-2/node_modules/.bin/workspace-1`)).toEqual(true); + + // add package + const childConfig = await makeConfigFromDirectory(`${config.cwd}/packages/workspace-1`, reporter, {binLinks: true}); + await add(childConfig, reporter, {}, ['max-safe-integer@1.0.0']); + + expect( + JSON.parse(await fs.readFile(path.join(config.cwd, 'packages/workspace-1/package.json'))).dependencies, + ).toEqual({ + 'max-safe-integer': '1.0.0', + }); + + // bin links should be preserved + expect(await fs.exists(`${config.cwd}/node_modules/.bin/rimraf`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/node_modules/.bin/touch`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/node_modules/.bin/workspace-1`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/packages/workspace-2/node_modules/.bin/rimraf`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/packages/workspace-2/node_modules/.bin/workspace-1`)).toEqual(true); + }); +}); diff --git a/__tests__/commands/install/workspaces-install.js b/__tests__/commands/install/workspaces-install.js index e2117e4127..55ed6ce173 100644 --- a/__tests__/commands/install/workspaces-install.js +++ b/__tests__/commands/install/workspaces-install.js @@ -1,10 +1,10 @@ /* @flow */ import {run as check} from '../../../src/cli/commands/check.js'; -import {Install} from '../../../src/cli/commands/install.js'; +import {Install, run as install} from '../../../src/cli/commands/install.js'; import * as reporters from '../../../src/reporters/index.js'; import * as fs from '../../../src/util/fs.js'; -import {runInstall, run as buildRun} from '../_helpers.js'; +import {runInstall, run as buildRun, makeConfigFromDirectory} from '../_helpers.js'; jasmine.DEFAULT_TIMEOUT_INTERVAL = 150000; @@ -242,4 +242,33 @@ test.concurrent('install should ignore node_modules in workspaces when used with }); }); +test.concurrent('install should link binaries properly when run from child workspace', async () => { + await runInstall({binLinks: true}, 'workspaces-install-bin', async (config, reporter): Promise => { + // initial install + expect(await fs.exists(`${config.cwd}/node_modules/.bin/rimraf`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/node_modules/.bin/touch`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/node_modules/.bin/workspace-1`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/packages/workspace-2/node_modules/.bin/rimraf`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/packages/workspace-2/node_modules/.bin/workspace-1`)).toEqual(true); + + // reset package folders to simulate running 'install' from + // child workspace _before_ running it in the root (this is not + // possible to do without an initial install using the current + // testing infrastructure) + await fs.unlink(`${config.cwd}/node_modules`); + await fs.unlink(`${config.cwd}/packages/workspace-1/node_modules`); + await fs.unlink(`${config.cwd}/packages/workspace-2/node_modules`); + + // run "install" in child package + const childConfig = await makeConfigFromDirectory(`${config.cwd}/packages/workspace-1`, reporter, {binLinks: true}); + await install(childConfig, reporter, {}, []); + + expect(await fs.exists(`${config.cwd}/node_modules/.bin/rimraf`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/node_modules/.bin/touch`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/node_modules/.bin/workspace-1`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/packages/workspace-2/node_modules/.bin/rimraf`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/packages/workspace-2/node_modules/.bin/workspace-1`)).toEqual(true); + }); +}); + // TODO need more thorough tests for all kinds of checks: integrity, verify-tree diff --git a/__tests__/commands/remove.js b/__tests__/commands/remove.js index c2b71aead5..40ef91ee2d 100644 --- a/__tests__/commands/remove.js +++ b/__tests__/commands/remove.js @@ -171,3 +171,31 @@ test.concurrent('removes from workspace packages', async () => { expect(lockFileLines[0]).toEqual('left-pad@1.1.3:'); }); }); + +test.concurrent('preserves unaffected bin links after removing workspace packages', async () => { + await runInstall({binLinks: true}, 'workspaces-install-bin', async (config): Promise => { + const reporter = new ConsoleReporter({}); + + expect(await fs.exists(`${config.cwd}/node_modules/.bin/rimraf`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/node_modules/.bin/touch`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/node_modules/.bin/workspace-1`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/packages/workspace-2/node_modules/.bin/rimraf`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/packages/workspace-2/node_modules/.bin/workspace-1`)).toEqual(true); + + // remove package + const childConfig = await makeConfigFromDirectory(`${config.cwd}/packages/workspace-1`, reporter, {binLinks: true}); + await remove(childConfig, reporter, {}, ['left-pad']); + await check(childConfig, reporter, {verifyTree: true}, []); + + expect( + JSON.parse(await fs.readFile(path.join(config.cwd, 'packages/workspace-1/package.json'))).devDependencies, + ).toEqual({}); + + // bin links should be preserved + expect(await fs.exists(`${config.cwd}/node_modules/.bin/rimraf`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/node_modules/.bin/touch`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/node_modules/.bin/workspace-1`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/packages/workspace-2/node_modules/.bin/rimraf`)).toEqual(true); + expect(await fs.exists(`${config.cwd}/packages/workspace-2/node_modules/.bin/workspace-1`)).toEqual(true); + }); +}); diff --git a/__tests__/fixtures/install/workspaces-install-bin/file.js b/__tests__/fixtures/install/workspaces-install-bin/file.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/__tests__/fixtures/install/workspaces-install-bin/package.json b/__tests__/fixtures/install/workspaces-install-bin/package.json new file mode 100644 index 0000000000..3f03c73ce8 --- /dev/null +++ b/__tests__/fixtures/install/workspaces-install-bin/package.json @@ -0,0 +1,12 @@ +{ + "name": "my-project", + "private": true, + "bin": {"file": "file.js"}, + "dependencies": {}, + "devDependencies": { + "touch": "^1.0.0" + }, + "workspaces": [ + "packages/*" + ] +} diff --git a/__tests__/fixtures/install/workspaces-install-bin/packages/workspace-1/bin.js b/__tests__/fixtures/install/workspaces-install-bin/packages/workspace-1/bin.js new file mode 100755 index 0000000000..e69de29bb2 diff --git a/__tests__/fixtures/install/workspaces-install-bin/packages/workspace-1/package.json b/__tests__/fixtures/install/workspaces-install-bin/packages/workspace-1/package.json new file mode 100644 index 0000000000..216d9c1197 --- /dev/null +++ b/__tests__/fixtures/install/workspaces-install-bin/packages/workspace-1/package.json @@ -0,0 +1,8 @@ +{ + "name": "workspace-1", + "version": "1.0.0", + "bin": "./bin.js", + "devDependencies": { + "left-pad": "1.0.0" + } +} diff --git a/__tests__/fixtures/install/workspaces-install-bin/packages/workspace-2/package.json b/__tests__/fixtures/install/workspaces-install-bin/packages/workspace-2/package.json new file mode 100644 index 0000000000..99b6e83285 --- /dev/null +++ b/__tests__/fixtures/install/workspaces-install-bin/packages/workspace-2/package.json @@ -0,0 +1,10 @@ +{ + "name": "workspace-2", + "version": "1.0.0", + "dependencies": { + "workspace-1": "^1.0.0" + }, + "devDependencies": { + "rimraf": "^2.6.2" + } +} diff --git a/__tests__/fixtures/install/workspaces-install-bin/yarn.lock b/__tests__/fixtures/install/workspaces-install-bin/yarn.lock new file mode 100644 index 0000000000..eccf7961af --- /dev/null +++ b/__tests__/fixtures/install/workspaces-install-bin/yarn.lock @@ -0,0 +1,90 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +brace-expansion@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +glob@^7.0.5: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +left-pad@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.0.0.tgz#c84e2417581bbb8eaf2b9e3d7a122e572ab1af37" + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + dependencies: + abbrev "1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +rimraf@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + dependencies: + glob "^7.0.5" + +touch@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-1.0.0.tgz#449cbe2dbae5a8c8038e30d71fa0ff464947c4de" + dependencies: + nopt "~1.0.10" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" diff --git a/__tests__/fixtures/request-cache/GET/registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz.bin b/__tests__/fixtures/request-cache/GET/registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz.bin new file mode 100644 index 0000000000000000000000000000000000000000..ee73ef834eb4858dcd1685f80088fdccfe8e97b8 GIT binary patch literal 2998 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 literal 0 HcmV?d00001 diff --git a/__tests__/fixtures/request-cache/GET/registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz.bin b/__tests__/fixtures/request-cache/GET/registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz.bin new file mode 100644 index 0000000000000000000000000000000000000000..a13b93d9f6689048c7447660a88f236b2fb31ed1 GIT binary patch literal 6231 zcmZuycQ~Buw{>(9y^}CX^kI}?jNV0!5+urGjKOGw88v$EAw-Q5L6qpdL_`guw~*+a zAc)?sbI!fb@80LR-(Tmj1qCAjfq=t8$%4oC$>W&izL)cim zqpW4EAs{g;Nik6n0wQW6<7)cLWqliK@d@hsHhZJ8i4e2LAfC@ zvL;CDzwHC>>;pw0|Hr&Ezy*%AlNFW*SficbC}&wAZ@8PYi-WBY0_`LX(7<9{^qd{N z$w;-~7%Wf+ZH=-)A+4bR9klZur3kGE$PA`(z>2`EVN-$Yc6;I>cz2UyBV!pa(9 z0~7&E*>I4Ns{U)}|7jN${on112m}&?xtrb@>xOm&Dmpr%J%M^|C|lHBM*L)?|8HFf ziM2ypW1s+a)xUQFN7y0%hXD$3f_nkswn$lsgg6NFFM$gdXaIM%Mc#E-d1H|nGE!p{ z918e*`yO{0pfGlKINQ7M#UOVbra(ian+MVwsN@X=ApRl8AmJh)Q4r8jRq^loKZ;O* z#^XEn|NaANps;uJ;(uQlp`4IzP=Mio79<3MfItutL1ROZpt0(m#y<*o7=$C*-P*2b$%mo1)z?Sc8$NJ(8i zvn4Kikyp~E;8So&lXRQMhidS2K$aeVeA{JKjz`O<+vPCR>3G|gYb!I~hEFY@8X6i} zKHs`+w49ur%n$e-SX`c}ScSNUHK&~-3-QF7d;?x8Xe3wTItI9V56k&WiWK02Pl3VT9ry*puMc3QpKYx z`@5omk^9|uP43R{@FklqL0vl^y{0|Ws|e1Em1hZkM%>Hlx3KG516|$#>f>h_Lln=; z^eOco&V3gJ;06eCcIW@OP;Uk%9+{q_-U=3ZZ+}RO4zQj1%G3)V_)upwFcLy8tCjQ~ z6vh}DZd8(tlfP#^vOh(kB6G3lb)`|$jarK6e$x~y!xZO-Qp_Mci0rx9Eg1JW(WIo2 zUxb_Ze1E)O^m1xnl&jSeE8Y9Sg6Gd6p#wX70B@gda9gt1fr_|7Rz6*fRH1!l2p%Zz z{L@+bM}j1~aZBm7p1|h#kq#T;G;ZEM6a0b#wznJQzU$@TablTpjoxql{$pXz>GM^* zMMu*0t#bB$PMzqRgflbIX84hL>0D#f2)*iqXq6k=b)M?Bty&3|W;Az*ln=LaE|;WN zdB*7Nn;u?nLlcx+Qn6B}OjNG{A5n#5JV&X;0tx~O1RWngrjP4$m>B)>B6CeoMHcq% zOFe%gDn(^^Ml4n_1mBl6%*55pi&vtdUgB8eUX6I)s%*%6uNap(T3B0T^?6y4KII`! zD0uwCz&Mz#i)p`=86!OqyJXW+=5; zOAnst0^Xyb2;bR^)UuRK9TjNOy`^)@+H_JAiyGU)D4p%7->)k0Z(^*lolG_eY6fq7 zYK|+Rge7;&DAxzYkOXotD=k{|@iKnr=<|hEBM^wFN$DEmIX&#!oeK@ne78jHUJh*=gpAj(B$)JK2+ z(H|)_Am~f;N^CU?ifT@_m~`ho=c4+tM@$dI619vfbIQCx?Px?@jtu` z=n_kN9Ay6Z?dC+Wv2^rCOjpj3fj*mLSB6on_N4xUf++d^1moi8yPvd`VEXmEV~oaz z5=+GEG2Cl@H~0Y}1q2i;=bFQ>XWL4=Ue7m2>E55S)6cXec@5@sPRt>x9bJHEb*pH) zsf(q59aYk%k<=`h=92bWc{zqB-iYTVv=qP0@{EOnt6eliNG;vuZED)O#Zgme6{o{J z`H*ytH*cRi{Vo@{*gzAqK^ZK5tG9lJ++y|{U&j8de|1VWDkV)XUWAeI^7Lnq|I(SH zyI(5|<>A4t5rW!=ST?{eM_5{E80H$X?#0UY(&7mGmGdymob_~Q{_x}c)@2fF3a@R< zk!0QYUiYYUtB2*Ou1`pg_mbqNFV7klJaH7>X2tB~wAkW}2B<3tzP0r1eq3>MkuNa+ z7B&I3m5;f(+|#eXjNvyk%)M8nIXZ$d24KnYe($FShKVdUVrIRyc+H73>@6MG=G_Ue zF(1ADD!EAI!Rxpg>^?7sNbS>fELSgd<7O#F6b7Re>KAD5a6z*K@Sjqp?(u}5j>MSb zREZcKb}W9pJjp+;f9Ww%5VaxW=Qg%ouc^8*Ldu?~|fn|$FDX9ZWV zS3cKIdj3&x3trf;7Pe#JC}RTP%{r( zH0+=x-$Yn8Bqw5aV3(M!bD_@n4O6OTTGyh7@{-J|7PUpG9c;%Oiv&d7*{+O(%3gwV zd83RHeK7xE(R;#C8+k=U9ev@4DKb2{zPFz?TlXjJm1%PIGL}iJnv^2t2tQIeDk6$p zbIwR!49<0t&Fm~(m^!G;P|mMw&@Osd3#E*dJs)&^>W-LH#`7jbbvRb_fv$>5D55;|OQOcQGg7ykkW`t~q<$5d-M z6m;2;8ZB!;l^*nkrY`zd@{gL187a}EJ)E$YkEHNl?QYmsxZhGCd?`;M^_S`Jlx6&UDHEm#?2x5AIw5rcNnW>Cok#kuyU)hrM@t1|^NEg5Cdw_EA+&V+B zrEthRP?O-rH78YwGO1g^ZsJbReUcf9gqt0c=Wr3Xjqm+s^_di z+`r|~Xi8~Zir~kj)M%7cx@dOTmxbk)T7xahae`-jS)*$ja;JYu$YT|S8nx@9!q5JyFrPs3D2r*GoJx6zO!SiGd$k}toi!sGq~Y(;=?$R3 z4!A(BR_7a^J2i#%OD`=)re77Jr@i{j98r5{og$lp9i>@|O-tjo!9s%eL)P=)eC_(; zO0Vo6O@&UY-~Gs1h^O@;dUE5p@+mV}g}_5!cQo`Evh#jgGfzG#v~RMud>vLb@+2$L zO-70GGCU}un{x_9!`L-SyUoBd9#O1iGtAx1C`*WG<6!#~(B!sBNz)%^iVPAF?(sA# zYJK&^%uZ_U;x$wRLdcd4&~*n(l3qQ;$1l*~qz zigMvmZRQF_4^L1zwxAk0J zKE+59z%Q@WXu`6Ox^ISLibl=e@EM{-!(V#QTJUU$o7vF%%v_PE{^J*rQWMgl}zHn!eesL z%dtq0XF=1{Z|>#NIf)$6g8+)$)8SYJx^OO2h)m0Tn8lYD#dr#j#*+!j%7PC@P?ZeT zznDAbl68DJluf-M$@immWNWzMm$mitaVi{rdAc#PeFn5rad6$RMx*K;I(BYKec@Rj z@%xJ8TqUv#qa?xb&8nz^qcmq7UtoPrw^qZTSfGb?*2R?N(?|>C*>_vOYV;#j;%CoW#whz` zdYaF2tEq?|z#4cvzmMUu=siljMeAAK@=^EPy$m78Ia#|5!X6(lVZvuO(VxskJAcA;85$*XOP^6bjFbrj-cL~9D|_zrQ6G+A{=7-XQlM`ta{rtGWE zCtah52Kczy1HE5hd1rkHU~7MEyery>s0iyT>^zP$lb@ZNsiZKEF)wv)ZIRnw9r>Yh z7O`GFU8tKcaV+~$N4MaRp+EOdb@4{i&D15sSXX7A{^<%)*O3=a;9WYY8) zFj16k5Q`6)T<5EUZ%eA`wh!S~4{3Vd;Lj%3jucw{QTRQRDl|EG#vR1E@?yG4u}xej z7X#Hjj4p01m=qkseT54!Nn<}%WO|iBzf7N-mtkD3g7z5>ek$x``0a?ZE3wVCyZ^#X z#g)`cnE#RB!=fMGS4TAazcCsw`%*BNHQIRm{%WvQk5VpCF0hFzn4El6 z=c5+A^3B|RTld=4Z@$Rf&5bA01Z9`iF3~-Cg+NABJq3vTNEN`+^|VGA&TAszDXS*Il{7?DdoV7Hz zudF8FUs?>VyR(}8C&a@vOOl(?_~ctwYQ^!&`Jhh*TX8!zaHUohq^)C)2hPe<+edfQ zkP{Y3t_>{v_EY!ZPEV*BMCi(Gv9bV;8Po1anHi6id=okXB6=1|RVux!#-4N_&Ea4q zH-5H!K;)m+Mmd6W3WJ^kf4g*TO~VGjy)*%!r0*`8^BD#w?_ZDs(q8 zuiql5Xke5;gakp-*m3vY&<`H{rL06_{Asm@`IGJ(LcE23r#mHdX@js z;7F-c$q8&~rYju>_VV6SHxhoE_H-RIiDQt$h_m-W`D^<~>A*&|Zmw-a~ym#{tXLk=!As^bE)KzG)a)l#8^Z-cXg&C7Fk3(OQmSBF>O z{bn|$Di0JD@Of@RcYc%l2-B1Y$khT`0QN%Fg}w(-w@g5pTn-@)e2!AO7f&^ho^GFQ zL#99bAfgC|0`?-3#B{Y#>6ijO3-|6*W|;wAp`(MFrdiGk-Li^Gb@__6e(sllzTi1F zvhhd+?Ic_k`c=>D8{+Dg|z#%z~jr$gH9<>N2SclOS^{#|T zdXlWpFiO|cxDFSWlP-|UjVpTRd@Xn&lOfl`J+#~yjGm^yFWhpOhCC`5B*)!6{t>Zu z`m~@bvXX?)GpT@`t4T(Dc-qAW8tI{q9MA6S@BjvoHg0c75}qfTn0f6|JH*oO@feiqerCslE<8q zn{qw~jD-2O5{)KDOU_;O7AIXk~?`xcq#702k1&OMmVbx_f1&1UPu zNMInJxnu+gE2rX`8E)i0l`+{ph@-7-4twnPvi(WEp0ZPerDNBnd@R7EarxDr4o-UD zOPWrl^bUsw!vPV)cjgrMG!*`tR(e1Dbpw#TIH10RV%3}4uiaM@S> z>j9Zce#oSqRRI>k5>MBWO8qIk?+;|0eEEzyu|TikDRoU5Z7O{)-^msQO`FAqvSDlj z(TEOl_Lf%LZfMpqdN1zB#!H|z=~fC^0OvXfEH{%Pr`TZlL*Cng-;!IZN=e+WsRs&- ztY$1wFnJytx&7caSYBS} z4b$k!m3Jp8**fykVgIeE**l{M3gcguN{7!6+p=quO~;Q;*L+X8Ar42fRSyWuqokuV z5(h&T9_7Vn<>W4U*A4+MQ`OCQURSjBtjegjn&3=6%_$qCjDge; z16YHL8b&m~HD-{Qj&@4MGELhM(-UZkc!MEcMk;O2c8?6kt^}%D1Ev-jzCT@Ve$*sB zrNPNozrDpu|HZ%yd3O4Q($Ht}WoOzUBGDoG2&w1k1=g#D{GL9#S6d`f>~|Tl)K| z9r>nRd8eGY779*nn`P=Qtr}t`P?=e~5&>?`J!gd@``sxO?-PF2%Q(Z_v4M`>&F*U5 zvkLe5<%1d=*>4yxrQZ$G3G(-xo?~{C!6aB_ { if (pkg._reference && pkg._reference.location && pkg.bin && Object.keys(pkg.bin).length) { - const binLoc = path.join(this.config.cwd, this.config.getFolder(pkg)); + const binLoc = path.join(this.config.lockfileFolder, this.config.getFolder(pkg)); await this.linkSelfDependencies(pkg, dest, binLoc); tickBin(); }