├── .document ├── .gitignore ├── .rspec ├── Gemfile ├── Gemfile.lock ├── LICENSE.txt ├── README.md ├── Rakefile ├── VERSION ├── bin └── lre ├── lib ├── lre.rb └── lre │ ├── file_reload.rb │ ├── rake_ext.rb │ └── watchr_ext.rb ├── lre.gemspec └── spec ├── lre_spec.rb ├── spec_helper.rb └── test_dir ├── .lre ├── bar.rb ├── file.rb └── foo.rb /.document: -------------------------------------------------------------------------------- 1 | lib/**/*.rb 2 | bin/* 3 | - 4 | features/**/*.feature 5 | LICENSE.txt 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # rcov generated 2 | coverage 3 | 4 | # rdoc generated 5 | rdoc 6 | 7 | # yard generated 8 | doc 9 | .yardoc 10 | 11 | # bundler 12 | .bundle 13 | 14 | # jeweler generated 15 | pkg 16 | 17 | # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore: 18 | # 19 | # * Create a file at ~/.gitignore 20 | # * Include files you want ignored 21 | # * Run: git config --global core.excludesfile ~/.gitignore 22 | # 23 | # After doing this, these files will be ignored in all your git projects, 24 | # saving you from having to 'pollute' every project you touch with them 25 | # 26 | # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line) 27 | # 28 | # For MacOS: 29 | # 30 | #.DS_Store 31 | # 32 | # For TextMate 33 | #*.tmproj 34 | #tmtags 35 | # 36 | # For emacs: 37 | #*~ 38 | #\#* 39 | #.\#* 40 | # 41 | # For vim: 42 | #*.swp 43 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | group :development do 4 | gem "rspec", "~> 2.8.0" 5 | gem "rdoc", "~> 3.12" 6 | gem "bundler", ">= 1.0" 7 | gem "jeweler", "~> 1.8.7" 8 | gem 'github-markup' 9 | gem 'rdiscount' 10 | end 11 | 12 | gem 'fattr' 13 | #gem 'rake' 14 | gem 'watchr' 15 | gem 'mharris_ext' -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | addressable (2.3.6) 5 | builder (3.2.2) 6 | diff-lcs (1.1.3) 7 | facets (2.9.3) 8 | faraday (0.8.9) 9 | multipart-post (~> 1.2.0) 10 | fattr (2.2.2) 11 | git (1.2.6) 12 | github-markup (1.2.1) 13 | posix-spawn (~> 0.3.8) 14 | github_api (0.10.1) 15 | addressable 16 | faraday (~> 0.8.1) 17 | hashie (>= 1.2) 18 | multi_json (~> 1.4) 19 | nokogiri (~> 1.5.2) 20 | oauth2 21 | hashie (2.1.1) 22 | highline (1.6.21) 23 | jeweler (1.8.8) 24 | builder 25 | bundler (~> 1.0) 26 | git (>= 1.2.5) 27 | github_api (= 0.10.1) 28 | highline (>= 1.6.15) 29 | nokogiri (= 1.5.10) 30 | rake 31 | rdoc 32 | json (1.8.1) 33 | jwt (0.1.11) 34 | multi_json (>= 1.5) 35 | mharris_ext (1.7.1) 36 | facets 37 | fattr 38 | multi_json (1.9.3) 39 | multi_xml (0.5.5) 40 | multipart-post (1.2.0) 41 | nokogiri (1.5.10) 42 | nokogiri (1.5.10-x86-mingw32) 43 | oauth2 (0.9.3) 44 | faraday (>= 0.8, < 0.10) 45 | jwt (~> 0.1.8) 46 | multi_json (~> 1.3) 47 | multi_xml (~> 0.5) 48 | rack (~> 1.2) 49 | posix-spawn (0.3.8) 50 | rack (1.5.2) 51 | rake (10.3.1) 52 | rdiscount (2.1.7.1) 53 | rdoc (3.12.2) 54 | json (~> 1.4) 55 | rspec (2.8.0) 56 | rspec-core (~> 2.8.0) 57 | rspec-expectations (~> 2.8.0) 58 | rspec-mocks (~> 2.8.0) 59 | rspec-core (2.8.0) 60 | rspec-expectations (2.8.0) 61 | diff-lcs (~> 1.1.2) 62 | rspec-mocks (2.8.0) 63 | watchr (0.7) 64 | 65 | PLATFORMS 66 | ruby 67 | x86-mingw32 68 | 69 | DEPENDENCIES 70 | bundler (>= 1.0) 71 | fattr 72 | github-markup 73 | jeweler (~> 1.8.7) 74 | mharris_ext 75 | rdiscount 76 | rdoc (~> 3.12) 77 | rspec (~> 2.8.0) 78 | watchr 79 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 mharris717 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LRE 2 | 3 | When debugging or poking around in a project, I often do several things 4 | 5 | * Start an IRB session. 6 | * Load some files at the beginning to setup my environment. 7 | * When the code I'm writing gets too long to comfortably write at the IRB prompt, move the code to a file and repeatedly load the file after making changes. 8 | * Make changes to existing files and load those changes. 9 | * Make changes to libraries and load those changes. 10 | 11 | LRE makes these things easy. 12 | 13 | ## Basics 14 | 15 | Start LRE with the lre command at the command prompt. 16 | 17 | On startup, LRE 18 | 19 | * Looks for .lre files in the root of the current directory and the home directory, and loads them if present. These files are plain ruby files. Put environment setup code and helper functions here. 20 | * Monitors the current directory for changes to .rb files, and automatically loads changed files. 21 | * Starts an IRB prompt. 22 | 23 | ## Additional Features 24 | 25 | You can monitor additional directories and file types. 26 | 27 | To monitor additional directories, add them in your .lre file. This will watch for .rb files. 28 | 29 | 30 | LRE.add_watch_dir "/code/something", "/code/something_else" 31 | 32 | To monitor addtional file types, add a watch in your .lre file 33 | 34 | LRE.watch(".*/run_on_change/.*\.sql") do |f| 35 | require 'sws' 36 | str = parse_erb_str(File.read(f)) 37 | SWS.execute_str! str 38 | end 39 | 40 | LRE won't automatically pick up on new files, only changed files. Calling LRE.start! will cause new files to be monitored going forward. 41 | 42 | LRE.start! 43 | 44 | 45 | ## Installing 46 | 47 | gem install lre 48 | 49 | ## Other 50 | 51 | LRE is short for Little Ruby Environment or nothing, depending on my mood. 52 | 53 | ## Contributing to lre 54 | 55 | * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet 56 | * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it 57 | * Fork the project 58 | * Start a feature/bugfix branch 59 | * Commit and push until you are happy with your contribution 60 | * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally. 61 | * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it. 62 | 63 | ## Copyright 64 | 65 | Copyright (c) 2011 mharris717. See LICENSE.txt for 66 | further details. 67 | 68 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'bundler' 3 | begin 4 | Bundler.setup(:default, :development) 5 | rescue Bundler::BundlerError => e 6 | $stderr.puts e.message 7 | $stderr.puts "Run `bundle install` to install missing gems" 8 | exit e.status_code 9 | end 10 | require 'rake' 11 | 12 | require 'jeweler' 13 | Jeweler::Tasks.new do |gem| 14 | # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options 15 | gem.name = "lre" 16 | gem.homepage = "http://github.com/mharris717/lre" 17 | gem.license = "MIT" 18 | gem.summary = %Q{lre} 19 | gem.description = %Q{lre} 20 | gem.email = "mharris717@gmail.com" 21 | gem.authors = ["mharris717"] 22 | # Include your dependencies below. Runtime dependencies are required when using your gem, 23 | # and development dependencies are only needed for development (ie running rake tasks, tests, etc) 24 | # gem.add_runtime_dependency 'jabber4r', '> 0.1' 25 | # gem.add_development_dependency 'rspec', '> 1.2.3' 26 | end 27 | Jeweler::RubygemsDotOrgTasks.new 28 | 29 | require 'rspec/core' 30 | require 'rspec/core/rake_task' 31 | RSpec::Core::RakeTask.new(:spec) do |spec| 32 | spec.pattern = FileList['spec/**/*_spec.rb'] 33 | end 34 | 35 | RSpec::Core::RakeTask.new(:rcov) do |spec| 36 | spec.pattern = 'spec/**/*_spec.rb' 37 | spec.rcov = true 38 | end 39 | 40 | task :default => :spec 41 | 42 | task :make_readme do 43 | require 'github/markup' 44 | require 'mharris_ext' 45 | 46 | loop do 47 | str = GitHub::Markup.render("README.md") 48 | File.create("README.html",str) 49 | sleep(0.5) 50 | end 51 | end -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 0.3.1 -------------------------------------------------------------------------------- /bin/lre: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require File.expand_path(File.dirname(__FILE__)+"/../lib")+"/lre.rb" 4 | 5 | LRE.from_cli!(ARGV[0]) -------------------------------------------------------------------------------- /lib/lre.rb: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'fattr' 3 | %w(file_reload rake_ext watchr_ext).each do |f| 4 | require File.expand_path(File.dirname(__FILE__)) + "/lre/#{f}.rb" 5 | end 6 | 7 | module LRE 8 | class << self 9 | fattr(:watch_dirs) do 10 | ["."] 11 | end 12 | def add_watch_dir(*ds) 13 | [ds].flatten.each do |d| 14 | self.watch_dirs << d 15 | end 16 | end 17 | def load_config! 18 | config_files = ["~/.lre","#{Dir.getwd}/.lre"] 19 | config_files.each do |f| 20 | load(f) if FileTest.exists?(f) 21 | end 22 | end 23 | def start_irb! 24 | return if @start_irb 25 | require 'irb' 26 | @start_irb = true 27 | IRB.start 28 | end 29 | def from_cli!(f) 30 | if f 31 | load_config! 32 | load(f) 33 | else 34 | start! 35 | end 36 | end 37 | def start! 38 | load_config! 39 | FileReload.run! 40 | 41 | start_irb! 42 | end 43 | def stop! 44 | FileReload.stop! 45 | end 46 | def watch(pattern,&b) 47 | FileReload.watches[pattern] = b 48 | end 49 | def on_every_file(&b) 50 | FileReload.on_every_file = b 51 | end 52 | def name(n=nil) 53 | if n 54 | FileReload.instance_name = n 55 | else 56 | FileReload.instance_name 57 | end 58 | end 59 | end 60 | end -------------------------------------------------------------------------------- /lib/lre/file_reload.rb: -------------------------------------------------------------------------------- 1 | module FileReload 2 | def self.method_missing(sym,*args,&b) 3 | Base.instance.send(sym,*args,&b) 4 | end 5 | class Base 6 | class << self 7 | fattr(:instance) { new } 8 | end 9 | attr_accessor :script, :on_every_file, :instance_name 10 | fattr(:threads) { [] } 11 | def should_load?(f) 12 | str = File.read(f) 13 | if str =~ /--dontload({.+})?/ 14 | if !$1 15 | false 16 | else 17 | n = $1[1..-2] 18 | !(instance_name.to_s == n) 19 | end 20 | elsif str =~ /--onlyload{(.+)}/ 21 | $1 == instance_name.to_s 22 | else 23 | true 24 | end 25 | end 26 | def process_file(f,&b) 27 | if !FileTest.exists?(f) 28 | puts "file doesn't exist #{f}" 29 | return 30 | end 31 | if should_load?(f) 32 | on_every_file[File.expand_path(f)] if on_every_file 33 | puts "loading #{f}" 34 | b[f] 35 | else 36 | puts "didn't load #{f}" 37 | end 38 | print ">" 39 | rescue => exp 40 | puts "error loading #{f}" 41 | puts exp.message + "\n" + exp.backtrace.join("\n") 42 | rescue SyntaxError => exp 43 | puts "syntax error loading #{f}" 44 | puts exp.message + "\n" + exp.backtrace.join("\n") 45 | rescue RuntimeError => exp 46 | puts "runtime error" 47 | puts exp.message 48 | end 49 | def stop! 50 | self.threads.each { |x| x.kill } 51 | self.threads = [] 52 | end 53 | fattr(:watches) do 54 | res = {} 55 | res[".*\.rb$"] = lambda do |f| 56 | load f 57 | end 58 | res 59 | end 60 | def run! 61 | require 'watchr' 62 | require 'pathname' 63 | self.script = Watchr::Script.new 64 | watches.each do |file_match,proc| 65 | script.watch(file_match) do |md| 66 | f = md[0] 67 | process_file(f,&proc) 68 | end 69 | end 70 | 71 | self.threads.each { |x| x.kill } 72 | self.threads = [] 73 | 74 | LRE.watch_dirs.uniq.each do |d| 75 | c = Watchr::Controller.new(script, Watchr.handler.new) 76 | c.base_path = d 77 | puts "adding thread #{d}" 78 | self.threads << Thread.new { c.run } 79 | end 80 | end 81 | end 82 | end 83 | 84 | -------------------------------------------------------------------------------- /lib/lre/rake_ext.rb: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | module Rake 3 | class Task 4 | def actions=(x) 5 | @actions = x 6 | end 7 | end 8 | end 9 | 10 | def gt(n) 11 | t = Rake::Task[n] 12 | #puts "action size #{t.actions.size}" 13 | t.actions = t.actions[-1..-1] if t.actions.size > 1 14 | t.invoke 15 | end 16 | 17 | def gte(n) 18 | t = Rake::Task[n] 19 | #puts "action size #{t.actions.size}" 20 | t.actions = t.actions[-1..-1] if t.actions.size > 1 21 | t.execute 22 | end -------------------------------------------------------------------------------- /lib/lre/watchr_ext.rb: -------------------------------------------------------------------------------- 1 | require 'watchr' 2 | 3 | Watchr::Controller.class_eval do 4 | attr_accessor :base_path 5 | def monitored_paths 6 | p = base_path ? "#{base_path}/**/*" : "**/*" 7 | paths = Dir[p].select do |path| 8 | @script.patterns.any? {|p| path.match(p) } 9 | end 10 | paths.push(@script.path).compact! 11 | paths.map {|path| Pathname(path).expand_path } 12 | end 13 | end 14 | 15 | -------------------------------------------------------------------------------- /lre.gemspec: -------------------------------------------------------------------------------- 1 | # Generated by jeweler 2 | # DO NOT EDIT THIS FILE DIRECTLY 3 | # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' 4 | # -*- encoding: utf-8 -*- 5 | # stub: lre 0.3.1 ruby lib 6 | 7 | Gem::Specification.new do |s| 8 | s.name = "lre" 9 | s.version = "0.3.1" 10 | 11 | s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= 12 | s.require_paths = ["lib"] 13 | s.authors = ["mharris717"] 14 | s.date = "2014-04-29" 15 | s.description = "lre" 16 | s.email = "mharris717@gmail.com" 17 | s.executables = ["lre"] 18 | s.extra_rdoc_files = [ 19 | "LICENSE.txt", 20 | "README.md" 21 | ] 22 | s.files = [ 23 | ".document", 24 | ".rspec", 25 | "Gemfile", 26 | "Gemfile.lock", 27 | "LICENSE.txt", 28 | "README.md", 29 | "Rakefile", 30 | "VERSION", 31 | "bin/lre", 32 | "lib/lre.rb", 33 | "lib/lre/file_reload.rb", 34 | "lib/lre/rake_ext.rb", 35 | "lib/lre/watchr_ext.rb", 36 | "lre.gemspec", 37 | "spec/lre_spec.rb", 38 | "spec/spec_helper.rb", 39 | "spec/test_dir/.lre", 40 | "spec/test_dir/bar.rb", 41 | "spec/test_dir/file.rb", 42 | "spec/test_dir/foo.rb" 43 | ] 44 | s.homepage = "http://github.com/mharris717/lre" 45 | s.licenses = ["MIT"] 46 | s.rubygems_version = "2.2.2" 47 | s.summary = "lre" 48 | 49 | if s.respond_to? :specification_version then 50 | s.specification_version = 4 51 | 52 | if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then 53 | s.add_runtime_dependency(%q, [">= 0"]) 54 | s.add_runtime_dependency(%q, [">= 0"]) 55 | s.add_runtime_dependency(%q, [">= 0"]) 56 | s.add_development_dependency(%q, ["~> 2.8.0"]) 57 | s.add_development_dependency(%q, ["~> 3.12"]) 58 | s.add_development_dependency(%q, [">= 1.0"]) 59 | s.add_development_dependency(%q, ["~> 1.8.7"]) 60 | s.add_development_dependency(%q, [">= 0"]) 61 | s.add_development_dependency(%q, [">= 0"]) 62 | else 63 | s.add_dependency(%q, [">= 0"]) 64 | s.add_dependency(%q, [">= 0"]) 65 | s.add_dependency(%q, [">= 0"]) 66 | s.add_dependency(%q, ["~> 2.8.0"]) 67 | s.add_dependency(%q, ["~> 3.12"]) 68 | s.add_dependency(%q, [">= 1.0"]) 69 | s.add_dependency(%q, ["~> 1.8.7"]) 70 | s.add_dependency(%q, [">= 0"]) 71 | s.add_dependency(%q, [">= 0"]) 72 | end 73 | else 74 | s.add_dependency(%q, [">= 0"]) 75 | s.add_dependency(%q, [">= 0"]) 76 | s.add_dependency(%q, [">= 0"]) 77 | s.add_dependency(%q, ["~> 2.8.0"]) 78 | s.add_dependency(%q, ["~> 3.12"]) 79 | s.add_dependency(%q, [">= 1.0"]) 80 | s.add_dependency(%q, ["~> 1.8.7"]) 81 | s.add_dependency(%q, [">= 0"]) 82 | s.add_dependency(%q, [">= 0"]) 83 | end 84 | end 85 | 86 | -------------------------------------------------------------------------------- /spec/lre_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + '/spec_helper') 2 | 3 | describe "Lre" do 4 | it 'smoke' do 5 | 2.should == 2 6 | LRE 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) 2 | $LOAD_PATH.unshift(File.dirname(__FILE__)) 3 | require 'rspec' 4 | require 'lre' 5 | 6 | # Requires supporting files with custom matchers and macros, etc, 7 | # in ./support/ and its subdirectories. 8 | Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f} 9 | 10 | RSpec.configure do |config| 11 | 12 | end 13 | -------------------------------------------------------------------------------- /spec/test_dir/.lre: -------------------------------------------------------------------------------- 1 | puts "hello" -------------------------------------------------------------------------------- /spec/test_dir/bar.rb: -------------------------------------------------------------------------------- 1 | puts 'bar' 2 | #--onlyload{thing} 3 | puts 'bar2' -------------------------------------------------------------------------------- /spec/test_dir/file.rb: -------------------------------------------------------------------------------- 1 | puts 'file.rb' -------------------------------------------------------------------------------- /spec/test_dir/foo.rb: -------------------------------------------------------------------------------- 1 | puts 'foo' 2 | #--dontload{thing} 3 | puts 'foo2' --------------------------------------------------------------------------------