Module: CocoaPodsLocalOverride
- Defined in:
- lib/cocoapods_plugin.rb
Constant Summary collapse
- CONFIG_FILE_NAME =
默认配置文件名(放在 Podfile 同级目录)
'Podfile.local'- ENV_DISABLE_KEY =
禁用插件的环境变量名
'COCOAPODS_LOCAL_OVERRIDE_DISABLE'- ENV_CONFIG_KEY =
自定义配置文件路径的环境变量名
'COCOAPODS_LOCAL_OVERRIDE_CONFIG'- PLUGIN_ROOT =
插件自身的根目录(gem 安装根路径),用于定位模板文件
File.('..', __dir__).freeze
- EXAMPLE_FILE =
模板文件:当 Podfile.local 不存在时自动从该文件复制创建
'Podfile.local.example'- C_RESET =
===========================================================================
终端 ANSI 颜色常量
颜色体系: C_RESET / C_DIM — 重置与弱化(箭头、箭头两边的空格等辅助元素) C_CYAN — 主要信息展示色(pod 路径/版本号/分支名等值) C_GREEN — 成功信息([+] 前缀、配置创建等正面状态) C_YELLOW — 警告信息([x] 前缀、路径不存在等异常状态) C_MAGENTA — 未使用(保留) C_RED — 未使用(保留) LABEL_COLORS — 标签专用色:蓝绿色系渐变,视觉统一但不突兀
"\e[0m"- C_DIM =
重置所有样式
"\e[2m"- C_CYAN =
暗淡/弱化效果(用于箭头 → 等辅助元素)
"\e[36m"- C_GREEN =
青色(用于显示的路径/版本/分支名等值)
"\e[32m"- C_YELLOW =
绿色([+] 成功前缀)
"\e[33m"- C_MAGENTA =
黄色([x] 警告前缀)
"\e[35m"- C_RED =
品红(保留未使用)
"\e[31m"- COLORS =
pod 值的颜色映射(用于显示的路径/版本号/分支名等)
{ local: C_CYAN, version: C_GREEN, branch: C_MAGENTA }.freeze
- LABEL_COLORS =
标签颜色映射([ LOCAL ] / [ VERSION ] / [ BRANCH ] 颜色) 使用 256 色调色板,蓝绿色系渐变:绿→青→蓝,同色系但有区分度
{ local: "\e[38;5;120m", # 春绿 version: "\e[38;5;80m", # 青蓝 branch: "\e[38;5;39m" # 湖蓝 }.freeze
- LABELS =
标签文字映射
{ local: '[ LOCAL ]', version: '[ VERSION ]', branch: '[ BRANCH ]' }.freeze
Class Method Summary collapse
-
.add_local_config_to_project(generated_projects) ⇒ Object
将 Podfile.local 添加到 Pods.xcodeproj 的主 Group 中,并移至首位.
-
.all_config_empty? ⇒ Boolean
检查所有配置项是否均为空(包括 nil 和空 Hash) 用于快速判断是否需要安装 monkey-patch,避免无配置时浪费性能.
-
.apply_podfile_hook! ⇒ Object
拦截 Podfile#pod 方法:根据 Podfile.local 配置改写 pod 声明 在模块底部自动调用(加载即生效).
-
.apply_pods_project_hook! ⇒ Object
安装 Pods 工程钩子:拦截 create_and_save_projects 以添加 Podfile.local.
-
.apply_transitive_dependency_hook! ⇒ Object
安装传递依赖注入钩子:在 resolve_dependencies 执行前注入.
-
.disabled? ⇒ Boolean
检查插件是否被环境变量禁用 首次调用时读取 COCOAPODS_LOCAL_OVERRIDE_DISABLE,结果缓存到 @disabled。 支持的值: 1, true, yes(不区分大小写).
-
.ensure_config_file(config_path) ⇒ Object
如果 Podfile.local 不存在,从 gem 内置的 Podfile.local.example 模板 复制一份到 Podfile 同级目录,方便开发者快速上手。 仅在执行 pod install / pod update 且目录存在 Xcode 工程时创建,否则跳过。.
-
.find_config_path ⇒ String
定位配置文件路径,优先级: 1.
-
.format_pod_line(category, name, value, via: nil) ⇒ String
格式化输出一行 pod 覆盖信息,格式示例: [ LOCAL ] SomePod → ../path/to/SomePod [ VERSION ] MyPod → 1.2.3 [ BRANCH ] SomeGitPod → develop-9.6.2.
-
.inject_transitive_local_pods(podfile) ⇒ Object
BFS 遍历依赖树,将未声明但已在 local_pods 中的传递依赖自动注入.
-
.install_or_update? ⇒ Boolean
判断当前执行的 pod 命令是否为 install / update。 插件会在任意 pod 命令运行时被加载(如 repo update / env / search 等), 但只有 install / update 才会解析 Podfile,因此仅在此时自动创建 Podfile.local, 避免其他命令在项目目录误生成配置文件。.
-
.load_config ⇒ Hash
加载并解析 Podfile.local(YAML 格式),结果缓存到 @config。 典型配置结构: local_pods: { PodName: "../relative/path" } replace_versions: { PodName: "1.2.3" } replace_branches: { PodName: "develop-x.y.z" }.
-
.local_pods ⇒ Hash
本地 pod 映射表 => relative_path.
-
.normalize_hash(raw) ⇒ Hash{String => String}
标准化 YAML 中的 Hash 值: 1.
-
.replace_branches ⇒ Hash
分支替换映射表 => branch_name.
-
.replace_versions ⇒ Hash
版本替换映射表 => version_string.
-
.resolve_podspec_path(local_path, pod_name = nil) ⇒ String?
从本地 pod 目录中查找 podspec 文件 优先按 pod 名称查找(Name.podspec / Name.podspec.json), 回退到扫描目录下任意 podspec。.
-
.xcode_project_dir?(config_path) ⇒ Boolean
判断 config_path 所在目录是否存在 Xcode 工程(*.xcodeproj)。 仅在有工程的目录才允许自动创建 Podfile.local, 避免在非 Xcode 项目目录误生成配置文件。.
Class Method Details
.add_local_config_to_project(generated_projects) ⇒ Object
将 Podfile.local 添加到 Pods.xcodeproj 的主 Group 中,并移至首位
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 |
# File 'lib/cocoapods_plugin.rb', line 484 def self.add_local_config_to_project(generated_projects) config_path = find_config_path return unless File.exist?(config_path) # 遍历所有生成的工程(通常只有 Pods.xcodeproj 一个) Array(generated_projects).each do |project| next unless project filename = File.basename(config_path) # 检查是否已经添加过(避免重复添加) already_added = project.files.any? do |f| f.path == filename || f.path == config_path || (f.real_path.to_s == File.(config_path) rescue false) end next if already_added # 作为文件引用添加到工程 project.add_podfile(config_path) # 将 Podfile.local 移到第一个位置(排在 Podfile 前面) main_group = project.main_group local_ref = main_group.children.find { |f| f.path == filename } if local_ref idx = main_group.children.index(local_ref) if idx && idx > 0 # 移除后插入到首位 main_group.children.delete_at(idx) main_group.children.insert(0, local_ref) end end project.save Pod::UI.puts "#{C_GREEN}[+] Added #{filename} to Pods project#{C_RESET}" end end |
.all_config_empty? ⇒ Boolean
检查所有配置项是否均为空(包括 nil 和空 Hash) 用于快速判断是否需要安装 monkey-patch,避免无配置时浪费性能
410 411 412 413 |
# File 'lib/cocoapods_plugin.rb', line 410 def self.all_config_empty? cfg = load_config cfg.values.all? { |v| v.nil? || v.empty? } end |
.apply_podfile_hook! ⇒ Object
拦截 Podfile#pod 方法:根据 Podfile.local 配置改写 pod 声明 在模块底部自动调用(加载即生效)
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 |
# File 'lib/cocoapods_plugin.rb', line 296 def self.apply_podfile_hook! return if @podfile_hook_applied # 预加载配置以触发 @max_name_len 计算 load_config # 如果被禁用或配置为空,不安装钩子 if disabled? || all_config_empty? @podfile_hook_applied = true return end # 打开 Pod::Podfile 的单例类(class_eval),注入自定义 pod 方法 Pod::Podfile.class_eval do # 幂等检查:如果已经 alias 过则跳过 unless method_defined?(:local_override_original_pod) # 1. 保存原始 pod 方法 alias_method :local_override_original_pod, :pod # 2. 定义新的 pod 方法,加入覆盖逻辑 define_method :pod do |*args| pod_name = args[0].to_s # 获取当前配置(每次调用都实时获取,但不触发重复解析) local_pods = CocoaPodsLocalOverride.local_pods replace_versions = CocoaPodsLocalOverride.replace_versions replace_branches = CocoaPodsLocalOverride.replace_branches # 按优先级匹配:local > version > branch > 原始调用 if local_pods && local_pods.key?(pod_name) handle_local(pod_name, local_pods[pod_name], args) elsif replace_versions && replace_versions.key?(pod_name) handle_version(pod_name, replace_versions[pod_name]) elsif replace_branches && replace_branches.key?(pod_name) handle_branch(pod_name, replace_branches[pod_name], args) else # 未命中任何覆盖,调用原始方法 local_override_original_pod(*args) end end # ===================================================================== # 私有辅助方法(注入 Pod::Podfile 实例) # ===================================================================== private # 处理 local 类型覆盖:将 pod 指向本地绝对路径 # 路径不存在时回退到远程版本,避免构建中断 define_method :handle_local do |name, dev_path, original_args| # 相对路径 → 基于 Podfile 目录计算绝对路径 abs_path = resolve_absolute_path(dev_path) if File.directory?(abs_path) # 打印覆盖信息,格式: [ LOCAL ] PodName → ../relative/path Pod::UI.puts CocoaPodsLocalOverride.format_pod_line(:local, name, dev_path) # 使用 :path 选项指向本地目录,:inhibit_warnings => false 保留编译警告 local_override_original_pod(name, :path => abs_path, :inhibit_warnings => false) else Pod::UI.warn "#{CocoaPodsLocalOverride::C_YELLOW}[x] path not found: #{abs_path}, use remote for #{name}#{CocoaPodsLocalOverride::C_RESET}" local_override_original_pod(*original_args) end end # 处理 version 类型覆盖:将 pod 锁定到指定版本号 define_method :handle_version do |name, new_version| Pod::UI.puts CocoaPodsLocalOverride.format_pod_line(:version, name, new_version) # 直接传递版本号字符串作为第二个位置参数 local_override_original_pod(name, new_version, :inhibit_warnings => false) end # 处理 branch 类型覆盖:将 pod 的 :branch 选项替换为目标分支 # 前提:原始声明中第二个参数必须是 Hash(如 pod 'X', :git => '...', :branch => '...') define_method :handle_branch do |name, new_branch, args| Pod::UI.puts CocoaPodsLocalOverride.format_pod_line(:branch, name, new_branch) args_copy = args.dup if args_copy[1].is_a?(Hash) # 合并 :branch key,覆盖原始值 args_copy[1] = args_copy[1].merge(:branch => new_branch) else # 第二个参数不是 Hash 时无法安全替换,跳过并警告 Pod::UI.warn "#{CocoaPodsLocalOverride::C_YELLOW}[x] #{name}: 2nd arg not Hash, branch replace skipped#{CocoaPodsLocalOverride::C_RESET}" end local_override_original_pod(*args_copy) end # 将相对路径转换为基于 Podfile 所在目录的绝对路径 # 已是绝对路径则原样返回 define_method :resolve_absolute_path do |rel_path| p = Pathname.new(rel_path) return rel_path if p.absolute? # 基准目录:Podfile 所在目录,兜底为当前工作目录 base = begin File.dirname(Pod::Config.instance.podfile_path) rescue StandardError Dir.pwd end File.(rel_path, base) end end end @podfile_hook_applied = true end |
.apply_pods_project_hook! ⇒ Object
安装 Pods 工程钩子:拦截 create_and_save_projects 以添加 Podfile.local
461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 |
# File 'lib/cocoapods_plugin.rb', line 461 def self.apply_pods_project_hook! return if @pods_project_hook_applied # 触发配置加载(可能在 Podfile 不存在时触发自动创建) load_config @pods_project_hook_applied = true Pod::Installer.class_eval do unless method_defined?(:local_override_original_create_and_save_projects) alias_method :local_override_original_create_and_save_projects, :create_and_save_projects # 在原始方法执行完后,额外将 Podfile.local 添加到生成的 Pods 工程中 define_method :create_and_save_projects do |*args| local_override_original_create_and_save_projects(*args) CocoaPodsLocalOverride.add_local_config_to_project(@generated_projects) end end end end |
.apply_transitive_dependency_hook! ⇒ Object
安装传递依赖注入钩子:在 resolve_dependencies 执行前注入
644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 |
# File 'lib/cocoapods_plugin.rb', line 644 def self.apply_transitive_dependency_hook! return if @transitive_dependency_hook_applied load_config # 禁用或没有本地 pod 时跳过 if disabled? || local_pods.nil? || local_pods.empty? @transitive_dependency_hook_applied = true return end Pod::Installer.class_eval do unless method_defined?(:local_override_original_resolve_deps) alias_method :local_override_original_resolve_deps, :resolve_dependencies # 在依赖解析之前注入传递依赖,确保本地版本优先被解析 define_method :resolve_dependencies do CocoaPodsLocalOverride.inject_transitive_local_pods(podfile) local_override_original_resolve_deps end end end @transitive_dependency_hook_applied = true end |
.disabled? ⇒ Boolean
检查插件是否被环境变量禁用 首次调用时读取 COCOAPODS_LOCAL_OVERRIDE_DISABLE,结果缓存到 @disabled。 支持的值: 1, true, yes(不区分大小写)
114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/cocoapods_plugin.rb', line 114 def self.disabled? return @disabled unless @disabled.nil? val = ENV[ENV_DISABLE_KEY] # 仅当环境变量值为 1 / true / yes 时才算禁用 @disabled = %w[1 true yes].include?(val.to_s.downcase) if @disabled Pod::UI.puts "#{C_DIM}[i] cocoapods-local-override disabled by #{ENV_DISABLE_KEY}=#{val}#{C_RESET}" end @disabled end |
.ensure_config_file(config_path) ⇒ Object
如果 Podfile.local 不存在,从 gem 内置的 Podfile.local.example 模板 复制一份到 Podfile 同级目录,方便开发者快速上手。 仅在执行 pod install / pod update 且目录存在 Xcode 工程时创建,否则跳过。
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/cocoapods_plugin.rb', line 179 def self.ensure_config_file(config_path) return if File.exist?(config_path) # 非 install / update 命令不自动创建 return unless install_or_update? # 目录下没有 .xcodeproj 工程不自动创建 return unless xcode_project_dir?(config_path) example_path = File.join(PLUGIN_ROOT, EXAMPLE_FILE) unless File.exist?(example_path) Pod::UI.warn "#{C_YELLOW}[x] Template #{EXAMPLE_FILE} not found in gem#{C_RESET}" return end begin # 确保目标目录存在 FileUtils.mkdir_p(File.dirname(config_path)) # 复制模板文件(copy_file 保留原始文件权限) FileUtils.copy_file(example_path, config_path) Pod::UI.puts "#{C_GREEN}[+] Created #{File.basename(config_path)} from #{EXAMPLE_FILE}#{C_RESET}" rescue StandardError => e Pod::UI.warn "#{C_YELLOW}[x] Failed to create #{config_path}: #{e.}#{C_RESET}" end end |
.find_config_path ⇒ String
定位配置文件路径,优先级:
- 环境变量 COCOAPODS_LOCAL_OVERRIDE_CONFIG 指定的路径
- 默认:Podfile 所在目录/Podfile.local
- 兜底:当前工作目录/Podfile.local
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/cocoapods_plugin.rb', line 131 def self.find_config_path # 优先使用环境变量指定的自定义路径 custom = ENV[ENV_CONFIG_KEY] unless custom.to_s.strip.empty? custom = custom.strip if File.exist?(custom) return custom else Pod::UI.warn "#{C_YELLOW}[x] #{ENV_CONFIG_KEY}=#{custom} not found, fallback to default#{C_RESET}" end end # 默认:从 Podfile 所在目录拼接 Podfile.local podfile = begin Pod::Config.instance.podfile_path rescue StandardError nil end base = podfile ? File.dirname(podfile) : Dir.pwd File.join(base, CONFIG_FILE_NAME) end |
.format_pod_line(category, name, value, via: nil) ⇒ String
格式化输出一行 pod 覆盖信息,格式示例: [ LOCAL ] SomePod → ../path/to/SomePod [ VERSION ] MyPod → 1.2.3 [ BRANCH ] SomeGitPod → develop-9.6.2
425 426 427 428 429 430 431 432 433 434 435 436 |
# File 'lib/cocoapods_plugin.rb', line 425 def self.format_pod_line(category, name, value, via: nil) label = LABELS[category] if via via_visible = " (via #{via})" name_str = "#{name}#{C_DIM}#{via_visible}#{C_RESET}" pad_len = [@max_name_len - name.length - via_visible.length, 0].max padded = "#{name_str}#{' ' * pad_len}" else padded = name.ljust(@max_name_len) end "#{LABEL_COLORS[category]}#{label}#{C_RESET} #{padded} #{C_DIM}→#{C_RESET} #{C_CYAN}#{value}#{C_RESET}" end |
.inject_transitive_local_pods(podfile) ⇒ Object
BFS 遍历依赖树,将未声明但已在 local_pods 中的传递依赖自动注入
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 |
# File 'lib/cocoapods_plugin.rb', line 567 def self.inject_transitive_local_pods(podfile) lp = local_pods return if lp.nil? || lp.empty? # 确定 Podfile 所在目录(用于计算相对路径的绝对路径) podfile_dir = begin File.dirname(podfile.defined_in_file || Dir.pwd) rescue StandardError Dir.pwd end # 收集 Podfile 中已显式声明的所有 pod 名称 declared_names = Set.new podfile.target_definitions.each_value do |td| td.non_inherited_dependencies.each { |dep| declared_names.add(dep.name) } end # BFS 初始化:起始队列 = 已声明且同时存在于 local_pods 中的 pod visit_queue = declared_names.select { |n| lp.key?(n) } visited = Set.new(visit_queue) # 已访问集合,防止循环依赖 # 获取根 target definition(Pods),后续注入都在这里进行 root_td = podfile.target_definitions['Pods'] || podfile.target_definitions.values.first return unless root_td # BFS 主循环 while (name = visit_queue.shift) # 计算本地路径的绝对路径 abs_path = File.(lp[name], podfile_dir) podspec_path = resolve_podspec_path(abs_path, name) unless podspec_path Pod::UI.warn "#{C_YELLOW}[x] #{name}: no podspec found in #{abs_path}#{C_RESET}" next end # 解析 podspec 获取依赖列表 begin spec = Pod::Specification.from_file(podspec_path) rescue StandardError => e Pod::UI.warn "#{C_YELLOW}[x] #{name}: failed to parse #{podspec_path} — #{e.}#{C_RESET}" next end # 遍历每个依赖 spec.dependencies.each do |dep| # 兼容不同的依赖表示:Pod::Dependency 或 [name, requirement] 数组 dep_name = dep.respond_to?(:name) ? dep.name : dep.first dep_name = dep_name.to_s # 跳过不在 local_pods 中的依赖 next unless lp.key?(dep_name) # 跳过已在 Podfile 中显式声明的依赖 next if declared_names.include?(dep_name) # 跳过已访问过的依赖(防止循环) next if visited.include?(dep_name) dep_rel_path = lp[dep_name] dep_abs_path = File.(dep_rel_path, podfile_dir) unless File.directory?(dep_abs_path) Pod::UI.warn "#{C_YELLOW}[x] #{dep_name} (dep of #{name}): path not found #{dep_abs_path}#{C_RESET}" next end # 注入到根 target definition 中 root_td.store_pod(dep_name, :path => dep_abs_path, :inhibit_warnings => false) declared_names.add(dep_name) # 标记为已声明,防止后续重复注入 visited.add(dep_name) # 标记为已访问 visit_queue.push(dep_name) # 加入队列继续 BFS Pod::UI.puts CocoaPodsLocalOverride.format_pod_line(:local, dep_name, dep_rel_path, via: name) end end end |
.install_or_update? ⇒ Boolean
判断当前执行的 pod 命令是否为 install / update。 插件会在任意 pod 命令运行时被加载(如 repo update / env / search 等), 但只有 install / update 才会解析 Podfile,因此仅在此时自动创建 Podfile.local, 避免其他命令在项目目录误生成配置文件。
162 163 164 |
# File 'lib/cocoapods_plugin.rb', line 162 def self.install_or_update? %w[install update].include?(ARGV[0].to_s.downcase) end |
.load_config ⇒ Hash
加载并解析 Podfile.local(YAML 格式),结果缓存到 @config。 典型配置结构:
local_pods: { PodName: "../relative/path" }
replace_versions: { PodName: "1.2.3" }
replace_branches: { PodName: "develop-x.y.z" }
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/cocoapods_plugin.rb', line 216 def self.load_config return @config if @config_loaded @config_loaded = true # 环境变量禁用时直接返回空配置,不执行后续逻辑 if disabled? @config = {} return @config end config_path = find_config_path # 文件不存在则自动创建模板 ensure_config_file(config_path) # 创建后仍可能为空(如环境变量指定了不存在的文件) unless File.exist?(config_path) @config = {} return @config end # 解析 YAML,使用 safe_load(Psych 默认行为) raw = YAML.load_file(config_path) @config = { 'local_pods' => normalize_hash(raw&.dig('local_pods')), 'replace_versions' => normalize_hash(raw&.dig('replace_versions')), 'replace_branches' => normalize_hash(raw&.dig('replace_branches')) } # 计算所有 pod 名称的最大长度,用于输出时的列对齐 all_names = @config.values.flat_map(&:keys) @max_name_len = all_names.map(&:length).max || 0 @config rescue Psych::SyntaxError => e Pod::UI.warn "#{C_YELLOW}[x] YAML parse error in #{File.basename(config_path)}: #{e.}#{C_RESET}" @config = {} rescue StandardError => e Pod::UI.warn "#{C_YELLOW}[x] Failed to load #{File.basename(config_path)}: #{e.}#{C_RESET}" @config = {} end |
.local_pods ⇒ Hash
Returns 本地 pod 映射表 => relative_path.
263 264 265 |
# File 'lib/cocoapods_plugin.rb', line 263 def self.local_pods load_config['local_pods'] end |
.normalize_hash(raw) ⇒ Hash{String => String}
标准化 YAML 中的 Hash 值:
- 所有 key 转为 String 并 strip 空白
- 所有 value 转为 String 并 strip 空白
- 跳过空 key
- nil 或非 Hash 输入返回空 {}
445 446 447 448 449 450 |
# File 'lib/cocoapods_plugin.rb', line 445 def self.normalize_hash(raw) return {} if raw.nil? || !raw.is_a?(Hash) raw.each_with_object({}) do |(k, v), h| h[k.to_s.strip] = v.to_s.strip unless k.to_s.strip.empty? end end |
.replace_branches ⇒ Hash
Returns 分支替换映射表 => branch_name.
273 274 275 |
# File 'lib/cocoapods_plugin.rb', line 273 def self.replace_branches load_config['replace_branches'] end |
.replace_versions ⇒ Hash
Returns 版本替换映射表 => version_string.
268 269 270 |
# File 'lib/cocoapods_plugin.rb', line 268 def self.replace_versions load_config['replace_versions'] end |
.resolve_podspec_path(local_path, pod_name = nil) ⇒ String?
从本地 pod 目录中查找 podspec 文件 优先按 pod 名称查找(Name.podspec / Name.podspec.json), 回退到扫描目录下任意 podspec。
548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 |
# File 'lib/cocoapods_plugin.rb', line 548 def self.resolve_podspec_path(local_path, pod_name = nil) return nil unless File.directory?(local_path) # 优先按 pod 名称查找(更精确) if pod_name && !pod_name.strip.empty? [File.join(local_path, "#{pod_name}.podspec"), File.join(local_path, "#{pod_name}.podspec.json")].each do |c| return c if File.exist?(c) end end # 回退:找目录下任意 .podspec(Ruby 格式优先于 JSON) (Dir.glob(File.join(local_path, '*.podspec')) + Dir.glob(File.join(local_path, '*.podspec.json'))).first end |
.xcode_project_dir?(config_path) ⇒ Boolean
判断 config_path 所在目录是否存在 Xcode 工程(*.xcodeproj)。 仅在有工程的目录才允许自动创建 Podfile.local, 避免在非 Xcode 项目目录误生成配置文件。
171 172 173 |
# File 'lib/cocoapods_plugin.rb', line 171 def self.xcode_project_dir?(config_path) !Dir.glob(File.join(File.dirname(config_path), '*.xcodeproj')).empty? end |