From b4a46b151361590ff1d061e240dff3467d246f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eloy=20Dur=C3=A1n?= Date: Thu, 4 Dec 2014 17:02:44 +0100 Subject: [PATCH] [Target] Consolidate common code and properly check if `bundle install` is required. --- lib/motion/project/target.rb | 166 +++++++++++++++++- lib/motion/project/target/extension_target.rb | 89 +--------- lib/motion/project/target/framework_target.rb | 87 +-------- 3 files changed, 174 insertions(+), 168 deletions(-) diff --git a/lib/motion/project/target.rb b/lib/motion/project/target.rb index 10a00724..861ef472 100644 --- a/lib/motion/project/target.rb +++ b/lib/motion/project/target.rb @@ -23,5 +23,169 @@ # (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/project/builder' + +module Motion; module Project + class Target + include Rake::DSL if Object.const_defined?(:Rake) && Rake.const_defined?(:DSL) + + attr_accessor :type + attr_reader :path + + def initialize(path, type, config, opts) + @path = path + @full_path = File.expand_path(path) + @type = type + @config = config + @opts = opts + end + + # Builds the target's product for the specified `platform` and the + # configured `distribution_mode`. + # + # @param [String] platform + # The platform identifier that's being build for, such as + # `iPhoneSimulator` or `iPhoneOS`. + # + # @return [void] + # + def build(platform) + @platform = platform + + task = if platform == 'iPhoneSimulator' + "build:simulator" + else + if @config.distribution_mode + "archive:distribution" + else + "build:device" + end + end + + unless rake(task) + App.fail "Target '#{@path}' failed to build" + end + end + + # Cleans the target's product. + # + # @return [void] + # + def clean + rake 'clean' + end + + # @return [String] The path to the platform + configuration based directory. + # + def build_dir + File.join(@path, 'build', @platform + + '-' + @config.deployment_target + + '-' + @config.build_mode_name) + end + + # -------------------------------------------------------------------------- + # @!group Executing commands/tasks in the target's context + # -------------------------------------------------------------------------- + + # Executes a rake task of the target's Rakefile. + # + # If the target has a Gemfile that should be used, ensure it is installed. + # + # @param [String] task + # The rake task to invoke in the target's context. + # + # @return [Boolean] Whether or not invoking the rake task succeeded. + # + def rake(task) + install_gemfile_if_necessary! + + command = "rake #{task}" + command = "#{command} --trace" if App::VERBOSE + command = "bundle exec #{command}" if use_gemfile? + system(command) + end + + # Executes a given command with the target path as the working-directory and + # assigns the `environment_variables` to the command's environment. + # + # If the current process is running in verbose mode, a pseudo description of + # the command is printed before executing the command. + # + # @param [String] command + # The command to execute. + # + # @return [Boolean] Whether or not the command exited with a succes status. + # + def system(command) + env = environment_variables + if App::VERBOSE + env_description = env.map { |k,v| "#{k}='#{v}'" }.join(' ') + puts "cd '#{@full_path}' && env #{env_description} #{command}" + end + Dir.chdir(@full_path) do + super(env, command) + end + end + + # @return [Hash] The environment variables that describes the current host + # application and which the target's build system depends on. + # + def environment_variables + env = { + "PWD" => @full_path, + "RM_TARGET_SDK_VERSION" => @config.sdk_version, + "RM_TARGET_DEPLOYMENT_TARGET" => @config.deployment_target, + "RM_TARGET_XCODE_DIR" => @config.xcode_dir, + "RM_TARGET_HOST_APP_NAME" => @config.name, + "RM_TARGET_HOST_APP_IDENTIFIER" => @config.identifier, + "RM_TARGET_HOST_APP_PATH" => File.expand_path(@config.project_dir), + "RM_TARGET_BUILD" => '1', + "RM_TARGET_ARCHS" => @config.archs.inspect, + } + env["BUNDLE_GEMFILE"] = gemfile_path if use_gemfile? + env + end + + # -------------------------------------------------------------------------- + # @!group Bundler/Gemfile related methods + # -------------------------------------------------------------------------- + + # @return [String] The absolute path to the target's Gemfile. + # + def gemfile_path + File.join(@full_path, 'Gemfile') + end + + # @return [Boolean] Whether or not the user is building the host application + # in a Bundler context and if the target has a Gemfile of its own. + # + def use_gemfile? + File.exist?(gemfile_path) && ENV['BUNDLE_GEMFILE'] + end + + # @return [Boolean] Whether or not the target's Gemfile has been installed. + # + def gemfile_installed? + return @gemfile_installed unless @gemfile_installed.nil? + @gemfile_installed = system("bundle check --no-color > /dev/null") + end + + # In case the target has a Gemfile that should be used and it is not yet + # installed, install it now. + # + # @return [void] + # + def install_gemfile_if_necessary! + if use_gemfile? && !gemfile_installed? + App.info 'Bundle', @full_path + unless system("bundle install") + App.fail "Failed to install the target's Gemfile." + end + @gemfile_installed = true + end + end + end +end; end + require 'motion/project/target/framework_target' -require 'motion/project/target/extension_target' \ No newline at end of file +require 'motion/project/target/extension_target' diff --git a/lib/motion/project/target/extension_target.rb b/lib/motion/project/target/extension_target.rb index 94e04074..52c9ad6d 100644 --- a/lib/motion/project/target/extension_target.rb +++ b/lib/motion/project/target/extension_target.rb @@ -23,69 +23,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/project/builder' +require 'motion/project/target' module Motion; module Project - class ExtensionTarget - include Rake::DSL if Object.const_defined?(:Rake) && Rake.const_defined?(:DSL) - - attr_accessor :type - - attr_reader :path - - def initialize(path, type, config, opts) - @path = path - @full_path = File.expand_path(path) - @type = type - @config = config - @opts = opts - end - - # This takes care of changing into the target's work directory, setting the - # required environment variables, and passing on whether to be verbose. - # - # @param [String] task - # The rake task to invoke in the target's context. - # - # @return [Boolean] Whether or not invoking the rake task succeeded. - # - def rake(task) - Dir.chdir(@full_path) do - ENV["PWD"] = @full_path - rake = "rake" - if File.exist?("Gemfile") && ENV["BUNDLE_GEMFILE"] - ENV["BUNDLE_GEMFILE"] = File.join(@full_path, "Gemfile") - system(ENV, "bundle install") unless File.exist?("Gemfile.lock") - rake = "bundle exec rake" - end - - command = "#{environment_variables} #{rake} #{task}" - if App::VERBOSE - command << " --trace" - puts command - end - system(ENV, command) - end - end - - def build(platform) - @platform = platform - - task = if platform == 'iPhoneSimulator' - "build:simulator" - else - if @config.distribution_mode - "archive:distribution" - else - "build:device" - end - end - - unless rake(task) - App.fail "Target '#{@path}' failed to build" - end - end - + class ExtensionTarget < Target def copy_products(platform) src_path = src_extension_path dest_path = destination_dir @@ -109,7 +50,7 @@ module Motion; module Project extension_bundle_indentifer = "#{@config.identifier}.#{extension_bundle_name}" end `/usr/libexec/PlistBuddy -c "set CFBundleIdentifier #{extension_bundle_indentifer}" "#{info_plist}"` - end + end end def codesign(platform) @@ -128,17 +69,9 @@ module Motion; module Project end end - def clean - rake 'clean' - end - - def build_dir(config, platform) - platform + '-' + config.deployment_target + '-' + config.build_mode_name - end - def src_extension_path @src_extension_path ||= begin - path = File.join(@path, 'build', build_dir(@config, @platform), '*.appex') + path = File.join(build_dir, '*.appex') Dir[path].sort_by{ |f| File.mtime(f) }.last end end @@ -163,19 +96,5 @@ module Motion; module Project def extension_name File.basename(src_extension_path) end - - def environment_variables - [ - "RM_TARGET_SDK_VERSION='#{@config.sdk_version}'", - "RM_TARGET_DEPLOYMENT_TARGET='#{@config.deployment_target}'", - "RM_TARGET_XCODE_DIR='#{@config.xcode_dir}'", - "RM_TARGET_HOST_APP_NAME='#{@config.name}'", - "RM_TARGET_HOST_APP_IDENTIFIER='#{@config.identifier}'", - "RM_TARGET_HOST_APP_PATH='#{File.expand_path(@config.project_dir)}'", - "RM_TARGET_BUILD='1'", - "RM_TARGET_ARCHS='#{@config.archs.inspect}'", - ].join(' ') - end - end end;end diff --git a/lib/motion/project/target/framework_target.rb b/lib/motion/project/target/framework_target.rb index e1215ef9..bf6d44f6 100644 --- a/lib/motion/project/target/framework_target.rb +++ b/lib/motion/project/target/framework_target.rb @@ -23,67 +23,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/project/builder' +require 'motion/project/target' module Motion; module Project - class FrameworkTarget - include Rake::DSL if Object.const_defined?(:Rake) && Rake.const_defined?(:DSL) - - attr_accessor :type - - def initialize(path, type, config, opts) - @path = path - @full_path = File.expand_path(path) - @type = type - @config = config - @opts = opts - end - - # This takes care of changing into the target's work directory, setting the - # required environment variables, and passing on whether to be verbose. - # - # @param [String] task - # The rake task to invoke in the target's context. - # - # @return [Boolean] Whether or not invoking the rake task succeeded. - # - def rake(task) - Dir.chdir(@full_path) do - ENV["PWD"] = @full_path - rake = "rake" - if File.exist?("Gemfile") && ENV["BUNDLE_GEMFILE"] - ENV["BUNDLE_GEMFILE"] = File.join(@full_path, "Gemfile") - system(ENV, "bundle install") unless File.exist?("Gemfile.lock") - rake = "bundle exec rake" - end - - command = "#{environment_variables} #{rake} #{task}" - if App::VERBOSE - command << " --trace" - puts command - end - system(ENV, command) - end - end - - def build(platform) - @platform = platform - - task = if platform == 'iPhoneSimulator' - "build:simulator" - else - if @config.distribution_mode - "archive:distribution" - else - "build:device" - end - end - - unless rake(task) - App.fail "Target '#{@path}' failed to build" - end - end - + class FrameworkTarget < Target def copy_products(platform) src_path = framework_path dest_framework_dir = File.join(@config.app_bundle(platform), 'Frameworks') @@ -93,7 +36,7 @@ module Motion; module Project App.info 'Copy', src_path FileUtils.mkdir_p(dest_framework_dir) FileUtils.cp_r(src_path, dest_framework_dir) - end + end end def codesign(platform) @@ -142,17 +85,9 @@ PLIST end end - def clean - rake 'clean' - end - - def build_dir(config, platform) - platform + '-' + config.deployment_target + '-' + config.build_mode_name - end - def framework_path @framework_path ||= begin - path = File.join(@path, 'build', build_dir(@config, @platform), '*.framework') + path = File.join(build_dir, '*.framework') Dir[path].sort_by{ |f| File.mtime(f) }.last end end @@ -165,17 +100,5 @@ PLIST def load? @opts[:load] end - - def environment_variables - [ - "RM_TARGET_SDK_VERSION=\"#{@config.sdk_version}\"", - "RM_TARGET_DEPLOYMENT_TARGET=\"#{@config.deployment_target}\"", - "RM_TARGET_XCODE_DIR=\"#{@config.xcode_dir}\"", - "RM_TARGET_HOST_APP_PATH=\"#{File.expand_path(@config.project_dir)}\"", - "RM_TARGET_BUILD=\"1\"", - "RM_TARGET_ARCHS='#{@config.archs.inspect}'" - ].join(' ') - end - end -end;end \ No newline at end of file +end;end