├── .gitignore ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── gem_reloader.gemspec └── lib ├── gem_reloader.rb └── gem_reloader ├── railtie.rb └── version.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | Gemfile.lock 7 | InstalledFiles 8 | _yardoc 9 | coverage 10 | doc/ 11 | lib/bundler/man 12 | pkg 13 | rdoc 14 | spec/reports 15 | test/tmp 16 | test/version_tmp 17 | tmp 18 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in gem_reloader.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Colin Young 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GemReloader 2 | 3 | Stop restarting your server after editing local gems! 4 | 5 | ## Usage 6 | 7 | In your `development.rb`, add: 8 | 9 | GemReloader.watch :my_gem 10 | 11 | Or, if you want to watch **all** local gems: 12 | 13 | GemReloader.watch_all! 14 | 15 | That's literally it. Tiny but useful. 16 | 17 | **Important Note**: 18 | 19 | > If your gems are in irregular directories (directories that aren't in your `autoload_paths`), you'll need to add those paths in your `application.rb`. GemReloader will automatically add `vendor/gems` to the autoload_paths for you. 20 | 21 | By the way, a gem will be picked up by `::watch_all!` if it has a :path attribute. 22 | 23 | ## Installation 24 | 25 | Add this line to your application's Gemfile: 26 | 27 | gem 'gem_reloader' 28 | 29 | And then execute: 30 | 31 | $ bundle 32 | 33 | Or install it yourself as: 34 | 35 | $ gem install gem_reloader 36 | 37 | ## Contributing 38 | 39 | 1. Fork it 40 | 2. Create your feature branch (`git checkout -b my-new-feature`) 41 | 3. Commit your changes (`git commit -am 'Added some feature'`) 42 | 4. Push to the branch (`git push origin my-new-feature`) 43 | 5. Create new Pull Request 44 | 45 | ## Changelog 46 | 47 | - v0.0.2: Added "vendor/gems" to the config.autoload_paths so the user doesn't have to. 48 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | require "bundler/gem_tasks" 3 | -------------------------------------------------------------------------------- /gem_reloader.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | require File.expand_path('../lib/gem_reloader/version', __FILE__) 3 | 4 | Gem::Specification.new do |gem| 5 | gem.authors = ["Colin Young"] 6 | gem.email = ["me@colinyoung.com"] 7 | gem.description = %q{Stop restarting your server after editing local gems} 8 | gem.summary = %q{With GemReloader, watch local gems just like you do your models and controllers.} 9 | gem.homepage = "https://github.com/colinyoung/gem_reloader" 10 | 11 | gem.files = `git ls-files`.split($\) 12 | gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } 13 | gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) 14 | gem.name = "gem_reloader" 15 | gem.require_paths = ["lib"] 16 | gem.version = GemReloader::VERSION 17 | end 18 | -------------------------------------------------------------------------------- /lib/gem_reloader.rb: -------------------------------------------------------------------------------- 1 | require "gem_reloader/version" 2 | require "gem_reloader/railtie" 3 | 4 | module GemReloader 5 | 6 | # All local gems (that is, ones which have a :path attribute) 7 | # will be automatically reloaded on each request. 8 | # 9 | # Add something like 'GemReloader.watch_all!' to your development.rb. 10 | def self.watch_all! 11 | reloadable_gems.each do |gem| 12 | watch gem[:name] 13 | end 14 | end 15 | 16 | # Watch a specific gem. 17 | # Add something like 'GemReloader.watch :my_gem' to your development.rb. 18 | def self.watch(gem_symbol) 19 | 20 | gem_path = gem_symbol.to_s 21 | klass = gem_path.classify 22 | 23 | app = Object.const_get(Rails.application.class.parent_name) 24 | app::Application.configure do 25 | 26 | ActionDispatch::Callbacks.to_prepare do 27 | 28 | # This code (slightly modified) comes almost entirely from 29 | # Tim Cardenas - http://timcardenas.com/automatically-reload-gems-in-rails-327-on-eve 30 | 31 | # If the gem's top level module is currently loaded, unload it 32 | if Object.const_defined?(klass) 33 | Object.send(:remove_const, klass) 34 | end 35 | 36 | # Instruct ruby to "unrequire" all of the gems files. 37 | # CAREFUL: make sure this only matches your gems files. 38 | $".delete_if {|s| s.include?(gem_path)} 39 | 40 | # Re-require your gem 41 | # Note: because we removed all files previously required they will be reloaded 42 | # even if you didn't use load/autoload in your gem. 43 | require gem_path 44 | 45 | end 46 | 47 | end 48 | end 49 | 50 | private 51 | 52 | PATH_REGEX = /^gem[\(| ]['"]([\w-]+)['"][|,](?:.*)path[ =>\:]+['"]([\w\/-]+)['"]/ 53 | 54 | def self.reloadable_gems 55 | Array.new.tap do |gems| 56 | File.open(Rails.root.join('Gemfile'), 'rb').each do |ln| 57 | matches = ln.match(PATH_REGEX) 58 | if matches 59 | gems << {name: matches[1], path: matches[2]} 60 | end 61 | end 62 | end 63 | end 64 | 65 | end 66 | -------------------------------------------------------------------------------- /lib/gem_reloader/railtie.rb: -------------------------------------------------------------------------------- 1 | class GemReloaderRailtie < Rails::Railtie 2 | initializer 'gem_reloader.autoload', :before => :set_autoload_paths do |app| 3 | app.config.autoload_paths += Dir["#{app.config.root}/vendor/gems/"] 4 | end 5 | end -------------------------------------------------------------------------------- /lib/gem_reloader/version.rb: -------------------------------------------------------------------------------- 1 | module GemReloader 2 | VERSION = "0.0.2" 3 | end 4 | --------------------------------------------------------------------------------