Giter Club home page Giter Club logo

require_all's Introduction

require_all

Gem Version Build Status Coverage

A wonderfully simple way to load your code.

Tired of futzing around with require statements everywhere, littering your code with require File.dirname(__FILE__) crap? What if you could just point something at a big directory full of code and have everything just automagically load?

Wouldn't that be nice? Well, now you can!

Installation

Add this line to your application's Gemfile:

gem 'require_all'

And then execute:

$ bundle

Or install it yourself as:

$ gem install require_all

Usage

require 'require_all'

# load all ruby files in the directory "lib" and its subdirectories
require_all 'lib'

# or load all files by using glob
require_all 'lib/**/*.rb'

# or load files in an Array
require_all Dir.glob("blah/**/*.rb").reject { |f| stupid_file? f }

# or load manually specified files
require_all 'lib/a.rb', 'lib/b.rb', 'lib/c.rb', 'lib/d.rb'

You can also load files relative to the current file by using require_rel:

# Instead of
require File.dirname(__FILE__) + '/foobar'

# you can do simply like this
require_rel 'foobar'

You can give all the same argument types to the require_rel as for require_all.

It is recommended to use require_rel instead of require_all since it will require files relatively to the current file (__FILE__) as opposed to loading files relative from the working directory.

load_all and load_rel methods also exist to use Kernel#load instead of Kernel#require!

Files are required in alphabetical order and if there are files in nested directories, they are required depth-first. If a NameError caused by a reference to an uninitialised constant is encountered during the requiring process, then a RequireAll::LoadError will be thrown, indicating the file that needs the dependency adding to.

autoload_all

This library also includes methods for performing autoload - what a bargain!

Similar syntax is used as for require_(all|rel) and load_(all|rel) methods with some caveats:

  • Directory and file names have to reflect namespaces and/or constant names:
# lib/dir1/dir2/my_file.rb
module Dir1
  module Dir2
    class MyFile
    end
  end
end

# lib/loader.rb
autoload_all File.dirname(__FILE__) + "/dir1"
  • A base_dir option has to be specified if loading directories or files from some other location than top-level directory:
# lib/dir1/other_file.rb
autoload_all File.dirname(__FILE__) + "/dir2/my_file.rb",
             base_dir: File.dirname(__FILE__) + "/../dir1"
  • All namespaces will be created dynamically by autoload_all - this means that defined?(Dir1) will return "constant" even if my_file.rb is not yet loaded!

Of course there's also an autoload_rel method:

autoload_rel "dir2/my_file.rb", base_dir: File.dirname(__FILE__) + "/../dir1"

If having some problems with autoload_all or autoload_rel then set $DEBUG=true to see how files are mapped to their respective modules and classes.

Version compatibility and upgrading

As of version 2, RequireAll will raise a RequireAll::LoadError if it encounters a NameError caused by a reference to an uninitialised constant during the requiring process. As such, it is not backwards compatible with version 1.x, but simple to upgrade by adding any requires to load dependencies in files that need them. See CHANGES for more details.

Questions? Comments? Concerns?

You can reach the author on github or by email [email protected]

License

MIT (see the LICENSE file for details)

require_all's People

Contributors

aaronklaassen avatar adam12 avatar chewi avatar enkessler avatar jarmo avatar joehorsnell avatar mvz avatar owst avatar swrobel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

require_all's Issues

Can't handle empty directories

The current version of the gem will raise an error if it encounters an empty directory. A quick glance at the code makes me think that it considers an empty directory to be an indication that something has gone wrong while reading the file system. As opposed to it treating empty directories as legitimate things that might exist on the file system.

"Could not require ... (uninitialized constant ...)" with 2.0.0

Hello,

I have a Cucumber project which uses require_all to, well, require some files in project subdirs. Since 2.0.0 whenever I try running the Cucumber tests (cucumber features), I get an error that:

Could not require C:/no_such_file/app/model/bbb.rb (uninitialized constant Model::Ccc). Please require the necessary files (RequireAll::LoadError)

