Class: Pod::Tdfire::BinarySpecificationRefactor

Inherits:
Object
  • Object
show all
Defined in:
lib/cocoapods-tdfire-binary/binary_specification_refactor.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target_spec) ⇒ BinarySpecificationRefactor

Returns a new instance of BinarySpecificationRefactor.



54
55
56
# File 'lib/cocoapods-tdfire-binary/binary_specification_refactor.rb', line 54

def initialize(target_spec)
	@target_spec = target_spec
end

Instance Attribute Details

#target_specObject

Returns the value of attribute target_spec.



52
53
54
# File 'lib/cocoapods-tdfire-binary/binary_specification_refactor.rb', line 52

def target_spec
  @target_spec
end

Instance Method Details

#configure_binary(spec) ⇒ Object

——————————————————————–# spec 是二进制依赖时的配置



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
# File 'lib/cocoapods-tdfire-binary/binary_specification_refactor.rb', line 93

def configure_binary(spec)
  # 限制二进制只支持 iOS 平台 (这里是 spec 或者 subpsec)
  set_platform_limitation(spec)

				# 组件 frameworks 的依赖
				target_spec.vendored_frameworks = "#{target_spec.root.name}.framework"
  # 如果不加这一句,会提示找不到 bundle。测试时需要 shift + cmd + k 清除 production
  #
  # static framework 不像 dynamic framework ,后者在生成 production 后,会有一个专门的 Frameworks 文件夹,其内部的结构和打包前是一致的, bundle 也会在 .framework 文件中
  # 而 static framework 的可执行文件部分,会被合并到 App 的可执行文件中, bundle 按逻辑会放到 main bundle 中,
  # 但是 CocoaPods 并不会帮 vendored_frameworks 中的 static framework  做 bundle 的拷贝工作,
  # 所以这里需要暴露 static framework 中的 bundle ,明确让 CocoaPods 拷贝 bundle 到 main bundle,
  # 可以查看 高德地图 和 友盟等 framework ,都已这种方式处理
  #
  # 如果组件不是用的 resource_bundle,而是用的 resources ,那么这里就不会拷贝组件的资源文件
  #

  framework_resources = spec.tdfire_recursive_value('resources', :ios)
  resource_bundles = spec.tdfire_recursive_value('resource_bundles', :ios)
  # 不判断 lint 会报错 did not match any file
  target_spec.resources = ["#{target_spec.root.name}.framework/Resources/*", "#{target_spec.root.name}.framework/Versions/A/Resources/*"] if resource_bundles.select(&:any?).any? || framework_resources.any?
  Pod::UI.message "Tdfire: resources for binary: #{target_spec.tdfire_recursive_value('resources', :ios).join(', ')}"

  # cococapods 会将以下头文件添加入 user search path ,这样使用者可以使用 " " 对头文件进行引用
  #
  #
  # 不能通过下面这种方式判断
  # Dir.glob("#{target_spec.root.name}.framework/Headers/*").count

  target_spec.source_files = ["#{target_spec.root.name}.framework/Headers/*", "#{target_spec.root.name}.framework/Versions/A/Headers/*"]
  target_spec.public_header_files = ["#{target_spec.root.name}.framework/Headers/*", "#{target_spec.root.name}.framework/Versions/A/Headers/*"]

  available_platforms(spec).each do |platform|
    Pod::UI.section("Tdfire: copying configuration for platform #{platform}") do
      target_platform = target_spec.send(platform.to_sym)

      # 保留对 frameworks lib 的依赖
      %w[frameworks libraries weak_frameworks].each do |name|
        value = spec.tdfire_recursive_value(name, platform )
        target_platform.send("#{name}=", value) unless value.empty?

        Pod::UI.message "Tdfire: #{name} for #{platform}: #{target_spec.tdfire_recursive_value(name, platform)}"
      end

      # 保留对其他组件的依赖
      dependencies = spec.tdfire_recursive_value('dependencies', platform)

      # 去除对自身子组件的依赖
      dependencies
          .select { |d| d.root_name != target_spec.root.name }
          .each { |d| target_platform.dependency(d.name, d.requirement.to_s) }

      Pod::UI.message "Tdfire: dependencies for #{platform}: #{target_spec.tdfire_recursive_value('dependencies', platform).map(&:name).join(', ')}"
    end
  end
end

#configure_binary_default_subspec(spec) ⇒ Object

——————————————————————–# 生成default subspec TdfireBinary ,并将源码依赖时的配置转移到此 subspec 上



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/cocoapods-tdfire-binary/binary_specification_refactor.rb', line 68

