GitHub and TextMate Unite

Posted by Dr Nic on May 26, 2008

I wanted to go from a source file to the equivalent file on github. I wanted a selection of lines in TextMate editor to also be selected when I was taken to github.com. I wanted to cut back on my senseless killing of innocent pasties.

Finally, I wanted to make a nice little video to show off the new GitHub.tmbundle.


TextMate and GitHub: Show the current file in GitHub from Dr Nic on Vimeo.

Which remote repository is it choosing?

If you have multiple remote references to github.com repositories, then the algorithm picks one in the following order:

  1. A remote named ‘github’
  2. A remote named ‘origin’
  3. The first remote for a github.com repository

What else could go in a GitHub textmate bundle?

TextMate bundles for Merb

Posted by Dr Nic on May 12, 2008

If you are using TextMate (OS X) or E Text Editor (Windows) then you’ll be dead keen to know there is a TextMate bundle for Merb, and another one for Datamapper.

[This is cross-posted on the new Merbunity community site for Merb]

Currently, you can access the bundles via git:

cd "~/Library/Application Support/TextMate/Bundles"
git clone git://github.com/drnic/datamapper-tmbundle.git Datamapper.tmbundle
git clone git://github.com/drnic/merb-tmbundle.git Merb.tmbundle

Now “Reload Bundles” or restart TextMate.

You can now select from three Merb syntax/scopes. Press Shift+Alt+Cmd+M to see the options (below)

Merb TextMate bundle - select ORM

  • If you select Merb (Datamapper) you will have access to the Merb bundle AND the Datamapper bundle.
  • If you select Merb (ActiveRecord) you have access to the Merb bundle AND the Ruby on Rails bundle.
  • If you select Merb (Sequel) then nothing special happens as there isn’t a Sequel bundle yet. Want to create one?

Currently there is no separation in the Rails bundle for ActiveRecord and non-ActiveRecord snippets and commands, so if you use Merb (ActiveRecord) there will be some snippets + commands that you don’t want from Rails. In future, there may be more separation to help the Merb bundle. Also, TextMate 2 may help this cause.

As always, to learn what snippets are available at any given cursor position, use Ctrl+Cmd+T.

If you have new snippets for any of the bundles, I suggest forking the git repositories, pushing up the changes to github and sending Pull Requests to me (drnic).

Sponsored by Engine Yard

The initial development of this bundle was sponsored by Engine Yard because they care.

Rails bundle

There is also the hughly popular Ruby on Rails bundle for TextMate that you can use. Download from http://railsbundle.com/ or via github.

If you want to learn everything about the new Ruby on Rails bundle for TextMate and daily life with TextMate (short cuts, editing bundles) then I highly recommend the new TextMate for Rails 2 Peepcode:

TextMate for Rails 2

This recommendation comes from inside information on the quality of the Peepcode… it was written by me, and incorporates the vocal skills of the operatic Geoffrey Grosenbach.

GitHub Badge for your Blog with 100% guarantee of more coolness

Posted by Dr Nic on May 03, 2008

GitHub Badge

The killer app for JavaScript in the 90s was to take a perfectly readable sequence of words - aka “a sentence” - and turn every single character a different colour. You did that, then you went back to doing normal work.

The killer app for JavaScript in the 00s is widgets/badges. Taking perfectly useful stuff from one website - aka “data” - and re-posting it on your blog sidebar.

In both circumstances, across two decades, you did this to look cool. Sure, it never works but you do it anyway.

Thusly, riding high on the world-dominating success of GitHub there seems to be a vacancy in the department of “JavaScript badge for my blog to make me look cool” projects, in the sub-category of “GitHub”.

The first entrant and thus market leader of the “Blog Badges for GitHub” micro-industry is the “GitHub Badge” It is beautifully demonstrated in static image form above, or if you click the image through to the website (or here to my blog and its aesthetically appealing enhancement with said GitHub Badge) you’ll see it live and interactive.

Touch it. Feel it. Press the “Show more” link for hours of entertainment.

Installation

Then get it for yourself. Read the GitHub Badge website or just…

Slap the following into your blog sidebar:

<div id="github-badge"></div>
<script type="text/javascript" charset="utf-8">
  GITHUB_USERNAME="drnic";
  GITHUB_LIST_LENGTH=10;
  GITHUB_HEAD="div"; // e.g. change to "h2" for wordpress sidebars
</script>
<script src="http://drnicjavascript.rubyforge.org/github_badge/dist/github-badge-launcher.js" type="text/javascript"></script>

Only GITHUB_USERNAME is a required pre-set variable. The others above show the defaults, and can be changed by being specified.

For my WordPress sidebar, which uses <li> and <h2> for sections and headers, I use the following:

<li id="github-badge"></li>
<script type="text/javascript" charset="utf-8">
  GITHUB_USERNAME="drnic";
  GITHUB_HEAD="h2";
</script>
<script src="http://drnicjavascript.rubyforge.org/github_badge/dist/github-badge-launcher.js" type="text/javascript"></script>

Thus the badge is inserted in the <li> element, and the “My projects (drnic)” header is an <h2> instead of a <div>.

