bridgetownrb / bridgetown

A next-generation progressive site generator & fullstack framework, powered by Ruby
https://www.bridgetownrb.com
MIT License
1.16k stars 112 forks source link

`bridgetown --help` raises an error outside of a Bridgetown project dir, if there's a `Gemfile` #653

Closed davidstosik closed 1 year ago

davidstosik commented 1 year ago

I first commented on issue #608, as it felt the cannot load such file -- rake error was related enough, but then I realized it might be different enough, and the currently suggested fix did not change the outcome for me, so I decided to create an issue instead.

Bridgetown Version: 1.1.0

To Reproduce

mkdir /tmp/reproduce
cd /tmp/reproduce
rbenv local 3.1.2
gem install bridgetown
touch Gemfile
bridgetown --help

Current behavior Bridgetown starts displaying the help text correctly, but when it comes to displaying the "Available Rake Tasks" sections, it craps out with an error:

bridgetown --help
Bridgetown v1.1.0 "Belmont" is a Webpack-aware, Ruby-powered static site generator for the modern Jamstack era

Usage:
  bridgetown <command> [options]

Commands:
  bridgetown apply                    # Applies an automation to the current site
  bridgetown build                    # Build your site and save to destination folder
  bridgetown clean                    # Clean the site (removes site output and metada...
  bridgetown configure CONFIGURATION  # Set up bundled Bridgetown configurations
  bridgetown console                  # Invoke an IRB console with the site loaded
  bridgetown dev                      # Alias of start
  bridgetown doctor                   # Search site and print specific deprecation war...
  bridgetown dream                    # There's a place where that idea still exists a...
  bridgetown esbuild ACTION           # Perform actions on the Bridgetown esbuild conf...
  bridgetown help <command>           # Show detailed command usage information and exit
  bridgetown new PATH                 # Creates a new Bridgetown site scaffold in PATH
  bridgetown plugins <command>        # List installed plugins or access plugin content
  bridgetown serve                    # DEPRECATED (Serve your site locally using WEBr...
  bridgetown start                    # Start the Puma server, frontend bundler, and B...
  bridgetown webpack ACTION           # Perform actions on the Bridgetown Webpack conf...

/Users/sto/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/bridgetown-core-1.1.0/lib/bridgetown-core/commands/base.rb:97:in `require': cannot load such file -- rake (LoadError)
        from /Users/sto/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/bridgetown-core-1.1.0/lib/bridgetown-core/commands/base.rb:97:in `help'
        from /Users/sto/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run'
        from /Users/sto/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command'
        from /Users/sto/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch'
        from /Users/sto/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/thor-1.2.1/lib/thor/base.rb:485:in `start'
        from /Users/sto/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/bridgetown-core-1.1.0/bin/bridgetown:38:in `<top (required)>'
        from /Users/sto/.rbenv/versions/3.1.2/bin/bridgetown:25:in `load'
        from /Users/sto/.rbenv/versions/3.1.2/bin/bridgetown:25:in `<main>'

Expected behavior

When I'm getting started with Bridgetown (or say I forgot the name of the Bridgetown command to start a new site), it shouldn't matter where I'm situated, bridgetown --help should work without displaying an error. (Maybe skip displaying rake tasks? Maybe detect it's not running in a Bridgetown project directory, and just display help for bridgetown new, like Rails does?)

Screenshots Not applicable.

Computing environment (please complete the following information):

Additional context

I guess it doesn't matter much, I can get started and things should work once I cd into the site directory, but I thought I'd mention it. It doesn't feel great to get an error message when you're getting started. 😬

sandstrom commented 1 year ago

The rake gem should be standard (installed by default) in Ruby 3.1.0, see https://stdgems.org/3.1.0/

So I don't really understand why this is happening.

A quick Google search turns up a few similar issues:

This isn't necessarily a bridgetown problem. Could also be something with your setup.

If you open irb in that directory, what happens if you run require 'rake' in that irb console?

davidstosik commented 1 year ago

If you open irb in that directory, what happens if you run require 'rake' in that irb console?