Full stacktrace is:

C:\no_such_file>cucumber features
Could not require C:/no_such_file/app/model/bbb.rb (uninitialized constant Model::Ccc). Please require the necessary files (RequireAll::LoadError)
C:/Programs/Ruby_x64/lib/ruby/gems/2.5.0/gems/require_all-2.0.0/lib/require_all.rb:102:in `rescue in block in require_all'
C:/Programs/Ruby_x64/lib/ruby/gems/2.5.0/gems/require_all-2.0.0/lib/require_all.rb:97:in `block in require_all'
C:/Programs/Ruby_x64/lib/ruby/gems/2.5.0/gems/require_all-2.0.0/lib/require_all.rb:96:in `each'
C:/Programs/Ruby_x64/lib/ruby/gems/2.5.0/gems/require_all-2.0.0/lib/require_all.rb:96:in `require_all'
C:/no_such_file/features/support/env.rb:3:in `<top (required)>'
C:/Programs/Ruby_x64/lib/ruby/gems/2.5.0/gems/cucumber-3.1.0/lib/cucumber/glue/registry_and_more.rb:106:in `load'
C:/Programs/Ruby_x64/lib/ruby/gems/2.5.0/gems/cucumber-3.1.0/lib/cucumber/glue/registry_and_more.rb:106:in `load_code_file'
C:/Programs/Ruby_x64/lib/ruby/gems/2.5.0/gems/cucumber-3.1.0/lib/cucumber/runtime/support_code.rb:147:in `load_file'
C:/Programs/Ruby_x64/lib/ruby/gems/2.5.0/gems/cucumber-3.1.0/lib/cucumber/runtime/support_code.rb:88:in `block in load_files!'
C:/Programs/Ruby_x64/lib/ruby/gems/2.5.0/gems/cucumber-3.1.0/lib/cucumber/runtime/support_code.rb:87:in `each'
C:/Programs/Ruby_x64/lib/ruby/gems/2.5.0/gems/cucumber-3.1.0/lib/cucumber/runtime/support_code.rb:87:in `load_files!'
C:/Programs/Ruby_x64/lib/ruby/gems/2.5.0/gems/cucumber-3.1.0/lib/cucumber/runtime.rb:270:in `load_step_definitions'
C:/Programs/Ruby_x64/lib/ruby/gems/2.5.0/gems/cucumber-3.1.0/lib/cucumber/runtime.rb:67:in `run!'
C:/Programs/Ruby_x64/lib/ruby/gems/2.5.0/gems/cucumber-3.1.0/lib/cucumber/cli/main.rb:33:in `execute!'
C:/Programs/Ruby_x64/lib/ruby/gems/2.5.0/gems/cucumber-3.1.0/bin/cucumber:9:in `<top (required)>'
C:/Programs/Ruby_x64/bin/cucumber:23:in `load'
C:/Programs/Ruby_x64/bin/cucumber:23:in `<main>'

Reverting to 1.5.0 solves the issue.

Environment is: Windows 10 x64, Ruby 2.5.0-2 x64 (Ruby installer). Project is newly set with "bundle install" and no gemfile.lock.

See attached file for a sample project: no_such_file.zip. To reproduce, bundle install in the project directory then cucumber features

Unable to install in application's Gemfile or outside of it

Gemfile contains:
gem 'require_all'

And environment contains:
require 'require_all'

But that produces the following error:
`require': cannot load such file -- require_all (LoadError)

Outside of my application, I used gem install require_all to install locally, and received a successful install message:
Successfully installed require_all-1.5.0
Parsing documentation for require_all-1.5.0
Done installing documentation for require_all after 0 seconds
1 gem installed

But the gem is not listed when I list all gems or use bundle info require_all to find details on require_all. Are there any dependencies I should be aware of, which might prevent me from installing within an application or outside of one?

Your NameError logic needs to be more selective

Some of my code was throwing:

