Fastlane(二):結(jié)構(gòu)

前言

在終端中執(zhí)行fastlane lane_name之后,fastlane會(huì)去執(zhí)行Fastfile中定義的同名lane,這個(gè)是如何實(shí)現(xiàn)的。
本文按照解析參數(shù)這一主線祸憋,嘗試解釋fastlane的執(zhí)行邏輯和內(nèi)部結(jié)構(gòu)。

在開始正文之前肖卧,有一些概念和名稱需要解釋一下蚯窥,在之前的文章中,已經(jīng)提到過一些fastlane的領(lǐng)域?qū)S妹Q,比如platform拦赠、lane巍沙、action等,除了這些以外荷鼠,還有兩個(gè)重要的名稱需要了解一下句携,Command和Tool。

1. Tool和Command

fastlane是一個(gè)龐大的工具集允乐,為了更好的使用和管理這些工具矮嫉,將功能相似的工具劃分在一起組成一個(gè)Tool,每一種Tool都代表fastlane的一個(gè)大的功能點(diǎn)牍疏。

fastlane中的Tool列表:

  TOOLS = [
    :fastlane,
    :pilot,
    :spaceship,
    :produce,
    :deliver,
    :frameit,
    :pem,
    :snapshot,
    :screengrab,
    :supply,
    :cert,
    :sigh,
    :match,
    :scan,
    :gym,
    :precheck
  ]

每一個(gè)Tool都有其特定的應(yīng)用領(lǐng)域蠢笋,比如cert用于證書相關(guān),sigh用于簽名相關(guān)鳞陨,gym用于打包相關(guān)昨寞,等等。
其中厦滤,fastlane是默認(rèn)的Tool援岩,比如fastlane lane_namefastlane init馁害、fastlane action action_namefastlane add_plugin plugin_name等蹂匹,因?yàn)檫@些命令都沒有顯式的指定Tool碘菜,所以使用的都是fastlane這個(gè)Tool,它是fastlane庫(kù)中最重要的Tool限寞。

每一種Tool下都有多個(gè)Command忍啸,如果把Tool看做是某個(gè)領(lǐng)域的專用工具,Command則是其中的一個(gè)操作履植,比如cert就是專門用于簽名證書相關(guān)的Tool计雌,當(dāng)需要?jiǎng)?chuàng)建新的簽名證書時(shí),可以使用cert下的create這個(gè)Command玫霎,其具體的執(zhí)行命令是fastlane cert creat凿滤,因?yàn)?code>create是默認(rèn)命令,所以也可以使用fastlane cert庶近;當(dāng)需要移除過期證書時(shí)翁脆,則可以使用revoke_expired這個(gè)Command,其具體的命令是fastlane cert revoke_expired鼻种。

上文中提到的幾條命令反番,fastlane init中的initfastlane action action_name中的actonfastlane add_plugin plugin_name中的add_plugin等罢缸,這些都是fastlane這個(gè)默認(rèn)Tool的Command篙贸。而fastlane lane_name使用的是默認(rèn)Tool的默認(rèn)Command:trigger

Command必須和Tool結(jié)合起來才有意義枫疆,因?yàn)椴煌琓ool下的Command可能會(huì)出現(xiàn)同名的情況爵川,fastlane允許這種情況出現(xiàn)。只有確定了Tool之后养铸,才能確定真正的Command雁芙。

2. lane、action

之前在Fastlane用法中有講到lane和action的簡(jiǎn)單使用钞螟,這里再結(jié)合Tool和Command兔甘,談一談它們的聯(lián)系和區(qū)別。

default_platform :ios

lane :build do
    match(git_url: your_git_url)
    gym(export_method: 'enterprise')
end

上述代碼中的build是一個(gè)lane鳞滨,matchgym都是action洞焙。

想一想如何執(zhí)行build這個(gè)lane

fastlane build

只要在終端執(zhí)行上述命令行就可以了

那么,執(zhí)行了上述命令之后拯啦,fastlane庫(kù)最終會(huì)調(diào)用哪一個(gè)Tool和Command呢
之前的文章中已經(jīng)說過了澡匪,當(dāng)沒有顯式指定Tool和Command時(shí),使用默認(rèn)的Tool:fastlane和默認(rèn)Tool的默認(rèn)Command:trigger褒链。

fastlane build的完整命令