I'd tried that before posting, and it worked. I also confirmed with gem list and ls that the rake gem was available. My guess is that maybe, similarly to #608, Bridgetown uses bundle exec somewhere, and because rake is not in my Gemfile, it is not made available to the command.

sandstrom commented 1 year ago

because rake is not in my Gemfile, it is not made available to the command.

Rake is bundled with ruby, see https://stdgems.org/3.1.0/

davidstosik commented 1 year ago

Rake is bundled with ruby, see https://stdgems.org/3.1.0/

Sure, but how do you explain this?

mkdir /tmp/test
cd /tmp/test
chruby local 3.1.2
bundle init
bundle install
bundle exec ruby -e "require 'rake'"
-e:1:in `require': cannot load such file -- rake (LoadError)
    from -e:1:in `<main>'

echo 'gem "rake"' >> Gemfile
bundle install
bundle exec ruby -e "require 'rake'"
# No error.

(Note this is using chruby, while my previous tests used rbenv. I'm on a different computer today.)

Again, if I run bridgetown --help in a directory that has a Gemfile, but that Gemfile does not include rake (for example the old Jekyll project I want to port 😬 ), then bridgetown --help will fail to require rake.

Did you try to reproduce, using the steps I provided in my original post? Allow me to copy-paste them here for convenience:

mkdir /tmp/reproduce
cd /tmp/reproduce
rbenv local 3.1.2          # use whatever you want to set your current Ruby version
gem install bridgetown
bundle init && bundle install      # this was `touch Gemfile` in my original steps, but using bundle is more "standard" I guess
bridgetown --help
sandstrom commented 1 year ago

Alright, maybe we need to detect if that gem is installed and gate that code (listing of rake tasks) behind that check.

https://makandracards.com/makandra/42521-detecting-if-a-ruby-gem-is-loaded

Would you like to put together a PR for this issue?

davidstosik commented 1 year ago

Would you like to put together a PR for this issue?

I would have already, if I understood exactly what's going on. I could test whether rake is present right before requiring it, I could rescue the error and bail early, but these sound like a workaround at best.

The real question is: why would that require "rake" be running in a Bundler context, whereas I initially ran bridgetown without prefixing it with bundle exec?

(This PR shows Bridgetown introduces – or used to introduce – a bundle exec in the mix.)

Hmm, I think this is it:

https://github.com/bridgetownrb/bridgetown/blob/a9649c47fc9ce9da484f6592d26ed84f58ef0e23/bridgetown-core/lib/bridgetown-core.rb#L142

The bridgetown command (which basically calls the gem's bin/bridgetown script, right?) calls to Bridgetown.begin!, which itself calls Bridgetown::PluginManager.setup_bundler

https://github.com/bridgetownrb/bridgetown/blob/a9649c47fc9ce9da484f6592d26ed84f58ef0e23/bridgetown-core/lib/bridgetown-core/plugin_manager.rb#L63-L78

To me, File.file?("Gemfile") sounds like Bridgetown assumes it is running in a Bridgetown project because it found a Gemfile, but that's not always correct. Should it also check that that Gemfile provides Bridgetown, and, with it, all its dependencies? (Including rake.) bridgetown might also stop working if I happen to call it inside a subdirectory of a Bridgetown project.

davidstosik commented 1 year ago

It might be interesting to look at Rails to understand how the gem's rails command will hook into the current Rails app's bin/rails, if it happens to be running within a Rails app.

See for example:

sandstrom commented 1 year ago

To me, File.file?("Gemfile") sounds like Bridgetown assumes it is running in a Bridgetown project because it found a Gemfile, but that's not always correct. Should it also check that that Gemfile provides Bridgetown, and, with it, all its dependencies? (Including rake.)

Bridgetown might also stop working if I happen to call it inside a subdirectory of a Bridgetown project.

This sounds like a likely culprit.

jaredcwhite commented 1 year ago

Shouldn't crash anymore if the rake gem isn't available with PR #656 merged.

davidstosik commented 1 year ago

Confirmed it's fixed in v1.2.0beta4. Thank you!