Source and tests on github

You can fetch the source from github - http://github.com/drnic/github_badges/tree/master - using:

git clone git://github.com/drnic/github_badges.git

You might want to add an option to turn off the auto-CSS generator so you can theme it yourself.

The JavaScript tests are in test/ folder. Either run them with rake test, or individually open the files in your browser.

Future cool things the badge could do…

Ultimately, when Chris Wanstrath (harass him on twitter) adds more fields and APIs to the GitHub API then the badge can do more. Currently it orders the projects in reverse order - that is, newest projects first. If I can get the network/watching counters then I can order the list using those values, etc.

Any other cool ideas for what the badge could do?

I’d like to be able to show project version numbers (e.g. gem version numbers) and other project meta-information. This would require GitHub to offer a CRUD UI for generic key/values and for the fields to be returned via their API.

If you know Chris and can throw heavy objects at him with moderate certainty of hitting him and not damaging any expensive equipment, please do so til he gives me this stuff.

Git for Rubyforge accounts

Posted by Dr Nic on April 08, 2008

rubyforge has git - account creation

First there was CVS, then came SVN to RubyForge. Actually, I’m guessing that CVS was the sole SCM initially, and SVN was added later. I just can’t imagine them starting RubyForge from scratch and explicitly saying “yeah we’ll offer CVS because …”. I don’t know how that sentence would have finished. It must have been added first. There is no valid “because …”.

But now, with each RubyForge project there is a Git repository. This is great for two very good reasons:

  1. the end is nigh for empty or unmaintained SVN repositories
  2. less centralised decentralised development

GitHub + Gitorious are the go-to-guys for somewhere to hang your proverbial hat: somewhere you push your local git repository to so other people can access it.

Yet when I’m investigate someone’s new RubyGem or other project, the first place I look for its source is RubyForge. I assume the project name is the same as the gem name, and goto http://rubyforge.org/projects/pastiepacker for example.

rubyforge scm link

Then I click on the SCM tab. Normally this gives SVN instructions. In this modern era, many projects SVN repos can now be blank or unmaintained with Git repos being preferred by many.

So, the reason to push your git repository to RubyForge’s new git system is to make life easier for me. I mean, I don’t know who else clicks on the SCM link, but I do.

While this is all well and great for new projects - you can select “git” instead of “svn” as per the first image above - but I’m not yet sure how to migrate old projects [follow support ticket].

The other reason is to actually help your distributed repository be distributed. Push it to github. Push it to gitorious. And now you can push it to rubyforge. Sweet.

Adding another remote repository

Since your default remote repository is probably called “origin”, you may wonder how such a naming schema could ever expand to multiple remote repositories? Might I suggest “rubyforge” as the name of the rubyforge repository?

git remote add rubyforge gitosis@rubyforge.org:pastiepacker.git
git push rubyforge master
git push origin master

If you do this for all your projects, perhaps a bash script is in order:

function gpall() {
  git push rubyforge master
  git push origin master
}

One project equals one repository, but multiple packages

Using a Rubyforge project’s git repository might be problematic where you release multiple packages/rubygems (codeforpeople, seattlerb, mongrel, drnicutilities, etc). Here I’d prefer one repository per package, rather than one repository for the whole “project”.

Perhaps you could push the master branch from your local repository for each package into different branches of the rubyforge git repository. Thoughts?

Can’t push to your rubyforge git repo?

From the FAQ:

RubyForge Git repositories are managed via gitosis; gitosis does authentication via public keys. This means that in order to push to a RubyForge Git repository you’ll need to upload a public key to your account - see notes on that here.

Generally, Git support is something we’ve just introduced, so feedback about it on the forums would be quite welcome.

What is Pastie Packer?

I can’t tell you. Its a secret.

The explicit Ruby metaclass you know you always wanted

Posted by Dr Nic on April 03, 2008

When you define a “static” or “class” method on a Ruby class, it actually stores the method on that class’s metaclass/singleton class/eigenclass.

_why’s metaid gem gives you a metaclass method to explicit access this object:

require 'metaid'
class Person
  def self.oldest
    # find oldest person
  end
end
Person.methods.grep(/oldest/) # => ['oldest']
Person.metaclass.instance_methods.grep(/oldest/) # => ['oldest']

So now here’s a new, fun way to access the metaclass of a class, look for a constant suffixed with ‘Metaclass’. For the Person class, look for PersonMetaclass. Yep, we can have explicit metaclass constants. Or try PersonClass or PersonEigen or PersonEigenclass. No one can agree on what they are called, so I made them all work.

$ gem install magic_metaclass
$ irb

In irb try:

require 'rubygems'
require 'magic_metaclass'
class Person; end
Person
# => Person
PersonMetaclass
# => #<Class:Person>
PersonClass
# => #<Class:Person>
PersonEigenclass
# => #<Class:Person>
PersonEigen
# => #<Class:Person>

Neat.

Finally, the example from above:

class Person
  def self.oldest
    # find oldest person
  end
end
PersonMetaclass.instance_methods.grep(/oldest/) # => ['oldest']

I wrote this gem with no known use cases. If you find any, let me know.