cocoapods-podgenerate 0.1.11 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5c79d61610d0b30ff557b52df29c28607ed0062d6c034ba6e69dc6ad7d2463ee
4
- data.tar.gz: e6d5e86da46594113833fa2d30a1bf3af3b99f9054099911c4e3d0e55badab4b
3
+ metadata.gz: 8339033a347400214385a8528759a3ca70fbe8d739579566bab631277f89e82c
4
+ data.tar.gz: aef46f6fbac5628e104b628efa2b4d37f3fd9e9a0e2eccaf9d30208b884c4837
5
5
  SHA512:
6
- metadata.gz: 52ef26a16cb084d8a65300700f3fe4a1ef868af792270b5140d4a33b006d2a72cc3e1c4472c3d92e636edc4d578c822d257b9cda27217cfb274444db66dbdc23
7
- data.tar.gz: 1d3f0d33c76d37690ee97d282f9f9034ee4d4e8de91afa594059fb4ccfc359f1d31543c48567a93fb346e837eed97ccc592e02878207a22477d971843a7a1110
6
+ metadata.gz: 26608721fe59f715e12457f268d45d8d9ccc375758d38c4e5fd4e9c0b678e8e09c3339f7ebf22deba6fe86d1ae5f5598d46d7400af58f78a0dfbaf8a4d3f1e27
7
+ data.tar.gz: 7a931fa7d0dc2613c35efffd823b76a0f6cabb53aef0b3834e9e9c6c4b2a4450528c960795cd1255e8380c0c2c6687ad34920ae06ab82d740e465a73ea6dc6d4
@@ -91,6 +91,23 @@ module Pod
91
91
  ptg = cache_analysis_result.pod_targets_to_generate
92
92
  atg = cache_analysis_result.aggregate_targets_to_generate
93
93
 
94
+ # ── 本地开发 pod 文件级变更检测 ──
95
+ # CocoaPods 的 TargetCacheKey 使用 spec attributes_hash(如
96
+ # source_files 的 glob 模式字符串)做哈希,不检查 glob 展开后的
97
+ # 实际文件列表。当本地开发 pod(:path)中源文件有增删时,
98
+ # glob 模式不变 → cache key 不变 → ptg 为空 → "No changes" 跳过。
99
+ # 解决方法:为每个开发 pod 计算当前源文件列表的 SHA256,
100
+ # 与上次运行的清单比较,有差异时强制加入 ptg。
101
+ if ptg.empty? && (atg.nil? || atg.empty?)
102
+ unless sandbox.development_pods.empty?
103
+ dev_changed = detect_dev_pod_file_changes
104
+ unless dev_changed.empty?
105
+ Pod::UI.puts "[cocoapods-podgenerate] Dev pod files changed: #{dev_changed.map(&:pod_name).join(', ')} — forcing regeneration"
106
+ ptg = dev_changed
107
+ end
108
+ end
109
+ end
110
+
94
111
  if ptg.empty? && (atg.nil? || atg.empty?)
95
112
  Pod::UI.puts "[cocoapods-podgenerate] No changes — skipping project generation"
96
113
 
@@ -110,6 +127,13 @@ module Pod
110
127
  # 清理沙盒中残留的文件
111
128
  Pod::Installer::SandboxDirCleaner.new(sandbox, pod_targets, aggregate_targets).clean!
112
129
 
130
+ # 跳过路径修复: touch Pods project.pbxproj 让 Xcode 感知到变化
131
+ # 否则 Xcode 的 Dynamic Project Reloading 不会触发
132
+ pods_pbxproj = File.join(sandbox.project_path.to_s, 'project.pbxproj')
133
+ if File.file?(pods_pbxproj)
134
+ FileUtils.touch(pods_pbxproj)
135
+ end
136
+
113
137
  # H1 修复: 当没有目标需要生成时,跳过 update_project_cache 调用
114
138
  # @target_installation_results 仅在 create_and_save_projects 内设置,
