[ANN] - install.rb hack # 42

this bloody hack makes install.rb handle user defined bindir (-b) and
auto-shebangifies any ruby programs found in the ./bin dir while installing
using the path to the ruby interpreter used for the install or the one named
with the -r switch.

essentially this allows you to write your scripts as in

   #!/my/crazy/local/path/to/ruby

   ...

and they will be installed as

   #!/users/path/to/ruby/used/with/install.rb
   #!/my/crazy/local/path/to/ruby

   ...

eg. the user's path to ruby will be added to the program and your script
appended vebetim.

i don't know who originally wrote install.rb or where i got it so thanks to
original author and here's the hack:

#!/usr/bin/env ruby
require 'rbconfig'
require 'find'
require 'ftools'
require 'tempfile'
include Config

LIBDIR = "lib"
LIBDIR_MODE = 0644

BINDIR = "bin"
BINDIR_MODE = 0755

$srcdir = CONFIG["srcdir"]
$version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
$libdir = File.join(CONFIG["libdir"], "ruby", $version)
$archdir = File.join($libdir, CONFIG["arch"])
$site_libdir = $:.find {|x| x =~ /site_ruby$/}
$bindir = CONFIG["bindir"]
$ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME']
$ruby = File.join($bindir, $ruby_install_name || 'ruby')

if !$site_libdir
   $site_libdir = File.join($libdir, "site_ruby")
elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
   $site_libdir = File.join($site_libdir, $version)
end

def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
#{{{
   path =
   dir =
   Find.find(srcdir) do |f|
     next unless FileTest.file?(f)
     next if (f = f[srcdir.length+1..-1]) == nil
     next if (/CVS$/ =~ File.dirname(f))
     path.push f
     dir |= [File.dirname(f)]
   end
   for f in dir
     next if f == "."
     next if f == "CVS"
     File::makedirs(File.join(destdir, f))
   end
   for f in path
     next if (/\~$/ =~ f)
     next if (/^\./ =~ File.basename(f))
     unless bin
       File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
     else
       from = File.join(srcdir, f)
       to = File.join(destdir, f)
       shebangify(from) do |sf|
         $deferr.print from, " -> ", File::catname(from, to), "\n"
         $deferr.printf "chmod %04o %s\n", mode, to
         File::install(sf, to, mode, false)
       end
     end
   end
#}}}
end
def shebangify f
#{{{
   open(f) do |fd|
     buf = fd.read 42
     if buf =~ %r/^\s*#\s*!.*ruby/o
       ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
       begin
         fd.rewind
         ftmp.puts "#!#{ $ruby }"
         while((buf = fd.read(8192)))
           ftmp.write buf
         end
         ftmp.close
         yield ftmp.path
       ensure
         ftmp.close!
       end
     else
       yield f
     end
   end
#}}}
end
def ARGV.switch
#{{{
   return nil if self.empty?
   arg = self.shift
   return nil if arg == '--'
   if arg =~ /^-(.)(.*)/
     return arg if $1 == '-'
     raise 'unknown switch "-"' if $2.index('-')
     self.unshift "-#{$2}" if $2.size > 0
     "-#{$1}"
   else
     self.unshift arg
     nil
   end
#}}}
end
def ARGV.req_arg
#{{{
   self.shift || raise('missing argument')
#}}}
end

···

#
# main program
#

libdir = $site_libdir
bindir = $bindir

begin
   while switch = ARGV.switch
     case switch
     when '-d', '--destdir'
       libdir = ARGV.req_arg
     when '-l', '--libdir'
       libdir = ARGV.req_arg
     when '-b', '--bindir'
       bindir = ARGV.req_arg
     when '-r', '--ruby'
       $ruby = ARGV.req_arg
     else
       raise "unknown switch #{switch.dump}"
     end
   end
rescue
   STDERR.puts $!.to_s
   STDERR.puts File.basename($0) +
     " -d <destdir>" +
     " -l <libdir>" +
     " -b <bindir>"
     " -r <ruby>"
   exit 1
end

install_rb(LIBDIR, libdir, LIBDIR_MODE)
install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)

-a
--

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
A flower falls, even though we love it;
and a weed grows, even though we do not love it. --Dogen

===============================================================================

Ara.T.Howard wrote:

i don't know who originally wrote install.rb or where i got it so thanks
to original author and here's the hack:

I believe install.rb is now setup.rb:
http://raa.ruby-lang.org/project/setup/

