2015-11-06 31 views
4

我想在預安裝時執行一些代碼,當從rubygems.org安裝gem時,使用類似gem install some-gem的命令。如何添加(預/後)_install_hook紅寶石

的文檔指出,你可以使用一個http://docs.ruby-lang.org/en/2.2.0/Gem.html pre_install鉤,看起來像這樣:

# File lib/rubygems.rb, line 724 
def self.pre_install(&hook) 
    @pre_install_hooks << hook 
end 

該文檔還指出:

RubyGems defaults are stored in rubygems/defaults.rb. If you're packaging RubyGems or implementing Ruby you can change RubyGems' defaults. For RubyGems packagers, provide lib/rubygems/defaults/operating_system.rb and override any defaults from lib/rubygems/defaults.rb. For Ruby implementers, provide lib/rubygems/defaults/#{RUBY_ENGINE}.rb and override any defaults from lib/rubygems/defaults.rb. If you need RubyGems to perform extra work on install or uninstall, your defaults override file can set pre and post install and uninstall hooks. See ::pre_install, ::pre_uninstall, ::post_install, ::post_uninstall.

這聽起來正是我想要的。所以,我創建的文件

  • 的lib/RubyGems的/默認/ defaults.rb
  • 的lib/RubyGems的/默認/ operating_system.rb
  • 的RubyGems/defaults.rb

,我把代碼

Gem.pre_install { puts 'pre install hook called!' } 

在所有列出的文件中。然後我說他們require_paths在這樣的gemspec:

s.require_paths = ["lib", "test", "rubygems"] 

但我看不出有任何輸出端子安裝寶石時。

我在做什麼錯?

+0

應該「我現在看到輸出」其實是「我看不到輸出'? –

+0

是的,它應該是「否」而不是「現在」。編輯了這個問題。謝謝。 –

回答

2

現在的答案是(2015-11-11)不,您不能在安裝時執行任意代碼對於特定的寶石。你的問題中提到的鉤子是由RubyGem安裝程序本身使用的,並不是特定於gem的。有關更多詳細信息,請參閱:How can I make a Ruby gem package copy files to arbitrary locations?

這些文件:

lib/rubygems/defaults/defaults.rb 
lib/rubygems/defaults/operating_system.rb 
rubygems/defaults.rb 

並沒有從寶石目錄調用。它們位於RubyGems系統位置。

如果您希望在安裝任何gem之前對每個gem執行相同的代碼,那麼您可以通過將代碼放入/usr/lib64/ruby/2.2.0/rubygems/defaults.rb或您的系統上安裝Ruby的任何版本的位置來使用pre_install掛鉤。 operating_system.rb文件也將從相同的位置加載。

+0

已將代碼更改爲'Gem.pre_install {puts'pre install hook called!' return true }',但我仍然沒有執行安裝前/後的代碼。即使Gem :: Installer會被中止,是不是應該先打印消息?但我沒看到沒有什麼... –

+0

$ irb 'irb(main):001:0> puts'pre install hook called!'返回true' 'SyntaxError:(irb):1:語法錯誤,意外的keyword_return,期待輸入結束' 'puts'預安裝鉤叫!' return true' –

+0

Maybe {puts('pre install hook called!');返回true}會工作嗎?或者可能是塊返回正在創建一個'LocalJumpError:意外返回',它正在被pre_install錯誤處理所吞噬? –

0

您可以添加本地擴展到寶石。

gemspec:s.extensions << 'path/to/extconf.rb'

但隨後gem install命令要在安裝時執行一個Makefile。

所以extconf.rb必須創建一個虛擬的Makefile:

dummy_make_content = "make:\n" \ 
        "\t:\n" \ 
        "install:\n" \ 
        "\t:\n" \ 
        "clean:\n" \ 
        "\t:\n" 
File.write('Makefile', dummy_make_content) 

或者你可以要求MKMF包,並使用預定義的函數:

require 'mkmf' 
create_makefile ''