Class: ReactNativeUtil::Project

Inherits:
Xcodeproj::Project
  • Object
show all
Includes:
Util
Defined in:
lib/react_native_util/project.rb

Constant Summary collapse

DEFAULT_DEPENDENCIES =
Array<String>

Xcode projects from react-native that may be in the Libraries group

%w[
  ART
  React
  RCTActionSheet
  RCTAnimation
  RCTBlob
  RCTCameraRoll
  RCTGeolocation
  RCTImage
  RCTLinking
  RCTNetwork
  RCTPushNotification
  RCTSettings
  RCTTest
  RCTText
  RCTVibration
  RCTWebSocket
]

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Util

#boolean_env_var?, #execute, #float_env_var, #have_command?, #log, #mac?, #platform, #run_command_with_spinner!, #validate_commands!

Instance Attribute Details

#app_nameObject

Returns the value of attribute app_name.



28
29
30
# File 'lib/react_native_util/project.rb', line 28

def app_name
  @app_name
end

Instance Method Details

#add_packager_script_from(react_project) ⇒ Object

Adds the Start Packager script from the React.xcodeproj under node_modules to the main application target before deleting React.xcodeproj from the Libraries group. Adjusts paths in the script to account for the different project location. If the relevant build phase is not found, a warning is logged, and this step is skipped.



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/react_native_util/project.rb', line 106

def add_packager_script_from(react_project)
  old_packager_phase = react_project.packager_phase
  unless old_packager_phase
    log 'Could not find packager build phase in React.xcodeproj. Skipping.'.yellow
    return
  end

  # location of project is different relative to packager script
  script = old_packager_phase.shell_script.gsub(%r{../scripts}, '../node_modules/react-native/scripts')

  phase = app_target.new_shell_script_build_phase old_packager_phase.name
  phase.shell_script = script

  # Move packager script to first position. This is independent of the
  # entire Xcode build process. As an optimization, the packager can
  # load its dependencies in parallel. This is the way it is on the
  # original React.xcodeproj.
  app_target.build_phases.delete phase
  app_target.build_phases.insert 0, phase
end

#app_targetObject



30
31
32
# File 'lib/react_native_util/project.rb', line 30

def app_target
  targets.find { |t| t.name == app_name }
end

#dependenciesArray<String>

A list of external dependencies from NPM requiring react-native link.

Returns:

  • (Array<String>)

    a list of NPM package names



76
77
78
79
80
81
82
83
84
# File 'lib/react_native_util/project.rb', line 76

def dependencies
  return [] if libraries_group.nil?

  dependency_paths.map do |path|
    # Find the root above the ios/*.xcodeproj under node_modules
    root = File.expand_path '../..', path
    File.basename root
  end
end

#dependency_pathsArray<String>

Paths to Xcode projects in the Libraries group from external deps.

Returns:

  • (Array<String>)

    a list of absolute paths to Xcode projects



88
89
90
91
92
93
# File 'lib/react_native_util/project.rb', line 88

def dependency_paths
  return [] if libraries_group.nil?

  paths = libraries_group.children.reject { |c| DEFAULT_DEPENDENCIES.include?(c.name.sub(/\.xcodeproj$/, '')) }.map(&:path)
  paths.map { |p| File.expand_path p, File.join(Dir.pwd, 'ios') }
end

#libraries_groupObject

A representation of the Libraries group (if any) from the Xcode project.

Returns:

  • the Libraries group



47
48
49
# File 'lib/react_native_util/project.rb', line 47

def libraries_group
  self['Libraries']
end

#library_rootsObject



95
96
97
98
99
# File 'lib/react_native_util/project.rb', line 95

def library_roots
  libraries_group.children.map do |library|
    File.basename(library.path).sub(/\.xcodeproj$/, '')
  end
end

#packager_phaseObject

Returns the original Start Packager build phase (from the React.xcodeproj under node_modules). This contains the original script.

Returns:

  • the packager build phase if found

  • nil if not found



137
138
139
# File 'lib/react_native_util/project.rb', line 137

def packager_phase
  targets.first.build_phases.find { |p| p.name =~ /packager/i }
end

#remove_libraries_from_target(target) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
# File 'lib/react_native_util/project.rb', line 62

def remove_libraries_from_target(target)
  log "Removing Libraries from #{target.name}"
  to_remove = target.frameworks_build_phase.files.select do |file|
    path = file.file_ref.pretty_print
    next false unless /^lib(.+)\.a$/.match?(path)

    static_libs.include?(path)
  end

  to_remove.each { |f| target.frameworks_build_phase.remove_build_file f }
end

#remove_libraries_groupObject

Remove the Libraries group from the xcodeproj in memory.



52
53
54
55
56
57
58
59
60
# File 'lib/react_native_util/project.rb', line 52

def remove_libraries_group
  # Remove links against these static libraries
  targets.reject { |t| t.name =~ /-tvOS/ }.each do |t|
    remove_libraries_from_target t
  end

  log 'Removing Libraries group'
  libraries_group.remove_from_project
end

#static_libsArray<String>

All static libraries from the Libraries group

Returns:

  • (Array<String>)

    an array of filenames



129
130
131
# File 'lib/react_native_util/project.rb', line 129

def static_libs
  library_roots.map { |root| "lib#{root}.a" }
end

#test_targetObject



34
35
36
# File 'lib/react_native_util/project.rb', line 34

def test_target
  targets.select(&:test_target_type?).reject { |t| t.name =~ /tvOS/ }.first
end

#validate_app_target!Object

Validate an assumption about the project. TODO: Provide override option.

Raises:

  • ConversionError if an application target is not found with the same name as the project.



40
41
42
43
# File 'lib/react_native_util/project.rb', line 40

def validate_app_target!
  raise ConversionError, "Unable to find target #{app_name} in #{path}." if app_target.nil?
  raise ConversionError, "Target #{app_name} is not an application target." unless app_target.product_type == 'com.apple.product-type.application'
end