to my knowledge setup.rb is distinct, and probably more fully featured, than
install.rb.

in either case i've been using intall.rb and it doesn't solve the 'shebang'
problem - does setup.rb handle the shebang issue? if so i'll probably start
using it - i use install.rb because i have been. :wink:

cheers.

-a

···

On Tue, 21 Sep 2004, Tim Hunter wrote:

Ara.T.Howard wrote:

i don't know who originally wrote install.rb or where i got it so thanks
to original author and here's the hack:

I believe install.rb is now setup.rb:
http://raa.ruby-lang.org/project/setup/

--

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
A flower falls, even though we love it;
and a weed grows, even though we do not love it. --Dogen

===============================================================================

I'm not sure, but I think setup.rb (because it is more fully featured) has
replaced install.rb.

The reason I'm not sure is that I am not much of a packaging person. :confused:
My packaging tends to consist of "here's a tgz, unpack it and put it wherever
you want." Yes, I need to break that habit.

Hal

···

Ara.T.Howard@noaa.gov wrote:

to my knowledge setup.rb is distinct, and probably more fully featured, than
install.rb.

in either case i've been using intall.rb and it doesn't solve the 'shebang'
problem - does setup.rb handle the shebang issue? if so i'll probably start
using it - i use install.rb because i have been. :wink:

I use my own variation of install.rb, but have wanted to use setup.rb instead
b/c it seems to be more robust and feature rich. BUT it clutters up the main
directory more (e.g. 'setup.rb' plus 'config.save' and 'InstalledFiles'), and
it also is not as simple to use, requiring three operations:

  ruby setup.rb config
  ruby setup.rb setup
  ruby setup.rb install

Lastly, install.rb is small enough to easily be placed in a rakefile, which
makes my life easir. Say you're currently in a test dir running a test, you
can fix a bug and run 'rake install' w/o cd'ing up the main dir. (Sure
there's many ways to deal with such things, but that's how I do it.)

If setup.rb ever addressed these issues then I would switch, but until then
install.rb works fine for my Ruby projects.

I like your modification too, I will use it :slight_smile:

Thanks!
T.

···

On Monday 20 September 2004 08:54 pm, Ara.T.Howard@noaa.gov wrote:

On Tue, 21 Sep 2004, Tim Hunter wrote:
> Ara.T.Howard wrote:
>> i don't know who originally wrote install.rb or where i got it so thanks
>> to original author and here's the hack:
>
> I believe install.rb is now setup.rb:
> http://raa.ruby-lang.org/project/setup/

to my knowledge setup.rb is distinct, and probably more fully featured,
than install.rb.

in either case i've been using intall.rb and it doesn't solve the 'shebang'
problem - does setup.rb handle the shebang issue? if so i'll probably
start using it - i use install.rb because i have been. :wink:

--
( o _ カラチ
// trans.
/ \ transami@runbox.com

I don't give a damn for a man that can only spell a word one way.
-Mark Twain

Ara.T.Howard wrote:

i don't know who originally wrote install.rb or where i got it so thanks
to original author and here's the hack:

I believe install.rb is now setup.rb:
http://raa.ruby-lang.org/project/setup/

to my knowledge setup.rb is distinct, and probably more fully featured,
than install.rb.

in either case i've been using intall.rb and it doesn't solve the 'shebang'
problem - does setup.rb handle the shebang issue? if so i'll probably
start using it - i use install.rb because i have been. :wink:

I use my own variation of install.rb, but have wanted to use setup.rb
instead b/c it seems to be more robust and feature rich. BUT it clutters up
the main directory more (e.g. 'setup.rb' plus 'config.save' and
'InstalledFiles'), and it also is not as simple to use, requiring three
operations:

ruby setup.rb config
ruby setup.rb setup
ruby setup.rb install

exactly.

Lastly, install.rb is small enough to easily be placed in a rakefile, which
makes my life easir. Say you're currently in a test dir running a test, you
can fix a bug and run 'rake install' w/o cd'ing up the main dir. (Sure
there's many ways to deal with such things, but that's how I do it.)

i'll look into that - i've never used rake. it seems very cool though.

If setup.rb ever addressed these issues then I would switch, but until then
install.rb works fine for my Ruby projects.

exactly again.

I like your modification too, I will use it :slight_smile:

it's been done the typical way - write - run once - seems to work - done!