def configure_binary_default_subspec(spec)
     # 限制二进制只支持 iOS 平台 (这里是 parent spec)
     set_platform_limitation(spec)

	default_subspec = "TdfireBinary"
	target_spec.subspec default_subspec do |ss|
		subspec_refactor = BinarySpecificationRefactor.new(ss)
		subspec_refactor.configure_binary(spec)
     end

	# 创建源码依赖时的 subspec,并且设置所有的 subspec 依赖 default_subspec
	spec.subspecs.each do |s|
		target_spec.subspec s.base_name do |ss|
			ss.dependency "#{target_spec.root.name}/#{default_subspec}"
		end
	end

	target_spec.default_subspec = default_subspec
	target_spec.default_subspec = default_subspec

	Pod::UI.message "Tdfire: subspecs for #{target_spec.name}: #{target_spec.subspecs.map(&:name).join(', ')}"
end

#configure_sourceObject



58
59
60
61
62
63
64
# File 'lib/cocoapods-tdfire-binary/binary_specification_refactor.rb', line 58

def configure_source
  # 在设置了 use_frameworks! 的情况下才会生效
  set_use_static_framework

  # cocoapods-package 打包时,只让 iOS 平台生效
  set_platform_limitation(target_spec) if Pod::Tdfire::BinaryStateStore.limit_platform
end

#set_framework_download_scriptObject

——————————————————————–#



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/cocoapods-tdfire-binary/binary_specification_refactor.rb', line 191

def set_framework_download_script
	download_url = Pod::Tdfire::BinaryUrlManager.pull_url_for_pod_version(target_spec.root.name, target_spec.version)

	download_script = <<-EOF
     #!/bin/sh

     if [[ -d #{framework_name} ]]; then
       echo "Tdfire: #{framework_name} is not empty"
       exit 0
     fi

     if [[ ! -d tdfire_download_temp ]]; then
       mkdir tdfire_download_temp
     fi

     cd tdfire_download_temp

     curl --fail -O -J -v #{download_url}

     if [[ -f #{framework_name}.zip ]]; then
       echo "Tdfire: copying #{framework_name} ..."

       unzip #{framework_name}.zip
       cp -fa #{framework_name} ../
     fi

     cd ..
     rm -fr tdfire_download_temp

     echo "pod cache path for #{target_spec.root.name}: $(pwd)"
	EOF

	combined_download_script = %Q[echo '#{download_script}' > download.sh && sh download.sh && rm download.sh]
	combined_download_script += " && " << target_spec.prepare_command unless target_spec.prepare_command.nil?

	target_spec.prepare_command = combined_download_script
end

#set_platform_limitation(spec) ⇒ Object



150
151
152
# File 'lib/cocoapods-tdfire-binary/binary_specification_refactor.rb', line 150

def set_platform_limitation(spec)
  target_spec.platform = :ios, deployment_target(spec, :ios)
end

#set_preserve_paths(spec) ⇒ Object

——————————————————————–# spec 是源码依赖时的配置



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/cocoapods-tdfire-binary/binary_specification_refactor.rb', line 155

def set_preserve_paths(spec)
     available_platforms(spec).each do |platform|
       Pod::UI.message("Tdfire: set preserve paths for platform #{platform}")
       # 源码、资源文件
       #
       source_files = spec.tdfire_recursive_value('source_files', platform)
       resources = spec.tdfire_recursive_value('resources', platform)
       resource_bundles = spec.tdfire_recursive_value('resource_bundles', platform)

       source_preserve_paths = source_files + resources + resource_bundles.map(&:values).flatten

       # 二进制文件
       framework_preserve_paths = [framework_name]
       preserve_paths = source_preserve_paths + framework_preserve_paths

       # 保留原有的 preserve_paths
       target_preserve_paths = target_spec.tdfire_recursive_value('preserve_paths', platform)
       preserve_paths += target_preserve_paths unless target_preserve_paths.empty?

       target_platform = target_spec.send(platform.to_sym)
       target_platform.preserve_paths = preserve_paths.uniq

       Pod::UI.message "Tdfire: preserve paths for #{platform}: #{preserve_paths.join(', ')}"
     end
end

#set_use_static_frameworkObject

——————————————————————–#



183
184
185
186
187
188
# File 'lib/cocoapods-tdfire-binary/binary_specification_refactor.rb', line 183

def set_use_static_framework
     # 1.4.0 版本生效
     # 使用 use_frameworks! 后,生成静态 Framework
     #
	target_spec.static_framework = true if target_spec.respond_to?('static_framework')
end