cocoapods源码5.2 - command/init.rb

1、CocoaPods/lib/cocoapods/command/init.rb

require 'xcodeproj'
require 'active_support/core_ext/string/strip'

module Pod
  class Command
    # init child command => pod init
    class Init < Command
      # 1、command 基本描述
      self.summary = 'Generate a Podfile for the current directory'
      self.description = <<-DESC
        Creates a Podfile for the current directory if none currently exists. If
        an `XCODEPROJ` project file is specified or if there is only a single
        project file in the current directory, targets will be automatically
        generated based on targets defined in the project.

        It is possible to specify a list of dependencies which will be used by
        the template in the `Podfile.default` (normal targets) `Podfile.test`
        (test targets) files which should be stored in the
        `~/.cocoapods/templates` folder.
      DESC

      # 2、参数 XCODEPROJ 指定为 xxx.xcodeproj 文件所在的路径
      self.arguments = [
        CLAide::Argument.new('XCODEPROJ', :false),
      ]
      
      # 3、init
      def initialize(argv)
        #puts "initialize():"
        #puts "Pathname.pwd = #{Pathname.pwd}"
        #puts "argv = #{argv}"
        
        # 3.1、获取 Podfile 文件的路径
        @podfile_path = Pathname.pwd + 'Podfile'
        #puts "@podfile_path = #{@podfile_path}"

        # 3.2 
        @project_path = argv.shift_argument
        #puts "@project_path = #{@project_path}"

        # 3.3、遍历获取所有的 xxx.xcodeproj
        @project_paths = Pathname.pwd.children.select { |pn| pn.extname == '.xcodeproj' }
        #puts "@project_paths = #{@project_paths}"

        # 3.4、
        super
      end

      # 4、命令行参数校验
      def validate!
        super
        
        # 1、config.podfile_path_in_dir(Pathname.pwd) != nil 时,抛出异常提示:【Podfile已经存在】
        # raise Informative, 'Existing Podfile found in directory' unless config.podfile_path_in_dir(Pathname.pwd).nil?
        
        # 2、找到合法的 xxx.xcodeproj 文件路径
        if @project_path
          help! "Xcode project at #{@project_path} does not exist" unless File.exist? @project_path
          project_path = @project_path
        else
          raise Informative, 'No Xcode project found, please specify one' unless @project_paths.length > 0
          raise Informative, 'Multiple Xcode projects found, please specify one' unless @project_paths.length == 1
          project_path = @project_paths.first
        end

        # 3、调用Xcodeproj打开xxx.xcodeproj
        @xcode_project = Xcodeproj::Project.open(project_path)
      end

      # 5、
      def run
        # 打开Podfile文件,输入预先的模板内容
        @podfile_path.open('w') { |f| 
          f << podfile_template(@xcode_project)
        }
      end

      # ------------------------------- private ------------------------------- 
      private

      # 1、创建Podfile文件内容模板
      # @param  [Xcodeproj::Project] project
      #         The xcode project to generate a podfile for.
      #
      # @return [String] the text of the Podfile for the provided project
      #
      def podfile_template(project)
        # 1.1、
        podfile = ''

        # 1.2、如果存在 @project_path ,则拼接 "project ..... "
        podfile << "project '#{@project_path}'\n\n" if @project_path

        # 1.3、platform :ios, '9.0'
        podfile << <<-PLATFORM.strip_heredoc
          # Uncomment the next line to define a global platform for your project
          # platform :ios, '9.0'
        PLATFORM

        # 1.4、遍历xcode工程所有的target,分为test与app两种类型的target
        test_targets, app_targets = project
                                    .native_targets()
                                    .sort_by() { |t| t.name.downcase }
                                    .partition(&:test_target_type?)
        # puts test_targets
        # puts app_targets

        # 1.5、app target + test app target
        app_targets.each do |app_target|
          # app => test_app 
          test_targets_for_app = test_targets.select do |target|
            target.name.downcase.start_with?(app_target.name.downcase)
          end

          # target_module([app], [test_app])
          podfile << target_module(app_target, test_targets_for_app)
        end
        
        # 1.6 return 
        podfile
      end

      # 2、组织 pod target 内容
      def target_module(app, tests)
        # 2.1、app.name 中的【'】单引号 =转义=>【\\'】
        target_module = "\ntarget '#{app.name.gsub(/'/, "\\\\\'")}' do\n"
          
        # 2.2、判断是否构建swift代码,如果是,则添加【use_frameworks!】
        target_module << if app.resolved_build_setting('SWIFT_OPTIMIZATION_LEVEL').values.any?
          <<-RUBY
          # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
          use_frameworks!
          RUBY
        else
          <<-RUBY
          # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
          # use_frameworks!

         RUBY
        end

        # 2.3、添加 "# Pods for App"
        # => config.default_podfile_path
        # => puts config.default_podfile_path
        # => /Users/xiongzenghui/.cocoapods/templates/Podfile.default
        # => 默认 .cocoapods 目录下,不存在【templates目录】,也就不存在【Podfile.default】
        # => 可通过手动添加【Podfile.default】,定制Podfile的模板内容
        target_module << template_contents(config.default_podfile_path, '  ', "Pods for #{app.name}\n")
        
        # 到此为止,构造Podfile文件内容如下:
        # Uncomment the next line to define a global platform for your project
        # platform :ios, '9.0'
        # 
        # target 'App' do
        #   # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
        #   # use_frameworks!
        #   # Pods for App
        # 
        # end

        # 2.4、继续构造 test target list
        # target test_app do 
        #   inherit! :search_paths
        #   # Pods for testing
        # 
        # end
        tests.each do |test|
          target_module << "\n  target '#{test.name.gsub(/'/, "\\\\\'")}' do\n"
          target_module << "    inherit! :search_paths\n"
          target_module << template_contents(config.default_test_podfile_path, '    ', 'Pods for testing')
          target_module << "\n  end\n"
        end

        # 2.5 对应【app target】末尾的 "end"
        target_module << "\nend\n"
      end

      # @param  [[Xcodeproj::PBXTarget]] targets
      #         An array which always has a target as its first item
      #         and may optionally contain a second target as its test target
      #
      # @return [String] the text for the target module
      #
      def template_contents(path, prefix, fallback)
        if path.exist?
          # String#chomp() => 去掉字符串末尾的\n或\r
          path.read.chomp.lines.map { |line| 
            "#{prefix}#{line}" # 每一行内容为:[prefix][Podfile.default文件每一行的内容]
          }.join("\n") # Podfile.default文件末尾追加\n换行
        else
          "#{prefix}# #{fallback}"
        end
      end
    end
  end
end

2、pod init

➜  App ls -l
total 0
drwxr-xr-x  28 xiongzenghui  staff  896  7 29 11:24 App
drwxr-xr-x@  5 xiongzenghui  staff  160  7 24 16:50 App.xcodeproj
➜  App 
➜  App pod init
➜  App cat Podfile
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'App' do
          # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
          # use_frameworks!

  # Pods for App

end
➜  App

3、pod init XCODEPROJ

➜  App tree
.
└── path1
    └── path2
        ├── App
        ├── App.xcodeproj
        └── Podfile

➜  App
➜  App pod init ./path1/path2/App.xcodeproj
➜  App cat Podfile
project './path1/path2/App.xcodeproj'

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'App' do
          # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
          # use_frameworks!

  # Pods for App

end
➜  App

比上面的pod init生成的podfile开始位置多一行project:

project './path1/path2/App.xcodeproj'
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容