in my office we call it the design-implement-test-production phase, it's how
nearly all of our important work gets done. :wink:

-a

···

On Tue, 21 Sep 2004, trans. (T. Onoma) wrote:

On Monday 20 September 2004 08:54 pm, Ara.T.Howard@noaa.gov wrote:

On Tue, 21 Sep 2004, Tim Hunter wrote:

--

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
A flower falls, even though we love it;
and a weed grows, even though we do not love it. --Dogen

===============================================================================

put your files in a subdir called 'lib' within your tarball. put install.rb
at the same level

   my_package/README
   my_package/install.rb
   my_package/lib/foo.rb
   my_package/lib/bar.rb

   tar cvfz my_package.tgz my_package/

done.

it's all i ever do - it's too not much, but 'just enough'.

cheers.

-a

···

On Tue, 21 Sep 2004, Hal Fulton wrote:

Ara.T.Howard@noaa.gov wrote:

to my knowledge setup.rb is distinct, and probably more fully featured,
than
install.rb.

in either case i've been using intall.rb and it doesn't solve the 'shebang'
problem - does setup.rb handle the shebang issue? if so i'll probably
start
using it - i use install.rb because i have been. :wink:

I'm not sure, but I think setup.rb (because it is more fully featured) has
replaced install.rb.

The reason I'm not sure is that I am not much of a packaging person. :confused:
My packaging tends to consist of "here's a tgz, unpack it and put it wherever
you want." Yes, I need to break that habit.

--

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
A flower falls, even though we love it;
and a weed grows, even though we do not love it. --Dogen

===============================================================================

Hi,

  In mail "Re: [ANN] - install.rb hack # 42"

I use my own variation of install.rb, but have wanted to use setup.rb instead
b/c it seems to be more robust and feature rich. BUT it clutters up the main
directory more (e.g. 'setup.rb' plus 'config.save' and 'InstalledFiles'), and
it also is not as simple to use, requiring three operations:

  ruby setup.rb config
  ruby setup.rb setup
  ruby setup.rb install

Try latest version of setup.rb (3.3.0).
you are only required to type:

  ruby setup.rb

It automatically invokes config, setup, then install.

There is one more new feature, `all':

  ruby setup.rb all --prefix=$HOME

This also invokes config-setup-install but you can invoke
setup.rb with any config options.

Minero Aoki

···

"trans. (T. Onoma)" <transami@runbox.com> wrote:

The reason I'm not sure is that I am not much of a packaging person. :confused:
My packaging tends to consist of "here's a tgz, unpack it and put it wherever
you want." Yes, I need to break that habit.

Don't be too hard on yourself. I've been known (as recently as 6 months
or so ago) to say:

        Here's the IP if the FTP server. Use "guest" and something that
        looks like an e-mail address. The file names should be pretty
        self explanatory. Enjoy.

-- MarkusQ

That's great!

That means it's almost there. Now if I can only integrate it with Rake, I'll
be a happy camper. Hmm... how best to do?

Also, minor question: why is config.save downcase, but InstalledFiles is
camelcase?

Thanks again,
T.

···

On Monday 20 September 2004 11:27 pm, Minero Aoki wrote:

Try latest version of setup.rb (3.3.0).
you are only required to type:

  ruby setup.rb

It automatically invokes config, setup, then install.

There is one more new feature, `all':

  ruby setup.rb all --prefix=$HOME

This also invokes config-setup-install but you can invoke
setup.rb with any config options.

Oh. Almost forgot. Does setup.rb have Ara's hack #42 ?

···

On Monday 20 September 2004 11:27 pm, Minero Aoki wrote:

Try latest version of setup.rb (3.3.0).

