Crate 0.1.1 Released

I’m pleased to announce that Crate, the project I spoke on at RubyConf
this year, has reached a releasable stage.

gem install crate

Crate is a tool to help package up your application as a custom static
build of the ruby interpreter plus all dependant binary extensions.
All the pure ruby code (the ruby application, the ruby stdlib, etc) is
packed into one or more SQLite databases.

The final distributable pieces are a single executable and a few SQLite
databases which can be then wrapped up appropriately as an OS X App; a
self extracting executable for Windows; a shar archive, rpm or tarball
for Unixes.

Project: http://copiousfreetime.rubyforge.org/crate/
Tutorial:
Packaging an Application With Crate

enjoy,

-jeremy

On Dec 1, 2008, at 9:12 AM, Jeremy H. wrote:

The final distributable pieces are a single executable and a few
SQLite
databases which can be then wrapped up appropriately as an OS X App; a
self extracting executable for Windows; a shar archive, rpm or tarball
for Unixes.

Project: http://copiousfreetime.rubyforge.org/crate/
Tutorial: Packaging an Application With Crate

This project is pure awesome, that is all.

Thanks
Ezra Z.
[email protected]

On Mon, Dec 1, 2008 at 12:12 PM, Jeremy H.
[email protected] wrote:

Crate is a tool to help package up your application as a custom static
build of the ruby interpreter plus all dependant binary extensions.
All the pure ruby code (the ruby application, the ruby stdlib, etc) is
packed into one or more SQLite databases.

Stupid question: what’s the advantage of using a SQLite DB over a
tarball or zip file?


Avdi

Home: http://avdi.org
Developer Blog: Avdi Grimm, Code Cleric
Twitter: http://twitter.com/avdi
Journal: http://avdi.livejournal.com

On Tue, Dec 02, 2008 at 04:21:05AM +0900, Ezra Z. wrote:

All the pure ruby code (the ruby application, the ruby stdlib, etc) is

This project is pure awesome, that is all.

Thank you Ezra. I happen to think so too :-).

enjoy,

-jeremy

On Dec 1, 3:12 pm, Jeremy H. [email protected] wrote:

tarball or zip file?
that. Rubyscript2exe takes this appraoch, and unpacks the .rb files to
the file system.

Off the top of my head, the main advantage I see of using sqlite over
zip/tar file is your application gets the free bonus of having a built
in relation database with no extra cost.

There may be some performance advantage for require in that it only has
to do a select from a db, vs open up .zip file for ever require, but I
won’t consider that a valid argument at this point.

Sorry to bring this, but Python packages the standard library and your
application into zip files.

It maps the File requests that deal with files to the zip file, which
the handler is open once and keep opened until the application ends.

There is one problem with this which is search for the proper
requirement, which I guess having a sqlite engine backing up will make
it easy.

I’ll need to check it out how it works with gems that depends on
extensions, since dlopen / LoadLibrary needs a real file and cannot
map a memory address to load the symbols (just thinking out loud here,
maybe you already figured this out).

enjoy,

BTW: great release!

Regards,

On Tue, Dec 02, 2008 at 04:26:39AM +0900, Avdi G. wrote:

On Mon, Dec 1, 2008 at 12:12 PM, Jeremy H.
[email protected] wrote:

Crate is a tool to help package up your application as a custom static
build of the ruby interpreter plus all dependant binary extensions.
All the pure ruby code (the ruby application, the ruby stdlib, etc) is
packed into one or more SQLite databases.

Stupid question: what’s the advantage of using a SQLite DB over a
tarball or zip file?

Stupid answer: I really have no idea. I didn’t even think about it.

One of the requirements I set for myself on this one was that there
would be no ‘unpacking’ of the ruby source code onto the deployed file
system. That, and I just like the idea of requiring ruby code that is
really a row in an sqlite database :-).

You could overwrite require to open up an archive file of some format
and load the ruby file, and I see no reason why someone shouldn’t write
that. Rubyscript2exe takes this appraoch, and unpacks the .rb files to
the file system.

