Module: Pod::PodGenerate::Patches::InstallerPatch::ForceIncrementalInstall

Defined in:
lib/cocoapods-podgenerate/patches/installer_patch.rb

Overview

── 优化 1: 强制启用增量安装模式 ──

在 install! 入口处设置 installation_options,强制启用:

- incremental_installation:   只重新生成有变更的 target
- generate_multiple_pod_projects: 每个 pod 独立 xcodeproj

这两个选项是 CocoaPods 内置的(默认关闭),我们通过 monkey-patch 在 super 之前设置,对所有后续流程生效。

Instance Method Summary collapse

Instance Method Details

#create_and_save_projects(pod_targets_to_generate, aggregate_targets_to_generate, build_configurations, project_object_version) ⇒ Object

── 优化 3+4: 项目生成 + 并行 configure_schemes ──

完全覆盖原 create_and_save_projects 方法,添加并行 configure_schemes。流程:

1. 创建 generator → 调用 generate!(并行安装 pod targets)
2. 设置实例变量(@pods_project 等)
3. UUID 预测 + 稳定化
4. 创建 writer → 并行清理/重建 scheme/保存
5. 并行 configure_schemes(每个 project 独立)


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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/cocoapods-podgenerate/patches/installer_patch.rb', line 135

def create_and_save_projects(pod_targets_to_generate, aggregate_targets_to_generate,
                             build_configurations, project_object_version)
  UI.section 'Generating Pods project' do
    generator = create_generator(pod_targets_to_generate, aggregate_targets_to_generate,
                                 build_configurations, project_object_version,
                                 installation_options.generate_multiple_pod_projects)

    pod_project_generation_result = generator.generate!
    @target_installation_results = pod_project_generation_result.target_installation_results
    @pods_project = pod_project_generation_result.project
    @pod_target_subprojects = pod_project_generation_result.projects_by_pod_targets.keys
    @generated_projects = ([pods_project] + pod_target_subprojects).compact
    @generated_pod_targets = pod_targets_to_generate
    @generated_aggregate_targets = aggregate_targets_to_generate || []
    projects_by_pod_targets = pod_project_generation_result.projects_by_pod_targets

    predictabilize_uuids(generated_projects) if installation_options.deterministic_uuids?
    stabilize_target_uuids(generated_projects)

    projects_writer = Pod::Installer::Xcode::PodsProjectWriter.new(sandbox, generated_projects,
                                                   target_installation_results.pod_target_installation_results,
                                                   installation_options)
    projects_writer.write! do
      run_podfile_post_install_hooks
    end

    # 并行 configure_schemes(多项目时)
    pods_project_pod_targets = pod_targets_to_generate - projects_by_pod_targets.values.flatten
    all_projects_by_pod_targets = {}
    if pods_project
      all_projects_by_pod_targets[pods_project] = pods_project_pod_targets
    end
    all_projects_by_pod_targets.merge!(projects_by_pod_targets) if projects_by_pod_targets

    if all_projects_by_pod_targets.size > 1
      parallel_configure_schemes(all_projects_by_pod_targets, generator, pod_project_generation_result)
    else
      all_projects_by_pod_targets.each do |project, pts|
        generator.configure_schemes(project, pts, pod_project_generation_result)
      end
    end
  end
end

#generate_pods_projectObject

── 优化 2: 完全无变更时跳过项目生成 + C2/H1 修复 ──

原流程即使没有任何 target 变更,create_and_save_projects 仍会被调用,执行大量 file I/O 操作。本方法在 analyze_project_cache 之后检查:

如果 pod_targets_to_generate 和 aggregate_targets_to_generate
都为空(即没有任何 target 需要重新生成),则:
  1. 跳过 create_and_save_projects(pod 项目已在磁盘上,内容未变)
  2. 仍执行 SandboxDirCleaner(清理可能被移除的 pod 的残留文件)
  3. 仍调用 update_project_cache(保持缓存时间戳最新)
  4. 仍调用 run_podfile_post_install_hooks(Podfile hook 不能跳过)

v0.1.4 修复 (C2):

- 设置 @pods_project = nil, @pod_target_subprojects = [],
  @generated_projects = [](避免下游引用 nil)
- 调用 run_podfile_post_install_hooks(之前被跳过导致 hook 静默丢失)

v0.1.4 修复 (H1):

- 使用上次的 @target_installation_results 更新缓存
  (而非空的 InstallationResults,避免清除 metadata_cache)


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
# File 'lib/cocoapods-podgenerate/patches/installer_patch.rb', line 84

def generate_pods_project
  stage_sandbox(sandbox, pod_targets)

  cache_analysis_result = analyze_project_cache
  ptg = cache_analysis_result.pod_targets_to_generate
  atg = cache_analysis_result.aggregate_targets_to_generate

  if ptg.empty? && (atg.nil? || atg.empty?)
    Pod::UI.puts "[cocoapods-podgenerate] No changes — skipping project generation"

    # C2 修复: 初始化所有实例变量(避免下游代码获得 nil)
    @generated_aggregate_targets = aggregate_targets
    @generated_pod_targets = []
    @pods_project = nil
    @pod_target_subprojects = []
    @generated_projects = []

    # C2 修复: 确保 post-install hooks 被调用
    run_podfile_post_install_hooks

    # 清理沙盒中残留的文件
    Pod::Installer::SandboxDirCleaner.new(sandbox, pod_targets, aggregate_targets).clean!

    # H1 修复: 使用上次的安装结果(而非空结果)更新缓存
    prev_results = @target_installation_results ||
      Pod::Installer::Xcode::PodsProjectGenerator::InstallationResults.new({}, {})
    update_project_cache(cache_analysis_result, prev_results)
    return
  end

  # 正常路径: 有 target 需要重新生成
  ptg.each do |pod_target|
    pod_target.build_headers.implode_path!(pod_target.headers_sandbox)
    sandbox.public_headers.implode_path!(pod_target.headers_sandbox)
  end

  create_and_save_projects(ptg, atg,
    cache_analysis_result.build_configurations, cache_analysis_result.project_object_version)
  Pod::Installer::SandboxDirCleaner.new(sandbox, pod_targets, aggregate_targets).clean!
  update_project_cache(cache_analysis_result, target_installation_results)
end

#install!Object



59
60
61
62
63
# File 'lib/cocoapods-podgenerate/patches/installer_patch.rb', line 59

def install!
  installation_options.incremental_installation = true
  installation_options.generate_multiple_pod_projects = true
  super
end