Project specific RubyGems

2008-04-14

Using your distributions version of rubygems has some drawbacks:

  • root permission needed when installing gems
  • shared by all users
  • shared by all projects
  • when backing up a project, the system wide rubygems are often overlooked

Therefore, I’ve switched to project specific installations of rubygems (and one installation for everyday usage). By using modules it’s even easy to switch between projects.

First install ruby and some required dependencies:

sudo apt-get install ruby libyaml-ruby libzlib-ruby

Download and extract the latest rubygems version:

mkdir ruby_test
cd ruby_test
wget http://rubyforge.org/frs/download.php/35283/rubygems-1.1.1.tgz
tar zxvf rubygems-1.1.1.tgz

Create a modules file for easy loading:

#%Module1.0

set BASEDIR /path/to/ruby_test/rubygems

setenv RUBYOPT rubygems
setenv GEM_HOME ${BASEDIR}/gem_repository/
prepend-path PATH ${BASEDIR}/bin
prepend-path RUBYLIB ${BASEDIR}/lib

Note that the rubygems tarball extracted to rubygems-1.1.1, while the base directory is set to /path/to/ruby_test/rubygems. The rubygems-1.1.1 tree will be used to install rubygems into the latter directory.

If you named your module file ruby, you can now load it with:

module load ruby

With the environment variables set, install rubygems:

cd rubygems-1.1.1
ruby setup.rb --prefix=/path/to/ruby_test/rubygems

and clean up:

cd ../
rm -rf rubygems-1.1.1.tgz rubygems-1.1.1.

From this point on, you can use your newly installed rubygems, e.g. for installing wirble (tab completion and syntax coloring in irb).

gem list -r
gem install wirble

The RubyGems User Manual provides more information if needed.

Managing environment variables with modules

2008-03-05

When dealing with different versions of a program (e.g. uclibc or glibc based cross compilers), you sometimes want to easily switch between them. In the past I used small env.sh files which contained the necessary additions to PATH and other environment settings. Because settings were never undone, this sometimes led to difficult to find problems.

When a former colleague showed me modules, these problems became a thing of the past: whenever I come to a situation were I previously wrote an env.sh or changed my .bashrc, I now write a modulefile. It’s a pity this software isn’t packaged inside debian (or I must have overlooked it). Therefore a quick installation guide:

wget http://heanet.dl.sourceforge.net/sourceforge/modules/modules-3.2.6.tar.bz2
tar xjvf modules-3.2.6.tar.bz2
cd modules-3.2.6
./configure
make
sudo make install

And add the following to your ~/.bashrc

. /usr/local/Modules/3.2.6/init/bash
module use ~/modules/

~/modules is the directory where I keep my modulefiles. For the codesourcery crosscompilers I currently have 2 files:

  • cross-gcc/arm-2007q3-53-arm-none-eabi-i686-pc-linux-gnu

    #%Module1.0
    setenv ARCH arm
    setenv CROSS_COMPILE arm-none-eabi-
    prepend-path PATH /home/jan/no_backup/tools/arm-2007q3-53-arm-none-eabi-i686-pc-linux-gnu/arm-2007q3/bin/
  • cross-gcc/arm-2007q3-51-arm-uclinuxeabi

    #%Module1.0
    setenv ARCH arm
    setenv CROSS_COMPILE arm-uclinuxeabi-
    prepend-path PATH /home/jan/no_backup/tools/arm-2007q3-51-arm-uclinuxeabi-i686-pc-linux-gnu/arm-2007q3/bin

Now I can use:

module avail
module load cross-gcc/arm-2007q3-51-arm-uclinuxeabi
module list
module unload cross-gcc

having fun with sed

2008-02-11

I wanted to convert a whole bunch of scripts from a c-like syntax into python scripts. Along came sed…

cat > /tmp/convert.sed <<EOF
# Remove ; at end of line
s/;$//g

# Remove white space in front of lines (python indentation)
s/^[[:space:]]*//g

# Convert // styled comments to #
s+//+#+g

# Comment out /* styled comments */
\/\*/,/\*\// {
  s/^/# /g
}

# if else statements
# Not all statements work correctly yet, e.g.
# statements with "else" inside them (something_else();)
/^[^#]*else/,/}/ {
   s/ *else/else:/
   s/{//
   /else/! { s/}// }
   /else/! { s/^/   / }
}

/^ *if/,/}/ {
  s/if *(\(.*\))/if \1:/
  s/{//
  /if/! { /}/! { s/^/   / } }
  s/}//
}

# pythonify for loops
/^ *for/,/}/ {
   s/for *( *int *\(..*\) *= *\(.*\) *; *\1 *< *\(..*\) *; *\1++ *)/for \1 in range(\2,\3):/
   s/}//
   s/{//
   /for/! {
     s/^/   /
   }
}
EOF

cat > /tmp/example.c <<EOF
// Let's start with something simple
  some_line_with_space_before();

/*
 * here we do something different
 */
if(foo()) {
not_wel_indented_here();
} else {
foo();
}

for(int i = 0; i < 10; i++) {
  more_stuff(i);
}
EOF

sed -f /tmp/convert.sed < /tmp/example.c

It was the first time I needed block statements. It sure is a powerful language.

smiley in bash prompt

2008-02-07

After the geekdinner of last Tuesday, I couldn’t resist creating my own blog.

As an appetizer, I’ll start with some code snippets I’ve found very usefull. For example the part of my .bashrc which configures the prompt:

smiley() {
    ret_val=$?
    if [ "$ret_val" = "0" ]
    then
        echo ":)"
    else
        echo ":( ($ret_val)"
    fi
}
Green="\033[0;32m"
Yellow="\033[1;33m"
Normal="\033[0m"
PS1="\[$Yellow\]\u@\h\[$Normal\]:\[$Green\]\w \$(smiley) \[$Normal\]"

I always use this because:

  • the coloring makes it easy to see where my previous command started
  • the smiley quickly shows me if and how the previous program exited