@@ -9,19 +9,22 @@ import {
99 mkdirSync ,
1010 unlinkSync ,
1111 mkdirpSync ,
12+ readdirSync ,
1213} from "fs-extra"
1314import { sync as rimraf } from "rimraf"
1415import { copySync } from "fs-extra"
15- import { dirSync } from "tmp"
1616import { getPatchFiles } from "./patchFs"
1717import {
1818 getPatchDetailsFromCliString ,
1919 getPackageDetailsFromPatchFilename ,
20+ PackageDetails ,
2021} from "./PackageDetails"
2122import { resolveRelativeFileDependencies } from "./resolveRelativeFileDependencies"
2223import { getPackageResolution } from "./getPackageResolution"
2324import { parsePatchFile } from "./patch/parse"
2425import { gzipSync } from "zlib"
26+ import readline from "readline"
27+ import { dirSync } from "tmp"
2528
2629function printNoPackageFoundError (
2730 packageName : string ,
@@ -32,9 +35,105 @@ function printNoPackageFoundError(
3235
3336 File not found: ${ packageJsonPath } ` ,
3437 )
38+ process . exit ( 1 )
39+ }
40+
41+ function printNoUnpluggedPackageFound ( {
42+ packageName,
43+ unpluggedDir,
44+ } : {
45+ packageName : string
46+ unpluggedDir : string
47+ } ) {
48+ console . error (
49+ `Could not find an unnplugged version of ${ packageName } in ${ unpluggedDir } ` ,
50+ )
51+ process . exit ( 1 )
3552}
3653
37- export function makePatch ( {
54+ async function findRelativePackagePath ( {
55+ appPath,
56+ packageDetails,
57+ packageManager,
58+ } : {
59+ appPath : string
60+ packageDetails : PackageDetails
61+ packageManager : PackageManager
62+ } ) : Promise < string > {
63+ if ( packageManager === "berry" ) {
64+ const unpluggedDir = join ( appPath , ".yarn/unplugged" )
65+ if ( ! existsSync ( unpluggedDir ) ) {
66+ printNoUnpluggedPackageFound ( {
67+ packageName : packageDetails . name ,
68+ unpluggedDir,
69+ } )
70+ }
71+ const dirs = readdirSync ( unpluggedDir ) . filter (
72+ name =>
73+ name . startsWith ( packageDetails . name ) &&
74+ name
75+ . slice ( packageDetails . name . length )
76+ // optional protocol (e.g. npm) - optional version - hash
77+ . match ( / ^ ( - \w + ) ? ( - \d + \. \d + \. \d + .* ?) ? - [ 0 - 9 a - f ] + $ / ) ,
78+ )
79+ if ( dirs . length === 0 ) {
80+ printNoUnpluggedPackageFound ( {
81+ packageName : packageDetails . name ,
82+ unpluggedDir,
83+ } )
84+ }
85+ if ( dirs . length > 1 ) {
86+ const rl = readline . createInterface ( {
87+ input : process . stdin ,
88+ output : process . stdout ,
89+ } )
90+
91+ return new Promise < string > ( resolvePromise => {
92+ rl . question (
93+ `There are mulitple unplugged versions of ${ chalk . bold (
94+ packageDetails . name ,
95+ ) } \n\n` +
96+ dirs
97+ . map (
98+ ( dir , index ) =>
99+ `${ chalk . cyan . bold ( index . toString ( ) ) } ${ chalk . gray (
100+ ")" ,
101+ ) } ${ dir } `,
102+ )
103+ . join ( "\n" ) +
104+ "\n\n" +
105+ `Please select a ${ chalk . cyan . bold ( "version" ) } ` +
106+ chalk . yellow . bold ( ">> " ) ,
107+ answer => {
108+ const index = Number ( answer . trim ( ) )
109+ if ( index != null && index >= 0 && index < dirs . length ) {
110+ resolvePromise (
111+ join (
112+ ".yarn/unplugged" ,
113+ dirs [ index ] ,
114+ "node_modules" ,
115+ packageDetails . name ,
116+ ) ,
117+ )
118+ } else {
119+ console . error ( chalk . red . bold ( "That didn't work." ) )
120+ console . error (
121+ `Please try again and provide a number in the range 0-${ dirs . length -
122+ 1 } `,
123+ )
124+ process . exit ( 1 )
125+ }
126+ } ,
127+ )
128+ } )
129+ }
130+ return join ( ".yarn/unplugged" , dirs [ 0 ] , "node_modules" , packageDetails . name )
131+ }
132+
133+ return packageDetails . path
134+ }
135+
136+ export async function makePatch ( {
38137 packagePathSpecifier,
39138 appPath,
40139 packageManager,
@@ -55,17 +154,22 @@ export function makePatch({
55154 console . error ( "No such package" , packagePathSpecifier )
56155 return
57156 }
58- const appPackageJson = require ( join ( appPath , "package.json" ) )
59- const packagePath = join ( appPath , packageDetails . path )
60- const packageJsonPath = join ( packagePath , "package.json" )
61-
62- if ( ! existsSync ( packageJsonPath ) ) {
63- printNoPackageFoundError ( packagePathSpecifier , packageJsonPath )
64- process . exit ( 1 )
157+ const appJson = require ( join ( appPath , "package.json" ) )
158+ const relativePackagePath = await findRelativePackagePath ( {
159+ appPath,
160+ packageDetails,
161+ packageManager,
162+ } )
163+
164+ const appPackageJsonPath = join ( appPath , relativePackagePath , "package.json" )
165+
166+ if ( ! existsSync ( appPackageJsonPath ) ) {
167+ // won't happen with berry
168+ printNoPackageFoundError ( packagePathSpecifier , appPackageJsonPath )
65169 }
66170
67171 const tmpRepo = dirSync ( { unsafeCleanup : true } )
68- const tmpRepoPackagePath = join ( tmpRepo . name , packageDetails . path )
172+ const tmpRepoPackagePath = join ( tmpRepo . name , relativePackagePath )
69173 const tmpRepoNpmRoot = tmpRepoPackagePath . slice (
70174 0 ,
71175 - `/node_modules/${ packageDetails . name } ` . length ,
@@ -92,7 +196,7 @@ export function makePatch({
92196 } ,
93197 resolutions : resolveRelativeFileDependencies (
94198 appPath ,
95- appPackageJson . resolutions || { } ,
199+ appJson . resolutions || { } ,
96200 ) ,
97201 } ) ,
98202 )
0 commit comments