8
8
$CODEGEN_OUTPUT_DIR = 'build/generated/ios'
9
9
$CODEGEN_COMPONENT_DIR = 'react/renderer/components'
10
10
$CODEGEN_MODULE_DIR = '.'
11
+ $REACT_CODEGEN_PODSPEC_GENERATED = false
12
+ $REACT_CODEGEN_DISCOVERY_DONE = false
11
13
12
14
def use_react_native! ( options = { } )
13
15
# The prefix to react-native
@@ -69,8 +71,6 @@ def use_react_native! (options={})
69
71
pod 'RCT-Folly' , :podspec => "#{ prefix } /third-party-podspecs/RCT-Folly.podspec"
70
72
71
73
if ENV [ 'USE_CODEGEN_DISCOVERY' ] == '1'
72
- Pod ::UI . puts "[Codegen] Building target with codegen library discovery enabled."
73
- # TODO: Make sure this is run only once per execution.
74
74
app_path = options [ :app_path ]
75
75
config_file_dir = options [ :config_file_dir ]
76
76
use_react_native_codegen_discovery! ( {
@@ -79,11 +79,14 @@ def use_react_native! (options={})
79
79
fabric_enabled : fabric_enabled ,
80
80
config_file_dir : config_file_dir ,
81
81
} )
82
+ else
83
+ # Generate a podspec file for generated files.
84
+ # This gets generated in use_react_native_codegen_discovery when codegen discovery is enabled.
85
+ react_codegen_spec = get_react_codegen_spec ( fabric_enabled : fabric_enabled )
86
+ generate_react_codegen_podspec! ( react_codegen_spec )
82
87
end
83
88
84
- # Generate a podspec file for generated files.
85
- temp_podinfo = generate_temp_pod_spec_for_codegen! ( fabric_enabled )
86
- pod temp_podinfo [ 'spec' ] [ 'name' ] , :path => temp_podinfo [ 'path' ]
89
+ pod 'React-Codegen' , :path => $CODEGEN_OUTPUT_DIR
87
90
88
91
if fabric_enabled
89
92
checkAndGenerateEmptyThirdPartyProvider! ( prefix )
@@ -267,10 +270,9 @@ def checkAndGenerateEmptyThirdPartyProvider!(react_native_path)
267
270
end
268
271
end
269
272
270
- def generate_temp_pod_spec_for_codegen! ( fabric_enabled )
271
- relative_installation_root = Pod ::Config . instance . installation_root . relative_path_from ( Pathname . pwd )
272
- output_dir = "#{ relative_installation_root } /#{ $CODEGEN_OUTPUT_DIR} "
273
- Pod ::Executable . execute_command ( "mkdir" , [ "-p" , output_dir ] ) ;
273
+ def get_react_codegen_spec ( options = { } )
274
+ fabric_enabled = options [ :fabric_enabled ] ||= false
275
+ script_phases = options [ :script_phases ] ||= nil
274
276
275
277
package = JSON . parse ( File . read ( File . join ( __dir__ , ".." , "package.json" ) ) )
276
278
version = package [ 'version' ]
@@ -283,7 +285,6 @@ def generate_temp_pod_spec_for_codegen!(fabric_enabled)
283
285
source [ :tag ] = "v#{ version } "
284
286
end
285
287
286
-
287
288
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
288
289
folly_version = '2021.06.28.00-v2'
289
290
boost_version = '1.76.0'
@@ -331,6 +332,161 @@ def generate_temp_pod_spec_for_codegen!(fabric_enabled)
331
332
} ) ;
332
333
end
333
334
335
+ if script_phases
336
+ Pod ::UI . puts "[Codegen] Adding script_phases to React-Codegen."
337
+ spec [ :'script_phases' ] = script_phases
338
+ end
339
+
340
+ return spec
341
+ end
342
+
343
+ def get_react_codegen_script_phases ( options = { } )
344
+ app_path = options [ :app_path ] ||= ''
345
+ if !app_path
346
+ Pod ::UI . warn '[Codegen] error: app_path is requried to use codegen discovery.'
347
+ exit 1
348
+ end
349
+
350
+ # We need to convert paths to relative path from installation_root for the script phase for CI.
351
+ relative_app_root = Pathname . new ( app_path ) . relative_path_from ( Pod ::Config . instance . installation_root )
352
+
353
+ config_file_dir = options [ :config_file_dir ] ||= ''
354
+ relative_config_file_dir = ''
355
+ if config_file_dir
356
+ relative_config_file_dir = Pathname . new ( config_file_dir ) . relative_path_from ( Pod ::Config . instance . installation_root )
357
+ end
358
+
359
+ fabric_enabled = options [ :fabric_enabled ] ||= false
360
+
361
+ # react_native_path should be relative already.
362
+ react_native_path = options [ :react_native_path ] ||= "../node_modules/react-native"
363
+
364
+ # Add a script phase to trigger generate artifact.
365
+ # Some code is duplicated so that it's easier to delete the old way and switch over to this once it's stabilized.
366
+ return {
367
+ 'name' : 'Generate Specs' ,
368
+ 'execution_position' : :before_compile ,
369
+ 'input_files' => [ '${DERIVED_FILE_DIR}/.tmpfile' ] ,
370
+ 'show_env_vars_in_log' : true ,
371
+ 'output_files' : [ "${DERIVED_FILE_DIR}/react-codegen.log" ] ,
372
+ 'script' : %{set -o pipefail
373
+ set -e
374
+
375
+ # A known hack to run this script every time.
376
+ # TODO: Further improvement will be to specify actual input files
377
+ # so that it doesn't have to rebuild libraries every time.
378
+ touch "${SCRIPT_INPUT_FILE_0}"
379
+
380
+ pushd "${PODS_ROOT}/../" > /dev/null
381
+ POD_INSTALLATION_ROOT=$(pwd)
382
+ popd >/dev/null
383
+ RN_DIR=$(cd "$POD_INSTALLATION_ROOT/#{ react_native_path } " && pwd)
384
+
385
+ GENERATED_SRCS_DIR="$\{ DERIVED_FILE_DIR\} /generated/source/codegen-discovery"
386
+ TEMP_OUTPUT_DIR="$GENERATED_SRCS_DIR/out"
387
+
388
+ APP_PATH="$POD_INSTALLATION_ROOT/#{ $relative_app_root} "
389
+ CONFIG_FILE_DIR="#{ relative_config_file_dir ? "$POD_INSTALLATION_ROOT/#{ relative_config_file_dir } " : '' } "
390
+ OUTPUT_DIR="$POD_INSTALLATION_ROOT"
391
+ FABRIC_ENABLED="#{ fabric_enabled } "
392
+
393
+ CODEGEN_REPO_PATH="$RN_DIR/packages/react-native-codegen"
394
+ CODEGEN_NPM_PATH="$RN_DIR/../react-native-codegen"
395
+ CODEGEN_CLI_PATH=""
396
+
397
+ # Determine path to react-native-codegen
398
+ if [ -d "$CODEGEN_REPO_PATH" ]; then
399
+ CODEGEN_CLI_PATH=$(cd "$CODEGEN_REPO_PATH" && pwd)
400
+ elif [ -d "$CODEGEN_NPM_PATH" ]; then
401
+ CODEGEN_CLI_PATH=$(cd "$CODEGEN_NPM_PATH" && pwd)
402
+ else
403
+ echo "error: Could not determine react-native-codegen location. Try running 'yarn install' or 'npm install' in your project root." >> "${SCRIPT_OUTPUT_FILE_0}" 2>&1
404
+ exit 1
405
+ fi
406
+
407
+ find_node () {
408
+ source "$RN_DIR/scripts/find-node.sh"
409
+
410
+ NODE_BINARY="${NODE_BINARY:-$(command -v node || true)}"
411
+ if [ -z "$NODE_BINARY" ]; then
412
+ echo "error: Could not find node. Make sure it is in bash PATH or set the NODE_BINARY environment variable." >> "${SCRIPT_OUTPUT_FILE_0}" 2>&1
413
+ exit 1
414
+ fi
415
+ }
416
+
417
+ setup_dirs () {
418
+ set +e
419
+ rm -rf "$GENERATED_SRCS_DIR"
420
+ set -e
421
+
422
+ mkdir -p "$GENERATED_SRCS_DIR" "$TEMP_OUTPUT_DIR"
423
+
424
+ # Clear output files
425
+ > "${SCRIPT_OUTPUT_FILE_0}"
426
+ }
427
+
428
+ describe () {
429
+ printf "\\ n\\ n>>>>> %s\\ n\\ n\\ n" "$1" >> "${SCRIPT_OUTPUT_FILE_0}" 2>&1
430
+ }
431
+
432
+ buildCodegenCLI () {
433
+ if [ ! -d "$CODEGEN_CLI_PATH/lib" ]; then
434
+ describe "Building react-native-codegen package"
435
+ bash "$CODEGEN_CLI_PATH/scripts/oss/build.sh"
436
+ fi
437
+ }
438
+
439
+ generateArtifacts () {
440
+ describe "Generating codegen artifacts"
441
+ pushd "$RN_DIR" >/dev/null || exit 1
442
+ CONFIG_FILE_DIR="$POD_INSTALLATION_ROOT/#{ $relative_config_file_dir} "
443
+ "$NODE_BINARY" "scripts/generate-artifacts.js" --path "$APP_PATH" --outputPath "$OUTPUT_DIR" --fabricEnabled "$FABRIC_ENABLED" --configFileDir "$CONFIG_FILE_DIR"
444
+ popd >/dev/null || exit 1
445
+ }
446
+
447
+ moveOutputs () {
448
+ mkdir -p "$OUTPUT_DIR"
449
+
450
+ # Copy all output to output_dir
451
+ cp -R "$TEMP_OUTPUT_DIR/" "$OUTPUT_DIR" || exit 1
452
+ echo "Output has been written to $OUTPUT_DIR:" >> "${SCRIPT_OUTPUT_FILE_0}" 2>&1
453
+ ls -1 "$OUTPUT_DIR" >> "${SCRIPT_OUTPUT_FILE_0}" 2>&1
454
+ }
455
+
456
+ main () {
457
+ setup_dirs
458
+ find_node
459
+ buildCodegenCLI
460
+ generateArtifacts
461
+ moveOutputs
462
+ }
463
+
464
+ main "$@"
465
+ echo 'Done.' >> "${SCRIPT_OUTPUT_FILE_0}" 2>&1
466
+ } ,
467
+ }
468
+
469
+ end
470
+
471
+ def set_react_codegen_podspec_generated ( value )
472
+ $REACT_CODEGEN_PODSPEC_GENERATED = value
473
+ end
474
+
475
+ def has_react_codegen_podspec_generated ( )
476
+ return $REACT_CODEGEN_PODSPEC_GENERATED
477
+ end
478
+
479
+ def generate_react_codegen_podspec! ( spec )
480
+ # This podspec file should only be create once in the session/pod install.
481
+ # This happens when multiple targets are calling use_react_native!.
482
+ if has_react_codegen_podspec_generated ( )
483
+ Pod ::UI . puts "[Codegen] Skipping React-Codegen podspec generation."
484
+ return
485
+ end
486
+ relative_installation_root = Pod ::Config . instance . installation_root . relative_path_from ( Pathname . pwd )
487
+ output_dir = "#{ relative_installation_root } /#{ $CODEGEN_OUTPUT_DIR} "
488
+ Pod ::Executable . execute_command ( "mkdir" , [ "-p" , output_dir ] ) ;
489
+
334
490
podspec_path = File . join ( output_dir , 'React-Codegen.podspec.json' )
335
491
Pod ::UI . puts "[Codegen] Generating #{ podspec_path } "
336
492
@@ -339,6 +495,8 @@ def generate_temp_pod_spec_for_codegen!(fabric_enabled)
339
495
f . fsync
340
496
end
341
497
498
+ set_react_codegen_podspec_generated ( true )
499
+
342
500
return {
343
501
"spec" => spec ,
344
502
"path" => $CODEGEN_OUTPUT_DIR, # Path needs to be relative to `Podfile`
@@ -349,27 +507,40 @@ def generate_temp_pod_spec_for_codegen!(fabric_enabled)
349
507
def use_react_native_codegen_discovery! ( options = { } )
350
508
return if ENV [ 'DISABLE_CODEGEN' ] == '1'
351
509
510
+ if $REACT_CODEGEN_DISCOVERY_DONE
511
+ Pod ::UI . puts "[Codegen] Skipping use_react_native_codegen_discovery."
512
+ return
513
+ end
514
+
352
515
Pod ::UI . warn '[Codegen] warn: using experimental new codegen integration'
353
516
react_native_path = options [ :react_native_path ] ||= "../node_modules/react-native"
354
517
app_path = options [ :app_path ]
355
518
fabric_enabled = options [ :fabric_enabled ] ||= false
356
519
config_file_dir = options [ :config_file_dir ] ||= ''
357
- if app_path
358
- out = Pod ::Executable . execute_command (
359
- 'node' ,
360
- [
361
- "#{ react_native_path } /scripts/generate-artifacts.js" ,
362
- "-p" , "#{ app_path } " ,
363
- "-o" , Pod ::Config . instance . installation_root ,
364
- "-e" , "#{ fabric_enabled } " ,
365
- "-c" , "#{ config_file_dir } " ,
366
- ] )
367
- Pod ::UI . puts out ;
368
- else
369
- Pod ::UI . warn '[Codegen] error: no app_path was provided'
520
+
521
+ if !app_path
522
+ Pod ::UI . warn '[Codegen] Error: app_path is required for use_react_native_codegen_discovery.'
370
523
Pod ::UI . warn '[Codegen] If you are calling use_react_native_codegen_discovery! in your Podfile, please remove the call and pass `app_path` and/or `config_file_dir` to `use_react_native!`.'
371
524
exit 1
372
525
end
526
+
527
+ # Generate React-Codegen podspec here to add the script phases.
528
+ script_phases = get_react_codegen_script_phases ( options )
529
+ react_codegen_spec = get_react_codegen_spec ( fabric_enabled : fabric_enabled , script_phases : script_phases )
530
+ generate_react_codegen_podspec! ( react_codegen_spec )
531
+
532
+ out = Pod ::Executable . execute_command (
533
+ 'node' ,
534
+ [
535
+ "#{ react_native_path } /scripts/generate-artifacts.js" ,
536
+ "-p" , "#{ app_path } " ,
537
+ "-o" , Pod ::Config . instance . installation_root ,
538
+ "-e" , "#{ fabric_enabled } " ,
539
+ "-c" , "#{ config_file_dir } " ,
540
+ ] )
541
+ Pod ::UI . puts out ;
542
+
543
+ $REACT_CODEGEN_DISCOVERY_DONE = true
373
544
end
374
545
375
546
def use_react_native_codegen! ( spec , options = { } )
@@ -453,7 +624,7 @@ def use_react_native_codegen!(spec, options={})
453
624
set -e
454
625
455
626
pushd "${PODS_ROOT}/../" > /dev/null
456
- PROJECT_DIR =$(pwd)
627
+ POD_INSTALLATION_ROOT =$(pwd)
457
628
popd >/dev/null
458
629
RN_DIR=$(cd "$\{ PODS_TARGET_SRCROOT\} /#{ prefix } " && pwd)
459
630
@@ -462,7 +633,7 @@ def use_react_native_codegen!(spec, options={})
462
633
TEMP_OUTPUT_DIR="$GENERATED_SRCS_DIR/out"
463
634
464
635
LIBRARY_NAME="#{ library_name } "
465
- OUTPUT_DIR="$PROJECT_DIR /#{ $CODEGEN_OUTPUT_DIR} "
636
+ OUTPUT_DIR="$POD_INSTALLATION_ROOT /#{ $CODEGEN_OUTPUT_DIR} "
466
637
467
638
CODEGEN_REPO_PATH="$RN_DIR/packages/react-native-codegen"
468
639
CODEGEN_NPM_PATH="$RN_DIR/../react-native-codegen"
0 commit comments