How to Automatically Log In Using SSH On Dreamhost

Posted by ben on September 25, 2009

If you build web sites and host (or want to host) them on Dreamhost, you will be well aware that at some stage you will be using SSH to log in and out of your hosting server. If you have many sites then this gradually becomes tiresome – especially if you use tools like Capistrano to deploy your applications, as you will constantly have to re-enter your passwords.

Fortunately you can certify your local computer, such that it will automatically enter the SSH password for you. Here are some quick tips on how to do it.

Generate Your Security Keys

Generate your private/public key pair on your local machine, from your home directory:

ssh-keygen -d

Now DON'T enter a password - just press return, otherwise you 
will still need to enter a password, when you log in with SSH.

Set Privileges And Copy The Public Key To Your Server

Use the following command to copy your newly created ~/.ssh/id_dsa.pub file up to the server you wish to remote log in to. Note that this command below will set the permissions both locally and remotely. The remote .ssh/* needs to be set to 0600.

N.B. Replace USERNAME and MY_DOMAIN with your own username and domain.

ssh USERNAME@ftp.MY_DOMAIN.COM 'test -d .ssh || mkdir -m 0700 .ssh ; cat >> .ssh/authorized_keys && chmod 0600 .ssh/*' < ~/.ssh/id_dsa.pub

  Enter the normal USERNAME password.

Log In Using SSH

Now log in using:

ssh USERNAME@ftp.MY_DOMAIN.COM

You shouldn't neet to enter a password.

Taking It Further

To simplify things even further you can modify the ~/.ssh/config file such:

Host NICKNAME
Hostname MY_DOMAIN.COM
User USERNAME

Now you only need to type:

ssh NICKNAME

And you will be automatically logged in.

Create Sinatra Partials The Rails Way

Posted by ben on September 25, 2009

This is just a quick post. I’ve been playing around with the Sinatra micro web framework, and have to say that it is excellent. It really is the perfect tool for rapidly creating small and useful Ruby micro-sites.

Being small and lightweight it doesn’t have many of the features of larger frameworks like Ruby on Rails. One of the features I’ve begun to need is the handling of Rails like partials.

Notably I need to pass both local variables and collections to the partial code and have the partials rendered accordingly. I started implementing my own version, and then came across a nice little Github project: Sinatra-Helpers by sbfaulkner.

Anyway here is the code he uses for Sinatra partials:

def haml_partial(name, options = {})
  item_name = name.to_sym
  counter_name = "#{name}_counter".to_sym
  if collection = options.delete(:collection)
    collection.enum_for(:each_with_index).collect do |item,index|
      haml_partial name, options.merge(:locals => {item_name => item, counter_name => index+1})
    end.join
  elsif object = options.delete(:object)
    haml_partial name, options.merge(:locals => {item_name => object, counter_name => nil})
  else
    haml "_#{name}".to_sym, options.merge(:layout => false)
  end
end

You can use his project or if you just need this feature just pop this code into your Sinatra helpers file application_helper.rb:

helpers do

  def partial(name, options = {})
    item_name = name.to_sym
    counter_name = "#{name}_counter".to_sym
    if collection = options.delete(:collection)
      collection.enum_for(:each_with_index).collect do |item, index|
        partial(name, options.merge(:locals => { item_name => item, counter_name => index + 1 }))
      end.join

    elsif object = options.delete(:object)
      partial name, options.merge(:locals => {item_name => object, counter_name => nil})
    else
      haml "_#{name}".to_sym, options.merge(:layout => false)
    end
  end
end

Now you can call the partial from a your page e.g. index.haml

= partial("mypartial", :locals => {:var1 => "value 1", :var2 => "value 2 and so on"})

Create a partial in the same directory as the calling page. Note that this code doesn’t like filenames truncated with a ‘-’, so avoid this if possible. Also like in Rails your partials should start with an underscore. e.g. _mypartial.haml

To access the variable from this partial simply call the local variable name in your code:

%h2 
  This is var1:
  = var1

%p 
  And this is var2:
  = var2

Handling collections, again, is similar to the way Rails handles partial collections. From your page call the partial with a collection such as:

= partial("listitem", :collection => ["item 1", "item 2 and so on"])

Now in the _listitem.haml partial code simply provide the partial name as a variable or the partialname with _counter for the increment number e.g.

%li
  = listitem
  is the 
  = listitem_counter
  in this array

Anyway all pretty basic stuff but I hope it helps the casual Sinatra surfer.

Goodluck.

18 Useful bash scripts for web developers 46

Posted by ben on June 05, 2009

Using bash scripts to become a more efficient web developer

Here are a few scripts, that I find really useful for speeding up my web development time.

I’ve been building up this list as I needed to use them – so they maybe a little raw.

For example often clients send me images with filenames that don’t match my naming standard, so running the appropriate script really helps keep me focussed on the job in hand and not waste too much time reformatting filenames etc.

Finally if you have any useful little bash scripts why don’t you add them to the comments below?

Bash script to append a .txt extension to a filename

Iterate over the current directory, get all files with .log and append .txt to the end of the entire filename:

for i in *.log*; do mv "$i" "$i.txt"; done

Script to make filenames lowercase

Converts all the file names in a directory and converts them to lowercase.

echo version:

for i in *.log*; do echo mv \"$i\" \"`echo $i| tr [A-Z] [a-z]`\"; done

real version:

for i in *.txt; do mv "$i" "`echo $i| tr [A-Z] [a-z]`"; done

Quick note on how to use grep to search for a string in file

-o print Only the matched parts of a matching line, with each part on a separate line. -H print the filename for each match. -n prefix each line of output with the 1 based line number. -R, -r recursively read all files under subdirectories.

grep -oHnr "some pattern"  *.txt

{txt,log} this globs the file extensions together. 2>/dev/null this passes all errors to a blackhole, so that they won’t be displayed.

grep 123741 ./adapter_logs/*.{txt,log} 2>/dev/null

Find all occurrences of 123741 in all .txt and .log files in all subdirectories.

for i in 'find . -type d'; do grep 123741 $i/*.{txt,log}; done 2>/dev/null

List all files that match this regular expression in the current direcory

All files with the number 5 in their name.

ls | grep -e .*5.*

Bash script to check whether a tag exists in a subversion repository

svn ls http://www.mysvnserver.co.uk/myproject/tags | grep mytag-0.7.0.1/

The [ ] is known as a Test, by default it tests integers Also to end an if statement you use fi

if [ 1 = 1 ] ; then echo YES; else echo NO; fi

if [ "`svn ls http://mysvnserver/mysvnrepository/myproject/tags | grep R-9.20.400.0/`" = "R-9.20.400.0/" ]; then echo YES; else echo NO; fi

Note need the / in the evaluation part of “it-0.9.0.7/”, don’t really need it in grep it-0.9.0.7/

$ if [ "`svn ls http://www.mysvnserver.co.uk/myproject/tags | grep it-0.7.0.1/`" = "it-0.7.0.1/" ]; then echo YES; else echo NO; fi

Quick note on how to increment a variable, in a bash script

j=0; j=$(($j+1))

incrementing in a loop

j=0;for i in *.txt; do echo "some_file_"$j".txt"; j=$(($j+1)); done

Using a bash for loop to list all text files and append whoopee

for i in *.txt; do echo $i"whoopee"; done

Change all filenames to be a specific incremented name, starting from file 16

j=16;for i in *.jpg; do mv "$i" "gallery_"$j".jpg"; j=$(($j+1)); done;ls

Script to loop through all .txt filenames and make them lower case

for i in *.txt; do mv "$i" "`echo $i| tr [A-Z] [a-z]`"; done

Get all JPG files and create the appropriate HTML list tags for them and add them to a file

Create an HTML version:

for i in *.jpg; do echo "\t<li>\r\t\t<img src='images/$i' alt='' />\r\t</li>"; done > list_items.html

Create a HAML version:

for i in *.jpg; do echo "\t%li\r\t\t%img{ :src => 'images/$i', :alt => '' }\r"; done > imgs.haml

Batch change a misspelled filename of certain files, using string replacement

for i in aples*.jpg; do mv $i ${i/aples/apples} ; done

Script to batch create files based on filenames in a file

Create a file called something like “my_files.txt” with the following content:

archive_error_112480_0040.txt archive_error_114390_0043.txt etc…

Commands:

for i in `sed -n -e 'p' my_files.txt`; do mkdir a_test/$i; done
or
while read x; do touch $x; done < my_files.txt
or
cat my_files.txt | xargs touch
(xargs passes each line as an argument into EACH touch)

Using bash Expansions, and allow escapes

-e is an undocumented flag that allows escapes Expansion ${command/parameter/substitution} everything else needs to be escaped.

echo -e ${PATH//\:/\\n}

Executing a .bash_script after making changes

source .bash_profile
or
. .bash_profile

NB: you can ‘include’ other bash .sh scripts in a .bash_profile file by using ’source’ or ‘.’

Quick tip on using curl for downloading files off the web

Use -O to name the remote file, curl will save it locally but remove the rest of the path.

curl -O http://rubyforge-files.ruby-forum.com/rubygems/rubygems-0.9.0.tgz

Bash command for testing the existence of files and directories

If a directory does NOT exist create it

[ -d "/var/cache/git" ] || mkdir /var/cache/git

If a file exists echo a message:

[ -f "./new_file.txt" ] && echo "its there"

Bash command to remove spaces from filenames

for i in *.html; do mv "$i" "`echo $i| tr -d ' '`"; done

replace spaces for underscores

for i in *.html; do mv "$i" "`echo $i| tr ' ' '_'`"; done

Vim regex to replace spaces in images file names of ah HTML page

:%s:\(images\/\)\(\w\+\)\s\(\w\+\.jpg\):\1\2_\3:g

Copy text to the clipboard

echo 'hello world'|pbcopy
cmd + v

Conclusion

Some of these are quite basic but useful none-the-less, please add your own to the comments below. Many thanks, and good luck.

Updated…

Script function for .bash_profile to cd to the last opened finder location

This is a script written by a colleague. James Power. Add the following function to your .bash_profile in Apple OSX. Now open a directory in Finder, then open terminal and type cdf, your terminal will now change directory to the same one as the last Finder opened.

# function to change directory to the one set in the last opened finder.
cdf () {
   currFolderPath=$( /usr/bin/osascript <<"         EOT"
       tell application "Finder"
           try
               set currFolder to (folder of the front window as alias)
           on error
               set currFolder to (path to desktop folder as alias)
           end try
           POSIX path of currFolder
       end tell
            EOT
   )
   echo "cd to \"$currFolderPath\""
   cd "$currFolderPath"
}

Also for a much more comprehensive list of commands check out: http://www.commandlinefu.com/commands/tagged/34/bash

Ruby Rush command-line tool

If you use Ruby maybe check out Rush, it allows you do use Ruby in a bash command-line like way.

Halcyon Events logo on Jenson Button’s Formula One helmet 2

Posted by ben on March 28, 2009

Jenson Button has just got pole position ready for the Australian Formula One race tomorrow. This is pretty exciting as on either side of his helmet is the Halcyon Events Ltd. logo.

Jenson Button's Helmet with Halcyon Logo

Jenson Button's Helmet with Halcyon Logo

Halcyon Events is a company that specialises in high end bespoke Formula One events. Through their contacts they can take you and your clients behind the scenes to areas not normally permitted, and give you a unique experience into Formula One (F1).

The web site was built by me, the design was created by Scamper Branding and the logo on Jenson’s helmet was designed by Firefly Creative.

Firefly Creative logo

Anyway fingers crossed for Jenson Button to win the Australian Grand Prix!.

– Update – Fantastic Jenson Button won the Melbourne Grand Prix! How exciting.

An apology and a promise

Posted by ben on March 12, 2009

This is just a quick note to apologise for not posting for the last couple of months. A lot has been happening and I have actually written a number of posts but never quite finished them. Also I promise to write more regularly come the end of March 2009 (hopefully).

Well my New Year started with a ‘Looney Dook‘ in the Firth of Fourth on New Years day. Man it was cold and a struggle to get in, but I felt fantastic afterwards. Its seems like quite a good analogy of how my year has been so far.

Anyway I’ve been busy building a couple of web sites, with a number still under development, if you get a moment please check them out and let me know what you think:

I’ve also been coming up with a number of little side line projects which I hope to share with you soon. One of them involves using Twitter and if you want to hear more when the time comes you can follow me on twitter/emson.

Finally this year for me, and I’m sure everyone, seems to be about how to restructure and think in terms of business and income. I expect if you are open to change and think a bit laterally there are many opportunities, if you don’t change you are likely to struggle.

The business world is changing beneath our feet and we need to be quick to act on the opportunities it presents us. Seth Godin’s quick article highlights this rather well.

So I’ll start putting together some interesting articles from the beginning of April onwards – I hope you can wait till then, and thanks for following me.

Ben…

Chrome is a Desktop Web Application platform 5

Posted by ben on September 04, 2008

Google Chrome is not just a browser

Google Chrome was launched a few days ago on the 2nd September 2008, since then there has been much hype and articles written about it. So what is it? Well, Wikipedia describes it: “Google Chrome is a free and open source web browser developed by Google.”, however it is more than that.

It comes dressed as a web browser but is actually a Desktop Web Application platform. It facilitates the creation of Web Applications that are desktop like in functionality. These Web Applications will, be much more responsive, secure and stable than the previous generation of web applications because these new technologies are forming a suitable infrasructure.

It’s one of the technologies ushering in a new era for the Internet.

I wrote an article recently that describes how these technologies are laying down foundations for applications should use the web: Desktop web applications using SproutCore/

Why is Chrome significant

Recently a number of the big Internet centred companies have been making strides to enable the next generation of Web Applications.

Adobe with its AIR technology, Microsoft with Silverlight, Apple with its endorsement of the SproutCore JavaScript framework, and Google, until this announcement, Gears.

The problem is none of these offerings is perfect, and some of them are very much propietary, tying users into their technology.

The problem Google has is that Gears is actually a very good product, but why would anybody download and install it if there aren’t may web sites using it? At the moment this is an additional step resulting in the fact that most users have no compelling reason to install it. In a nut shell nobody is using it.

However with Chrome Google is able to hedge its bets, it has merged several standalone technologies into one very capable and pleasing package.

  • It has an awesome JavaScript engine enabling JavaScript to approach Desktop Application speeds.
  • It has Gears enabling developers to create offline applications that can interact with your desktop.
  • It can open a Web Application directly in its own window, without any of the traditional browser tool bar and menu overheads. Making Web Applications look like Desktop Applications.
  • It has added stability by making each tab a separate process, essentially each tab behaves like its very own browser.
  • It is secure in that it has been designed from the ground up following proven security models, such as sandboxing.
  • Its elegant, meaning that it feels small, light and fit for purpose. It has taken some leaves out of Apple’s book and made the UI simple yet powerful.

Chrome is OpenSource and follows standards

This next era of the Internet is going to very busy. Everyday there are vast numbers of web pages and Web Applications created, and with this colosal amounts of data and information to sift through.

For an individual it is becoming harder and harder to focus and extract the useful information from all that data. In essance attention is a currency and with all these web sites and applications vying for our eyeballs how do we as users filter the wheat from the chaff?

That part of the Internet isn’t completely written yet but for certain, by following Web Standards and by incorporating OpenSource technologies we are laying the foundations for future tools to help us do this. Chrome is one such OpenSource technology.

Chrome needs to follow standards as these will pull it along and it will evolve into something very powerful. Even if it doesn’t some of its components may find there way into some technology that does. I dare say that Google will have a finger in that pie no matter. As a result it is a win win situation for Google.

This also highlights the point that Microsoft’s Internet Explorer browser is gradually getting left behind. Admittedly standards aren’t followed by all these companies but Microsoft has certainly been more relunctant to endorse them.

JavaScript is a key web technology

JavaScript is old, it appeared in the early browser wars and there hasn’t been any significant changes since. Its been buggy, doesn’t scale well, and there are differences on just about every browser implementation, but it is everywhere.

Recently, with Web 2.0, JavaScript has had a bit of a resurgance and some very useful frameworks have emerged which mitigate the implementation issues and improve its stability. However up until recently it has been slow. Too slow to be useful in terms of creating sophisticated Desktop like Web Applications.

It seems that in order to compete in the new Desktop Web Application arena companies need to implement a fast JavaScript engine. Apple’s Safari is implementing SquirrelFish, and Firefox is implementing TraceMonkey and now Google has created V8.

John Resig has done a comparison of the relevant JavaScript engines and it seems that V8 is very fast. Matthieu Riou says that V8 is closer to a compiler than a traditional VM. It takes JavaScript code and converts it into low level byte code. It is still early days but we can expect this performance to keep improving.

Desktop Web Applications, Slickening the Web.

This era of the Internet is seeing a ’slickening of the web’. Web Applications are becoming more Desktop like. Platforms like Chrome are only going to push us faster along this path.

We can expect to see more applications like Gmail, MobileMe, GoogleMaps, GoogleDocs, etc. but Chrome puts Google very definately in one of the front seats for the future.

Its not fully there yet as its still missing features but it will evolve quickly. Google has vast resources and is able to test the browser against millions of web sites before it ever sees a user. This will only help to refine and improve it.

With Google Chrome, the Web is changing up a Gear.

Cannot select text with mouse in Microsoft Word, fix. 47

Posted by ben on August 21, 2008

A friend had the following problem with their laptop the other day. When they open Microsoft Word they cannot select any text with the mouse, they couldn’t even place the cursor into the text by clicking the mouse on the text.

She said that the situation seemed to have occured when Norton Antivirus requested an update at the same time she was doing something in Word.

I suspected that it was that Word had somehow got corrupted, so I ran a repair, by inserting her Microsoft Office DVD and bring up the installer, and selecting Repair.

This made no difference, I then reinstalled Office, still the problem persisted. This made me think that the problem was related to the Registry, so I did a Google search.

Fixing Word text selection

I found these articles:

To summarise the fix:

  • Backup the Word\Data part of the Registry first
  • delete the the Word\Data section
  • restart Word
  • if it works then its completed, else restore the backup and keep Google searching.

Warning about Word registry changes

This fix involves removing the Word/Data registry key. By deleting this key you will loose some options you have set, this just means that you will need to reset them again. Additionally you will loose the list of files in your recently used files list at the bottom of the file menu.

Additionally be really careful about deleting anything out of the registry, because it can cause serious problems. All the main Windows programs use it, and you could end up reinstalling everything including your copy of Windows.

Backup the offending part of your computer’s registry:

  1. Exit all Office programs, Word, Excel, Outlook etc if they are running.
  2. Open regedit by: Clicking Start/Run, then type regedit, and select OK.
  3. Navigate the registry and select the appropriate Word registry subkey:

    • Word 2002:
      HKEY_CURRENT_USER\Software\Microsoft Office\10.0\Word\Data
    • Word 2003:
      HKEY_CURRENT_USER\Software\Microsoft Office\11.0\Word\Data
    • Word 2007:
      HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Word\Data
  4. Select the Data node, then from the File menu choose Export.

  5. Name this backup file something like word_data.reg, and save it your desktop.

Delete the Word\Data registry node

  1. Select the appropriate Word\Data node mentioned in part 3.
  2. From the Edit menu select Delete, and then click Yes.
  3. Exit regedit.

Restart Word

  1. Restart Word. This will cause Word to recreate this registry node, but you may have to re-enter some of your Word options. If everything is working as expected you can finish. If you still have a problem follow the next section.

Restore the backed up registry node

If the problem still persists then restore your registry back, and keep looking for a solution. To restore the registry back to normal simply:

  • Double-click the word_data.reg file on your desktop.
  • and select Yes, and then OK.

Everyday MySQL Commands

Posted by ben on August 18, 2008

I’m trying to put together a number of blog articles and many of them use the MySQL database, so I figured that I would post up some of my most used everyday MySQL SQL commands. Most likely I will append further commands as I write more articles so this is page is really a work in progress.

I’ve also assumed that you want to have full rights when executing these commands so I’ve used sudo, however you may not need this depending on your set up.

Finally if some other web site covers the command better or I’m feeling lazy I’ll just pop it in the links list at the bottom of this page.

Useful MySQL Commands

Starting MySQL Demon

Start your MySQL database and get it running as a background process:

sudo mysqld_safe
Ctrl + Z
bg

MySQL create databases script

Make a SQL script that creates 3 databases and assigns all rights to my username. Copy the following SQL and paste it into a file called create_databases.sql:

create database mydb_development;
create database mydb_test;
create database mydb_production;
grant all on mydb_development.* to 'my_username'@'localhost';
grant all on mydb_test.* to 'my_username'@'localhost';
grant all on mydb_production.* to 'my_username'@'localhost' identified by 'my_password';

MySQL drop databases script

Make a script to drop databases. Copy the following SQL and paste it into a file called drop_databases.sql:

drop database nemos_production;
drop database mydb_development;
drop database nemos_test;

Executing a script from MySQL

The above scripts can be executed from the command-line with the either of these commands:

sudo mysql < create_database.sql
or
sudo mysql < drop_database.sql

Showing MySQL databases

To check that the databases were created :

sudo mysqlshow
or
sudo mysql
show databases;

Displaying database tables

Displaying the tables of a database:

sudo mysqlshow mydb_development
or
sudo mysql
show tables from mydb_development;

Displaying details about a database table

Displaying details about a particular database table:

sudo mysqlshow mydb_development mytable

Droping a database table

Dropping a table from a database:

sudo mysql
use mydb_development;
drop table mytable;

Displaying information about a table

Displaying the fields and field metadata about a table:

show fields from my_table; 
or
desc my_table;

Useful Links

These are just a few quick and simple MySQL commands that you will always use. Hope this helps.

SproutCore and Web Applications

Posted by ben on August 18, 2008

It’s been a wee while since my last article, which has largely been due to my summer holiday. Anyway I’ve been reading up and experimenting with the SproutCore JavaScript framework.

Its excellent but I wanted to explain why companies and developers should consider using it. So I’ve written an article on my business partner’s web site http://rapidappsgroup.com/content/desktop-web-applications-using-sproutcore/.

Please check it out as it tries to answer a lot of the general questions about web applications and JavaScript frameworks.

BE…

An Almost Fix for Creating RubyGems on Windows 5

Posted by ben on June 25, 2008

Introduction

I wrote this article originally so that I could write command-line apps using Ruby, as I got further and further down the line I realised that what I really wanted to do was create a command-line app using RubyGems. I use both Windows and an Apple Mac and I quickly found myself having problems trying to create RubyGems on Windows.

In this article I try to explain my thought process and the problems I encountered. Unfortunately I had to employ a manual process when trying to package up my project into a tar file, as there isn’t a simple way to do this in Windows (let me know if you have a solution), however everything else seems to work.

What’s a RubyGem?

One of the joys of Ruby is the RubyGems packaging system. It is essentially a tool written in Ruby, for packaging up source code for deployment.

The RubyGems site describes it as follows:

RubyGems is the premier ruby packaging system. It provides:

  • A standard format for destributing Ruby programs and libraries.
  • An easy to use tool for managing the installation of gem packages.
  • A gem server utility for serving gems from any machine where RubyGems is installed.

Why should I create a RubyGem?

Maybe a better question should be when should I package my code up into a RubyGem. Obviously there are no hard and fast rules but if you are going to share your code libraries with others or even with other applications of yours, you should think about using a gem.

Now you might think that you don’t want to make all your code public on RubyForge, and there are very good reason not to publish every gem, so you don’t have to. RubyGems comes with its own local gem server so you can create your own gem library and share it amoung your other Ruby applications.

This is really quite useful, you get the power of RubyGems without the commitment and maintenance work of making your code OpenSource. Plus at any point in time you can then make it OpenSource, and live off the joy of the Ruby community :) .

The reason I wrote this article is because I wanted to create a simple command-line application using Ruby. I went through a number of steps before realising that the best way was to use RubyGems.

I started by creating my own command-line structure and then found this great article by Todd Werth. He has a single Ruby file that you just replace various sections and viola you have a very simple command-line app. But it wasn’t quite what I wanted. I didn’t want to have to type:

./my_super_app 'some params'

I wanted to type:

my_super_app 'some params'

I also wanted the structure of the application to follow a standard structure and I didn’t want to put ‘.’ into my path, for security reasons. Dr Nic came to the rescue with a couple of excellent articles describing how to create gems using newgem and specifically command-line apps as gems.

Installing newgem on Windows

To install newgem on Windows use the RubyGems install method.

gem install newgem

This will install the gem and its dependencies. However one of its dependencies is the Hoe gem, and there is a slight issue using it on Windows.

What is hoe?

Hoe is a compliment to rake, it was created by Ryan Davis and provides rake tasks for testing, packaging, and releasing RubyGems. Geoffrey Grosenbach has a nice tutorial for using hoe and also describes how to create a project structure using the sow task.

Hoe uses a .hoerc file for configuration, and this file should reside in the user’s home directory, something like:

C:\Documents and Settings\MyUserName

An example .hoerc file should look like the one below. Please note that this is a YAML file and if you copy it from here remember to follow the indentation convention:

---
publish_on_announce: false
exclude: !ruby/regexp/tmp$|CVS|\.svn|_darcs|\.git|log$|local/.*\.rb$|Makefile|.*\.o$|.*\.bundle$|.*\.so$|.*\.dll$/ 
str: ""
"@taguri": tag:ruby.yaml.org,2002:regexp/tmp$|CVS|\.svn|_darcs|\.git|log$|local/.*\.rb$|Makefile|.*\.o$|.*\.bundle$|.*\.so$|.*\.dll$/
blogs:
- user: user
  url: url
  extra_headers:
    mt_convert_breaks: markdown
  blog_id: blog_id
  password: password

On Unix systems there is a shortcut to the user’s home directory which is ‘~’ and on Windows this isn’t a shortcut. Windows however does have an environment variable HOMEPATH which will point to the user’s home directory. The problem is that the Hoe gem code uses ‘~’ in its hoe.rb file and this causes problems for Windows users.

Patching the hoe.rb file

OK, be brave, lets tweak the hoe.rb file so that it will work on the Windows platform. The Hoe gem hoe.rb file can be found in the following directory (assuming you installed Ruby to the standard location):

C:\ruby\lib\ruby\gems\1.8\gems\hoe-1.6.0\lib

To make it work for Windows PCs you will need to modify this file with the following changes.

Locate the define_tasks method:

def define_tasks # :nodoc:
  def with_config # :nodoc:
    rc = File.expand_path("~/.hoerc")
    exists = File.exist? rc
    config = exists ? YAML.load_file(rc) : {}
    yield(config, rc)
  end

And add a new method above it such as this, and modify the line rc = File.expand_path(”~/.hoerc”) as below:

def get_home_dir
  home_file_path = "~/"
  home_file_path = "#{ENV['HOMEPATH']}\\" if WINDOZE
  home_file_path
end

def define_tasks # :nodoc:
 def with_config # :nodoc:
   rc = File.expand_path(get_home_dir + '.hoerc')
   exists = File.exist? rc
   config = exists ? YAML.load_file(rc) : {}
   yield(config, rc)
 end

Finally you will need to locate and change the task :config_hoe so that it reads:

"signing_key_file" => "#{get_home_dir}.gem/gem-private_key.pem",
"signing_cert_file" => "#{get_home_dir}.gem/gem-public_cert.pem",

If all has gone correctly save this file and you are now ready to create a RubyGem.

Creating a basic RubyGem

Using the newgem RubyGem enter the following command at the command prompt:

newgem my_app -b greetings -T rspec -W

This will create a my_app subdirectory, with a command-line command app called greetings located in the bin directory. It will use the testing framework RSpec and finally will not generate the RubyForge web site code. This is assuming you don’t want to relese your code as OpenSource. The output will be something like this:

     create
     create  config
     create  doc
     create  lib
     create  script
     ... blah ...
     create  script/console
     create  script/console.cmd
     create  Manifest.txt
     readme  readme
Important
=========

* Open config/hoe.rb
* Update missing details (gem description, dependent gems, etc.)

If you want to add RSpec Stories to this project there is a useful command-line generator to do this. First navigate into the root of you new project app directory, in this case my_app. Now execute the generate script:

ruby script/generate install_rspec_stories

You should then get the following output:

  create  stories/steps
  create  stories/steps/my_app_steps.rb
  create  stories/sell_my_app.story
  create  stories/all.rb

Modify your greetings command so that it does something. Do this by editing the file located here:

my_app/bin/greetings

Open up this file and at the very end, add some code such as this, and save the file:

# do stuff
puts 'Greetings the world is my oyster!'

Packaging caveat

As mentioned in the begining of this article I couldn’t use rake to tar this project up for deployment to RubyForge. The reason is that rake makes a Unix platform dependent call to tar the package using a Ruby task file packagetask.rb located:

C:\ruby\lib\ruby\gems\1.8\gems\rake-0.8.1\lib\rake 

This means that on Windows you will have to manually tar this file.

However you can still create the gem using the rake task, and a gem file my_app-0.0.1.gem, will appear in the pkg directory:

rake gem

This new RubyGem can now be installed by using the gem install commands:

gem install pkg/my_app-0.0.1.gem

You should get the following output:

For more information on my_app, see http://my_app.rubyforge.org

NOTE: Change this information in PostInstall.txt
You can also delete it if you don't want it.


Successfully installed my_app, version 0.0.1
Installing ri documentation for my_app-0.0.1...
Installing RDoc documentation for my_app-0.0.1...

Finally you should now be able to execute your command-line command in the command prompt, simply by typing:

greetings

I hope this is useful and helps with your understanding of how RubyGems work, specifically on Windows, also please jot down some comments if you have any ideas or suggestions.

Links

Here is a list of useful RubyGems links: