CocoaPods Plugins 开发

开始

CocoaPods Plugins 是一个Ruby gem,你需要安装Ruby和CocoaPods来为你的插件开发做准备。
要开始开发一个新的插件,你还需要安装cocoapods-plugins :

gem install cocoapods-plugins

为了演示和调试的目的,我们要先创建一个xcode工程,并且在其根目录下执行

git init
pod init

将其初始化为一个git仓库,以及添加Podfile到该工程

创建CocoaPods Plugins

运行下面的命令就可以生成一个插件模板工程

pod plugins create githooks

工程目录是这样的

插件工程目录

.gemspec文件是插件的主要配置文件。所有的spec字段都是自描述的(你可以查看我们的gemspec),但是我想指出一件事:

默认情况下,spec.files是指向git仓库并引用其中的文件。但是如果您试图在git仓库中没有文件(还未进行版本控制)时构建gem,您将得到一个空的.gem文件,同时会没有任何警告或错误。我的建议是现在就将spec.files的值设置为Dir[' lib/*/ '],它将引用lib目录下的所有文件。

替换其中spec.files这一行为

spec.files = Dir['lib/**/*']

Gemfile会包含所需的全部gem依赖。查看Bundle Doc 以获得更多信息
Rakefile包含测试所需要的引用,spec文件夹包含测试用例。有关Rake的更多信息,请访问官方Rake repo
我们现在还不需要更改Gemfile和Rakefile,所以保持其原样。
lib是我们要使用的主文件夹。它包含构建.gem的所有ruby文件。
为了确保一切设置正确,运行下面的的命令:

gem build cocoapods-githooks.gemspec

你将看到'Successfully built RubyGem'的成功消息,同时Cocoapods-githooks-0.0.1.gem 也将会出现在目录之下

实现插件

Cocoapods-githooks这个插件我们只需要它做一件简单的事情:将项目的.git-hooks目录中的所有文件复制到.git/hooks/目录中,并在每次运行podinstall、pod update 或 pod githooks时执行这个操作。
为了实现这一点,我们将创建一个执行文件操作的类,并将其链接到 pre-install和post-install这两个CocoaPods钩子以及githooks命令。
在/lib/cocoapods-githooks中创建githooks-sync.rb文件
Require'cocoapods'和“fileutils”模块,并在CocoapodsGitHooks模块中使用同步方法创建GitHooksSync类。

require 'cocoapods'
require 'fileutils'
module CocoapodsGitHooks
    class GitHooksSync
        def sync

        end
    end
end

在复制git-hook之前,我们需要检查一些事情:
确保我们在git仓库中
确保.git-hooks目录存在
确保.git-hooks目录不是空的
我们可以通过在sync方法的开头添加下面的条件语句来实现这一点:

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中,如果不存在,创建它:

if !File.directory?(".git/hooks")
    FileUtils.mkdir ".git/hooks"
end

现在我们准备将钩子从.git-hooks复制到.git/hooks:

FileUtils.cp_r(“.git-hooks/.”, “.git/hooks/”)

下一步是删除shell脚本文件扩展名(如果存在)使文件可执行:

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

我们还添加了两个UI.puts 在同步方法的开始和结束处显示具有同步状态的系统通知。如果你遵循了上面所有的步骤,您得到的githook -sync.rb文件看起来如下所示:

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

注册CocoaPods钩子

现在让我们在每次pod install 或pod update之后调用sync方法。为此,我们需要在CocoaPods钩子管理器中注册post_install和post_update钩子。打开lib/cocoapods_plugin.rb写下下面的内容:

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

正如你所看到的,我们在HooksManager中注册了post_install和post_update钩子,每次用户运行pod install或pod update后,都会调用GitHooksSync类的sync方法。

测试

先构建这个gem:

gem build cocoapods-githooks.gemspec

安装并运行:

gem install cocoapods-githooks-0.0.1.gem

如果你遇到权限问题的话:

gem install cocoapods-githooks-0.0.1.gem --user-install

运行这条命令以确保安装正确。它应该出现在已安装插件的列表中

pod plugins installed
#输出
- cocoapods-githooks    : 0.0.1 (post_install and post_update hooks)

如果您看到弃用警告,不要担心,我们将在下一个步骤中修复它。
现在让我们回到测试项目。打开Podfile,在开头添加:

plugin 'cocoapods-githooks'

回到命令行执行:

pod install

你应该会看到下面两行打印的内容:

Synchronizing git hooks
.git-hooks directory not found, nothing to sync

这是因为我们没有创建.git-hooks目录。创建一个空的pre-commit.sh文件,并将其放入.git-hooks目录。
回到命令行执行:

pod update

你会看到下面的输出

Synchronizing git hooks
Git hooks synchronized

现在检查.git/hooks目录,它应该包含pre-commit这一可执行文件。

添加自定义CocoaPods命令

添加新命令非常简单。您只需要创建command类的子类。打开lib/cocoapods-githooks/command/githooks.rb,将其内容替换为:

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

它是一个简单的githooks命令,不带参数并调用sync方法。
现在 rebuild和重装重新构建后的gem:

gem build cocoapods-githooks.gemspec
gem install cocoapods-githooks-0.0.1.gem

删除.git中的hooks目录然后执行:

pod githooks

下面是发布时间

请保持官方 RubyGems 的整洁,避免发布测试和演示用的gem

发布CocoaPods插件需要两个步骤。首先,您需要创建一个帐户,然后将您的gem publish到RubyGems.org。之后你可以直接从RubyGems安装插件:

gem install cocoapods-PLUGIN_NAME

如果你想让你的插件被列在官方cocoapods插件列表中,运行:

pod plugins publish

它将在cocoapods-plugins库中创建一个issue并要求将您的插件添加到官方列表中。为了加速这个过程,您可以fork cocoapods-plugins,将生成的json对象添加为plugins.json文件中plugins数组中的最后一个对象,并创建一个pull请求。

最后

我们已经构建了一个非常简单的CocoaPods插件,但是你可以在这个强大的工具上添加更多的东西。如果你想为你未来的项目寻找灵感,可以运行以下程序浏览现有的多个插件:

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

推荐阅读更多精彩内容