--
( o _ カラチ
// trans.
/ \ transami@runbox.com

I don't give a damn for a man that can only spell a word one way.
-Mark Twain

It has been doing shebang correction since mmm the beginning of time :slight_smile:

···

On Tue, Sep 21, 2004 at 01:19:48PM +0900, trans. (T. Onoma) wrote:

On Monday 20 September 2004 11:27 pm, Minero Aoki wrote:
> Try latest version of setup.rb (3.3.0).

Oh. Almost forgot. Does setup.rb have Ara's hack #42 ?

--
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Hi,

  In mail "Setup+ (was: install.rb hack # 42 <-- TMOLTUE ;)"

···

"trans. (T. Onoma)" <transami@runbox.com> wrote:

Also, minor question: why is config.save downcase, but InstalledFiles is
camelcase?

Because capital filenames are shown before lower case filenames
in UNIX ls. I think that users may want to use InstalledFiles,
but not config.save.

By the way, config.save is now renamed to ".config".

Regards,
Minero Aoki

i know it's supposed to - but i can't seem to make it:

   jib:~/eg/ruby/tmp > for f in bin/*;do file $f;done
   bin/a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), not stripped
   bin/a.pl: a perl script text executable
   bin/a.rb: a ruby script text executable

   jib:~/eg/ruby/tmp > ruby setup.rb config --ruby-path=/dmsp/reference/bin/ruby --bin-dir=/home/ahoward/bin
   ---> bin
   <--- bin

   jib:~/eg/ruby/tmp > ruby setup.rb setup
   ---> bin
   <--- bin

   jib:~/eg/ruby/tmp > ruby setup.rb install
   ---> bin
   mkdir -p /home/ahoward/bin/
   install a.out /home/ahoward/bin/
   install a.rb /home/ahoward/bin/
   install a.pl /home/ahoward/bin/
   <--- bin

   jib:~/eg/ruby/tmp > cat /home/ahoward/bin/a.rb
   #!/usr/bin/env ruby
   puts 42

?? what am i doing wrong ??

but:

   jib:~/eg/ruby/tmp > ruby install.rb -b ~/bin/
   bin/a.pl -> /home/ahoward/bin/a.pl
   chmod 0755 /home/ahoward/bin/a.pl
   bin/a.rb -> /home/ahoward/bin/a.rb
   chmod 0755 /home/ahoward/bin/a.rb
   bin/a.out -> /home/ahoward/bin/a.out
   chmod 0755 /home/ahoward/bin/a.out

   jib:~/eg/ruby/tmp > cat /home/ahoward/bin/a.rb
   #!/dmsp/reference/bin/ruby
   #!/usr/bin/env ruby
   puts 42

also, the commandline parsing in setup.rb is very dangerous.

when i was playing around i did this:

   jib:~/eg/ruby/tmp > ruby setup.rb config --ruby-path=`which ruby` --bin-dir ~/bin
   config: --bin-dir requires argument
   Try 'ruby setup.rb --help' for detailed usage.

oops, forget the '='s

   jib:~/eg/ruby/tmp > ruby setup.rb config --ruby-path=`which ruby` --bin-dir=~/bin
   ---> bin
   <--- bin

   jib:~/eg/ruby/tmp > ruby setup.rb setup
   ---> bin
   <--- bin

looks good

   jib:~/eg/ruby/tmp > ruby setup.rb install
   ---> bin
   mkdir -p ~/bin/
   install a.out ~/bin/
   install a.rb ~/bin/
   install a.pl ~/bin/
   ---> bin/~
   mkdir -p ~/bin/~
   ---> bin/~/bin
   mkdir -p ~/bin/~/bin
   install a.out ~/bin/~/bin
   install a.rb ~/bin/~/bin
   install a.pl ~/bin/~/bin
   ---> bin/~/bin/~
   mkdir -p ~/bin/~/bin/~
   ---> bin/~/bin/~/bin
   mkdir -p ~/bin/~/bin/~/bin
   setup.rb:396:in `mkdir_p': Interrupt from setup.rb:394:in `each_index'
           from setup.rb:394:in `mkdir_p'
           from setup.rb:1159:in `install_files'
           from setup.rb:1140:in `install_dir_bin'
           from setup.rb:1292:in `__send__'
           from setup.rb:1292:in `traverse'
           from setup.rb:1290:in `dive_into'
           from setup.rb:1290:in `traverse'
            ... 25 levels...
           from setup.rb:644:in `__send__'
           from setup.rb:644:in `invoke'
           from setup.rb:616:in `invoke'
           from setup.rb:1323

yikes - i've started making a recursive directory structure. this was my own
fault: because i said

   --bin-dir=~/bin

the shell could not expand the '~' and i gave it '~/bin' instead of
'/home/ahoward/bin' as bin-dir. for some reason this resulted in the the
recursive dir hierarchy being made - i haven't checked to figure out why. my
point is that configure lines will often contain shell meta characters, and
that having to slam them up against the '=' sign can result in suprising
behaviour. it would probably be better if setup.rb used getoptlong or
optparse for this bit of code since they allow the

   --bin-dir ~/bin

syntax.

that being said, setup.rb is about a million times better than install.rb; if
i can figure out the shebang problem i will probably migrate too.

regards.

-a

···

On Tue, 21 Sep 2004, Mauricio [iso-8859-1] Fernández wrote:

On Tue, Sep 21, 2004 at 01:19:48PM +0900, trans. (T. Onoma) wrote:

On Monday 20 September 2004 11:27 pm, Minero Aoki wrote:

Try latest version of setup.rb (3.3.0).

Oh. Almost forgot. Does setup.rb have Ara's hack #42 ?

It has been doing shebang correction since mmm the beginning of time :slight_smile:

--

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
A flower falls, even though we love it;
and a weed grows, even though we do not love it. --Dogen

===============================================================================

Hi,

  In mail "Setup+ (was: install.rb hack # 42 <-- TMOLTUE ;)"

> Also, minor question: why is config.save downcase, but InstalledFiles is
> camelcase?

Because capital filenames are shown before lower case filenames
in UNIX ls. I think that users may want to use InstalledFiles,
but not config.save.

I see. I wonder if there's a constant I can change? I'll have to look. I'd
might prefer it be called 'FILES' instead, to go along with my other files,
like README, TODO, etc.

By the way, config.save is now renamed to ".config".

Getting better all the time! :slight_smile:

Thank you very much Minero Aoki,
T.

···

On Wednesday 22 September 2004 04:10 am, Minero Aoki wrote:

    "trans. (T. Onoma)" <transami@runbox.com> wrote:

--
( o _ カラチ (a place in Paki)
// trans.
/ \ transami@runbox.com

I don't give a damn for a man that can only spell a word one way.
-Mark Twain

>It has been doing shebang correction since mmm the beginning of time :slight_smile:

i know it's supposed to - but i can't seem to make it:

[...]

  jib:~/eg/ruby/tmp > cat /home/ahoward/bin/a.rb
  #!/usr/bin/env ruby

From setup.rb:

  # modify: #!/usr/bin/ruby
  # modify: #! /usr/bin/ruby
  # modify: #!ruby
  # not modify: #!/usr/bin/env ruby

that being said, setup.rb is about a million times better than install.rb;
if
i can figure out the shebang problem i will probably migrate too.

It works that way by design, but you could try to convince Minero Aoki
to change it, or just modify the associated regexp yourself:

  SHEBANG_RE = /\A\#!\s*\S*ruby\S*/

···

On Tue, Sep 21, 2004 at 11:45:05PM +0900, Ara.T.Howard@noaa.gov wrote:

--
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Hi,

  In mail "Re: [ANN] - install.rb hack # 42"

>> Oh. Almost forgot. Does setup.rb have Ara's hack #42 ?
>
> It has been doing shebang correction since mmm the beginning of time :slight_smile:

i know it's supposed to - but i can't seem to make it:

   jib:~/eg/ruby/tmp > cat /home/ahoward/bin/a.rb
   #!/usr/bin/env ruby

?? what am i doing wrong ??

setup.rb does not replace #!/usr/bin/env hack because
it is better than the abstract path, in many cases.
In the past day someone (I forget) asked me this feature.
When and only when you use abstract path to ruby,
setup.rb replaces shabeng.

Regards,
Minero Aoki

···

Ara.T.Howard@noaa.gov wrote:

this makes good sense - but i do think it there should be a flag to override
it. in any case you'll be happy to know that i'm in the process of switching
much of my packages over to setup.rb - nice work on that!

cheers.

-a

···

On Wed, 22 Sep 2004, Minero Aoki wrote:

Hi,

In mail "Re: [ANN] - install.rb hack # 42"
   Ara.T.Howard@noaa.gov wrote:

Oh. Almost forgot. Does setup.rb have Ara's hack #42 ?

It has been doing shebang correction since mmm the beginning of time :slight_smile:

i know it's supposed to - but i can't seem to make it:

   jib:~/eg/ruby/tmp > cat /home/ahoward/bin/a.rb
   #!/usr/bin/env ruby

?? what am i doing wrong ??

setup.rb does not replace #!/usr/bin/env hack because
it is better than the abstract path, in many cases.
In the past day someone (I forget) asked me this feature.
When and only when you use abstract path to ruby,
setup.rb replaces shabeng.

--

EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
PHONE :: 303.497.6469
A flower falls, even though we love it;
and a weed grows, even though we do not love it. --Dogen

===============================================================================