fastlane fastlane trigger build

當(dāng)使用在Fastfile中定義的lane進(jìn)行打包唁情、測(cè)試和發(fā)布時(shí),最終調(diào)用的都是trigger這個(gè)Command甫匹。

lane和action是trigger這個(gè)Command內(nèi)部定義的領(lǐng)域名稱甸鸟,它們只能在trigger中使用,它們和Command不是同一個(gè)層次的兵迅。只要說起lane和action抢韭,那么就默認(rèn)了Tool是fastlane,Command是trigger恍箭。

當(dāng)執(zhí)行build這個(gè)lane之后刻恭,最終目的是去執(zhí)行它包含的action,build內(nèi)部包含了兩個(gè)action扯夭,分別是matchgym鳍贾,而這兩個(gè)action最終會(huì)去調(diào)用它們同名的Tool。
除了fastlane這個(gè)默認(rèn)的Tool交洗,其他所有的Tool都有其同名的action贾漏,通過在lane中添加action,可以調(diào)用其他所有的Tool藕筋。

除了這些與Tool同名的action纵散,fastlane還內(nèi)置了其他很多action梳码,比如關(guān)于git和pod的。

3. fastlane執(zhí)行流程

fastlane中所有命令的執(zhí)行都可以簡(jiǎn)單的分為兩步:

  1. 解析Command
  2. 執(zhí)行Command

比如常用的fastlane lane_name伍掀,這條命令沒有顯式的指定Tool和Command掰茶,所以,fastlane會(huì)使用默認(rèn)Tool:fastlane和默認(rèn)Tool的默認(rèn)Command:trigger蜜笤,然后執(zhí)行trigger濒蒋。

3.1. 解析Command

fastlane庫(kù)中幾乎所有命令都可以寫成下列格式:(如果把fastlane-credentials也當(dāng)做是一種Tool的話,那這個(gè)幾乎就可以去掉了把兔。)

fastlane [tool] [command] [args][--key value]

tool和command指定使用的Tool和其Command沪伙;args通常是一個(gè)或多個(gè)字符串組成的數(shù)組;類似--key value-k value格式的組合會(huì)被當(dāng)做option县好。args和option會(huì)被當(dāng)做參數(shù)傳給Command围橡。
其中tool、command缕贡、args和option用[]包含起來翁授,表示它們可以被省略。如果省略了command和tool晾咪,則會(huì)使用默認(rèn)的tool和默認(rèn)tool的默認(rèn)command收擦。

下圖中展示的是解析Command的簡(jiǎn)易流程


下列以兩個(gè)例子來說明

  1. 獲取ARGV
    例一:終端輸入fastlane lane_name,則ARGV = ["lane_name"]谍倦;
    例二:終端輸入fastlane cert --username "your_usernmae" --development false塞赂,則ARGV = ["cert", "--username", "your_username", "--development", "false"]

  2. 解析Tool
    不同Tool包含的Command不同,確定了Tool昼蛀,才能真正確定Command宴猾。如果ARGV.first是一個(gè)Tool的名字,比如:fastlane曹洽、cert等鳍置,則加載這個(gè)Tool辽剧,require 'tool_name/commands_generator'送淆;如果ARGV.first等于 "fastlane-credentials",則加載require 'credentials_manager'怕轿;如果都不是偷崩,則加載fastlane這個(gè)默認(rèn)的Tool,require "fastlane/commands_generator"撞羽。
    如果匹配上了Tool之后阐斜,刪除ARGV.first。
    例一:使用默認(rèn)Tool:fastlane诀紊,ARGV = [ "lane_name"]
    例二:使用Tool:cert谒出,ARGV = ["--username", "your_username", "--development", "false"]

  3. 解析Command
    將ARGV復(fù)制給一個(gè)新數(shù)組,在新數(shù)組中去掉所有以-開頭的字符串對(duì)象,然后使用數(shù)組的第一個(gè)對(duì)象去匹配此Tool下的command列表笤喳,如果能匹配上为居,則使用匹配到的Command;如果不能杀狡,則使用默認(rèn)Command蒙畴。
    如果匹配上,則將匹配上的字符串對(duì)象從ARGV中刪除呜象。
    例一:使用fastlane這個(gè)Tool的默認(rèn)Command:trigger膳凝,ARGV = [ "lane_name"]
    例二:使用cert這個(gè)Tool的默認(rèn)Command:createARGV = ["--username", "your_username", "--development", "false"]
    這里有個(gè)問題需要注意一下恭陡,當(dāng)在終端輸入fastlane match --type enterprise時(shí)蹬音,這條命令的初衷是想使用match這個(gè)Tool的默認(rèn)Command:run,但按照本步驟的方法子姜,最終使用的是enterprise這個(gè)Command祟绊。所以在這里最好顯示指定要使用的Command,fastlane match run --type enterprise哥捕。

  4. 解析command對(duì)應(yīng)的option
    遍歷ARGV牧抽,如果字符串是以---開頭,則將此字符串對(duì)象和其后的字符串對(duì)象作為一對(duì)key-value值遥赚,并從ARGV中刪除這兩個(gè)對(duì)象扬舒。遍歷完畢之后,將ARGV中剩余的的參數(shù)賦值給args凫佛。
    例一:option等于nil讲坎,args等于lane_name
    例二:option等于{"username":"your_username", "development": false},args等于nil

  1. 執(zhí)行command
    每個(gè)command都會(huì)設(shè)置一個(gè)對(duì)應(yīng)的block愧薛,匹配到這個(gè)command并解析完option之后晨炕,則執(zhí)行其對(duì)應(yīng)的block,并將[步驟4]中獲取的option和args傳給這個(gè)block毫炉。
    從這個(gè)地方開始瓮栗,業(yè)務(wù)代碼才會(huì)真正開始執(zhí)行。

