06 Dec 2013, 22:08
Generic-user-small

Carles Jove i Buxeda (3 posts)

Hello David,

I’ve been reading your book and created a simple CLI app using GLI 2.8.1

Everything works fine, but after packaging the gem and installing it locally, following the steps in chapter 7.1, I still get the “need to use bundle exec…” message. But running bundle exec bin/myapp will result in a “Could not locate Gemfile” message. I’ve searched around both in the forums and your book, but have not found a way to go beyond this.

Any suggestions?

Thank you very much.

06 Dec 2013, 22:49
Dmfcb_pragsmall

David Copeland (98 posts)

Is this the message:

In development, you need to use `bundle exec bin/#{project_name}` to run your app
At install-time, RubyGems will make sure lib, etc. are in the load path
Feel free to remove this message from bin/#{project_name} now

If so, you’ll need to remove that from your app. It’s odd that you are getting a load error, though. Can you post both your bin file and your gemspec?

07 Dec 2013, 23:10
Generic-user-small

Carles Jove i Buxeda (3 posts)

Hello David,

I just saw that in the bin file there’s a comment saying that the begin/rescue block has to be removed before distribution. I’ve done so, and now get a different error. In order to make it easier, I’ve created a new app from scratch. Here’s what I’ve done:

$ gli scaffold myapp hello

$ cd myapp

$ bundle exec bin/myapp # outputs hello command ran

remove begin/rescue block in bin/myapp

$ rake package

$ gem install pkg/myapp-0.0.1.gem

open a new Terminal window and run $ myapp

Get this error:

/Users/carles/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/myapp-0.0.1/bin/myapp:8:in `<top (required)>': uninitialized constant Myapp (NameError)
    from /Users/carles/.rbenv/versions/2.0.0-p247/bin/myapp:23:in `load'
    from /Users/carles/.rbenv/versions/2.0.0-p247/bin/myapp:23:in `<main>'

Here is the gemspeck (exactly the same that was generated with scaffolding):

# Ensure we require the local version and not one we might have installed already
require File.join([File.dirname(__FILE__),'lib','myapp','version.rb'])
spec = Gem::Specification.new do |s| 
  s.name = 'myapp'
  s.version = Myapp::VERSION
  s.author = 'Your Name Here'
  s.email = 'your@email.address.com'
  s.homepage = 'http://your.website.com'
  s.platform = Gem::Platform::RUBY
  s.summary = 'A description of your project'
# Add your other files here if you make them
  s.files = %w(
bin/myapp
lib/myapp/version.rb
lib/myapp.rb
  )
  s.require_paths << 'lib'
  s.has_rdoc = true
  s.extra_rdoc_files = ['README.rdoc','myapp.rdoc']
  s.rdoc_options << '--title' << 'myapp' << '--main' << 'README.rdoc' << '-ri'
  s.bindir = 'bin'
  s.executables << 'myapp'
  s.add_development_dependency('rake')
  s.add_development_dependency('rdoc')
  s.add_development_dependency('aruba')
  s.add_runtime_dependency('gli','2.8.1')
end

Here is the bin file (only removed the begin/rescue block):

#!/usr/bin/env ruby
require 'gli'

include GLI::App

program_desc 'Describe your application here'

version Myapp::VERSION

desc 'Describe some switch here'
switch [:s,:switch]

desc 'Describe some flag here'
default_value 'the default'
arg_name 'The name of the argument'
flag [:f,:flagname]

desc 'Describe hello here'
arg_name 'Describe arguments to hello here'
command :hello do |c|
  c.desc 'Describe a switch to hello'
  c.switch :s

  c.desc 'Describe a flag to hello'
  c.default_value 'default'
  c.flag :f
  c.action do |global_options,options,args|

    puts "hello command ran"
  end
end
    
pre do |global,command,options,args|
  # Pre logic here
  # Return true to proceed; false to abort and not call the
  # chosen command
  # Use skips_pre before a command to skip this block
  # on that command only
  true
end
    
post do |global,command,options,args|
  # Post logic here
  # Use skips_post before a command to skip this
  # block on that command only
end

on_error do |exception|
  # Error logic here
  # return false to skip default error handling
  true
end

exit run(ARGV)

Thank you very much.

09 Dec 2013, 13:50
Dmfcb_pragsmall

David Copeland (98 posts)

Looks like you removed the require 'myapp' which is what you need to bring the code in lib into scope. When you remove the begin..rescue, you’ll want to leave that require in.

Basically what that rescue is doing is giving you a message about why just running your app in dev mode won’t work, whereas in “production” (i.e. when installed via RubyGems) the error shouldn’t even happen.

So, change this:

#!/usr/bin/env ruby
require 'gli'
begin # XXX: Remove this begin/rescue before distributing your app
require 'myapp'
rescue LoadError
  STDERR.puts "In development, you need to use `bundle exec bin/myapp` to run your app"
  STDERR.puts "At install-time, RubyGems will make sure lib, etc. are in the load path"
  STDERR.puts "Feel free to remove this message from bin/myapp now"
  exit 64
end

include GLI::App

program_desc 'Describe your application here'

version Myapp::VERSION

to this:

#!/usr/bin/env ruby
require 'gli'

require 'myapp'

include GLI::App

program_desc 'Describe your application here'

version Myapp::VERSION
09 Dec 2013, 15:53
Generic-user-small

Carles Jove i Buxeda (3 posts)

Oh my God… I can’t believe I made such a stupid mistake. I’m very sorry, David, for making you lose your time like that.

Thank you very much. I’m having a great time reading your book and using GLI.

10 Dec 2013, 14:27
Dmfcb_pragsmall

David Copeland (98 posts)

Seriously, don’t fret about it. This sorts of things are the best problems to have, because they are easy to fix, and we all make them :)

BTW, thanks for buying the book!

  You must be logged in to comment