crate 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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