NoMethodError: undefined method `foo'

and since: class NoMethodError < NameError it was getting caught by the NameError logic. The file was then getting required again by the loop, but since I was using ::ActiveSupport::Concern a module was getting included multiple times which led to its own error, which was really confusing.

So just fix up the rescue to not catch descendants of NameError

Thanks!

Trying to use `require_all` with a folder of the same name as the target file fails

Exercism/Ruby track has a folder in the lib folder that has the same name as a file that is wanted to be required (except for the extension of .rb). This seems to be failing to load due to this, as another file name requested does load.

/home/kotp/projects/exercism/ruby/lib
bookkeeping.md
disable_skip.rb
generator
generator.rb
helper.rb
tasks
 => ["pwd", "ls -1"]
2.4.1 :004 > require_all '.'
LoadError: cannot load such file -- lib/generator.rb
        from /home/kotp/projects/exercism/ruby/lib/generator/exercise.rb:1:in `load'
        from /home/kotp/projects/exercism/ruby/lib/generator/exercise.rb:1:in `<top (required)>'
        from /home/kotp/.rvm/gems/ruby-2.4.1/gems/require_all-2.0.0/lib/require_all.rb:208:in `require'
        from /home/kotp/.rvm/gems/ruby-2.4.1/gems/require_all-2.0.0/lib/require_all.rb:208:in `__require'
        from /home/kotp/.rvm/gems/ruby-2.4.1/gems/require_all-2.0.0/lib/require_all.rb:98:in `block in require_all'
        from /home/kotp/.rvm/gems/ruby-2.4.1/gems/require_all-2.0.0/lib/require_all.rb:96:in `each'
        from /home/kotp/.rvm/gems/ruby-2.4.1/gems/require_all-2.0.0/lib/require_all.rb:96:in `require_all'
        from /home/kotp/.rvm/gems/ruby-2.4.1/gems/require_all-2.0.0/lib/require_all.rb:118:in `block in require_rel'
        from /home/kotp/.rvm/gems/ruby-2.4.1/gems/require_all-2.0.0/lib/require_all.rb:117:in `each'
        from /home/kotp/.rvm/gems/ruby-2.4.1/gems/require_all-2.0.0/lib/require_all.rb:117:in `require_rel'
        from /home/kotp/projects/exercism/ruby/lib/generator.rb:2:in `<top (required)>'
        from /home/kotp/.rvm/gems/ruby-2.4.1/gems/require_all-2.0.0/lib/require_all.rb:208:in `require'
        from /home/kotp/.rvm/gems/ruby-2.4.1/gems/require_all-2.0.0/lib/require_all.rb:208:in `__require'
        from /home/kotp/.rvm/gems/ruby-2.4.1/gems/require_all-2.0.0/lib/require_all.rb:98:in `block in require_all'
        from /home/kotp/.rvm/gems/ruby-2.4.1/gems/require_all-2.0.0/lib/require_all.rb:96:in `each'
        from /home/kotp/.rvm/gems/ruby-2.4.1/gems/require_all-2.0.0/lib/require_all.rb:96:in `require_all'
        from (irb):4
        from /home/kotp/.rvm/rubies/ruby-2.4.1/bin/irb:11:in `<main>'

require_all does not respect $LOAD_PATH

RSpec automatically adds the lib directory to $LOAD_PATH, but it seems like require_all doesn't respect it since it cannot load relative files that work fine with normal ruby require.

For example, with this class located in lib/a/test_class.rb:

module A
  class TestClass
    def self.hello
      'Hello, world!'
    end
  end
end

and this spec in spec/test_class_spec.rb:

require 'require_all'
# This works: require 'a/test_class'
require_all 'a' # This doesn't work

describe 'TestClass' do
  it 'says hello' do
    expect(A::TestClass.hello).to eq 'Hello, world!'
  end
end

I get the following error: 'rescue in require_all': no such file to load -- a (LoadError).

Example project code: http://www.filedropper.com/requireall-example

How do I load a directory of files relative to the LOAD_PATH?

So require_all loads relative to the current working directory, and require_rel loads relative to the current file.