上述解析過程描述的非常粗糙瞄勾,如果想了解詳細(xì)的解析過程费奸,可以參考commander,fastlane內(nèi)部通過這個(gè)庫(kù)來解析這些參數(shù)的进陡。

把這個(gè)過程再豐富一下愿阐,就變成了下圖


(由于篇幅原因,圖中只畫出了cert趾疚、sighfastlane這三個(gè)Tool)

3.2. 執(zhí)行Command

到了這一步缨历,就開始深入到各個(gè)Tool的核心內(nèi)容了以蕴,在fastlane這個(gè)庫(kù)中,Tool共有16個(gè)辛孵,在這里并不會(huì)對(duì)所有的Tool展開討論舒裤,這里只討論默認(rèn)Command:trigger

4. trigger

trigger是fastlane這個(gè)Tool的默認(rèn)命令觉吭,其作用是運(yùn)行一個(gè)指定的lane腾供,而fastlane這個(gè)Tool又是fastlane庫(kù)的默認(rèn)Tool,所以一般在運(yùn)行l(wèi)ane的時(shí)候鲜滩,可以省略掉Tool和Command伴鳖,只需要執(zhí)行命令fastlane [platform_name] lane_name,如果設(shè)置了default_platform徙硅,platform_name也可以省略榜聂。

trigger的目的是去運(yùn)行一個(gè)指定的lane,而運(yùn)行l(wèi)ane的目的是去執(zhí)行其中的action嗓蘑,根據(jù)這一需求须肆,作圖如下

下面以例子的方式來了解這一過程,本文準(zhǔn)備了兩個(gè)自定義action桩皿,分別是example_actionexample_action_second豌汇,fastlane會(huì)將它們加載作為外部action。

1. 前提條件
相關(guān)文件的目錄結(jié)構(gòu)

-fastlane
  -Fastfile
  -actions
    -example_action.rb
    -example_action_second.rb

fastfile

default_platform :ios

platform :ios do
    lane :test do |options|
        puts "lane options #{options}"
        example_action(foo:"ruby", bar:"ios")
        example_action_second(foo:"ruby", bar:"ios")
    end 
end

lane :test_without_platform do
    puts "lane whithout platform"
end

example_action.rb

module Fastlane
  module Actions
    class ExampleActionAction < Action
      def self.run(options)
          binding.pry
        puts "this is example_action action"  
        puts options
      end 

      def self.is_supported?(platform)
        true
      end 

      def self.available_options
        []  
      end 
    end 
  end 
end

example_action_second.rb

