sudo motion update すると
Connecting to the server... Your software license is expired, please visit http://account.rubymotion.com to renew.
というメッセージが出るようになりました。
更新方法
http://account.rubymotion.com
にアクセスして10,000円おさめるだけのようです。
licenceの管理方法は?
ライセンス管理用のAPIに投げて処理しているんだろうと思うのですが
motion update時の挙動が気になったのでソースを見てみました。
まずは/usr/bin/motion
require 'motion/project/command' command_paths = [File.join($motion_libdir, 'motion/project/command'), File.join(ENV['HOME'], 'Library/RubyMotion/command')] command_paths.each do |path| Dir.glob(File.join(path, '*.rb')).each { |x| require x } end Motion::Project::Command.main(ARGV)
motion/project/command及び関連ファイルをrequireしてmainを実行しているだけです。
では、mainを見てみましょう。
/Library/RubyMotion/lib/motion/project/command.rb
見やすいように簡略化しています。
module Motion; module Project class Command Commands = [] def self.inherited(klass) Commands << klass if self == Command end def self.main(args) command = Commands.find { |command| command.name == arg } usage unless command command.new.run(args) end
ここで面白いなと思ったのが、self.inheritedを使ってサブクラスがrequireされたら
Commandsという配列に突っ込むという手法。
サブクラスはmotionの中でrequireしているので適切なサブクラスかどうかが判断できます。
あとは、そのサブクラスをnew.runしているだけです。
ついでですが、licenseファイルは下記のようです。
LicensePath = '/Library/RubyMotion/license.key'
次は、そのサブクラス。
/Library/RubyMotion/lib/motion/project/command/update.rb
module Motion; module Project class UpdateCommand < Command self.name = 'update' self.help = 'Update the software' def run(args) license_key = read_license_key product_version = Motion::Version if check_mode update_check_file = File.join(ENV['TMPDIR'] || '/tmp', '.motion-update-check') if !File.exist?(update_check_file) or (Time.now - File.mtime(update_check_file) > 60 * 60 * 24) resp = curl("-s -d \"product=rubymotion\" -d \"current_software_version=#{product_version}\" -d \"license_key=#{license_key}\" https://secure.rubymotion.com/latest_software_version") exit 1 unless resp.match(/^\d+\.\d+/) File.open(update_check_file, 'w') { |io| io.write(resp) } end
予想通りhttps://secure.rubymotion.com/latest_software_version にpostでパラメータをセットして投げています。
def curl(cmd) resp = `/usr/bin/curl --connect-timeout 60 #{cmd}` if $?.exitstatus != 0 die "Error when connecting to the server. Check your Internet connection and try again." end resp end
こんな感じですね。
$ curl -s -d "product=rubymotion" -d "current_software_version=2.0" -d "license_key=xxxxxxxxxxxxxxxxxxx" https://secure.rubymotion.com/latest_software_version 2.0|Your license is expired. Run `motion account' to renew it.%
あと、あんまり関係ないですが
sudoでの実行かどうかの判断ロジックが勉強になりました。
Process.uidで判断できるんですね。
def need_root if Process.uid != 0 die "You need to be root to run this command." end end