Gem creation: run code on installation - ruby

I want to create a gem that installs some binaries on "/usr/local/bin". In order to work, I need to run some "cp"/"ln"/"chmod" commands when the user (me) runs gem install mygem.
Is there any callback/method that is called at the installation and that I can override it?
UPDATE:
I found a better way to achieve it: gemspec has a section to add binary files on the system. I put the answer below, but I still wonder how to run code after/before gem installation.

See this https://github.com/rubygems/rubygems/issues/608 you have to run the default task after installation

I found a better way to achieve it: gemspec has a section to add binary files on the system.
Eg:
spec.bindir = "bin"
...
spec.executables << 'your_app'
Then, put your_app in bin.
PS: I'm the OP, but I will not accept this as solution because I still wonder how to run code after/before gem installation.

Related

Struggling to run my ruby cli app

I built a small Cli app in ruby (first ever ruby app), but I'm not able to actually run it.
I started the project off with bundle gem. I have been testing it inside my apps folder by running bundle exec bin/konstruct and everything works fine.
I want to install it locally and test it before I submit it, and so I ran bundle exec rake install after updating all of the info in my gemspec file. It gave successfull output:
konstruct 0.1.1 built to pkg/konstruct-0.1.1.gem.
konstruct (0.1.1) installed.
But when I run the app by entering $ konstruct it gives me an Could not locate Gemfile or .bundle/ directory error, unless I run it from within the root folder of the app.
I have tried to Google but I can't pin the results down to the same issue as I'm having. I've been having this problem even in development (How can I test my Ruby CLI app while still in development?)
I do have a Gemfile and it contains:
source 'https://rubygems.org'
# Specify your gem's dependencies in konstruct.gemspec
gemspec
I don't have a .bundle/ folder though. I'm not sure where/how that folder should be generated. I have run bundle and bundle install many times now.
I have a konstruct.gemspec file which contains: https://github.com/konstruct/konstruct.cli/blob/master/konstruct.gemspec
Most of that file is as it was generated. I just filled it in where I could.
I'm sorry if this is a stupid question, but I am super stuck.
You have the following line in your gemspec:
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
I believe that means if you move your executable file into an exe directory instead of a bin directory, it will work as you expect.
http://guides.rubygems.org/specification-reference/#executables
It turns out I am a first class idiot. Some time ago I added Konstruct in my .path file, which obviously was now overriding the proper konstruct command. Back then what I did din't work, so I just forgot about it.
So the answer to this question: It's not broken. OP is an idiot. :-/

Adding files when installing a gem

I'm writing a gem which needs a directory to store some config. I want to do this upon installation but I'm not sure how best to insert code into the installation process.
By adding the code to the Rakefile and adding spec.extensions = ["Rakefile"] to my gemspec, I've achieved what I want to do but this method means the installation process tells me I'm building native extensions; this is misleading.
Is there a built in way of doing this or via bundler? I'm assuming Bundler::GemHelper.install_tasks is close to what I'm after but I can't find helpful documentation.
EDIT: My current Rakefile.
It seems like the RubyGems designers intentionally left the option to run a script during installation... so I would say that the accepted way is to do the directory creation in the application.
The unix way is for the application to create the directory (vi and git do this).
FileUtils.mkdir_p is handy... it will save you from having to check if the directory is already there.

Add ruby script in gem to path

I just created a very simple rubygem which has only one file that takes a couple of parameters.
I want to automatically add this ruby script to the path when I install it so that i can use it from anywhere in terminal like:
myruby "param1" "param2"
Have a look at this documentation from RubyGems.
Adding an executable to a gem is a simple process. You just need to place the file in your gem’s bin directory, and then add it to the list of executables in the gemspec. Let’s add one for the Hola gem. First create the file and make it executable:
This article also seems to be pretty good and it covers the essential details of adding an executable.

How do I pass two build parameters to bundle config?

I'm trying to configure bundler such that building the mysql2 gem will pass the necessary parameters to extconf. Problem is, I can't figure out how to pass more than one parameter.
In my Gemfile, I just have:
gem mysql2, '= 0.3.11'
(There is some problem with the latest version which prevents compiling it at all, so I'm using 0.3.11 based on a recommendation I found on another post somewhere around here.)
I tried this:
bundle config build.mysql2 --with-mysql-include=C:\DevEnv\Tools\Ruby\mysql-connector-c-noinstall-6.0.2-winx64\include --with-mysql-lib=C:\DevEnv\Tools\Ruby\mysql-connector-c-noinstall-6.0.2-winx64\lib
I also tried quoting the parameters into a single parameter:
bundle config build.mysql2 "--with-mysql-include=C:\DevEnv\Tools\Ruby\mysql-connector-c-noinstall-6.0.2-winx64\include --with-mysql-lib=C:\DevEnv\Tools\Ruby\mysql-connector-c-noinstall-6.0.2-winx64\lib"
I can tell it isn't working because gem is showing me the command-line which is actually being used, and then the build fails because it can't provide the lib):
C:/DevEnv/Tools/Ruby/Ruby200-x64/bin/ruby.exe extconf.rb --with-mysql-include=C:\DevEnv\Tools\Ruby\mysql-connector-c-noinstall-6.0.2-winx64\include
If I provide just the --with-mysql-lib parameter or swap the order of the parameters, the build passes on looking for the lib but fails on a missing include instead.
If I pass the same flags to gem directly, that works fine. But that won't be terribly great when it comes time to deploy.
How are other people doing this?
PS a binary DLL would have been nice, but I guess they stopped doing that.
For the next poor sap that has to deal with this, the answer is a lot of quoting:
bundle config build.mysql2 "--with-mysql-include=\"C:\DevEnv\Tools\Ruby\mysql-connector-c-noinstall-6.0.2-winx64\include\" --with-mysql-lib=\"C:\DevEnv\Tools\Ruby\mysql-connector-c-noinstall-6.0.2-winx64\lib\""
bundle config --local --with-mysql-include 'C:\INC_PATH\include'
bundle config --local --with-mysql-lib 'C:\LIB_PATH\lib'
The above will store configuration directives in current directory in .bundle/config file. After you have these two directives run, try normal build install. Hope it helps.
More info.

How to develop a Ruby GEM without having to install it first?

I'm developing a GEM that I've forked and I'm trying to modify it slightly for my app.
I'm finding it difficult and time consuming because for every change I make I have to
uninstall
build
re-install
run the app
Is there an easier way of which doesn't require repeating all steps above?
To use it in some app using bundler
If what you mean is for using it in a app to test it / use it, you can just specify a path for your gem or even point to a git repo in the Gemfile http://gembundler.com/gemfile.html
Like
gem "mygem", :path => "~/code/gems/mygem"
To use it as a standalone gem. i.e: like rspec or rake that can run outside of an app.
Just specify the path to your gem binary when running the gem command, like:
$ ~/path_to_my_gem/bin/mygem some args
If you can execute inside your gem directory (i.e: the command does not create files in the current directory, or needs any specific files from the current directory), just do this:
$ ./bin/mygem some args
Note that this last one is just for future reference, I think it's not applicable in the OP context.
use require_relative to include your files:
require_relative 'yourgem/yourclass'
This is the documentation for the function.

Resources