mirror of
https://github.com/zhigang1992/RubyMotion.git
synced 2026-04-21 02:50:14 +08:00
Merge branch 'claide'
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -4,3 +4,6 @@
|
||||
[submodule "vendor/XCPretty"]
|
||||
path = vendor/XCPretty
|
||||
url = https://github.com/alloy/XCPretty.git
|
||||
[submodule "vendor/CLAide"]
|
||||
path = vendor/CLAide
|
||||
url = https://github.com/CocoaPods/CLAide.git
|
||||
|
||||
5
NEWS
5
NEWS
@@ -36,10 +36,13 @@
|
||||
the `:cflags` option.
|
||||
* [iOS] Made the UI test helper search for views from the `keyWindow' instead
|
||||
of the `current' window that was created specifically for the test. This
|
||||
makes it easier to interact with modal views such as `UIAlertView`.
|
||||
makes it easier to interact with modal views such as `UIAlertView'.
|
||||
* [iOS] Fixed a bug in build system where link error was caused when the app
|
||||
is built for ARM64 with Xcode 5.1. Thanks to Andrew Larssen for the patch
|
||||
(pull request #146).
|
||||
* Improved command-line interface, e.g. `$ motion create --help' will now no
|
||||
longer create an application called ‘--help’. This deprecates the interface
|
||||
for any command plugins and this will fully be removed with RubyMotion v3.
|
||||
|
||||
= RubyMotion 2.19 =
|
||||
|
||||
|
||||
3
Rakefile
3
Rakefile
@@ -175,6 +175,9 @@ task :install do
|
||||
end
|
||||
end
|
||||
|
||||
# Include the CLAide gem.
|
||||
data.concat(FileList["./vendor/CLAide/{LICENSE,lib/**/*.rb}"])
|
||||
|
||||
# Include the XCPretty gem.
|
||||
binaries << './vendor/XCPretty/bin/xcpretty'
|
||||
data.concat(FileList["./vendor/XCPretty/{LICENSE.txt,lib/**/*.rb}"])
|
||||
|
||||
14
bin/motion
14
bin/motion
@@ -4,17 +4,11 @@
|
||||
# This file is subject to the terms and conditions of the End User License
|
||||
# Agreement accompanying the package this file is a part of.
|
||||
|
||||
require 'fileutils'
|
||||
|
||||
relative_libdir = File.expand_path(File.join(File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__), '../lib'))
|
||||
file = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
|
||||
relative_libdir = File.expand_path('../../lib', file)
|
||||
$motion_libdir = File.exist?(File.join(relative_libdir, 'motion')) ? relative_libdir : '/Library/RubyMotion/lib'
|
||||
$:.unshift($motion_libdir)
|
||||
|
||||
require 'motion/project/command'
|
||||
require 'motion/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::Command.run(ARGV)
|
||||
|
||||
114
lib/motion/command.rb
Normal file
114
lib/motion/command.rb
Normal file
@@ -0,0 +1,114 @@
|
||||
# Copyright (c) 2012, HipByte SPRL and contributors
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
require 'motion/version'
|
||||
require 'motion/error'
|
||||
|
||||
$:.unshift File.expand_path('../../../vendor/CLAide/lib', __FILE__)
|
||||
require 'claide'
|
||||
|
||||
module Motion
|
||||
# This will cause these errors to only show their message when raised, unless
|
||||
# the `--verbose` option is specified.
|
||||
class InformativeError
|
||||
include CLAide::InformativeError
|
||||
end
|
||||
end
|
||||
|
||||
module Motion
|
||||
# -------------------------------------------------------------------------
|
||||
# Base command class of RubyMotion
|
||||
# -------------------------------------------------------------------------
|
||||
class Command < CLAide::Command
|
||||
require 'motion/command/account'
|
||||
require 'motion/command/activate'
|
||||
require 'motion/command/changelog'
|
||||
require 'motion/command/create'
|
||||
require 'motion/command/device_console'
|
||||
require 'motion/command/ri'
|
||||
require 'motion/command/support'
|
||||
require 'motion/command/update'
|
||||
|
||||
# TODO support RubyGems plugins?
|
||||
# require 'rubygems'
|
||||
# self.plugin_prefix = 'motion'
|
||||
|
||||
self.abstract_command = true
|
||||
self.command = 'motion'
|
||||
self.description = 'RubyMotion lets you develop native iOS and OS X ' \
|
||||
'applications using the awesome Ruby language.'
|
||||
|
||||
def self.options
|
||||
[
|
||||
['--version', 'Show the version of RubyMotion'],
|
||||
].concat(super)
|
||||
end
|
||||
|
||||
def self.run(argv)
|
||||
argv = CLAide::ARGV.new(argv)
|
||||
if argv.flag?('version')
|
||||
$stdout.puts Motion::Version
|
||||
exit 0
|
||||
end
|
||||
super(argv)
|
||||
end
|
||||
|
||||
#def self.report_error(exception)
|
||||
# TODO in case we ever want to report expections.
|
||||
#end
|
||||
|
||||
protected
|
||||
|
||||
def die(message)
|
||||
raise InformativeError, message
|
||||
end
|
||||
|
||||
def need_root
|
||||
if Process.uid != 0
|
||||
die "You need to be root to run this command."
|
||||
end
|
||||
end
|
||||
|
||||
def pager
|
||||
ENV['PAGER'] || '/usr/bin/less'
|
||||
end
|
||||
|
||||
LicensePath = '/Library/RubyMotion/license.key'
|
||||
def read_license_key
|
||||
unless File.exist?(LicensePath)
|
||||
die "License file not present. Please activate RubyMotion with `motion activate' and try again."
|
||||
end
|
||||
File.read(LicensePath).strip
|
||||
end
|
||||
|
||||
def guess_email_address
|
||||
require 'uri'
|
||||
# Guess the default email address from git.
|
||||
URI.escape(`git config --get user.email`.strip)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Now load the deprecated Motion::Project::Command class and plugins.
|
||||
# TODO remove in RM-3.
|
||||
require 'motion/project/command'
|
||||
@@ -21,19 +21,15 @@
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
module Motion; module Project
|
||||
class AccountCommand < Command
|
||||
self.name = 'account'
|
||||
self.help = 'Access the software license account'
|
||||
|
||||
def run(args)
|
||||
unless args.empty?
|
||||
die "Usage: motion account"
|
||||
end
|
||||
|
||||
module Motion; class Command
|
||||
class Account < Command
|
||||
self.summary = 'Access account details.'
|
||||
self.description = 'Access the details of your software license account.'
|
||||
|
||||
def run
|
||||
license_key = read_license_key
|
||||
email = guess_email_address
|
||||
|
||||
|
||||
system("open \"https://secure.rubymotion.com/account?license_key=#{license_key}&email=#{email}\"")
|
||||
end
|
||||
end
|
||||
@@ -21,25 +21,32 @@
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
module Motion; module Project
|
||||
class ActivateCommand < Command
|
||||
self.name = 'activate'
|
||||
self.help = 'Activate the software license'
|
||||
|
||||
def run(args)
|
||||
module Motion; class Command
|
||||
class Activate < Command
|
||||
self.summary = 'Activate software license.'
|
||||
self.description = 'Activate your RubyMotion software license key.'
|
||||
|
||||
self.arguments = 'LICENSE-KEY'
|
||||
|
||||
def initialize(argv)
|
||||
@license_key = argv.shift_argument
|
||||
super
|
||||
end
|
||||
|
||||
def validate!
|
||||
super
|
||||
help! "Activating a license requires a `LICENSE-KEY`." unless @license_key
|
||||
end
|
||||
|
||||
def run
|
||||
if File.exist?(LicensePath)
|
||||
die "Product is already activated. Delete the license file `#{LicensePath}' if you want to activate a new license."
|
||||
end
|
||||
|
||||
if args.size != 1
|
||||
die "Usage: motion activate <license-key>"
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
||||
need_root
|
||||
File.open(LicensePath, 'w') { |io| io.write license_key }
|
||||
puts "Product activated. Thanks for purchasing RubyMotion :-)"
|
||||
@@ -21,19 +21,14 @@
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
module Motion; module Project
|
||||
class ChangelogCommand < Command
|
||||
self.name = 'changelog'
|
||||
self.help = 'View the changelog'
|
||||
module Motion; class Command
|
||||
class Changelog < Command
|
||||
self.summary = 'View the changelog.'
|
||||
self.description = 'View the changes that have been made in all ' \
|
||||
'RubyMotion versions.'
|
||||
|
||||
def run(args)
|
||||
unless args.empty?
|
||||
die "Usage: motion changelog"
|
||||
end
|
||||
|
||||
pager = (ENV['PAGER'] or '/usr/bin/less')
|
||||
def run
|
||||
system("#{pager} /Library/RubyMotion/NEWS")
|
||||
end
|
||||
end
|
||||
end; end
|
||||
|
||||
@@ -24,44 +24,49 @@
|
||||
require 'motion/project/app'
|
||||
require 'motion/project/template'
|
||||
|
||||
module Motion; module Project
|
||||
class CreateCommand < Command
|
||||
self.name = 'create'
|
||||
self.help = 'Create a new project'
|
||||
|
||||
module Motion; class Command
|
||||
class Create < Command
|
||||
DefaultTemplate = 'ios'
|
||||
|
||||
def run(args)
|
||||
app_name = nil
|
||||
template_name = DefaultTemplate
|
||||
args.each do |a|
|
||||
case a
|
||||
when /--([^=]+)=(.+)/
|
||||
opt_name = $1.to_s.strip
|
||||
opt_val = $2.to_s.strip
|
||||
case opt_name
|
||||
when 'template'
|
||||
template_name = opt_val
|
||||
else
|
||||
die "Incorrect option `#{opt_name}'"
|
||||
end
|
||||
else
|
||||
if app_name
|
||||
app_name = nil
|
||||
break
|
||||
else
|
||||
app_name = a
|
||||
end
|
||||
end
|
||||
|
||||
def self.all_templates
|
||||
Motion::Project::Template.all_templates.keys
|
||||
end
|
||||
|
||||
def self.templates_description
|
||||
all_templates.map do |x|
|
||||
x == DefaultTemplate ? "#{x} (default)" : x
|
||||
end.join(', ')
|
||||
end
|
||||
|
||||
self.summary = 'Create a new project.'
|
||||
|
||||
self.description = "Create a new RubyMotion project from one of the " \
|
||||
"following templates: #{templates_description}."
|
||||
|
||||
self.arguments = 'APP-NAME'
|
||||
|
||||
def self.options
|
||||
[
|
||||
['--template=NAME', "One of #{templates_description}."],
|
||||
].concat(super)
|
||||
end
|
||||
|
||||
def initialize(argv)
|
||||
@template = argv.option('template') || DefaultTemplate
|
||||
@app_name = argv.shift_argument
|
||||
super
|
||||
end
|
||||
|
||||
def validate!
|
||||
super
|
||||
help! "A name for the new project is required." unless @app_name
|
||||
unless self.class.all_templates.include?(@template)
|
||||
help! "Invalid template specified `#{@template}'."
|
||||
end
|
||||
|
||||
unless app_name
|
||||
$stderr.puts "Usage: motion create [--template=<template_name>] <app-name>"
|
||||
$stderr.puts "Available templates: " + Motion::Project::Template.all_templates.keys.map { |x| x == DefaultTemplate ? "#{x} (default)" : x }.join(', ')
|
||||
exit 1
|
||||
end
|
||||
|
||||
Motion::Project::App.create(app_name, template_name)
|
||||
end
|
||||
|
||||
def run
|
||||
Motion::Project::App.create(@app_name, @template)
|
||||
end
|
||||
end
|
||||
end; end
|
||||
@@ -21,16 +21,21 @@
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
module Motion; module Project
|
||||
class DeviceConsoleCommand < Command
|
||||
self.name = 'device:console'
|
||||
self.help = 'Print the device console logs'
|
||||
module Motion; class Command
|
||||
class DeprecatedDeviceConsole < Command
|
||||
self.command = 'device:console'
|
||||
|
||||
def run(args)
|
||||
unless args.empty?
|
||||
die "Usage: motion device:console"
|
||||
end
|
||||
def run
|
||||
warn "[!] The usage of the `device:console` command is deprecated" \
|
||||
"use the `device-console` command instead."
|
||||
DeviceConsole.run([])
|
||||
end
|
||||
end
|
||||
|
||||
class DeviceConsole < Command
|
||||
self.summary = 'Print iOS device logs'
|
||||
|
||||
def run
|
||||
deploy = File.join(File.dirname(__FILE__), '../../../../bin/ios/deploy')
|
||||
devices = `\"#{deploy}\" -D`.strip.split(/\n/)
|
||||
if devices.empty?
|
||||
@@ -43,4 +48,3 @@ module Motion; module Project
|
||||
end
|
||||
end
|
||||
end; end
|
||||
|
||||
49
lib/motion/command/ri.rb
Normal file
49
lib/motion/command/ri.rb
Normal file
@@ -0,0 +1,49 @@
|
||||
# Copyright (c) 2012, HipByte SPRL and contributors
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
module Motion; class Command
|
||||
class RI < Command
|
||||
self.summary = 'Display API reference.'
|
||||
self.description = 'Display Cocoa(Touch) API reference documentation ' \
|
||||
'using a command-line interface.'
|
||||
|
||||
self.arguments = 'API-NAME'
|
||||
|
||||
def initialize(argv)
|
||||
@api_name = argv.shift_argument
|
||||
super
|
||||
end
|
||||
|
||||
def validate!
|
||||
super
|
||||
help! "Specify a term to search the API reference for." unless @api_name
|
||||
end
|
||||
|
||||
def run
|
||||
line = "/Library/RubyMotion/lib/yard/bin/yri --db /Library/RubyMotion/doc/yardoc "
|
||||
line << "-p #{pager} "
|
||||
line << "#{@api_name}"
|
||||
system(line)
|
||||
end
|
||||
end
|
||||
end; end
|
||||
@@ -23,19 +23,16 @@
|
||||
|
||||
require 'uri'
|
||||
|
||||
module Motion; module Project
|
||||
class SupportCommand < Command
|
||||
self.name = 'support'
|
||||
self.help = 'Create a support ticket'
|
||||
|
||||
def run(args)
|
||||
unless args.empty?
|
||||
die "Usage: motion support"
|
||||
end
|
||||
|
||||
module Motion; class Command
|
||||
class Support < Command
|
||||
self.summary = 'Create a support ticket.'
|
||||
# TODO make more elaborate
|
||||
# self.description = '...'
|
||||
|
||||
def run
|
||||
license_key = read_license_key
|
||||
email = guess_email_address
|
||||
|
||||
|
||||
# Collect details about the environment.
|
||||
osx_vers = `/usr/bin/sw_vers -productVersion`.strip
|
||||
rm_vers = Motion::Version
|
||||
@@ -49,9 +46,9 @@ module Motion; module Project
|
||||
vers = 'unknown' if vers.empty?
|
||||
vers
|
||||
end
|
||||
|
||||
|
||||
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
|
||||
@@ -23,10 +23,53 @@
|
||||
|
||||
require 'motion/project/builder'
|
||||
|
||||
module Motion; module Project
|
||||
class UpdateCommand < Command
|
||||
self.name = 'update'
|
||||
self.help = 'Update the software'
|
||||
module Motion; class Command
|
||||
class Update < Command
|
||||
self.summary = 'Update the software.'
|
||||
# TODO make more elaborate
|
||||
# self.description = '...'
|
||||
|
||||
def self.options
|
||||
[
|
||||
['--check', 'Only check whether or not a newer version is available'],
|
||||
['--cache-version=VERSION', 'Install a specific RubyMotion version'],
|
||||
].concat(super)
|
||||
end
|
||||
|
||||
def initialize(argv)
|
||||
@check_mode = argv.flag?('check', false)
|
||||
@wanted_software_version = argv.option('cache-version')
|
||||
@force_version = argv.option('force-version')
|
||||
super
|
||||
end
|
||||
|
||||
def validate!
|
||||
super
|
||||
if @force_version
|
||||
help! "--force-version has been deprecated in favor of --cache-version"
|
||||
end
|
||||
if @wanted_software_version && File.exist?('/Library/RubyMotion.old')
|
||||
die("/Library/RubyMotion.old already exists, please move this directory before using --cache-version")
|
||||
end
|
||||
end
|
||||
|
||||
def run
|
||||
if @check_mode
|
||||
perform_check
|
||||
else
|
||||
perform_update
|
||||
end
|
||||
end
|
||||
|
||||
def product_version
|
||||
Motion::Version
|
||||
end
|
||||
|
||||
def latest_version?(product, latest)
|
||||
product = product.split(".")
|
||||
latest = latest.split(".")
|
||||
(product[0].to_i >= latest[0].to_i) && (product[1].to_i >= latest[1].to_i)
|
||||
end
|
||||
|
||||
def curl(cmd)
|
||||
resp = `/usr/bin/curl --connect-timeout 60 #{cmd}`
|
||||
@@ -36,59 +79,34 @@ module Motion; module Project
|
||||
resp
|
||||
end
|
||||
|
||||
def latest_version?(product, latest)
|
||||
product = product.split(".")
|
||||
latest = latest.split(".")
|
||||
(product[0].to_i >= latest[0].to_i) && (product[1].to_i >= latest[1].to_i)
|
||||
def perform_check
|
||||
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=#{read_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
|
||||
|
||||
latest_version, message = File.read(update_check_file).split('|', 2)
|
||||
message ||= ''
|
||||
unless latest_version?(product_version, latest_version)
|
||||
message = "A new version of RubyMotion is available. Run `sudo motion update' to upgrade.\n" + message
|
||||
end
|
||||
message.strip!
|
||||
unless message.empty?
|
||||
puts '=' * 80
|
||||
puts message
|
||||
puts '=' * 80
|
||||
puts ''
|
||||
end
|
||||
exit 1
|
||||
end
|
||||
|
||||
def run(args)
|
||||
check_mode = false
|
||||
wanted_software_version = nil
|
||||
args.each do |a|
|
||||
case a
|
||||
when '--check'
|
||||
check_mode = true
|
||||
when /--cache-version=(.+)/
|
||||
die("/Library/RubyMotion.old already exists, please move this directory before using --cache-version") if File.exist?('/Library/RubyMotion.old')
|
||||
wanted_software_version = $1.to_s
|
||||
when /--force-version=(.+)/
|
||||
die "--force-version has been removed in favor of --cache-version"
|
||||
else
|
||||
die "Usage: motion update [--cache-version=X]"
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
latest_version, message = File.read(update_check_file).split('|', 2)
|
||||
message ||= ''
|
||||
unless latest_version?(product_version, latest_version)
|
||||
message = "A new version of RubyMotion is available. Run `sudo motion update' to upgrade.\n" + message
|
||||
end
|
||||
message.strip!
|
||||
unless message.empty?
|
||||
puts '=' * 80
|
||||
puts message
|
||||
puts '=' * 80
|
||||
puts ''
|
||||
end
|
||||
exit 1
|
||||
end
|
||||
|
||||
def perform_update
|
||||
need_root
|
||||
|
||||
$stderr.puts "Connecting to the server..."
|
||||
resp = curl("-s -d \"product=rubymotion\" -d \"current_software_version=#{product_version}\" -d \"wanted_software_version=#{wanted_software_version}\" -d \"license_key=#{license_key}\" https://secure.rubymotion.com/update_software")
|
||||
resp = curl("-s -d \"product=rubymotion\" -d \"current_software_version=#{product_version}\" -d \"@wanted_software_version=#{@wanted_software_version}\" -d \"license_key=#{read_license_key}\" https://secure.rubymotion.com/update_software")
|
||||
unless resp.match(/^http:/)
|
||||
die resp
|
||||
end
|
||||
@@ -98,7 +116,7 @@ module Motion; module Project
|
||||
tmp_dest = '/tmp/_rubymotion_su.pkg'
|
||||
curl("-# \"#{url}\" -o #{tmp_dest}")
|
||||
|
||||
if wanted_software_version
|
||||
if @wanted_software_version
|
||||
$stderr.puts 'Saving current RubyMotion version...'
|
||||
FileUtils.mv '/Library/RubyMotion', '/Library/RubyMotion.old'
|
||||
end
|
||||
@@ -106,14 +124,14 @@ module Motion; module Project
|
||||
$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')}"
|
||||
die "An error occurred while installing the software update: #{File.read('/tmp/installer.stderr')}"
|
||||
end
|
||||
FileUtils.rm_f tmp_dest
|
||||
|
||||
if wanted_software_version
|
||||
FileUtils.mv '/Library/RubyMotion', "/Library/RubyMotion#{wanted_software_version}"
|
||||
if @wanted_software_version
|
||||
FileUtils.mv '/Library/RubyMotion', "/Library/RubyMotion#{@wanted_software_version}"
|
||||
$stderr.puts 'Restoring current RubyMotion version...' # done in ensure
|
||||
$stderr.puts "RubyMotion #{wanted_software_version} installed as /Library/RubyMotion#{wanted_software_version}. To use it in a project, edit the Rakefile to point to /Library/RubyMotion#{wanted_software_version}/lib instead of /Library/RubyMotion/lib."
|
||||
$stderr.puts "RubyMotion #{@wanted_software_version} installed as /Library/RubyMotion#{@wanted_software_version}. To use it in a project, edit the Rakefile to point to /Library/RubyMotion#{@wanted_software_version}/lib instead of /Library/RubyMotion/lib."
|
||||
else
|
||||
$stderr.puts "Software update installed.\n\n"
|
||||
news = File.read('/Library/RubyMotion/NEWS')
|
||||
@@ -133,7 +151,7 @@ module Motion; module Project
|
||||
|
||||
FileUtils.rm_rf Motion::Project::Builder.common_build_dir
|
||||
ensure
|
||||
if wanted_software_version && File.exist?('/Library/RubyMotion.old')
|
||||
if @wanted_software_version && File.exist?('/Library/RubyMotion.old')
|
||||
FileUtils.mv '/Library/RubyMotion.old', '/Library/RubyMotion'
|
||||
end
|
||||
end
|
||||
@@ -21,22 +21,9 @@
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
module Motion; module Project
|
||||
class RICommand < Command
|
||||
self.name = 'ri'
|
||||
self.help = 'Display API reference'
|
||||
|
||||
def run(args)
|
||||
if args.size <= 0
|
||||
die "Usage: motion ri <API-name>"
|
||||
end
|
||||
|
||||
line = "/Library/RubyMotion/lib/yard/bin/yri --db /Library/RubyMotion/doc/yardoc "
|
||||
if pager = ENV['PAGER']
|
||||
line << "-p #{pager} "
|
||||
end
|
||||
line << "#{args[0]}"
|
||||
system(line)
|
||||
end
|
||||
end
|
||||
end; end
|
||||
module Motion
|
||||
# This class is extended, when using the commands, with the
|
||||
# `CLAide::InformativeError` module. This will cause these errors to only
|
||||
# show their message when raised, unless the `--verbose` option is specified.
|
||||
class InformativeError < StandardError; end
|
||||
end
|
||||
@@ -21,76 +21,62 @@
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
require 'motion/version'
|
||||
|
||||
module Motion; module Project
|
||||
class Command
|
||||
# Deprecated base command class, will be removed in RM v3.
|
||||
#
|
||||
# See the Motion::Command class in lib/motion/command.rb instead.
|
||||
#
|
||||
class Command < Motion::Command
|
||||
self.ignore_in_command_lookup = true
|
||||
|
||||
class << self
|
||||
attr_accessor :name
|
||||
attr_accessor :help
|
||||
end
|
||||
|
||||
Commands = []
|
||||
def self.inherited(klass)
|
||||
Commands << klass if self == Command
|
||||
end
|
||||
|
||||
def self.main(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
|
||||
# This is lifted straight from CLAide, but adjusted slightly because
|
||||
# the Class#name method is overriden in the old (deprecated) API below.
|
||||
def command
|
||||
@command ||= __name__.split('::').last.gsub(/[A-Z]+[a-z]*/) do |part|
|
||||
part.downcase << '-'
|
||||
end[0..-2]
|
||||
end
|
||||
command = Commands.find { |command| command.name == arg }
|
||||
usage unless command
|
||||
command.new.run(args)
|
||||
end
|
||||
|
||||
def self.usage
|
||||
$stderr.puts 'Usage:'
|
||||
$stderr.puts " motion [-h, --help]"
|
||||
$stderr.puts " motion [-v, --version]"
|
||||
$stderr.puts " motion <command> [<args...>]"
|
||||
$stderr.puts ''
|
||||
$stderr.puts 'Commands:'
|
||||
Commands.each do |command|
|
||||
$stderr.puts " #{command.name}".ljust(20) + command.help
|
||||
class << self
|
||||
alias_method :__name__, :name
|
||||
end
|
||||
exit 1
|
||||
|
||||
def inherited(klass)
|
||||
warn "[!] Inheriting from `Motion::Project::Command' has been " \
|
||||
"deprecated, inherit from `Motion::Command' instead. " \
|
||||
"(Called from: #{caller.first})"
|
||||
super
|
||||
end
|
||||
|
||||
# Override initializer to return a proxy that calls the instance with
|
||||
# the expected arguments when needed.
|
||||
#
|
||||
# Normal CLAide command classes are called with `Command#run`, whereas
|
||||
# these deprecated classes need to be called with `Command#run(argv)`.
|
||||
def new(argv)
|
||||
instance = super(argv)
|
||||
wrapper = lambda { instance.run(argv.remainder) }
|
||||
def wrapper.run; call; end # Call lambda which forwards to #run(argv)
|
||||
def wrapper.validate!; end # Old command has no notion of validation.
|
||||
wrapper
|
||||
end
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
alias_method :name, :command
|
||||
def name=(command); self.command = command; end
|
||||
|
||||
alias_method :help, :summary
|
||||
def help=(summary); self.summary = summary; end
|
||||
end
|
||||
|
||||
def run(args)
|
||||
# To be implemented by subclasses.
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
LicensePath = '/Library/RubyMotion/license.key'
|
||||
def read_license_key
|
||||
unless File.exist?(LicensePath)
|
||||
die "License file not present. Please activate RubyMotion with `motion activate' and try again."
|
||||
end
|
||||
File.read(LicensePath).strip
|
||||
end
|
||||
|
||||
def guess_email_address
|
||||
# Guess the default email address from git.
|
||||
URI.escape(`git config --get user.email`.strip)
|
||||
end
|
||||
end
|
||||
end; end
|
||||
|
||||
# Now load plugins installed the old way.
|
||||
#
|
||||
# TODO deprecate in favor of RubyGems plugins?
|
||||
Dir.glob(File.join(ENV['HOME'], 'Library/RubyMotion/command', '*.rb')).each { |x| require x }
|
||||
|
||||
@@ -21,7 +21,10 @@
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
require 'motion/error'
|
||||
|
||||
require 'erb'
|
||||
require 'fileutils'
|
||||
|
||||
module Motion; module Project
|
||||
class Template
|
||||
@@ -57,19 +60,17 @@ module Motion; module Project
|
||||
|
||||
@template_directory = self.class.all_templates[@template_name]
|
||||
unless @template_directory
|
||||
$stderr.puts "Cannot find template `#{@template_name}' in #{Paths.join(' or ')}"
|
||||
$stderr.puts "Available templates: " + self.class.all_templates.keys.join(', ')
|
||||
exit 1
|
||||
raise InformativeError, "Cannot find template `#{@template_name}' in " \
|
||||
"#{Paths.join(' or ')}. Available templates: " \
|
||||
"#{self.class.all_templates.keys.join(', ')}"
|
||||
end
|
||||
|
||||
unless app_name.match(/^[\w\s-]+$/)
|
||||
$stderr.puts "Invalid app name"
|
||||
exit 1
|
||||
raise InformativeError, "Invalid project name."
|
||||
end
|
||||
|
||||
if File.exist?(app_name)
|
||||
$stderr.puts "Directory `#{app_name}' already exists"
|
||||
exit 1
|
||||
raise InformativeError, "Directory `#{app_name}' already exists"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
1
vendor/CLAide
vendored
Submodule
1
vendor/CLAide
vendored
Submodule
Submodule vendor/CLAide added at 8eab84977b
Reference in New Issue
Block a user