@@ -21,12 +21,16 @@ import * as PackageManager from '../../tools/packageManager';
21
21
import { installPods } from '@react-native-community/cli-doctor' ;
22
22
import banner from './banner' ;
23
23
import TemplateAndVersionError from './errors/TemplateAndVersionError' ;
24
+ import { getBunVersionIfAvailable } from '../../tools/bun' ;
25
+ import { getNpmVersionIfAvailable } from '../../tools/npm' ;
26
+ import { getYarnVersionIfAvailable } from '../../tools/yarn' ;
24
27
25
28
const DEFAULT_VERSION = 'latest' ;
26
29
27
30
type Options = {
28
31
template ?: string ;
29
32
npm ?: boolean ;
33
+ pm ?: PackageManager . PackageManager ;
30
34
directory ?: string ;
31
35
displayName ?: string ;
32
36
title ?: string ;
@@ -39,6 +43,7 @@ interface TemplateOptions {
39
43
projectName : string ;
40
44
templateUri : string ;
41
45
npm ?: boolean ;
46
+ pm ?: PackageManager . PackageManager ;
42
47
directory : string ;
43
48
projectTitle ?: string ;
44
49
skipInstall ?: boolean ;
@@ -82,6 +87,7 @@ async function createFromTemplate({
82
87
projectName,
83
88
templateUri,
84
89
npm,
90
+ pm,
85
91
directory,
86
92
projectTitle,
87
93
skipInstall,
@@ -90,6 +96,24 @@ async function createFromTemplate({
90
96
logger . debug ( 'Initializing new project' ) ;
91
97
logger . log ( banner ) ;
92
98
99
+ let packageManager = pm ;
100
+
101
+ if ( pm ) {
102
+ packageManager = pm ;
103
+ } else {
104
+ const userAgentPM = userAgentPackageManager ( ) ;
105
+ // if possible, use the package manager from the user agent. Otherwise fallback to default (yarn)
106
+ packageManager = userAgentPM || 'yarn' ;
107
+ }
108
+
109
+ if ( npm ) {
110
+ logger . warn (
111
+ 'Flag --npm is deprecated and will be removed soon. In the future, please use --pm npm instead.' ,
112
+ ) ;
113
+
114
+ packageManager = 'npm' ;
115
+ }
116
+
93
117
const projectDirectory = await setProjectDirectory ( directory ) ;
94
118
95
119
const loader = getLoader ( { text : 'Downloading template' } ) ;
@@ -100,7 +124,11 @@ async function createFromTemplate({
100
124
try {
101
125
loader . start ( ) ;
102
126
103
- await installTemplatePackage ( templateUri , templateSourceDir , npm ) ;
127
+ await installTemplatePackage (
128
+ templateUri ,
129
+ templateSourceDir ,
130
+ packageManager ,
131
+ ) ;
104
132
105
133
loader . succeed ( ) ;
106
134
loader . start ( 'Copying template' ) ;
@@ -137,7 +165,7 @@ async function createFromTemplate({
137
165
138
166
if ( ! skipInstall ) {
139
167
await installDependencies ( {
140
- npm ,
168
+ packageManager ,
141
169
loader,
142
170
root : projectDirectory ,
143
171
} ) ;
@@ -153,18 +181,18 @@ async function createFromTemplate({
153
181
}
154
182
155
183
async function installDependencies ( {
156
- npm ,
184
+ packageManager ,
157
185
loader,
158
186
root,
159
187
} : {
160
- npm ?: boolean ;
188
+ packageManager : PackageManager . PackageManager ;
161
189
loader : Loader ;
162
190
root : string ;
163
191
} ) {
164
192
loader . start ( 'Installing dependencies' ) ;
165
193
166
194
await PackageManager . installAll ( {
167
- preferYarn : ! npm ,
195
+ packageManager ,
168
196
silent : true ,
169
197
root,
170
198
} ) ;
@@ -176,6 +204,20 @@ async function installDependencies({
176
204
loader . succeed ( ) ;
177
205
}
178
206
207
+ function checkPackageManagerAvailability (
208
+ packageManager : PackageManager . PackageManager ,
209
+ ) {
210
+ if ( packageManager === 'bun' ) {
211
+ return getBunVersionIfAvailable ( ) ;
212
+ } else if ( packageManager === 'npm' ) {
213
+ return getNpmVersionIfAvailable ( ) ;
214
+ } else if ( packageManager === 'yarn' ) {
215
+ return getYarnVersionIfAvailable ( ) ;
216
+ }
217
+
218
+ return false ;
219
+ }
220
+
179
221
function createTemplateUri ( options : Options , version : string ) : string {
180
222
const isTypescriptTemplate =
181
223
options . template === 'react-native-template-typescript' ;
@@ -202,13 +244,32 @@ async function createProject(
202
244
projectName,
203
245
templateUri,
204
246
npm : options . npm ,
247
+ pm : options . pm ,
205
248
directory,
206
249
projectTitle : options . title ,
207
250
skipInstall : options . skipInstall ,
208
251
packageName : options . packageName ,
209
252
} ) ;
210
253
}
211
254
255
+ function userAgentPackageManager ( ) {
256
+ const userAgent = process . env . npm_config_user_agent ;
257
+
258
+ if ( userAgent ) {
259
+ if ( userAgent . startsWith ( 'yarn' ) ) {
260
+ return 'yarn' ;
261
+ }
262
+ if ( userAgent . startsWith ( 'npm' ) ) {
263
+ return 'npm' ;
264
+ }
265
+ if ( userAgent . startsWith ( 'bun' ) ) {
266
+ return 'bun' ;
267
+ }
268
+ }
269
+
270
+ return null ;
271
+ }
272
+
212
273
export default ( async function initialize (
213
274
[ projectName ] : Array < string > ,
214
275
options : Options ,
@@ -223,6 +284,13 @@ export default (async function initialize(
223
284
const version = options . version || DEFAULT_VERSION ;
224
285
const directoryName = path . relative ( root , options . directory || projectName ) ;
225
286
287
+ if ( options . pm && ! checkPackageManagerAvailability ( options . pm ) ) {
288
+ logger . error (
289
+ 'Seems like the package manager you want to use is not installed. Please install it or choose another package manager.' ,
290
+ ) ;
291
+ return ;
292
+ }
293
+
226
294
await createProject ( projectName , directoryName , version , options ) ;
227
295
228
296
const projectFolder = path . join ( root , directoryName ) ;
0 commit comments