motion-require-0.2.0/0000755000175000017510000000000014125041622013302 5ustar rmb571rmb571motion-require-0.2.0/spec/0000755000175000017510000000000014125041622014234 5ustar rmb571rmb571motion-require-0.2.0/spec/spec_helper.rb0000644000175000017510000000022014125041622017044 0ustar rmb571rmb571require 'rspec' require 'motion-require' RSpec.configure do |config| config.color_enabled = true config.formatter = 'documentation' endmotion-require-0.2.0/spec/motion_require_spec.rb0000644000175000017510000000134714125041622020641 0ustar rmb571rmb571require 'spec_helper' describe Motion::Require do it 'should run' do true.should == true end describe 'should check_platform' do it 'should support `nil`' do Motion::Require.check_platform(:ios, nil).should == true end it 'should support Symbol' do Motion::Require.check_platform(:ios, :ios).should == true Motion::Require.check_platform(:ios, :osx).should == false end it 'should support Array' do Motion::Require.check_platform(:ios, [:ios]).should == true Motion::Require.check_platform(:ios, [:ios, :osx]).should == true Motion::Require.check_platform(:osx, [:ios, :osx]).should == true Motion::Require.check_platform(:ios, [:osx]).should == false end end endmotion-require-0.2.0/spec/TestApp/0000755000175000017510000000000014125041622015614 5ustar rmb571rmb571motion-require-0.2.0/spec/TestApp/app/0000755000175000017510000000000014125041622016374 5ustar rmb571rmb571motion-require-0.2.0/spec/TestApp/app/app_delegate.rb0000644000175000017510000000016114125041622021331 0ustar rmb571rmb571class AppDelegate def application(application, didFinishLaunchingWithOptions:launchOptions) true end end motion-require-0.2.0/lib/0000755000175000017510000000000014125041622014050 5ustar rmb571rmb571motion-require-0.2.0/lib/motion-require.rb0000644000175000017510000001040314125041622017352 0ustar rmb571rmb571require 'ripper' require 'pathname' module Motion module Require class << self attr_accessor :require_relative_enabled end class RequireBuilder < Ripper::SexpBuilder REQUIREMENT_TOKENS = %w[motion_require require_relative] attr_accessor :requires def requires @requires ||= [] end def on_command(command, args) # scanner event type, name, position = command if valid_require_command(name) file = parse_args(args) requires << file end end def valid_require_command(name) if name == 'require_relative' && !Motion::Require.require_relative_enabled raise NoMethodError, 'require_relative is not enabled, see Motion::Require.require_relative_enabled' end REQUIREMENT_TOKENS.include?(name) end def parse_args(args) value = nil args.each do |arg| if arg.is_a?(Array) type = arg.first if type == :@tstring_content return arg[1] end value = parse_args(arg) end end value end end module_function def dependencies_for(files) dependencies = {} files.each do |file_path| requires = requires_in(file_path) if !requires.empty? dependencies[file_path] = requires.map { |required| required_path = resolve_path(file_path, required) if !File.exist?(required_path) && File.extname(required) != ".rb" required_path += ".rb" end if !File.exist?(required_path) # TODO: Report line number of failing require raise LoadError, "ERROR! In `#{file_path}', could not require `#{required}', file not found." end required_path } dependencies[file_path].unshift ext_file end end dependencies end def requires_in(file) parser = Motion::Require::RequireBuilder.new(File.read(file)) parser.parse parser.requires end # Join `required` to directory containing `source`. # Preserves relative/absolute nature of source def resolve_path(source, required) Pathname.new(source).dirname.join(required.to_str).cleanpath.to_path end # Scan specified files. When nil, fallback to RubyMotion's default (app/**/*.rb). def all(files=nil, options={}) # if you want the default 'app.files', you can just pass in the options if files.is_a?(Hash) && options == {} options = files files = nil end check_platform = options.fetch(:platform, nil) current_platform = App.respond_to?(:template) ? App.template : :ios return unless Motion::Require.check_platform(current_platform, check_platform) Motion::Project::App.setup do |app| app.exclude_from_detect_dependencies << ext_file if files.nil? || files.empty? app.files.push ext_file app.exclude_from_detect_dependencies += app.files app.files_dependencies dependencies_for(app.files.flatten) else # Place files prior to those in ./app, otherwise at the end. preceding_app = app.files.index { |f| f =~ %r(^(?:\./)?app/) } || -1 required = Array(files).map { |f| explicit_relative(f) } app.exclude_from_detect_dependencies += required app.files.insert(preceding_app, ext_file, *required) app.files.uniq! # Prevent redundancy app.files_dependencies dependencies_for(required) end end end def check_platform(current_platform, check_platform) case check_platform when nil true when Array check_platform.include?(current_platform) when Symbol current_platform == check_platform else puts "Unrecognized value for 'check_platform': #{check_platform.inspect}" false end end # RubyMotion prefers relative paths to be explicitly prefixed with ./ def explicit_relative(path) # Paths that do not start with "/", "./", or "../" will be prefixed with ./ path.sub(%r(^(?!\.{0,2}/)), './') end def ext_file File.expand_path(File.join(File.dirname(__FILE__), "../motion/ext.rb")) end end end motion-require-0.2.0/lib/motion-require/0000755000175000017510000000000014125041622017027 5ustar rmb571rmb571motion-require-0.2.0/lib/motion-require/version.rb0000644000175000017510000000007414125041622021042 0ustar rmb571rmb571module Motion module Require VERSION="0.2.0" end endmotion-require-0.2.0/.gitignore0000644000175000017510000000003014125041622015263 0ustar rmb571rmb571pkg/* *.gem Gemfile.lockmotion-require-0.2.0/motion-require.gemspec0000644000175000017510000000125314125041622017627 0ustar rmb571rmb571# -*- encoding: utf-8 -*- require File.expand_path('../lib/motion-require/version', __FILE__) Gem::Specification.new do |s| s.name = "motion-require" s.version = Motion::Require::VERSION s.authors = ["Clay Allsopp"] s.email = ["clay@usepropeller.com"] s.homepage = "https://github.com/clayallsopp/motion-require" s.summary = "Dependency management for RubyMotion, using a pseudo `require`" s.description = "Dependency management for RubyMotion, using a pseudo `require`" s.files = `git ls-files`.split($\) s.require_paths = ["lib"] s.test_files = Dir.glob("spec/**/*.rb") s.add_development_dependency 'rspec', '~> 2.5' endmotion-require-0.2.0/LICENSE0000644000175000017510000000204014125041622014303 0ustar rmb571rmb571Copyright (c) 2013 Clay Allsopp Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. motion-require-0.2.0/motion/0000755000175000017510000000000014125041622014607 5ustar rmb571rmb571motion-require-0.2.0/motion/ext.rb0000644000175000017510000000022214125041622015730 0ustar rmb571rmb571# This is run in the RubyMotion environment module Kernel def motion_require(*args) end alias_method :require_relative, :motion_require endmotion-require-0.2.0/Rakefile0000644000175000017510000000013514125041622014746 0ustar rmb571rmb571require "bundler/gem_tasks" require 'rspec/core/rake_task' RSpec::Core::RakeTask.new('spec')motion-require-0.2.0/Gemfile0000644000175000017510000000013414125041622014573 0ustar rmb571rmb571source "http://rubygems.org" # Specify your gem's dependencies in Routable.gemspec gemspec motion-require-0.2.0/README.md0000644000175000017510000000436414125041622014570 0ustar rmb571rmb571# motion-require Miss `require`? Well, this is a step in that direction: ```ruby # in a RubyMotion file motion_require "base_view_controller" motion_require "../util/controller_helper" class MyController < BaseViewController include ControllerHelper end ``` ```ruby # in your Rakefile require 'motion/project' require 'motion-require' Motion::Require.all Motion::Project::App.setup do |app| # ... end ``` ![Whoa.](http://i.imgur.com/JLpjqkk.jpg) To enable `motion_require` for only select files: ```ruby Motion::Require.all(Dir.glob('app/models/**/*.rb')) # if you're writing a gem that supports iOS and OS X, you might need to filter # based on the platform: Motion::Require.all(Dir.glob('lib/ios/**/*.rb'), platform: :ios) Motion::Require.all(Dir.glob('lib/osx/**/*.rb'), platform: :osx) ``` You **should not** use `app.files <<` in your `setup` block if using motion-require; opt to use `Motion::Require.all` and it will be taken care of. It's used in: - [Formotion](https://github.com/clayallsopp/formotion) - [MotionSupport](https://github.com/tkadauke/motion-support) - [Basecamp](https://itunes.apple.com/us/app/id599139477) ([ref](https://twitter.com/qrush/status/343324117140897792)) ## Installation `gem install motion-require` Can also add to your `Gemfile` etc ## How? motion-require uses static analysis (via [`ripper`](http://www.ruby-doc.org/stdlib-1.9.3/libdoc/ripper/rdoc/Ripper.html)) to find the files using `motion_require` and automatically add the declared dependencies to `Motion::Project::Config#dependencies`. Then the `Kernel#motion_require` method is overriden at compile-time to be a noop. The paths attached to `motion_require` are treated like those with `require_relative`. If you want to use `require_relative` instead of `motion_require`, you can enable this: ```ruby require 'motion-require' Motion::Require.require_relative_enabled = true # now Motion::Require will detect require_relative Motion::Require.all(Dir.glob("app/**/*.rb")) ``` ## Contact Clay Allsopp ([http://clayallsopp.com](http://clayallsopp.com)) - [http://twitter.com/clayallsopp](http://twitter.com/clayallsopp) - [clay@usepropeller.com](clay@usepropeller.com) ## License motion-require is available under the MIT license. See the LICENSE file for more info.