crate 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY ADDED
@@ -0,0 +1,9 @@
1
+ = Changelog
2
+ == Version 0.1.1
3
+
4
+ * fix packing of ruby stdlib extension's pure ruby components
5
+ * checksum on upstream source is optional
6
+
7
+ == Version 0.1.0
8
+
9
+ * Initial public release
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2008, Jeremy Hinegardner
2
+
3
+ Permission to use, copy, modify, and/or distribute this software for any purpose
4
+ with or without fee is hereby granted, provided that the above copyright notice
5
+ and this permission notice appear in all copies.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
9
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
11
+ OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
12
+ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
13
+ THIS SOFTWARE.
data/README ADDED
@@ -0,0 +1,39 @@
1
+ == crate
2
+
3
+ * Homepage[http://copiousfreetime.rubyforge.org/crate]
4
+ * {Rubyforge Project}[http://rubyforge.org/projects/copiousfreetime/]
5
+ * email jeremy at copiousfreetime dot org
6
+ * git clone url git://github.com/copiousfreetime/crate.git
7
+ * {Packaging an Application With Crate}[http://copiousfreetime.org/articles/2008/11/30/package-an-application-with-crate.html
8
+
9
+ == DESCRIPTION
10
+
11
+ Crate is a developer tool to help package up your application as a custom static
12
+ build of the ruby interpreter plus all dependedent binary extensions. All the
13
+ pure ruby code (the ruby application, the ruby stdlib, etc ) is packed into one
14
+ or more SQLite databases.
15
+
16
+ The final distributable pieces are a single executable and a few SQLite
17
+ databases which can be then wrapped up appropriately as an OS X App; a self
18
+ extracting executable for Windows; a shar archive, rpm or tarball for Unixes.
19
+
20
+ == INSTALL
21
+
22
+ gem install crate
23
+
24
+ == LICENSE
25
+
26
+ Copyright (c) 2008, Jeremy Hinegardner
27
+
28
+ Permission to use, copy, modify, and/or distribute this software for any purpose
29
+ with or without fee is hereby granted, provided that the above copyright notice
30
+ and this permission notice appear in all copies.
31
+
32
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
33
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
34
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
35
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
36
+ OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
37
+ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
38
+ THIS SOFTWARE.
39
+
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'crate/main'
5
+ rescue LoadError
6
+ $: << File.expand_path( File.join( File.dirname( __FILE__ ), %w[ .. lib ] ) )
7
+ require 'crate/main'
8
+ end
9
+ ::Crate::Main.run( ARGV )
@@ -0,0 +1,5 @@
1
+ CFLAGS=-I/opt/local/lib/ruby/1.8/i686-darwin9.2.2/
2
+ LDFLAGS=-L/opt/local/lib/ruby/1.8/i686-darwin9.2.2/ -L/opt/local/lib -lruby -lobjc -ldl
3
+
4
+ crate_boot: crate_boot.o
5
+ $(CC) -o crate_boot crate_boot.o $(LDFLAGS)
@@ -0,0 +1,77 @@
1
+ #
2
+ # Top level Rakefile for building a custom static ruby based application
3
+ #
4
+ require 'crate'
5
+
6
+ #
7
+ # The name of your project. This will be the name of the final executable in
8
+ # the dist directory.
9
+ #
10
+ PROJ_NAME = "mycrateapp"
11
+
12
+ Crate::Project.new( PROJ_NAME ) do |crate|
13
+
14
+ # This is the configuration used to launch your program.
15
+ #
16
+ # main_file -> the file to 'require'
17
+ # main_class -> the Class in the main_file to instantiate
18
+ # run_method -> the instance method in main_class to invoke
19
+ #
20
+ #The new main of your program will essentially do:
21
+ #
22
+ # require 'application'
23
+ # app = App.new
24
+ # app.run( ARGV, ENV )
25
+ #
26
+ crate.main_file = "application"
27
+ crate.main_class = "App"
28
+ crate.run_method = "run"
29
+
30
+
31
+ # The list of extra files to include as packed into the app.db file
32
+ # This default one one will make sure to get any top level .rb files
33
+ # in the crate application directory.
34
+ #
35
+ crate.packing_lists << Crate::PackingList.new( Dir.glob("*.rb") )
36
+
37
+
38
+ # The extensions to compile into your project. Remove the ones you do not
39
+ # want or leave them commented out with a #
40
+ #
41
+ crate.extensions = %w[
42
+ #Win32API
43
+ bigdecimal
44
+ #curses
45
+ #dbm
46
+ digest
47
+ digest/md5
48
+ #digest/rmd160
49
+ digest/sha1
50
+ #digest/sha2
51
+ #dl
52
+ enumerator
53
+ etc
54
+ fcntl
55
+ #gdbm
56
+ #iconv
57
+ io/wait
58
+ nkf
59
+ #pty
60
+ openssl
61
+ #racc/cparse
62
+ #readline
63
+ #sdbm
64
+ socket
65
+ stringio
66
+ strscan
67
+ syck
68
+ #syslog
69
+ #tcltklib
70
+ thread
71
+ #tk
72
+ #win32ole
73
+ zlib
74
+ ]
75
+
76
+ end
77
+
@@ -0,0 +1,47 @@
1
+ class App
2
+ def initialize
3
+ puts "initialized #{self.class}"
4
+ end
5
+
6
+ def run( argv, env )
7
+ puts "Executing : #{$0}"
8
+ puts "ARGV : #{argv.join(' ')}"
9
+ puts "ENV :"
10
+ env.keys.sort.each do |k|
11
+ puts " #{k} => #{env[k]}"
12
+ end
13
+ exit 42
14
+ end
15
+ end
16
+
17
+ class App2 < App
18
+ def initialize
19
+ super
20
+ end
21
+
22
+ def run_me( argv, env )
23
+ run( argv, env )
24
+ end
25
+ end
26
+
27
+ class App3 < App
28
+ def initialize
29
+ super
30
+ end
31
+ def b
32
+ raise NotImplementedError, "run has not been implemented"
33
+ end
34
+
35
+ def a
36
+ b
37
+ end
38
+
39
+
40
+ def run( argv, env )
41
+ a
42
+ end
43
+ end
44
+
45
+ if $0 == __FILE__ then
46
+ App3.new.run( nil, nil )
47
+ end
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Copyright (c) 2008, Jeremy Hinegardner
3
+ *
4
+ * Permission to use, copy, modify, and/or distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14
+ * PERFORMANCE OF THIS SOFTWARE.
15
+ *
16
+ */
17
+
18
+ #include <stdlib.h>
19
+ #include <getopt.h>
20
+ #include <ruby.h>
21
+
22
+ /** from ruby's original main.c **/
23
+ #if defined(__MACOS__) && defined(__MWERKS__)
24
+ #include <console.h>
25
+ #endif
26
+
27
+ #include "crate_boot.h"
28
+
29
+ struct crate_app {
30
+ char *file_name;
31
+ char *class_name;
32
+ VALUE app_instance;
33
+ char *method_name;
34
+ ID run_method;
35
+ } ;
36
+
37
+ typedef struct crate_app crate_app;
38
+
39
+ /* crate 'secret' options */
40
+ static struct option longopts[] = {
41
+ { "crate-file", required_argument, NULL, 1 },
42
+ { "crate-class", required_argument, NULL, 2 },
43
+ { "crate-method", required_argument, NULL, 3 },
44
+ { NULL, 0, NULL, 0 }
45
+ };
46
+
47
+ int crate_init_from_options(crate_app *ca, int argc, char** argv )
48
+ {
49
+ int ch ;
50
+ int done = 0;
51
+ int old_opterr = opterr;
52
+
53
+ /* turn off printing to stderr */
54
+ opterr = 0;
55
+
56
+ ca->file_name = strdup( CRATE_MAIN_FILE );
57
+ ca->class_name = strdup( CRATE_MAIN_CLASS );
58
+ ca->method_name = strdup( CRATE_RUN_METHOD );
59
+
60
+ while ( !done && (ch = getopt_long( argc, argv, "", longopts, NULL ) ) != -1 ) {
61
+ switch ( ch ) {
62
+ case 1:
63
+ free( ca->file_name );
64
+ ca->file_name = strdup( optarg );
65
+ break;
66
+
67
+ case 2:
68
+ free( ca->class_name );
69
+ ca->class_name = strdup( optarg );
70
+ break;
71
+
72
+ case 3:
73
+ free( ca->method_name );
74
+ ca->method_name = strdup( optarg );
75
+ break;
76
+
77
+ default:
78
+ /* if we have a non-option then we are done and be sure to decrement
79
+ * optind so we keep the option that caused it to faile
80
+ */
81
+ done = 1;
82
+ optind--;
83
+ break;
84
+ }
85
+ }
86
+
87
+ opterr = old_opterr;
88
+ return optind;
89
+ }
90
+
91
+ /**
92
+ * Make the actual application call, we call the application instance with the
93
+ * method given and pass it ARGV and ENV in that order
94
+ */
95
+ VALUE crate_wrap_app( VALUE arg )
96
+ {
97
+ crate_app *ca = (crate_app*)arg;
98
+ char *r = "Amalgalite::Requires.new( :dbfile_name => 'lib.db' )\n"\
99
+ "Amalgalite::Requires.new( :dbfile_name => 'app.db' )\n";
100
+ char buf[BUFSIZ];
101
+ char* dot ;
102
+
103
+ /* require the class file */
104
+
105
+ dot = strchr( ca->file_name, '.');
106
+ if ( NULL != dot ) { *dot = '\0' ; }
107
+ sprintf( buf,"%s\nrequire '%s'", r, ca->file_name);
108
+ rb_eval_string(buf);
109
+
110
+ /* get an instance of the application class and pack up the instance and the
111
+ * method
112
+ */
113
+ ca->app_instance = rb_class_new_instance(0, 0, rb_const_get( rb_cObject, rb_intern( ca->class_name ) ) );
114
+ ca->run_method = rb_intern( ca->method_name );
115
+
116
+ return rb_funcall( ca->app_instance,
117
+ ca->run_method, 2,
118
+ rb_const_get_at( rb_cObject, rb_intern("ARGV") ),
119
+ rb_const_get_at( rb_cObject, rb_intern("ENV") ) );
120
+ }
121
+
122
+ static VALUE dump_backtrace( VALUE elem, VALUE n )
123
+ {
124
+ fprintf( stderr, "\tfrom %s\n", RSTRING(elem)->ptr );
125
+ }
126
+
127
+ /**
128
+ * ifdef items from ruby's original main.c
129
+ */
130
+
131
+ /* to link startup code with ObjC support */
132
+ #if (defined(__APPLE__) || defined(__NeXT__)) && defined(__MACH__)
133
+ static void objcdummyfunction( void ) { objc_msgSend(); }
134
+ #endif
135
+
136
+ extern VALUE cARB;
137
+
138
+ int main( int argc, char** argv )
139
+ {
140
+ int state = 0;
141
+ int rc = 0;
142
+ int opt_mv = 0;
143
+
144
+ crate_app ca;
145
+
146
+ /** startup items from ruby's original main.c */
147
+ #ifdef _WIN32
148
+ NtInitialize(&argc, &argv);
149
+ #endif
150
+ #if defined(__MACOS__) && defined(__MWERKS__)
151
+ argc = ccommand(&argv);
152
+ #endif
153
+
154
+ /* setup ruby */
155
+ ruby_init();
156
+ ruby_script( argv[0] );
157
+ ruby_init_loadpath();
158
+
159
+ /* strip out the crate specific arguments from argv using --crate- */
160
+ opt_mv = crate_init_from_options( &ca, argc, argv );
161
+ argc -= opt_mv;
162
+ argv += opt_mv;
163
+
164
+ /* printf("crate file : %s\n", ca.file_name); */
165
+ /* printf("crate class : %s\n", ca.class_name); */
166
+ /* printf("crate method: %s\n", ca.method_name); */
167
+
168
+ /* make ARGV available */
169
+ ruby_set_argv( argc, argv );
170
+
171
+ /* initialize all extensions */
172
+ Init_ext();
173
+
174
+ /* load up the amalgalite libs */
175
+ am_bootstrap_lift( cARB, Qnil );
176
+
177
+ /* remove the current LOAD_PATH */
178
+ rb_ary_clear( rb_gv_get( "$LOAD_PATH" ) );
179
+
180
+ /* invoke the class / method passing in ARGV and ENV */
181
+ rb_protect( crate_wrap_app, (VALUE)&ca, &state );
182
+
183
+ /* check the results */
184
+ if ( state ) {
185
+
186
+ /* exception was raised, check the $! var */
187
+ VALUE lasterr = rb_gv_get("$!");
188
+
189
+ /* system exit was called so just propogate that up to our exit */
190
+ if ( rb_obj_is_instance_of( lasterr, rb_eSystemExit ) ) {
191
+
192
+ rc = NUM2INT( rb_attr_get( lasterr, rb_intern("status") ) );
193
+ /*printf(" Caught SystemExit -> $? will be %d\n", rc ); */
194
+
195
+ } else {
196
+
197
+ /* some other exception was raised so dump that out */
198
+ VALUE klass = rb_class_path( CLASS_OF( lasterr ) );
199
+ VALUE message = rb_obj_as_string( lasterr );
200
+ VALUE backtrace = rb_funcall( lasterr, rb_intern("backtrace"), 0 );
201
+
202
+ fprintf( stderr, "%s: %s\n", RSTRING( klass )->ptr, RSTRING( message )->ptr );
203
+ rb_iterate( rb_each, backtrace, dump_backtrace, Qnil );
204
+
205
+ rc = state;
206
+ }
207
+ }
208
+
209
+ free( ca.file_name );
210
+ free( ca.class_name );
211
+ free( ca.method_name );
212
+
213
+ /* shut down ruby */
214
+ ruby_finalize();
215
+
216
+ /* exit the program */
217
+ exit( rc );
218
+ }
219
+
@@ -0,0 +1,7 @@
1
+ #
2
+ # The recipe for integrating amalgalite into the ruby build
3
+ #
4
+ Crate::GemIntegration.new("amalgalite", "0.5.1") do |t|
5
+ t.upstream_source = "http://rubyforge.org/frs/download.php/47660/amalgalite-0.5.1.gem"
6
+ t.upstream_sha1 = "fca93f2ab3abf46c86e78202d46489f25b7acb33"
7
+ end
@@ -0,0 +1,7 @@
1
+ #
2
+ # The recipe for integrating arrayfields into the ruby build
3
+ #
4
+ Crate::GemIntegration.new("arrayfields", "4.6.0") do |t|
5
+ t.upstream_source = "http://rubyforge.org/frs/download.php/39810/arrayfields-4.6.0.gem"
6
+ t.upstream_sha1 = "d1caaea59a6cd37efbf769f12bd3340bbd3104bb"
7
+ end
@@ -0,0 +1,7 @@
1
+ #
2
+ # The recipe for integrating configuration into the ruby build
3
+ #
4
+ Crate::GemIntegration.new("configuration", "0.0.5") do |t|
5
+ t.upstream_source = "http://rubyforge.org/frs/download.php/32720/configuration-0.0.5.gem"
6
+ t.upstream_sha1 = "ae65a38666706959aaaa034fb7cb3d0234349ecc"
7
+ end