#!/usr/bin/ruby require 'fileutils' require 'uri' relative_libdir = File.expand_path(File.join(File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__), '../lib')) $motion_libdir = File.exist?(File.join(relative_libdir, 'motion')) ? relative_libdir : '/Library/Motion/lib' $:.unshift($motion_libdir) require 'motion/version' class Command class << self attr_accessor :name attr_accessor :help def die(*msg) $stderr.puts msg exit 1 end def need_root if Process.uid != 0 die "You need to be root to run this command." end end end end class CreateCommand < Command self.name = 'create' self.help = 'Create a new project' def self.run(args) if args.size != 1 die "Usage: motion create " end app_name = args.shift unless app_name.match(/^[a-zA-Z\d\s]+$/) die "Invalid app name" end if File.exist?(app_name) die "Directory `#{app_name}' already exists" end Dir.mkdir(app_name) Dir.chdir(app_name) do File.open('Rakefile', 'w') do |io| io.puts <" end license_key = args[0] unless license_key.match(/^[a-f0-9]{40}$/) die "Given license key `#{license_key}' seems invalid. It should be a string of 40 hexadecimal characters. Check the mail you received after the order, or contact us if you need any help: info@hipbyte.com" end if File.exist?(LicensePath) die "Product is already activated. Delete the license file `#{LicensePath}' if you want to activate a new license." end need_root File.open(LicensePath, 'w') { |io| io.write license_key } puts "Product activated. Thanks for purchasing RubyMotion :-)" end end class SupportCommand < Command self.name = 'support' self.help = 'Create a support ticket' def self.run(args) unless args.empty? die "Usage: motion support" end unless File.exist?(LicensePath) die "License file not present. Please activate RubyMotion with `motion activate' and try again." end license_key = File.read(LicensePath) # Guess the default email address from git. email = URI.escape(`git config --get user.email`.strip) # Collect details about the environment. osx_vers = `sw_vers -productVersion`.strip rm_vers = Motion::Version xcode_vers = `xcodebuild -version`.strip.scan(/Xcode\s(.+)$/).flatten[0].to_s xcode_vers = 'unknown' if xcode_vers.empty? environment = URI.escape("OSX #{osx_vers}, RubyMotion #{rm_vers}, Xcode #{xcode_vers}") system("open \"https://secure.rubymotion.com/new_support_ticket?license_key=#{license_key}&email=#{email}&environment=#{environment}\"") end end class UpdateCommand < Command self.name = 'update' self.help = 'Update the software' def self.curl(cmd) resp = `/usr/bin/curl #{cmd}` if $?.exitstatus != 0 die "Error when connecting to the server. Check your Internet connection and try again." end resp end def self.run(args) check_mode = args.delete('--check') unless args.empty? die "Usage: motion update" end 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}\" http://secure.rubymotion.com/latest_software_version") exit 1 unless resp.match(/^\d+\.\d+/) File.open(update_check_file, 'w') { |io| io.write(resp) } end exit File.read(update_check_file) > product_version ? 2 : 0 end unless File.exist?(LicensePath) die "License file not present. Please activate RubyMotion with `motion activate' and try again." end need_root license_key = File.read(LicensePath) $stderr.puts "Connecting to the server..." resp = curl("-s -d \"product=rubymotion\" -d \"current_software_version=#{product_version}\" -d \"license_key=#{license_key}\" https://secure.rubymotion.com/update_software") unless resp.match(/^http:/) die resp end $stderr.puts "Downloading software update..." url = resp tmp_dest = '/tmp/_rubymotion_su.pkg' curl("-# \"#{url}\" -o #{tmp_dest}") $stderr.puts "Installing software update..." installer = "/usr/sbin/installer -pkg \"#{tmp_dest}\" -target / >& /tmp/installer.stderr" unless system(installer) die "An error happened when installing the software update: #{File.read('/tmp/installer.stderr')}" end FileUtils.rm_f tmp_dest $stderr.puts "Software update installed.\n\n" news = File.read('/Library/Motion/NEWS') news.lines.each do |line| if md = line.match(/^=\s+RubyMotion\s+(.+)\s+=$/) break if md[1] <= product_version end $stderr.puts line end $stderr.puts "(See the `/Library/Motion/NEWS' file for all changes.)" end end class MotionMainCommand Commands = [CreateCommand, ActivateCommand, UpdateCommand, SupportCommand] def initialize(args) arg = args.shift case arg when '-h', '--help' usage when '-v', '--version' $stdout.puts Motion::Version exit 1 when /^-/ $stderr.puts "Unknown option: #{arg}" exit 1 end command = Commands.find { |command| command.name == arg } usage unless command command.run(args) end def usage $stderr.puts 'Usage:' $stderr.puts " #{File.basename(__FILE__)} [-h, --help]" $stderr.puts " #{File.basename(__FILE__)} [-v, --version]" $stderr.puts " #{File.basename(__FILE__)} []" $stderr.puts '' $stderr.puts 'Commands:' Commands.each do |command| $stderr.puts " #{command.name}".ljust(15) + command.help end exit 1 end end MotionMainCommand.new(ARGV)