Install Homebrew from within a ruby script - ruby

I've created a ruby script that sets up a new mac.
Among other things it creates a .bash_profile, .gitconfig and configures various system settings such as displaying the full POSIX path as the Finder window title (super useful).
Mostly I'm running commands in backticks such as `defaults write com.apple.finder _FXShowPosixPathInTitle -bool true` the aforementioned full POSIX path as the Finder window title trick.
All this works just fine.
What I want to do is have this ruby script run the Homebrew installer too. The bash command for this is :
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
However this doesn't work when called using backticks.
So my question is how do I run another ruby script (which the Homebrew installer is) from within a ruby script?
And more specifically how would I kick off the web based interactive Homebrew installer (well you have to press return at least once) from within a ruby script and for it's output to show in the terminal?
I know that I could rewrite this all as bash script but I'd really rather keep it all within ruby.

Let's decompose what $ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" actually does:
download, via curl, the homebrew install ruby file. Since the command is surrounded by $(), it executes the command and passes the output to ruby.
execute the script via Ruby. The -e flag instructs Ruby to execute the script from the command line instead of loading a specified file.
Since we know that it's a ruby script, we can just do the following:
using Net::HTTP or some other ruby library, download, the homebrew install file.
eval() or otherwise execute the homebrew ruby script.
Of course, eval() is dangerous, especially with untrusted input, but you're already essentially running eval on the script anyways with the install command provided.
In script form that would be:
require 'net/http'
homebrew_uri = URI('https://raw.githubusercontent.com/Homebrew/install/master/install')
homebrew_script = Net::HTTP.get(homebrew_uri)
eval(homebrew_script)

Related

How to locally execute a ruby script hosted on github in single CLI command