module Fastlane
  module Actions
    class ExampleActionSecondAction < Action
      def self.run(options)
        puts "this is example action second action, options:"
        puts "foo:#{options[:foo]}"
        puts "bar:#{options[:bar]}"
      end

      def self.is_supported?(platform)
        true
      end

      def self.available_options
          [
            FastlaneCore::ConfigItem.new(key: :foo,
                                     short_option: "-f",
                                     description: "this is foo"),
            FastlaneCore::ConfigItem.new(key: :bar,
                                     short_option: "-b",
                              description: "this is bar")
          ]
      end
    end
  end
end

2. 執(zhí)行trigger
在終端執(zhí)行fastlane test key1:value1 key2:value2 --env local1,local2泄隔,按照上文所說的拒贱,第一步解析command后,fastlane庫(kù)找到需要執(zhí)行的目標(biāo)command:trigger佛嬉,然后執(zhí)行此command對(duì)應(yīng)的block逻澳。

fastlane庫(kù)中trigger命令的定義

command :trigger do |c|
        c.syntax = 'fastlane [lane]'
        c.description = 'Run a specific lane. Pass the lane name and optionally the platform first.'
        c.option('--env STRING[,STRING2]', String, 'Add environment(s) to use with `dotenv`')
        c.option('--disable_runner_upgrades', 'Prevents fastlane from attempting to update FastlaneRunner swift project')

        c.action do |args, options|
          if ensure_fastfile
            Fastlane::CommandLineHandler.handle(args, options)
          end
        end
      end