Off the top of my head, the main advantage I see of using sqlite over
zip/tar file is your application gets the free bonus of having a built
in relation database with no extra cost.

There may be some performance advantage for require in that it only has
to do a select from a db, vs open up .zip file for ever require, but I
won’t consider that a valid argument at this point.

enjoy,

-jeremy

Jeremy H. wrote:

On Tue, Dec 02, 2008 at 11:04:32AM +0900, Luis L. wrote:

That way, if the require is a loaded module (which is now statically
compiled in) the ruby internal rb_require() will return success, and if
it is a .rb file LoadError will be raised and then amalgalite will take
care of loading the appropriate file from the sqlite database.

So, still wondering about Luis’s question… how do you load extensions?

On Tue, Dec 02, 2008 at 11:04:32AM +0900, Luis L. wrote:

On Dec 1, 3:12?pm, Jeremy H. [email protected] wrote:

[…]

the handler is open once and keep opened until the application ends.
Cool, I didn’t know that. And I see that the rubyzip library does
override
require and that might another option for a future crate.

There is one problem with this which is search for the proper
requirement, which I guess having a sqlite engine backing up will make
it easy.

I’ll need to check it out how it works with gems that depends on
extensions, since dlopen / LoadLibrary needs a real file and cannot
map a memory address to load the symbols (just thinking out loud here,
maybe you already figured this out).

You might call it cheating, what I do is clear out $LOAD_PATH after
initializing the interpreter and before handing off control to the
wrapped up ruby application. The require order is then, the ruby
original require followed by the amalgalite overridden require.

That way, if the require is a loaded module (which is now statically
compiled in) the ruby internal rb_require() will return success, and if
it is a .rb file LoadError will be raised and then amalgalite will take
care of loading the appropriate file from the sqlite database.

This is the same approach used by rubygems.

What this means for a crate application is that mixing filesystem .rb
files with those stored in sqlite databases may cause odd behavior if
something fiddles with $LOAD_PATH.

BTW: great release!

Thanks!

enjoy,

-jeremy

On Wed, Dec 03, 2008 at 06:12:53AM +0900, Joel VanderWerf wrote:

original require followed by the amalgalite overridden require. That way,
if the require is a loaded module (which is now statically
compiled in) the ruby internal rb_require() will return success, and if
it is a .rb file LoadError will be raised and then amalgalite will take
care of loading the appropriate file from the sqlite database.

So, still wondering about Luis’s question… how do you load extensions?

Crate applications are standalone applications. There is no loading of
extensions per se. When you package your ruby application with crate
you
compile in all the necessary extensions statically. They are all
initialized
when the interpreter starts.

An issue arises when, in your .rb files, you have a “require ‘zlib’” or
some
other require that would in a standard ruby execution would dynamically
load an
extension. In a crate packaged application, this is really a noop
because the
extension is already loaded, since it is comopiled in, but the require
statement
needs to not throw a LoadError.

By having the built in require (rb_require()) attempt first, it
essentially does
this noop and does not throw the LoadError, and the application goes
ahead and
uses the classes that it wants. And the issue is gone.

Make sense?

enjoy,

-jeremy

On Dec 2, 4:12 pm, Joel VanderWerf [email protected] wrote:

wrapped up ruby application. The require order is then, the ruby
original require followed by the amalgalite overridden require.

That way, if the require is a loaded module (which is now statically
compiled in) the ruby internal rb_require() will return success, and if
it is a .rb file LoadError will be raised and then amalgalite will take
care of loading the appropriate file from the sqlite database.

So, still wondering about Luis’s question… how do you load extensions?

I got my answer looking at Jeremy presentation at RubyConf.

Basically you “integrate” the gem C extension into ruby itself, so
there is no need to carry the .so files around.

The only problem with that approach is you need to install all the
required dependencies to build those extensions, and have some gems
developers play nice in their extconf.rb files too.

Yet still, the ruby interpreter is quite capable of loading the .so
files form the file system if they existed.

Regards,