Want to execute this script
on my laptop which has ruby already installed
so I first download the script office-thinner.rb and then run
sudo ruby office-thinner.rb
How can I avoid the 1st step of downloading of the file every time and in single command get the script and execute it?
Can wget, filestream and linux piping do the magic?
Either you go the full "bash run" and pipe the script into bash (or the shell of your choice), which will then also take into account all the stuff that happens when your shell executes (e.g. if you are using [rvm][1] it will make ruby being your selected ruby):
wget -O - https://gist.github.com/JackDrogon/53678a54a326b9aaf4102180eeb58cab | bash
Or, you give the script to the ruby interpreter yourself:
wget -O - https://gist.github.com/JackDrogon/53678a54a326b9aaf4102180eeb58cab | ruby
or
wget -O - https://gist.github.com/JackDrogon/53678a54a326b9aaf4102180eeb58cab | /usr/bin/ruby2.5 --verbose
In the later case you can also use options to ruby (e.g. switch on the JIT compiler, verbosity settings, etc.
In the first case, your shell will most likely only execute the script if it has the magical shebang at top (e.g. #/usr/bin/env ruby). In the second case, ruby will take whatever comes.

Shell Script Ruby Command Not Found

I have a shell script that is running under crontab that kicks back the error: "Ruby: Command not found" for the invocation of a Ruby script. I have no issue running this script when I invoke it through a terminal it is only when running under crontab that I have issues. Anyone have any thoughts?
EDIT: Using RVM, running RHEL.
/path/to/rvm 2.1 do /path/to/script.rb args...
because cron doesn't have your rvm settings, you need to start your script through rvm script (not rvm function) to explicitly choose a Ruby. (Obviously, replace 2.1 with whatever Ruby you want to execute under.)

RVM on Ruby Scripts

I need for a Ruby script to be run using an rvm-selected version. I cannot change how the script is invoked, but I can modify the script. The script starts with:
#!/usr/bin/env ruby
Now, based on some information I found (in this question, for example), I tried this:
#!/usr/bin/env rvm-shell ree-1.8.7-2012.02#gitorious
But this only gives me this error message:
/usr/bin/env: rvm-shell ree-1.8.7-2012.02#gitorious: No such file or directory
Now, rvm is available, because this works (but doesn't bring the required ruby/gemset):
#!/usr/bin/env rvm-shell
I've tried this as well:
#!/usr/local/rvm/bin/rvm-shell ree-1.8.7-2012.02#gitorious
But this doesn't bring in the environment ("gem", which is only installed inside that gemset, is not available, for example). If I run that on the command line itself, it does open a shell with the proper environment.
So, has anyone done something like this? How can I fix it?
Does this work?
#!/location/of/rvm/folder/rubies/ree-1.8.7-2012.02#gitorious/bin/ruby

How to run Ruby scripts in Geektool?

I want to run a Ruby script in Geektool that refreshes every 3 hours (so I set the refresh rate to 10,800 seconds) and the shell command in Geektool has this code in it:
ruby "/file.rb"
The file is located at root for convenience. Problem is, it won't run. I tried different commands, such as:
/Users/userhere/.rvm/rubies/ruby-1.9.3-p0/bin/ruby /file.rb
But it still doesn't work. I don't want it to use my /usr/bin/ruby installation (which, by default, is 1.8.7), I want it to use 1.9.3. So doing: /usr/bin/ruby "/file.rb" won't work for me.
In Terminal, if I run any of those commands they all work (except for the latter, because of dependencies) and my script works fine, but Geektool fails to even execute it. I tried with and without double quotes around the file name, even single quotes don't work.
Any help would be greatly appreciated.
I needed an rvm gemset as well; I created a shell file:
/Users/Dave/.rvm/bin/rvm use 1.9.3-p0 > /dev/null
/Users/Dave/.rvm/rubies/ruby-1.9.3-p0/bin/ruby ~/foo.rb
With that shell file (which happens to reside in a directory off my ~) as the shell command it works fine.
Without the full paths to each command it doesn't work. GeekTool doesn't run your .bash_profile AFAICT. Also not sure that running an rvm Ruby w/o using it would do what you want anyway.

Cannot execute RVM shell commands in ruby

Long time lurker, first time poster!
Goal
My ultimate goal is to make a Rake setup script to setup my rvm environment stuff (I need to dynamically create gemsets, install gems to those gemsets, and run ruby scripts within those gemsets).
Problem
I need to setup rvm in the shell that I'm executing rvm commands in. The basic idea is to source the rvm scripts as outlined here.
The problem arises when I try and source the rvm script when executing a shell command within ruby. Its well documented that rvm only supports bash, but ruby doesn't seem to be using bash when executing shell commands.
What I've Tried
I've tried all the methods to execute shell commands listed here to no avail. I'll use the 'exec' method below for simplicity.
It seems that although ruby thinks its using the bash shell to execute these commands ... it is not. Observe!
exec 'echo $SHELL'
=> /bin/bash
But
exec 'source ~/.rvm/scripts/rvm; type rvm | head -1;'
=> sh: source: not found
=> rvm is ~/.rvm/bin/rvm
Which tells me that ruby is really using /bin/sh not /bin/bash (that output should return rvm is a function). I even went so far as to print the ruby env stuff, and ENV[SHELL] is '/bin/bash'
'Brute Force' Solution
I do have a workaround, but its really kludgy (this would necessitate that I 'AND' all of the commands together):
exec 'echo \'source ~/.rvm/scripts/rvm && type rvm | head -1\' | /bin/bash'
I'd like to avoid using shell scripts if possible -- it seems reasonable that I can accomplish this within ruby.
As it happens, RVM actually exposes a Ruby API that's included by default. Add $HOME/.rvm/lib to your $LOAD_PATH; you can now use require 'rvm'.
As far as I can tell, the main documentation for this is in the source files themselves (a summary is in rvm.rb).
Now you can write Ruby scripts that manipulate RVM, like this:
require 'rvm'
env = RVM.current
env.gemset.create('newgemset')
And so on.
Call bash with the -c parameter:
command = 'source ~/.rvm/scripts/rvm; type rvm | head -1'
exec "bash -c #{command.inspect}"

Resources