開(kāi)始
CocoaPods Plugins 是一個(gè)Ruby gem,你需要安裝Ruby和CocoaPods來(lái)為你的插件開(kāi)發(fā)做準(zhǔn)備。
要開(kāi)始開(kāi)發(fā)一個(gè)新的插件莱睁,你還需要安裝cocoapods-plugins :
gem install cocoapods-plugins
為了演示和調(diào)試的目的,我們要先創(chuàng)建一個(gè)xcode工程,并且在其根目錄下執(zhí)行
git init
pod init
將其初始化為一個(gè)git倉(cāng)庫(kù)义辕,以及添加Podfile到該工程
創(chuàng)建CocoaPods Plugins
運(yùn)行下面的命令就可以生成一個(gè)插件模板工程
pod plugins create githooks
工程目錄是這樣的
.gemspec文件是插件的主要配置文件。所有的spec字段都是自描述的(你可以查看我們的gemspec)酿联,但是我想指出一件事:
默認(rèn)情況下终息,spec.files是指向git倉(cāng)庫(kù)并引用其中的文件。但是如果您試圖在git倉(cāng)庫(kù)中沒(méi)有文件(還未進(jìn)行版本控制)時(shí)構(gòu)建gem贞让,您將得到一個(gè)空的.gem文件,同時(shí)會(huì)沒(méi)有任何警告或錯(cuò)誤柳譬。我的建議是現(xiàn)在就將spec.files的值設(shè)置為Dir[' lib/*/ ']喳张,它將引用lib目錄下的所有文件。
替換其中spec.files這一行為
spec.files = Dir['lib/**/*']
Gemfile會(huì)包含所需的全部gem依賴(lài)美澳。查看Bundle Doc 以獲得更多信息
Rakefile包含測(cè)試所需要的引用销部,spec文件夾包含測(cè)試用例摸航。有關(guān)Rake的更多信息,請(qǐng)?jiān)L問(wèn)官方Rake repo舅桩。
我們現(xiàn)在還不需要更改Gemfile和Rakefile酱虎,所以保持其原樣。
lib是我們要使用的主文件夾擂涛。它包含構(gòu)建.gem的所有ruby文件读串。
為了確保一切設(shè)置正確,運(yùn)行下面的的命令:
gem build cocoapods-githooks.gemspec
你將看到'Successfully built RubyGem'的成功消息撒妈,同時(shí)Cocoapods-githooks-0.0.1.gem 也將會(huì)出現(xiàn)在目錄之下
實(shí)現(xiàn)插件
Cocoapods-githooks這個(gè)插件我們只需要它做一件簡(jiǎn)單的事情:將項(xiàng)目的.git-hooks目錄中的所有文件復(fù)制到.git/hooks/目錄中恢暖,并在每次運(yùn)行podinstall、pod update 或 pod githooks時(shí)執(zhí)行這個(gè)操作狰右。
為了實(shí)現(xiàn)這一點(diǎn)杰捂,我們將創(chuàng)建一個(gè)執(zhí)行文件操作的類(lèi),并將其鏈接到 pre-install和post-install這兩個(gè)CocoaPods鉤子以及githooks命令棋蚌。
在/lib/cocoapods-githooks中創(chuàng)建githooks-sync.rb文件
Require'cocoapods'和“fileutils”模塊嫁佳,并在CocoapodsGitHooks模塊中使用同步方法創(chuàng)建GitHooksSync類(lèi)。
require 'cocoapods'
require 'fileutils'
module CocoapodsGitHooks
class GitHooksSync
def sync
end
end
end
在復(fù)制git-hook之前谷暮,我們需要檢查一些事情:
確保我們?cè)趃it倉(cāng)庫(kù)中
確保.git-hooks目錄存在
確保.git-hooks目錄不是空的
我們可以通過(guò)在sync方法的開(kāi)頭添加下面的條件語(yǔ)句來(lái)實(shí)現(xiàn)這一點(diǎn):
if !File.directory?(".git")
Pod::UI.puts "Git repository not found"
return
end
if !File.directory?(".git-hooks")
Pod::UI.puts ".git-hooks directory not found, nothing to sync"
return
end
if Dir['.git-hooks/*'].empty?
Pod::UI.puts ".git-hooks directory is empty, nothing to sync"
return
end
在這之后脱拼,我們檢查hooks目錄是否存在于.git中,如果不存在坷备,創(chuàng)建它:
if !File.directory?(".git/hooks")
FileUtils.mkdir ".git/hooks"
end
現(xiàn)在我們準(zhǔn)備將鉤子從.git-hooks復(fù)制到.git/hooks:
FileUtils.cp_r(“.git-hooks/.”, “.git/hooks/”)
下一步是刪除shell腳本文件擴(kuò)展名(如果存在)使文件可執(zhí)行:
path = ".git/hooks/"
Dir.open(path).each do |p|
filename = File.basename(p, File.extname(p))
if File.extname(p) == ".sh"
FileUtils.mv("#{path}/#{p}", "#{path}/#{filename}")
end
FileUtils.chmod("+x", "#{path}/#{filename}")
end
我們還添加了兩個(gè)UI.puts 在同步方法的開(kāi)始和結(jié)束處顯示具有同步狀態(tài)的系統(tǒng)通知熄浓。如果你遵循了上面所有的步驟,您得到的githook -sync.rb文件看起來(lái)如下所示:
require 'cocoapods'
require 'fileutils'
module CocoapodsGitHooks
class GitHooksSync
def sync
Pod::UI.puts "Synchronizing git hooks"
if !File.directory?(".git")
Pod::UI.puts "Git repository not found"
return
end
if !File.directory?(".git-hooks")
Pod::UI.puts ".git-hooks folder not found, nothing to sync"
return
end
if Dir['.git-hooks/*'].empty?
Pod::UI.puts ".git-hooks folder is empty, nothing to sync"
return
end
if !File.directory?(".git/hooks")
FileUtils.mkdir ".git/hooks"
end
FileUtils.cp_r(".git-hooks/.", ".git/hooks/")
path = ".git/hooks/"
Dir.open(path).each do |p|
filename = File.basename(p, File.extname(p))
if File.extname(p) == ".sh"
FileUtils.mv("#{path}/#{p}", "#{path}/#{filename}")
end
FileUtils.chmod("+x", "#{path}/#{filename}")
end
Pod::UI.puts "Git hooks synchronized"
end
end
end
注冊(cè)CocoaPods鉤子
現(xiàn)在讓我們?cè)诿看蝡od install 或pod update之后調(diào)用sync方法省撑。為此赌蔑,我們需要在CocoaPods鉤子管理器中注冊(cè)post_install和post_update鉤子。打開(kāi)lib/cocoapods_plugin.rb寫(xiě)下下面的內(nèi)容:
require 'command/githooks'
require_relative 'githooks-sync'
module CocoapodsGitHooks
Pod::HooksManager.register('cocoapods-githooks', :post_install)
do |context|
GitHooksSync.new.sync()
end
Pod::HooksManager.register('cocoapods-githooks', :post_update)
do |context|
GitHooksSync.new.sync()
end
end
正如你所看到的竟秫,我們?cè)贖ooksManager中注冊(cè)了post_install和post_update鉤子娃惯,每次用戶(hù)運(yùn)行pod install或pod update后,都會(huì)調(diào)用GitHooksSync類(lèi)的sync方法肥败。
測(cè)試
先構(gòu)建這個(gè)gem:
gem build cocoapods-githooks.gemspec
安裝并運(yùn)行:
gem install cocoapods-githooks-0.0.1.gem
如果你遇到權(quán)限問(wèn)題的話(huà):
gem install cocoapods-githooks-0.0.1.gem --user-install
運(yùn)行這條命令以確保安裝正確趾浅。它應(yīng)該出現(xiàn)在已安裝插件的列表中
pod plugins installed
#輸出
- cocoapods-githooks : 0.0.1 (post_install and post_update hooks)
如果您看到棄用警告,不要擔(dān)心馒稍,我們將在下一個(gè)步驟中修復(fù)它皿哨。
現(xiàn)在讓我們回到測(cè)試項(xiàng)目。打開(kāi)Podfile纽谒,在開(kāi)頭添加:
plugin 'cocoapods-githooks'
回到命令行執(zhí)行:
pod install
你應(yīng)該會(huì)看到下面兩行打印的內(nèi)容:
Synchronizing git hooks
.git-hooks directory not found, nothing to sync
這是因?yàn)槲覀儧](méi)有創(chuàng)建.git-hooks目錄证膨。創(chuàng)建一個(gè)空的pre-commit.sh文件,并將其放入.git-hooks目錄鼓黔。
回到命令行執(zhí)行:
pod update
你會(huì)看到下面的輸出
Synchronizing git hooks
Git hooks synchronized
現(xiàn)在檢查.git/hooks目錄央勒,它應(yīng)該包含pre-commit這一可執(zhí)行文件不见。
添加自定義CocoaPods命令
添加新命令非常簡(jiǎn)單。您只需要?jiǎng)?chuàng)建command類(lèi)的子類(lèi)崔步。打開(kāi)lib/cocoapods-githooks/command/githooks.rb稳吮,將其內(nèi)容替換為:
require 'cocoapods'
require 'cocoapods-githooks/githooks-sync'
include CocoapodsGitHooks
module Pod
class Command
class Githooks < Command
self.summary = <<-SUMMARY
Syncs hooks between team members
SUMMARY
self.description = <<-DESC
CocoaPods plugins that syncs git-hooks placed in .git-hooks directory between team members
DESC
self.arguments = []
def run
CocoapodsGitHooks::GitHooksSync.new.sync()
end
end
end
end
它是一個(gè)簡(jiǎn)單的githooks命令,不帶參數(shù)并調(diào)用sync方法井濒。
現(xiàn)在 rebuild和重裝重新構(gòu)建后的gem:
gem build cocoapods-githooks.gemspec
gem install cocoapods-githooks-0.0.1.gem
刪除.git中的hooks目錄然后執(zhí)行:
pod githooks
下面是發(fā)布時(shí)間
請(qǐng)保持官方 RubyGems 的整潔灶似,避免發(fā)布測(cè)試和演示用的gem
發(fā)布CocoaPods插件需要兩個(gè)步驟。首先眼虱,您需要?jiǎng)?chuàng)建一個(gè)帳戶(hù)喻奥,然后將您的gem publish到RubyGems.org。之后你可以直接從RubyGems安裝插件:
gem install cocoapods-PLUGIN_NAME
如果你想讓你的插件被列在官方cocoapods插件列表中捏悬,運(yùn)行:
pod plugins publish
它將在cocoapods-plugins庫(kù)中創(chuàng)建一個(gè)issue并要求將您的插件添加到官方列表中撞蚕。為了加速這個(gè)過(guò)程,您可以fork cocoapods-plugins过牙,將生成的json對(duì)象添加為plugins.json文件中plugins數(shù)組中的最后一個(gè)對(duì)象甥厦,并創(chuàng)建一個(gè)pull請(qǐng)求。
最后
我們已經(jīng)構(gòu)建了一個(gè)非常簡(jiǎn)單的CocoaPods插件寇钉,但是你可以在這個(gè)強(qiáng)大的工具上添加更多的東西刀疙。如果你想為你未來(lái)的項(xiàng)目尋找靈感,可以運(yùn)行以下程序?yàn)g覽現(xiàn)有的多個(gè)插件:
pod plugins list