Class: PodBuilder::Command::Build

Inherits:
Object
  • Object
show all
Defined in:
lib/pod_builder/command/build.rb

Class Method Summary collapse

Class Method Details

.callObject



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/pod_builder/command/build.rb', line 6

def self.call
  Configuration.check_inited
  PodBuilder::prepare_basepath

  argument_pods = ARGV.dup

  unless argument_pods.count > 0
    return -1
  end

  raise "\n\nPlease rename your Xcode installation path removing spaces, current `#{`xcode-select -p`.strip()}`\n".red if `xcode-select -p`.strip().include?(" ")

  Podfile.sanity_check()
  check_not_building_subspecs(argument_pods)

  puts "Loading Podfile".yellow

  install_update_repo = OPTIONS.fetch(:update_repos, true)
  installer, analyzer = Analyze.installer_at(PodBuilder::basepath, install_update_repo)

  all_buildable_items = Analyze.podfile_items(installer, analyzer)
  prebuilt_items = all_buildable_items.select { |x| x.is_prebuilt }
  buildable_items = all_buildable_items - prebuilt_items

  build_all = argument_pods.first == "*"
  if build_all
    argument_pods = all_buildable_items.map(&:root_name).uniq
  else
    argument_pods = Podfile::resolve_pod_names(argument_pods, all_buildable_items)
    argument_pods.uniq!
  end

  available_argument_pods = argument_pods.select { |x| all_buildable_items.map(&:root_name).include?(x) }
  (argument_pods - available_argument_pods).each { |x|
    puts "'#{x}' not found, skipping".magenta
  }
  argument_pods = available_argument_pods.uniq

  Podfile.restore_podfile_clean(all_buildable_items)

  restore_file_error = Podfile.restore_file_sanity_check

  check_pods_exists(argument_pods, all_buildable_items)

  pods_to_build = resolve_pods_to_build(argument_pods, buildable_items)
  buildable_items -= pods_to_build

  argument_pods += pods_to_build.map(&:root_name)
  argument_pods.uniq!

  # We need to split pods to build in 4 groups
  # 1. pods to build in debug
  # 2. pods to build in release
  # 3. pods to build in debug as xcframeworks
  # 4. pods to build in release as xcframeworks

  check_not_building_development_pods(pods_to_build)

  # We need to recursively add dependencies to properly split pods in groups.
  # Example:
  # 1. PodA has a dep to PodB
  # 2. PodB is marked to be built as xcframework
  # 3. We rebuild PodA only (pods_to_build contains only PodA)
  # 4. We need to add dependencies recursively so that PodB is is added to pods_to_build_release_xcframework
  pods_to_build = pods_to_build.map { |t| t.recursive_dependencies(all_buildable_items) }.flatten.uniq

  pods_to_build_debug = pods_to_build.select { |x| x.build_configuration == "debug" }
  pods_to_build_release = pods_to_build - pods_to_build_debug

  pods_to_build_debug_xcframework = pods_to_build_debug.select { |x| x.build_xcframework }
  pods_to_build_debug -= pods_to_build_debug_xcframework

  pods_to_build_release_xcframework = pods_to_build_release.select { |x| x.build_xcframework }
  pods_to_build_release -= pods_to_build_release_xcframework

  check_dependencies_build_configurations(all_buildable_items)

  # When building mixed framwork/xcframeworks pods xcframeworks should be built last
  # so that the .xcframework overwrite the .framework if the same pod needs to be built
  # in both ways.
  # For example we might have configured to build only PodA as xcframework, another pod
  # PodB has a dependency to PodA. When Building PodB, PodA gets rebuilt as .framework
  # but then PodA gets rebuilt again as .xcframework overwriting the .framework.
  podfiles_items = [pods_to_build_debug] + [pods_to_build_release] + [pods_to_build_debug_xcframework] + [pods_to_build_release_xcframework]

  install_using_frameworks = Podfile::install_using_frameworks(analyzer)
  if Configuration.react_native_project
    if install_using_frameworks
      raise "\n\nOnly static library packaging currently supported for react native projects. Please remove 'use_frameworks!' in #{PodBuilder::basepath("Podfile")}\n".red
    end
    prepare_defines_modules_override(all_buildable_items)
  else
    unless install_using_frameworks
      raise "\n\nOnly framework packaging currently supported. Please add 'use_frameworks!' at root level (not nested in targets) in #{PodBuilder::basepath("Podfile")}\n".red
    end
  end

  build_catalyst = should_build_catalyst(installer)

  install_result = InstallResult.new
  podfiles_items.reject { |x| x.empty? }.each do |podfile_items|
    build_configuration = podfile_items.map(&:build_configuration).uniq.first

    # We need to recursively find dependencies again because some of the required dependencies might have been moved to a separate group
    # Example:
    # 1. PodA has a dep to PodB
    # 2. PodB is marked to be built as xcframework -> PodB will be added to pods_to_build_release_xcframework and won't be present in
    # pods_to_build_release and therefore build will fail
    podfile_items = podfile_items.map { |t| t.recursive_dependencies(all_buildable_items) }.flatten.uniq

    podfile_content = Podfile.from_podfile_items(podfile_items, analyzer, build_configuration, install_using_frameworks, build_catalyst, podfile_items.first.build_xcframework)

    PodBuilder::safe_rm_rf(Configuration.build_path)
    FileUtils.mkdir_p(Configuration.build_path)

    init_git(Configuration.build_path) # this is needed to be able to call safe_rm_rf

    Configuration.pre_actions[:install]&.execute()

    install_result += Install.podfile(podfile_content, podfile_items, argument_pods, podfile_items.first.build_configuration)

    FileUtils.rm_f(PodBuilder::basepath("Podfile.lock"))

    Configuration.post_actions[:build]&.execute()
  end

  install_result.write_prebuilt_info_files

  Clean::prebuilt_items(all_buildable_items)

  Licenses::write(install_result.licenses, all_buildable_items)

  Podspec::generate(all_buildable_items, analyzer, install_using_frameworks)

  builded_pods = podfiles_items.flatten

  builded_pods_and_deps = podfiles_items.flatten.map { |t| t.recursive_dependencies(all_buildable_items) }.flatten.uniq
  builded_pods_and_deps.select! { |x| !x.is_prebuilt }

  prebuilt_pods_to_install = prebuilt_items.select { |x| argument_pods.include?(x.root_name) }
  Podfile::write_restorable(builded_pods_and_deps + prebuilt_pods_to_install, all_buildable_items, analyzer)
  if !OPTIONS.has_key?(:skip_prebuild_update)
    Podfile::write_prebuilt(all_buildable_items, analyzer)
  end

  Podfile::install

  if (restore_file_error = restore_file_error) && Configuration.restore_enabled
    puts "\n\n⚠️ Podfile.restore was found invalid and was overwritten. Error:\n #{restore_file_error}".red
  end

  puts "\n\n🎉 done!\n".green
  return 0
end