Is there no way to load a directory relative to the $LOAD_PATH as a normal require would? I'm getting duplicate load errors, presumably because require_all is requiring files in a way that prevents ruby from realizing they've already been required.

Defining a module that fails to load, makes other modules that include it not have methods

Module A includes module B which includes module C

Module A
  include B
end

Module B
  include C
end

Module C ; end

When start none are defined. Files are required in sorted order A,B then C

  1. A is required and tries to include B which raises a NameError. The module namespace A is now defined even though the include failed. It will be tried again later
  2. B is required and tries to include C which raises a NameError. The module namespace B is now defined even though the include failed. It will be tried again later.
  3. C is required and loads cleanly because it has no dependencies.
  4. A is required again because it previously failed. It includes B which is now defined as a namespace but has NO METHODS in it because it failed to fully load before. Or at least not the ones from C which it should have since it includes C. So A included B successfully and did not get the methods from C but it worked.

A now does not have the methods you would expect and everything loaded cleanly.

I now understand the problem but I'm having a hard time coming up with a not awful solution to it.

Any thoughts?

License missing from gemspec

RubyGems.org doesn't report a license for your gem. This is because it is not specified in the gemspec of your last release.

via e.g.

spec.license = 'MIT'
# or
spec.licenses = ['MIT', 'GPL-2']

Including a license in your gemspec is an easy way for rubygems.org and other tools to check how your gem is licensed. As you can imagine, scanning your repository for a LICENSE file or parsing the README, and then attempting to identify the license or licenses is much more difficult and more error prone. So, even for projects that already specify a license, including a license in your gemspec is a good practice. See, for example, how rubygems.org uses the gemspec to display the rails gem license.

There is even a License Finder gem to help companies/individuals ensure all gems they use meet their licensing needs. This tool depends on license information being available in the gemspec. This is an important enough issue that even Bundler now generates gems with a default 'MIT' license.

I hope you'll consider specifying a license in your gemspec. If not, please just close the issue with a nice message. In either case, I'll follow up. Thanks for your time!

Appendix:

If you need help choosing a license (sorry, I haven't checked your readme or looked for a license file), GitHub has created a license picker tool. Code without a license specified defaults to 'All rights reserved'-- denying others all rights to use of the code.
Here's a list of the license names I've found and their frequencies

p.s. In case you're wondering how I found you and why I made this issue, it's because I'm collecting stats on gems (I was originally looking for download data) and decided to collect license metadata,too, and make issues for gemspecs not specifying a license as a public service :). See the previous link or my blog post about this project for more information.

how about '#require_dependency if defined? Rails' ?

Hi!

I can't foresee now all possible consequences, but it seems to be possible to have #require_dependency instead of #require when require_all is operating in Rails app context.

What do you think?

And...

Thank you for a nice gem!

Handles directories containing glob characters incorrectly.

This ticket was inspired by the following (from troessner/reek#455):

I also fondly remember the wise words of Michael Grünewald:

Hobby: creating bug tickets, waiting for people to find out about my home directory – which happens to contain spaces, stars and newlines.

This is a tricky edge case:

Say you have directories foo*bar and foobazbar, both containing a subdirectory baz with some ruby files. You want to load all files from baz from a file inside foo*bar called req.rb. Like so:

 +- foo*bar
 |  +- baz
 |  |  + foo.rb
 |  +- req.rb
 +- foobazbar
    +- baz
       + qux.rb

foo*bar/req.rb would contain the following:

require 'require_all'

require_rel 'baz'

If you now run ruby req.rb from inside foo*bar, it will only load foo.rb. However, if you run ruby foo\*bar/req.rb from the top-level directory, it will also load qux.rb.

I realize that having glob characters in your directory names may be a case of 'well don't do that then', but there are more subtle issues with glob patterns not only matching the exact characters provided: https://bugs.ruby-lang.org/issues/10700

make it cross-platform compatible

Currently all specs pass under 1.8.x MRI. Make specs passing also on 1.9.x and JRuby. Failing specs doesn't necessarily mean that functionality itself isn't working, but the specs themselves might need some refining.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.