1# Copyright 2018-present 650 Industries. All rights reserved. 2 3module Expo 4 class ReactImportPatcher 5 6 public def initialize(installer, options) 7 @root = installer.sandbox.root 8 @module_dirs = get_module_dirs(installer) 9 @options = options 10 end 11 12 public def run! 13 args = [ 14 'node', 15 '--no-warnings', 16 '--eval', 17 'require(require.resolve(\'expo-modules-autolinking\', { paths: [\'' + __dir__ + '\'] }))(process.argv.slice(1))', 18 'patch-react-imports', 19 '--pods-root', 20 File.expand_path(@root), 21 ] 22 23 if @options[:dry_run] 24 args.append('--dry-run') 25 end 26 27 @module_dirs.each do |dir| 28 args.append(File.expand_path(dir)) 29 end 30 Pod::UI.message "Executing ReactImportsPatcher node command: #{Shellwords.join(args)}" 31 32 time_begin = Process.clock_gettime(Process::CLOCK_MONOTONIC) 33 system(*args) 34 elapsed_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) - time_begin 35 Pod::UI.info "expo_patch_react_imports! took #{elapsed_time.round(4)} seconds to transform files." 36 end 37 38 private def get_module_dirs(installer) 39 unless installer.pods_project 40 Pod::UI.message '`pods_project` not found. This is expected when `:incremental_installation` is enabled in your project\'s Podfile.' 41 return [] 42 end 43 44 result = [] 45 installer.pods_project.development_pods.children.each do |pod| 46 if pod.is_a?(Xcodeproj::Project::Object::PBXFileReference) && pod.path.end_with?('.xcodeproj') 47 # Support generate_multiple_pod_projects or use_frameworks! 48 project = Xcodeproj::Project.open(File.join(installer.sandbox.root, pod.path)) 49 groups = project.groups.select { |group| !(['Dependencies', 'Frameworks', 'Products'].include? group.name) } 50 groups.each do |group| 51 result.append(group.real_path.to_s) 52 end 53 else 54 result.append(pod.real_path.to_s) 55 end 56 end 57 58 result 59 .select { |dir| dir.include? '/node_modules/' } 60 .reject do |dir| 61 # Exclude known dirs unnecessary to patch and reduce processing time 62 # Since we are using real (absolute) pathnames we need to assert that we are inside of the node_modules 63 # directory to not collide with other directories in the user's filesystem. 64 # We reject the react-native package and packages starting with expo- 65 dir.match(%r{^.*/node_modules/(react-native(/.*)?|expo-.*)$}) 66 end 67 end 68 69 end # class ReactImportPatcher 70end # module Expo 71