I am trying to build a command line ruby gem. I am using bundler to create the gem and install the gem locally. It generated the needed directories. I also was able to test that if I require my Gem I can use methods inside of it. I am trying to get the command line piece working now and can't seem to get it working. I want to be able to do something like
gemname command
Similar to how rspec works:
rspec test/whatever.rb
Any help on how to be able to execute through the command line would be great.
In order to declared the executables you have to just make a proper line in your yourgem.gemspec:
`git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
This line, along with an other useful line is generated by bundle gem yourgem command. Just execute it, and then fix the yourgem.gemspec according your needs. Put executables into bin/ folder of your gem, and all libraries, including the version, into lib/ folder.
The next step is to use the binary. When you are installing the gem into a system, the binary folder is automatically included into binary search path. So your gem is avaiable to execute from anywere. But when your gem isn't installed you are still able to simelate the case with a bundler's exec as follows:
bundle exec bin/your_exec
It picks the require librarires up from lib/ folder, and the executable will work properly.
To make sure that the executable will work, build the gem with gem build yourgem.gemspec, then install it with gem install yourgem.gem, and try.
I think the problem is that you've not commited your code yet.
Check if git ls-files -- bin/* shows you the script you want to execute.
When you commit your file, then git ls-files will return it and the spec will be able to load the script.
Checkout these blog posts:
http://robdodson.me/blog/2012/06/14/how-to-write-a-command-line-ruby-gem/
http://rubylearning.com/blog/2011/01/03/how-do-i-make-a-command-line-tool-in-ruby/
I'm not really sure what you've built so far but here are a few points of interest:
#!/usr/bin/env ruby for first line in the executable file (in the /bin folder).
chmod +x filname to make it executable
ARGV[0] Variables passed in are retrieved from ARGV[0]
s.executables << 'your_file' Add executable to gemspec
I figured this out at least for my specific issue. I just need to call out the bin command directly instead of that git ls loop. The top one works the bottom one doesn't for some reason.
spec.executables = ["toolshed"]
vs
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
Related
I'm following this tutorial while creating my first Ruby gem. At the end of step 4 described there, there's a file my_gem-0.0.0.gem. For the time being, I'd like to keep this gem locally, so I tried putting it in a gems directory at the root of my rails project.
In the Gemfile I added this line:
gem 'my_gem', path: 'gems'
We use Docker, and when I try starting this container, I see my new gem is not found:
Bundler::GemNotFound: Could not find gem 'my_gem' in the source at `gems`
The source does not contain any versions of 'my_gem'
I tried adding/removing the gem extension and the -0.0.1 part both in the filename and in the Gemfile, but nothing worked. What's wrong here?
To works with Docker you need to clone the repository from github to your custom folder. In example below the steps to reproduce how I use custom path to edit gems in a separeted folder:
In my local machine I use a /gems folder inside my rails application folder: mkdir <my-app>/gems.
cd <my-app>/gems.
git clone <gem-repository-source>. Is necessary to clone because if you copy from other folder in your computer probably some files are missed.
Set in your Gemfile: gem '<gem-name>', path: '/bundle/custom_gems/<gem-name>'.
If you use docker-compose, you need to bind folders with volumes config, like below:
volumes:
- ./app/gems:/bundle/custom_gems
With this, your local folder (your machine) copy files inside ./app/gems to /bundle/custom_gems in Docker container.
Restart service.
If you NOT use docker-compose, you need add in Dockerfile some like:
ADD ./app/gems /bundle/custom_gems
I am trying to push into rubygems.orge a simple gem following this tutorial. Basically I am using bundler and I have write a simple Hello World class. Then, I try to push the gem as follows:
bundle gem my_first_gem
gem build my_first_gem-0.0.1.gem
and I get:
Signed in.
Pushing gem to https://rubygems.org...
Repushing of gem versions is not allowed.
Please use `gem yank` to remove bad gem releases.
So, I have checked and there is already a gem with such name. So, is there an easy way to rename the gem I have including changing the gem name in all generate by bulder files:
or if I should rename the files by hand, could you tell which are the critical ones?
Instead of renaming files by hand. As it is just a tutorial gem, I would suggest you to create a new gem with
bundle gem gotqn_first_gem
and just move your HelloWorld class in lib. And follow the rest of the commands suggested in Railscasts.
Don't forget that after renaming you need to call git add -A to update your files list.
The reason for that is because (unless that you have changed) your my_first_gem.gemspec have a line like that:
spec.files = `git ls-files -z`.split("\x0")
So, when you call gem build my_first_gem-0.0.1.gem, the above command will search for your older files and ignore the renamed ones.
In our project, we ran
bundle package --all
one time, which according to documentation, remembers the "--all" option in subsequent calls. If I want to test a gem on my project by hardcoding it's path into the Gemfile such as:
gem 'blocks', :path => "/Users/hunterae/Projects/blocks",
anytime I run bundle install, all of the source code for this gem will be copied into my /vendor/cache directory. This means that if I make a change to the gem I am testing, I have to shut down my rails server and run bundle install again, whereas before "bundle package --all" was run, I used to be able to just stop and start my rails server.
My question is how do I get "bundle package" to once again only package gems and not try and cache :path gems? Where is the "--all" option remembered in bundler?
Look in .bundle/config in your project directory for a line that says BUNDLE_CACHE_ALL: true.
Delete that line to make it revert to packaging only standard gems.
In general, remembered options are stored in .bundle/config.
+1 to the answer form Tim Moore. Following is an addition to it.
You should avoid using :path in your Gemfile if possible and if working with a gem available on github. Since Bundler 1.9 you can use sth. like
bundle config local.name_of_gem /path/to/checked_out/repo
This will add an entry in ~/.bundle/config like
less ~/.bundle/config
---
BUNDLE_LOCAL__NAME_OF_GEM:
"/path/to/checked_out/repo/name_of_gem"
You can remove the config with the same command and including --delete like
bundle --delete config local.name_of_gem /path/to/checked_out/repo
This will avoid many problems and is easy to maintain.
I have thor tasks in one Thor class. I want to extract it to my_gem and use it like bin. It is possible? Now i move this task to lib/my_gem/thor/tasks and i add Thorfile to gem, then i create my_gem.rb in my_gem/bin, but it is didn't work. If anybody know another way, please help. Thanks!
Yes this is possible, you need to add this, or similar to your my_gem.gemspec (this works for a gem created by bundle gem, and where files list has already been assigned):
Gem::Specification.new do |gem|
# All the other usual stuff, e.g. gem.files = `git ls-files`.split($/)
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
end
The executables should then get correctly handled on gem install (or bundle install etc), and put on your path.
Also important: The executable script should start
#!/usr/bin/env ruby
The .rb extension is optional, and usually omitted for command-line scripts because otherwise you need to type it when invoking your script.
I am using the gem whenever
To update the crontab, it executes the whenever command in the root directory of my application.
The trouble is: my production environment doesn't have the gem installed, so I unpacked the whenever gem into my application and running 'whenever' from my application root directory fails to find the file
How do I run the frozen gem executable from the root directory of my application?
I found that
cd #{release_path} && /usr/bin/ruby #{release_path}/script/runner #{release_path}/vendor/gems/whenever-0.4.1/bin/whenever --update-crontab #{application}
works; but this seems like the 'wrong' answer
This has the answer you're looking for:
http://www.mail-archive.com/rubyonrails-talk#googlegroups.com/msg45169.html
Finally, you usually can add gems to
the load path by doing the following
within your environment.rb:
Option 1: add gems using less ruby
code within the environment.rb file
# Add additional load paths for your
own custom dirs config.load_paths +=
%W( #{RAILS_ROOT}/extras )
Option 2: add gems using more ruby
code within the environment.rb file
Dir.glob( File.expand_path(
"#{RAILS_ROOT}/vendor/gems/*",
FILE) ).each do | gem |
$:.unshift File.join( gem, 'lib' ) end
Option 3: using a combination of
Option (1) and (2).
Read the whole message, it's quite instructive.