trigger支持兩種option,分別是--env STRING[,STRING2]disable_runner_upgrades暖呕,其中第一個(gè)option的作用是指定文件名斜做,這些文件會(huì)被dotenv加載,用來配置環(huán)境變量湾揽。在當(dāng)前這個(gè)例子中瓤逼,設(shè)置了--env local1,local2,如果.env.local1.env.local2這兩個(gè)文件存在于Fastfile所在的文件夾或其上級(jí)文件夾钝腺,則dotenv會(huì)去加載它們來設(shè)置環(huán)境變量抛姑。(不管--env有沒有設(shè)置艳狐,dotenv都默認(rèn)加載.env.env.default

執(zhí)行trigger就是執(zhí)行下列代碼

 c.action do |args, options|
    if ensure_fastfile
       Fastlane::CommandLineHandler.handle(args, options)
    end
 end

當(dāng)fastlane庫(kù)執(zhí)行這個(gè)block時(shí),傳入了兩個(gè)參數(shù)皿桑,argsoptions毫目,通過解析命令字符串可知蔬啡,其中args的值為["test", "key1:value1", "key2:value2"]options的值是一個(gè)Options類型的對(duì)象镀虐,且options.env 的值為 "local1,local2"箱蟆。

3. 解析lane
解析lane的目的就是獲取Fastfile中定義的Lane類型的對(duì)象

在這個(gè)階段,fastlane庫(kù)會(huì)加載Fastfile刮便,并將其中定義的lane轉(zhuǎn)換成Fastlane::Lane類型的對(duì)象空猜,并將這些對(duì)象保存在一個(gè)Hash類型的對(duì)象lanes中。

Fastlane::Lane中定義的變量

module Fastlane
  # Represents a lane
  class Lane
    attr_accessor :platform
    attr_accessor :name
    # @return [Array] 
    attr_accessor :description
    attr_accessor :block
    # @return [Boolean] Is that a private lane that can't be called from the CLI?
    attr_accessor :is_private
  end
end

Fastlane::Lane類型的對(duì)象中保存了一個(gè)lane的所有信息恨旱,:platform指定lane使用的平臺(tái)辈毯,:name指定lane的名字,:block保存了lane對(duì)應(yīng)的執(zhí)行代碼搜贤。

在本節(jié)例子中谆沃,lanes保存了所有Fastlane::Lane類型的對(duì)象,它的具體結(jié)構(gòu)如下:

{
  ios:          {
                    test: Lane.new
                },
  nil:          {
                    test_without_platform: lane.new
                }
}

fastlane庫(kù)使用lanes這個(gè)Hash對(duì)象結(jié)合之前得到的args來獲取對(duì)應(yīng)Lane類型對(duì)象
其偽代碼如下:

#使用platform_lane_info保存platform名稱和lane名稱
platform_lane_info = [] 
#過濾掉帶有冒號(hào)":"的字符串對(duì)象
args.each do |current|
     unless current.include?(":")
         platform_lane_info << current
     end
end

#獲取platform名稱和lane名稱
platform_name = nil
lane_name = nil
if platform_lane_info.size >= 2
    platform_name = platform_lane_info[0]
    lane_name = platform_lane_info[1]
else
    if platform_lane_info.first 是一個(gè)平臺(tái)名字 || platform_lane_info是空數(shù)組
        platform_name = platform_lane_info.first
        lane_name = 在終端打印一個(gè)lane列表供用戶選擇
    else
        lane_name = platform_lane_info.first
        if platform==nil && lanes[nil][lane_name]==nil
            platform = default_platform
        end
    end
end
#返回lane對(duì)象
return lanes[platform][lane_name]

args的值為["test", "key1:value1", "key2:value2"]仪芒,把argslanes帶入到上述偽代碼中唁影,可以得到相應(yīng)的Lane類型對(duì)象。

4. 解析lane的options
回顧一下掂名,之前在Fastfile文件中定義test這個(gè)lane的代碼

platform :ios do
    lane :test do |options|
        puts "lane options #{options}"
        example_action(foo:"ruby", bar:"ios")
        example_action_second(foo:"ruby", bar:"ios")
    end 
end

本步驟的目的就是要獲取傳給testoptions据沈,它是一個(gè)Hash類型的對(duì)象。

這個(gè)options參數(shù)的值是如何得到的饺蔑,其實(shí)卓舵,也是通過解析args獲取的。

其實(shí)現(xiàn)邏輯如下

options = {} 
args.each do |current|
    if current.include?(":") 
        key, value = current.split(":", 2)
        if key.empty?
            報(bào)錯(cuò)
        end
        value = true if value == 'true' || value == 'yes'
        value = false if value == 'false' || value == 'no'
        options[key.to_sym] = value
    end
end

上述代碼是在fastlane庫(kù)源代碼的基礎(chǔ)上作了一些修改

args帶入到上述代碼中膀钠,可以得出lane:test的options的值為{key1:value1, key2:value2}

fastlane test key1:value1 key2:value2 --env local1,local2掏湾,在終端執(zhí)行后,一部分輸出如下

[16:37:43]: ------------------------------
[16:37:43]: --- Step: default_platform ---
[16:37:43]: ------------------------------
[16:37:43]: Driving the lane 'ios test' ??
[16:37:43]: lane options {:key1=>"value1", :key2=>"value2"}

5. 解析action
解析action的目的是找到action_name對(duì)應(yīng)的類肿嘲,本例中融击,需要執(zhí)行兩個(gè)action,其action_name分別是example_actionexample_action_second雳窟,其對(duì)應(yīng)類分別是ExampleActionActionExampleActionSecondAction

其實(shí)現(xiàn)邏輯如下

tmp = action_name.delete("?")
class_name = tmp.split("_").collect!(&:capitalize).join + "Action"
class_ref = Fastlane::Actions.const_get(class_name)
unless class_ref
    class_ref = 嘗試把a(bǔ)ction_name當(dāng)做別名尊浪,重新加載
end

if action_name 是一個(gè)lane的名字
    執(zhí)行這個(gè)lane
elsif class_ref && class_ref.respond_to?(:run)
    解析action的options
    執(zhí)行action
else
    報(bào)錯(cuò)
end

6. 解析action的options
action的options指的是傳給action的參數(shù),比如example_action_second這個(gè)action的options是{foo:"ruby", bar:"ios"}封救,準(zhǔn)確的來說應(yīng)該是[{foo:"ruby", bar:"ios"}]拇涤,不過一般都只是用這個(gè)數(shù)組的第一個(gè)對(duì)象,所以接下來會(huì)去掉外面的一層數(shù)組誉结。
本步驟的目的是將傳給action的options轉(zhuǎn)換成Configuration類型的對(duì)象鹅士,并且在轉(zhuǎn)換過程中,驗(yàn)證options中keyvalue的合法性惩坑。
action和Configuration類型的對(duì)象是一一對(duì)應(yīng)的掉盅,Configuration類的作用主要是存儲(chǔ):availabel_options:values也拜,在執(zhí)行action的時(shí)候,也就是在執(zhí)行action響應(yīng)類的run方法時(shí)趾痘,把Configuration類型的對(duì)象當(dāng)做參數(shù)傳入慢哈,然后action響應(yīng)類使用它來獲取key對(duì)應(yīng)的value。

Configuration中定義的實(shí)例變量

module FastlaneCore
  class Configuration
    attr_accessor :available_options
    attr_accessor :values
    # @return [Array] 
    attr_reader :all_keys
    # @return [String]
    attr_accessor :config_file_name
    # @return [Hash] 
    attr_accessor :config_file_options
  end
end

:availabel_options表示action響應(yīng)類中定義的available_options永票,比如example_action_second這個(gè)action卵贱,它的響應(yīng)類是ExampleActionSecondActionExampleActionSecondAction中類方法available_options的定義

def self.available_options
          [   
            FastlaneCore::ConfigItem.new(key: :foo,
                                     short_option: "-f",
                                     description: "this is foo"),
            FastlaneCore::ConfigItem.new(key: :bar,
                                     short_option: "-b",
                                     description: "this is bar")
          ]   
      end 

:values表示傳給action的options侣集,給:values賦值之后還需要驗(yàn)證它的key艰赞、value是否合法,如果不合法肚吏,程序中止方妖。比如example_action_second這個(gè)action的options是{foo:"ruby", bar:"ios"}

:all_key表示:available_options中的key的數(shù)組罚攀,具體代碼:@available_options.collect(&:key)党觅。

:config_file_name:config_file_options:在action的響應(yīng)類中,可以使用Configuration.load_configuration_file(config_file_name)來加載這個(gè)action專有的配置文件斋泄,然后把文件中的數(shù)據(jù)以key:value的方式存儲(chǔ)在:cofnig_file_options變量中杯瞻。

其實(shí)現(xiàn)代碼如下

values = 傳給action的options
action_responder = action響應(yīng)類
first_element = (action_responder.available_options || []).first

if (first_element && first_element kind_of?(FastlaneCore::ConfigItem)) || first_element == nil
    values = {} if first_element==nil
    return FastlaneCore::Configuration.create(action_responder.available_options, values)
else
    #action響應(yīng)類中定義了available_options類方法,且其返回對(duì)象的第一個(gè)元素的類型不是FastlaneCore::ConfigItem炫掐,則不對(duì)values做任何處理魁莉,直接返回。
    return values
end

創(chuàng)建FastlaneCore::Configuration時(shí)募胃,內(nèi)部的驗(yàn)證邏輯

values = 傳給action的options
action_responder = action響應(yīng)類
available_options = action_responder.available_options

#available_options必須是一個(gè)Array旗唁,且其內(nèi)部的元素都必須是FastlaneCore::ConfigItem的類型
verify_input_types

#values中的每一個(gè)key都必須在available_options中定義過,如果在創(chuàng)建FastlaneCore::ConfigItem類型的對(duì)象時(shí)痹束,設(shè)置了type和verify_block检疫,則values中對(duì)應(yīng)的value都必須滿足。
verify_value_exists

#不能再available_options中重復(fù)定義同一個(gè)key
verify_no_duplicates

#在定義FastlaneCore::ConfigItem類型的對(duì)象時(shí)祷嘶,可以設(shè)置與自己沖突的key屎媳,在values中,不能同時(shí)存在沖突的兩個(gè)key论巍。
verify_conflicts

#在定義FastlaneCore::ConfigItem類型的對(duì)象時(shí)烛谊,同時(shí)設(shè)置了default_value和verify_block,且values中沒有設(shè)置這個(gè)key嘉汰,則需要調(diào)用verify_block驗(yàn)證default_value的合法性丹禀。
verify_default_value_matches_verify_block

7. 執(zhí)行action
執(zhí)行action就是執(zhí)行action響應(yīng)類的類方法run,同時(shí)將[步驟6]的解析結(jié)果傳給run作為參數(shù)。類方法run中包含了這個(gè)action的所有業(yè)務(wù)代碼湃崩,fastlane庫(kù)中所有的內(nèi)置action都遵循這一設(shè)定,同樣接箫,在定義外部action時(shí)攒读,也應(yīng)該這樣做。

例子中actionexample_action_second的響應(yīng)類ExampleActionSecondAction中的run的定義

def self.run(options)
    puts "this is example action second action, options:"
    puts "foo:#{options[:foo]}"
    puts "bar:#{options[:bar]}"
end

其中參數(shù)options是一個(gè)FastlaneCore::Configuration的對(duì)象辛友,可以通過options[key]options.fetch(key)的方式來獲取key對(duì)應(yīng)的value薄扁。

4. trigger總結(jié)

1

之前一節(jié),以圖1的步驟詳細(xì)講解了trigger命令的執(zhí)行過程废累,圖中的幾個(gè)步驟完全是從使用者的角度來劃分的邓梅,單看這幾個(gè)步驟并不能對(duì)fastlane庫(kù)有一個(gè)直觀的了解,下列兩個(gè)圖在圖一的基礎(chǔ)上增加了一些細(xì)節(jié)邑滨。

2

3

圖2中描述了trigger命令的部分執(zhí)行過程日缨,大致可以和圖1中的前三個(gè)步驟相對(duì)應(yīng)。相比之前的執(zhí)行步驟掖看,圖2中增加了一些細(xì)節(jié)步驟匣距,并且將這些步驟以泳道的方式進(jìn)行劃分。除了Commander之外哎壳,其他步驟的執(zhí)行者比如CLIToolsDistributor毅待、CommandsGenerator等都是fastlane庫(kù)中定義的類,而Commander則是fastlane庫(kù)引用的外部庫(kù)归榕。

圖3承接圖2的步驟尸红,主要描述了Fastfile中定義的lane的執(zhí)行過程,大致可以和圖1中的后三個(gè)步驟相對(duì)應(yīng)刹泄,圖3中步驟的執(zhí)行者基本上都是Runner這個(gè)類外里。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市特石,隨后出現(xiàn)的幾起案子级乐,更是在濱河造成了極大的恐慌,老刑警劉巖县匠,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件风科,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡乞旦,警方通過查閱死者的電腦和手機(jī)贼穆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來兰粉,“玉大人故痊,你說我怎么就攤上這事【凉茫” “怎么了愕秫?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵慨菱,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我戴甩,道長(zhǎng)符喝,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任甜孤,我火速辦了婚禮协饲,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘缴川。我一直安慰自己茉稠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布把夸。 她就那樣靜靜地躺著而线,像睡著了一般。 火紅的嫁衣襯著肌膚如雪恋日。 梳的紋絲不亂的頭發(fā)上吞获,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音谚鄙,去河邊找鬼各拷。 笑死闷营,一個(gè)胖子當(dāng)著我的面吹牛速蕊,可吹牛的內(nèi)容都是我干的规哲。 我是一名探鬼主播唉锌,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼绿语!你這毒婦竟也來了吕粹?” 一聲冷哼從身側(cè)響起匹耕,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤良漱,失蹤者是張志新(化名)和其女友劉穎矾兜,沒想到半個(gè)月后椅寺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體返帕,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了踊谋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片殖蚕。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡胚股,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出摘刑,到底是詐尸還是另有隱情枷恕,我是刑警寧澤徐块,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站昼激,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏凡傅。R本人自食惡果不足惜夏跷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望硼莽。 院中可真熱鬧,春花似錦匆光、人聲如沸夺巩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至雨膨,卻和暖如春歼指,著一層夾襖步出監(jiān)牢的瞬間踩身,已是汗流浹背琼娘。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工坷备, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留省撑,地道東北人娃惯。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親仗颈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • fastlane運(yùn)行所需要的環(huán)境: OS X 10.9以上 Ruby 2.0 以上 Xcode 擁有一個(gè)開發(fā)者賬號(hào)...
    阿姣_0405閱讀 2,960評(píng)論 0 4
  • 什么是Fastlane? 官方自己的定義是這樣的: fastlane is a tool for iOS, Mac...
    會(huì)武功的蚊子閱讀 7,337評(píng)論 5 15
  • fastlane是一個(gè)自動(dòng)化構(gòu)建工具眼虱,主要包含測(cè)試撞蚕、打包、發(fā)布等功能,它內(nèi)部是由ruby實(shí)現(xiàn)的,是一款自動(dòng)化非常高...
    wangzzzzz閱讀 6,486評(píng)論 3 19
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器删性,智...
    卡卡羅2017閱讀 134,651評(píng)論 18 139
  • 早晨七點(diǎn)巴帮,正值學(xué)生上學(xué)的高峰期客给。附近有一所小學(xué),只見背著大大的書包桩引,穿著比自身大出好幾碼校服的小學(xué)生們?nèi)齼蓛傻赝?..
    琬珂玥閱讀 248評(píng)論 2 1