p;& contents.encoding.name != 'UTF-8'
contents.encode!('UTF-8')
end
if contents.tr!('“”‘’?', %(""'''))
# Changes have been made
CoreUI.warn "Smart quotes were detected and ignored in your #{path.basename}. " \
'To avoid issues in the future, you should not use ' \
'TextEdit for editing it. If you are not using TextEdit, ' \
'you should turn off smart quotes in your editor of choice.'
end
# 实例podfile对象
podfile = Podfile.new(path) do
# rubocop:disable Lint/RescueException
begin
# 执行podFile内容(执行之前会先执行Podfile初始化Block回调前的内容)
eva l(contents, nil, path.to_s)
# DSL的异常抛出
rescue Exception => e
message = "Invalid `#{path.basename}` file: #{e.message}"
raise DSLError.new(message, path, e, contents)
end
# rubocop:enable Lint/RescueException
end
podfile
end
def self.from_yaml(path)
string = File.open(path, 'r:utf-8', &:read)
# Work around for Rubinius incomplete encoding in 1.9 mode
if string.respond_to?(:encoding) && string.encoding.name != 'UTF-8'
string.encode!('UTF-8')
end
hash = YAMLHelper.load_string(string)
from_hash(hash, path)
end
def initialize(defined_in_file = nil, internal_hash = {}, &block)
self.defined_in_file = defined_in_file
@internal_hash = internal_hash
if block
default_target_def = TargetDefinition.new('Pods', self)
default_target_def.abstract = true
@root_target_definitions = [default_target_def]
@current_target_definition = default_target_def
instance_eva l(&block)
else
@root_target_definitions = []
end
end
从上面的源码可以知道,整个的 Podfile
的读取流程如下: 1. 判断路径是否合法,不合法抛出异常 2. 判断扩展名类型,如果是 '', '.podfile', '.rb' 扩展按照 ruby
语法规则解析,如果是yaml
则按照 yaml
文件格式解析,以上两者如果都不是,则抛出格式解析异常 3. 如果解析按照 Ruby
格式解析的话过程如下:
? 按照utf-8
格式读取 Podfile
文件内容,并存储到 contents
中
? 内容符号容错处理,主要涉及" “”‘’?" 等 符号,同时输出警告信息
? 实例 Podfile
对象,同时在实例过程中初始化 TargetDefinition
对象并配置默认的Target
信息
? 最终通过 eva l(contents, nil, path.to_s)
方法执行 Podfile
文件内容完成配置记录
这里或许有一个疑问:Podfile里面定义了 Cocoapods
自己的一套DSL语法
,那么执行过程中是如何解析DSL语法
的呢?上面的源码文件中,如果仔细查看的话,会发现有下面这一行内容:
include Pod::Podfile::DSL
不错,这就是DSL解析
的本体,其实你可以将DSL语法
理解为基于Ruby
定义的一系列的领域型方法,DSL的解析的过程本质是定义的方法执行的过程
。在Cocoapods
中定义了很多DSL语法
,定义与实现均放在了 cocoapods-core
这个核心组件中,比如在dsl.rb
文件中的以下关于Podfile
的 DSL
定义(摘取部分):
module Pod
class Podfile
module DSL
def install!(installation_method, options = {})
unless current_target_definition.root?
raise Informative, 'The installation method can only be set at the root level of the Podfile.'
end
set_hash_value('installation_method', 'name' => installation_method, 'options' => options)
end
def pod(name = nil, *requirements)
unless name
raise StandardError, 'A dependency requires a name.'
end
current_target_definition.store_pod(name, *requirements)
end
def podspec(options = nil)
current_target_definition.store_podspec(options)
end
def target(name, options = nil)
if options
raise Informative, "Unsupported options `#{options}` for " \
"target `#{name}`."
end
parent = current_target_definition
definition = TargetDefinition.new(name, parent)
self.current_target_definition = definition
yield if block_given?
ensure
self.current_target_definition = parent
end
def inherit!(inheritance)
current_target_definition.inheritance = inheritance
end
def platform(name, target = nil)
# Support for deprecate