115
139
  # 在跳过路径上始终为 nil,回退到空 InstallationResults.new({}, {})
@@ -294,6 +318,92 @@ module Pod
294
318
  pool.kill
295
319
  end
296
320
  end
321
+
322
+ # ── 本地开发 pod 文件级变更检测 ──
323
+ #
324
+ # CocoaPods 的 TargetCacheKey 使用 pod_target.root_spec.attributes_hash
325
+ # 作为缓存键的一部分。attributes_hash 中包含 source_files 等 glob 模式
326
+ # 字符串(如 "lib/**/*.rb"),而不是实际展开后的文件列表。
327
+ # 当本地开发 pod 的源文件在文件系统层面发生增删时,glob 模式不变,
328
+ # 缓存键也就不会变化,导致 "No changes — skipping project generation"
329
+ # 漏掉文件级变更。
330
+ #
331
+ # 解决方法:为每个开发 pod 维护一个 SHA256 清单文件,记录其 source_files
332
+ # glob 展开后的实际文件列表的哈希值。每次 pod install 时重新计算并比较。
333
+ # 清单存储在 Pods/.cocoapods-podgenerate-devpod-manifest.yaml 中。
334
+ DEV_POD_FILE_MANIFEST = '.cocoapods-podgenerate-devpod-manifest.yaml'
335
+
336
+ # 检测开发 pod 中源文件是否有增删
337
+ # 返回需要重新生成的 PodTarget 数组
338
+ def detect_dev_pod_file_changes
339
+ dev_pods = sandbox.development_pods
340
+ return [] if dev_pods.empty?
341
+
342
+ manifest_path = File.join(sandbox.root.to_s, DEV_POD_FILE_MANIFEST)
343
+
344
+ # 读取上次记录的 hash 值
345
+ previous = {}
346
+ if File.exist?(manifest_path)
347
+ begin
348
+ data = YAML.safe_load(File.read(manifest_path))
349
+ previous = data if data.is_a?(Hash)
350
+ rescue => e
351
+ Pod::UI.warn "[cocoapods-podgenerate] Failed to read dev pod manifest: #{e.message}"
352
+ end
353
+ end
354
+
355
+ current = {}
356
+ changed = []
357
+
358
+ pod_targets.each do |pt|
359
+ name = pt.pod_name
360
+ next unless dev_pods.key?(name)
361
+
362
+ current[name] = compute_dev_pod_file_digest(pt)
363
+ if previous[name] != current[name]
364
+ changed << pt
365
+ end
366
+ end
367
+
368
+ # 持久化当前清单
369
+ begin
370
+ File.write(manifest_path, YAML.dump(current))
371
+ rescue => e
372
+ Pod::UI.warn "[cocoapods-podgenerate] Failed to write dev pod manifest: #{e.message}"
373
+ end
374
+
375
+ changed
376
+ end
377
+
378
+ # 计算开发 pod 当前源文件列表的 SHA256
379
+ # 使用 podspec 中的 source_files/headers glob 模式,
380
+ # 在文件系统层面展开后对相对路径排序做哈希。
381
+ # @return [String] 十六进制 SHA256(空文件列表则是空字符串哈希)
382
+ def compute_dev_pod_file_digest(pod_target)
383
+ pod_name = pod_target.pod_name
384
+ pod_dir = sandbox.pod_dir(pod_name)
385
+ return '' unless pod_dir && File.directory?(pod_dir)
386
+
387
+ pod_dir_str = pod_dir.to_s
388
+ files = []
389
+
390
+ pod_target.spec_consumers.each do |consumer|
391
+ patterns = []
392
+ patterns.concat(Array(consumer.source_files))
393
+ patterns.concat(Array(consumer.public_header_files))
394
+ patterns.concat(Array(consumer.private_header_files))
395
+
396
+ patterns.each do |pattern|
397
+ full_pattern = File.join(pod_dir_str, pattern)
398
+ Dir.glob(full_pattern).each do |f|
399
+ next unless File.file?(f)
400
+ files << f.sub("#{pod_dir_str}/", '')
401
+ end
402
+ end
403
+ end
404
+
405
+ Digest::SHA256.hexdigest(files.uniq.sort.join("\n"))
406
+ end
297
407
  end
298
408
 
299
409
  # ── 优化 3: 并行化 PodTargetIntegrator(修复 M3)──
@@ -75,26 +75,38 @@ module Pod
75
75
  # 增量 + 并行保存项目
76
76
  #
77
77
  # 流程:
78
- # 1. 过滤: 跳过 pbxproj 内容未变的项目(SHA256 摘要比对)
79
- # 2. 排序: 对需要保存的项目调用 sort(:groups_position => :below)
80
- # 3. 保存: 多项目并行写入(每个 xcodeproj 独立目录)
78
+ # 1. SHA256 摘要比对,分出变更和未变更项目
79
+ # 2. 未变更项目:touch pbxproj 更新时间戳(触发 Xcode 动态刷新)
80
+ # 3. 变更项目:排序后并行保存
81
81
  #
82
82
  # 【Bug 修复 L1】
83
- # 只有当 old_digest 和 current_digest 都非 nil 且相等时才跳过。
83
+ # 只有当 old_digest 和 current_digest 都非 nil 且相等时才跳过保存。
84
84
  # 如果任一为 nil(例如文件不可读),一律重新保存以确保项目完整性。
85
85
  #
86
+ # 【Xcode 动态刷新】
87
+ # v0.1.12 修复:未变更的项目也需要 touch pbxproj 文件,
88
+ # 否则 Xcode 不会触发 Dynamic Project Reloading(项目树不刷新)。
89
+ #
86
90
  # @param projects [Array<Project>] 要保存的项目列表
87
91
  def save_projects(projects)
88
- to_save = projects.select do |project|
92
+ to_save = []
93
+ unchanged = []
94
+ projects.each do |project|
89
95
  old = @project_digests[project.object_id]
90
96
  cur = digest_pbxproj(project)
91
97
  if old && cur && old == cur
92
- Pod::UI.message "- Skipping unchanged project #{UI.path project.path}"
93
- false
98
+ unchanged << project
94
99
  else
95
- true
100
+ to_save << project
96
101
  end
97
102
  end
103
+
104
+ # 先 touch 未变更项目(轻量操作,触发 Xcode 动态刷新)
105
+ unless unchanged.empty?
106
+ Pod::UI.message "- Touching #{unchanged.size} unchanged projects for Xcode refresh"
107
+ unchanged.each { |p| touch_pbxproj(p) }
108
+ end
109
+
98
110
  return if to_save.empty?
99
111
 
100
112
  # 排序(串行 — sort 操作轻量,并行开销反而更大)
@@ -262,6 +274,24 @@ module Pod
262
274
  nil
263
275
  end
264
276
 
277
+ # touch 项目的 pbxproj 文件,更新修改时间戳
278
+ #
279
+ # Xcode 的 Dynamic Project Reloading 通过检测 xcodeproj 内
280
+ # project.pbxproj 的修改时间来触发。当 SHA256 摘要未变化时
281
+ # 跳过 save 会导致 Xcode 无法感知变化,项目树不刷新。
282
+ # 本方法即使内容不变也更新文件修改时间。
283
+ #
284
+ # @param project [Project] Xcodeproj 项目
285
+ def touch_pbxproj(project)
286
+ path = project.path
287
+ return unless path
288
+ pbx_path = path.to_s.end_with?('.xcodeproj') ? File.join(path.to_s, 'project.pbxproj') : path.to_s
289
+ return unless File.file?(pbx_path)
290
+ FileUtils.touch(pbx_path)
291
+ rescue StandardError
292
+ nil
293
+ end
294
+
265
295
  # 计算线程池大小
266
296
  def compute_pool_size
267
297
  [[Etc.nprocessors - 1, 2].max, 16].min
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocoapods-podgenerate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.11
4
+ version: 0.1.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - PodGenerate Team