From 20b072659f83ee1605b51ca84a69f9630f4d22d8 Mon Sep 17 00:00:00 2001 From: rpothukuchi Date: Tue, 4 Nov 2008 00:35:42 +0000 Subject: [PATCH] vendorized hoe git-svn-id: http://svn.gid.gap.com/svn/gid/qa/trunk/taza@325724 d1bde68c-af00-0410-813c-e860f6c31c7f --- Rakefile | 2 +- vendor/gems/bin/rake | 19 + vendor/gems/bin/rubyforge | 19 + vendor/gems/bin/sow | 19 + vendor/gems/cache/hoe-1.8.2.gem | Bin 0 -> 19456 bytes vendor/gems/cache/rake-0.8.3.gem | Bin 0 -> 100352 bytes vendor/gems/cache/rubyforge-1.0.1.gem | Bin 0 -> 16384 bytes vendor/gems/gems/hoe-1.8.2/History.txt | 280 ++ vendor/gems/gems/hoe-1.8.2/Manifest.txt | 7 + vendor/gems/gems/hoe-1.8.2/README.txt | 95 + vendor/gems/gems/hoe-1.8.2/Rakefile | 28 + vendor/gems/gems/hoe-1.8.2/bin/sow | 74 + vendor/gems/gems/hoe-1.8.2/lib/hoe.rb | 1030 +++++++ vendor/gems/gems/hoe-1.8.2/test/test_hoe.rb | 97 + vendor/gems/gems/rake-0.8.3/CHANGES | 400 +++ vendor/gems/gems/rake-0.8.3/MIT-LICENSE | 21 + vendor/gems/gems/rake-0.8.3/README | 285 ++ vendor/gems/gems/rake-0.8.3/Rakefile | 418 +++ vendor/gems/gems/rake-0.8.3/TODO | 20 + vendor/gems/gems/rake-0.8.3/bin/rake | 31 + .../gems/rake-0.8.3/doc/example/Rakefile1 | 38 + .../gems/rake-0.8.3/doc/example/Rakefile2 | 35 + vendor/gems/gems/rake-0.8.3/doc/example/a.c | 6 + vendor/gems/gems/rake-0.8.3/doc/example/b.c | 6 + .../gems/gems/rake-0.8.3/doc/example/main.c | 11 + vendor/gems/gems/rake-0.8.3/doc/glossary.rdoc | 51 + vendor/gems/gems/rake-0.8.3/doc/jamis.rb | 591 ++++ .../gems/gems/rake-0.8.3/doc/proto_rake.rdoc | 127 + vendor/gems/gems/rake-0.8.3/doc/rake.1.gz | Bin 0 -> 1369 bytes vendor/gems/gems/rake-0.8.3/doc/rakefile.rdoc | 534 ++++ vendor/gems/gems/rake-0.8.3/doc/rational.rdoc | 151 + .../doc/release_notes/rake-0.4.14.rdoc | 23 + .../doc/release_notes/rake-0.4.15.rdoc | 35 + .../doc/release_notes/rake-0.5.0.rdoc | 53 + .../doc/release_notes/rake-0.5.3.rdoc | 78 + .../doc/release_notes/rake-0.5.4.rdoc | 46 + .../doc/release_notes/rake-0.6.0.rdoc | 141 + .../doc/release_notes/rake-0.7.0.rdoc | 119 + .../doc/release_notes/rake-0.7.1.rdoc | 59 + .../doc/release_notes/rake-0.7.2.rdoc | 121 + .../doc/release_notes/rake-0.7.3.rdoc | 47 + .../doc/release_notes/rake-0.8.0.rdoc | 114 + .../doc/release_notes/rake-0.8.2.rdoc | 165 ++ .../doc/release_notes/rake-0.8.3.rdoc | 112 + vendor/gems/gems/rake-0.8.3/install.rb | 88 + vendor/gems/gems/rake-0.8.3/lib/rake.rb | 2468 +++++++++++++++++ .../rake-0.8.3/lib/rake/classic_namespace.rb | 8 + vendor/gems/gems/rake-0.8.3/lib/rake/clean.rb | 33 + .../lib/rake/contrib/compositepublisher.rb | 24 + .../rake-0.8.3/lib/rake/contrib/ftptools.rb | 153 + .../rake-0.8.3/lib/rake/contrib/publisher.rb | 75 + .../lib/rake/contrib/rubyforgepublisher.rb | 18 + .../lib/rake/contrib/sshpublisher.rb | 47 + .../gems/rake-0.8.3/lib/rake/contrib/sys.rb | 209 ++ .../rake-0.8.3/lib/rake/gempackagetask.rb | 103 + .../rake-0.8.3/lib/rake/loaders/makefile.rb | 35 + .../gems/rake-0.8.3/lib/rake/packagetask.rb | 185 ++ .../rake-0.8.3/lib/rake/rake_test_loader.rb | 5 + .../gems/gems/rake-0.8.3/lib/rake/rdoctask.rb | 147 + .../lib/rake/ruby182_test_unit_fix.rb | 23 + .../gems/gems/rake-0.8.3/lib/rake/runtest.rb | 23 + .../gems/gems/rake-0.8.3/lib/rake/tasklib.rb | 23 + .../gems/gems/rake-0.8.3/lib/rake/testtask.rb | 161 ++ vendor/gems/gems/rake-0.8.3/lib/rake/win32.rb | 54 + .../gems/rake-0.8.3/test/capture_stdout.rb | 26 + .../gems/rake-0.8.3/test/check_expansion.rb | 5 + .../gems/rake-0.8.3/test/contrib/test_sys.rb | 47 + .../gems/rake-0.8.3/test/data/chains/Rakefile | 15 + .../rake-0.8.3/test/data/default/Rakefile | 19 + .../gems/rake-0.8.3/test/data/dryrun/Rakefile | 22 + .../test/data/file_creation_task/Rakefile | 33 + .../rake-0.8.3/test/data/imports/Rakefile | 19 + .../gems/rake-0.8.3/test/data/imports/deps.mf | 1 + .../rake-0.8.3/test/data/multidesc/Rakefile | 17 + .../rake-0.8.3/test/data/namespace/Rakefile | 57 + .../rake-0.8.3/test/data/rakelib/test1.rb | 3 + .../rake-0.8.3/test/data/rbext/rakefile.rb | 3 + .../gems/gems/rake-0.8.3/test/data/sample.mf | 12 + .../test/data/statusreturn/Rakefile | 8 + .../rake-0.8.3/test/data/unittest/Rakefile | 1 + .../gems/gems/rake-0.8.3/test/filecreation.rb | 32 + .../gems/gems/rake-0.8.3/test/functional.rb | 15 + .../gems/rake-0.8.3/test/in_environment.rb | 30 + .../gems/rake-0.8.3/test/rake_test_setup.rb | 10 + vendor/gems/gems/rake-0.8.3/test/reqfile.rb | 3 + vendor/gems/gems/rake-0.8.3/test/reqfile2.rb | 3 + .../rake-0.8.3/test/session_functional.rb | 337 +++ .../gems/gems/rake-0.8.3/test/shellcommand.rb | 3 + .../gems/rake-0.8.3/test/test_application.rb | 694 +++++ .../gems/gems/rake-0.8.3/test/test_clean.rb | 14 + .../gems/rake-0.8.3/test/test_definitions.rb | 82 + .../gems/rake-0.8.3/test/test_earlytime.rb | 35 + .../gems/rake-0.8.3/test/test_extension.rb | 63 + .../test/test_file_creation_task.rb | 62 + .../gems/rake-0.8.3/test/test_file_task.rb | 139 + .../gems/rake-0.8.3/test/test_filelist.rb | 618 +++++ .../gems/rake-0.8.3/test/test_fileutils.rb | 250 ++ vendor/gems/gems/rake-0.8.3/test/test_ftp.rb | 59 + .../rake-0.8.3/test/test_invocation_chain.rb | 75 + .../rake-0.8.3/test/test_makefile_loader.rb | 25 + .../gems/rake-0.8.3/test/test_multitask.rb | 45 + .../gems/rake-0.8.3/test/test_namespace.rb | 36 + .../gems/rake-0.8.3/test/test_package_task.rb | 116 + .../gems/gems/rake-0.8.3/test/test_pathmap.rb | 209 ++ vendor/gems/gems/rake-0.8.3/test/test_rake.rb | 41 + .../gems/gems/rake-0.8.3/test/test_require.rb | 33 + .../gems/gems/rake-0.8.3/test/test_rules.rb | 347 +++ .../rake-0.8.3/test/test_task_arguments.rb | 89 + .../gems/rake-0.8.3/test/test_task_manager.rb | 170 ++ .../gems/gems/rake-0.8.3/test/test_tasklib.rb | 12 + .../gems/gems/rake-0.8.3/test/test_tasks.rb | 371 +++ .../gems/rake-0.8.3/test/test_test_task.rb | 75 + .../test/test_top_level_functions.rb | 84 + .../gems/gems/rake-0.8.3/test/test_win32.rb | 57 + vendor/gems/gems/rubyforge-1.0.1/History.txt | 82 + vendor/gems/gems/rubyforge-1.0.1/Manifest.txt | 11 + vendor/gems/gems/rubyforge-1.0.1/README.txt | 24 + vendor/gems/gems/rubyforge-1.0.1/Rakefile | 39 + .../gems/gems/rubyforge-1.0.1/bin/rubyforge | 223 ++ .../gems/rubyforge-1.0.1/lib/rubyforge.rb | 475 ++++ .../rubyforge-1.0.1/lib/rubyforge/client.rb | 134 + .../lib/rubyforge/cookie_manager.rb | 51 + .../rubyforge-1.0.1/test/test_rubyforge.rb | 390 +++ .../test/test_rubyforge_client.rb | 122 + .../test/test_rubyforge_cookie_manager.rb | 97 + vendor/gems/specifications/hoe-1.8.2.gemspec | 38 + vendor/gems/specifications/rake-0.8.3.gemspec | 31 + .../specifications/rubyforge-1.0.1.gemspec | 32 + 128 files changed, 15660 insertions(+), 1 deletion(-) create mode 100755 vendor/gems/bin/rake create mode 100755 vendor/gems/bin/rubyforge create mode 100755 vendor/gems/bin/sow create mode 100644 vendor/gems/cache/hoe-1.8.2.gem create mode 100644 vendor/gems/cache/rake-0.8.3.gem create mode 100644 vendor/gems/cache/rubyforge-1.0.1.gem create mode 100644 vendor/gems/gems/hoe-1.8.2/History.txt create mode 100644 vendor/gems/gems/hoe-1.8.2/Manifest.txt create mode 100644 vendor/gems/gems/hoe-1.8.2/README.txt create mode 100644 vendor/gems/gems/hoe-1.8.2/Rakefile create mode 100755 vendor/gems/gems/hoe-1.8.2/bin/sow create mode 100644 vendor/gems/gems/hoe-1.8.2/lib/hoe.rb create mode 100644 vendor/gems/gems/hoe-1.8.2/test/test_hoe.rb create mode 100644 vendor/gems/gems/rake-0.8.3/CHANGES create mode 100644 vendor/gems/gems/rake-0.8.3/MIT-LICENSE create mode 100644 vendor/gems/gems/rake-0.8.3/README create mode 100644 vendor/gems/gems/rake-0.8.3/Rakefile create mode 100644 vendor/gems/gems/rake-0.8.3/TODO create mode 100755 vendor/gems/gems/rake-0.8.3/bin/rake create mode 100644 vendor/gems/gems/rake-0.8.3/doc/example/Rakefile1 create mode 100644 vendor/gems/gems/rake-0.8.3/doc/example/Rakefile2 create mode 100644 vendor/gems/gems/rake-0.8.3/doc/example/a.c create mode 100644 vendor/gems/gems/rake-0.8.3/doc/example/b.c create mode 100644 vendor/gems/gems/rake-0.8.3/doc/example/main.c create mode 100644 vendor/gems/gems/rake-0.8.3/doc/glossary.rdoc create mode 100644 vendor/gems/gems/rake-0.8.3/doc/jamis.rb create mode 100644 vendor/gems/gems/rake-0.8.3/doc/proto_rake.rdoc create mode 100644 vendor/gems/gems/rake-0.8.3/doc/rake.1.gz create mode 100644 vendor/gems/gems/rake-0.8.3/doc/rakefile.rdoc create mode 100644 vendor/gems/gems/rake-0.8.3/doc/rational.rdoc create mode 100644 vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.4.14.rdoc create mode 100644 vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.4.15.rdoc create mode 100644 vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.5.0.rdoc create mode 100644 vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.5.3.rdoc create mode 100644 vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.5.4.rdoc create mode 100644 vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.6.0.rdoc create mode 100644 vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.7.0.rdoc create mode 100644 vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.7.1.rdoc create mode 100644 vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.7.2.rdoc create mode 100755 vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.7.3.rdoc create mode 100644 vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.8.0.rdoc create mode 100644 vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.8.2.rdoc create mode 100644 vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.8.3.rdoc create mode 100644 vendor/gems/gems/rake-0.8.3/install.rb create mode 100755 vendor/gems/gems/rake-0.8.3/lib/rake.rb create mode 100644 vendor/gems/gems/rake-0.8.3/lib/rake/classic_namespace.rb create mode 100644 vendor/gems/gems/rake-0.8.3/lib/rake/clean.rb create mode 100644 vendor/gems/gems/rake-0.8.3/lib/rake/contrib/compositepublisher.rb create mode 100644 vendor/gems/gems/rake-0.8.3/lib/rake/contrib/ftptools.rb create mode 100644 vendor/gems/gems/rake-0.8.3/lib/rake/contrib/publisher.rb create mode 100644 vendor/gems/gems/rake-0.8.3/lib/rake/contrib/rubyforgepublisher.rb create mode 100644 vendor/gems/gems/rake-0.8.3/lib/rake/contrib/sshpublisher.rb create mode 100644 vendor/gems/gems/rake-0.8.3/lib/rake/contrib/sys.rb create mode 100644 vendor/gems/gems/rake-0.8.3/lib/rake/gempackagetask.rb create mode 100644 vendor/gems/gems/rake-0.8.3/lib/rake/loaders/makefile.rb create mode 100644 vendor/gems/gems/rake-0.8.3/lib/rake/packagetask.rb create mode 100644 vendor/gems/gems/rake-0.8.3/lib/rake/rake_test_loader.rb create mode 100644 vendor/gems/gems/rake-0.8.3/lib/rake/rdoctask.rb create mode 100755 vendor/gems/gems/rake-0.8.3/lib/rake/ruby182_test_unit_fix.rb create mode 100644 vendor/gems/gems/rake-0.8.3/lib/rake/runtest.rb create mode 100644 vendor/gems/gems/rake-0.8.3/lib/rake/tasklib.rb create mode 100644 vendor/gems/gems/rake-0.8.3/lib/rake/testtask.rb create mode 100644 vendor/gems/gems/rake-0.8.3/lib/rake/win32.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/capture_stdout.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/check_expansion.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/contrib/test_sys.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/data/chains/Rakefile create mode 100644 vendor/gems/gems/rake-0.8.3/test/data/default/Rakefile create mode 100644 vendor/gems/gems/rake-0.8.3/test/data/dryrun/Rakefile create mode 100644 vendor/gems/gems/rake-0.8.3/test/data/file_creation_task/Rakefile create mode 100644 vendor/gems/gems/rake-0.8.3/test/data/imports/Rakefile create mode 100644 vendor/gems/gems/rake-0.8.3/test/data/imports/deps.mf create mode 100644 vendor/gems/gems/rake-0.8.3/test/data/multidesc/Rakefile create mode 100644 vendor/gems/gems/rake-0.8.3/test/data/namespace/Rakefile create mode 100644 vendor/gems/gems/rake-0.8.3/test/data/rakelib/test1.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/data/rbext/rakefile.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/data/sample.mf create mode 100644 vendor/gems/gems/rake-0.8.3/test/data/statusreturn/Rakefile create mode 100644 vendor/gems/gems/rake-0.8.3/test/data/unittest/Rakefile create mode 100644 vendor/gems/gems/rake-0.8.3/test/filecreation.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/functional.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/in_environment.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/rake_test_setup.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/reqfile.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/reqfile2.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/session_functional.rb create mode 100755 vendor/gems/gems/rake-0.8.3/test/shellcommand.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_application.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_clean.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_definitions.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_earlytime.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_extension.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_file_creation_task.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_file_task.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_filelist.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_fileutils.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_ftp.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_invocation_chain.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_makefile_loader.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_multitask.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_namespace.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_package_task.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_pathmap.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_rake.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_require.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_rules.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_task_arguments.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_task_manager.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_tasklib.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_tasks.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_test_task.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_top_level_functions.rb create mode 100644 vendor/gems/gems/rake-0.8.3/test/test_win32.rb create mode 100644 vendor/gems/gems/rubyforge-1.0.1/History.txt create mode 100644 vendor/gems/gems/rubyforge-1.0.1/Manifest.txt create mode 100644 vendor/gems/gems/rubyforge-1.0.1/README.txt create mode 100644 vendor/gems/gems/rubyforge-1.0.1/Rakefile create mode 100755 vendor/gems/gems/rubyforge-1.0.1/bin/rubyforge create mode 100755 vendor/gems/gems/rubyforge-1.0.1/lib/rubyforge.rb create mode 100644 vendor/gems/gems/rubyforge-1.0.1/lib/rubyforge/client.rb create mode 100644 vendor/gems/gems/rubyforge-1.0.1/lib/rubyforge/cookie_manager.rb create mode 100644 vendor/gems/gems/rubyforge-1.0.1/test/test_rubyforge.rb create mode 100644 vendor/gems/gems/rubyforge-1.0.1/test/test_rubyforge_client.rb create mode 100644 vendor/gems/gems/rubyforge-1.0.1/test/test_rubyforge_cookie_manager.rb create mode 100644 vendor/gems/specifications/hoe-1.8.2.gemspec create mode 100644 vendor/gems/specifications/rake-0.8.3.gemspec create mode 100644 vendor/gems/specifications/rubyforge-1.0.1.gemspec diff --git a/Rakefile b/Rakefile index bc87c5c..88f503f 100644 --- a/Rakefile +++ b/Rakefile @@ -2,8 +2,8 @@ $:.unshift(File.join(File.dirname(__FILE__), 'lib')) require 'rubygems' -require 'hoe' require 'config/vendorized_gems' +require 'hoe' require 'taza' require 'rbconfig' require 'spec/rake/spectask' diff --git a/vendor/gems/bin/rake b/vendor/gems/bin/rake new file mode 100755 index 0000000..60939df --- /dev/null +++ b/vendor/gems/bin/rake @@ -0,0 +1,19 @@ +#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby +# +# This file was generated by RubyGems. +# +# The application 'rake' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then + version = $1 + ARGV.shift +end + +gem 'rake', version +load 'rake' diff --git a/vendor/gems/bin/rubyforge b/vendor/gems/bin/rubyforge new file mode 100755 index 0000000..5348ec8 --- /dev/null +++ b/vendor/gems/bin/rubyforge @@ -0,0 +1,19 @@ +#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby +# +# This file was generated by RubyGems. +# +# The application 'rubyforge' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then + version = $1 + ARGV.shift +end + +gem 'rubyforge', version +load 'rubyforge' diff --git a/vendor/gems/bin/sow b/vendor/gems/bin/sow new file mode 100755 index 0000000..841663f --- /dev/null +++ b/vendor/gems/bin/sow @@ -0,0 +1,19 @@ +#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -ws +# +# This file was generated by RubyGems. +# +# The application 'hoe' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then + version = $1 + ARGV.shift +end + +gem 'hoe', version +load 'sow' diff --git a/vendor/gems/cache/hoe-1.8.2.gem b/vendor/gems/cache/hoe-1.8.2.gem new file mode 100644 index 0000000000000000000000000000000000000000..6add4b7d8c15db4725803988bfb0c005a1c78e1c GIT binary patch literal 19456 zcmeFZLzFH+(?I3y8jDjVqsxs2O?zr zU$vnBeq1+~|5*Q@={+pX%xwRA;D6BnXZZhV+J9%<|Iqz^*CIhQBv7+9h!ha$m9LEs z&REjjd)HS~+i?wPf_T8SZcCaS2-Z!~yGiT>RQ~bu>Pt6>)PaeOowEsc!XZOp_$7Yw;=-gT! z@3;H6gYmP%W#V&YX=c9QV|p^#nWll>cVA=Mrl$X< zwzf99jWM#g6LFB`vBb9_vM3fWhOySwX!@YSoXSGvs1a%eQ3`kb;gn>^lOf@UiGWU-X9%z#TR+`OTMHA$fZ4y1pmPMU zT}I0Ua{wU^MDogUW2XB#&_sY1y10cgI~vpvKG>2fm>)JEQi2gaNXiFT(R_h6RN$T! z=4hNCx|uYL+s_#wiEQQbPm9i6C@Xd-uj4Lx{x-HSHREpeweXzvJbZ}8iR*!dnzF$3 zkV0df%yKX+IM*uHNb0Cti7^j3g|q`QSjGoS6cn>IgZy3~*e`8X4UXK8)BOS@kD{6K z>Jw{PKO+_�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 literal 0 HcmV?d00001 diff --git a/vendor/gems/cache/rake-0.8.3.gem b/vendor/gems/cache/rake-0.8.3.gem new file mode 100644 index 0000000000000000000000000000000000000000..15b02acfd3eaa87c293c5f57c93fcfea3495f2ea GIT binary patch literal 100352 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

}?;J!xu+~ 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 literal 0 HcmV?d00001 diff --git a/vendor/gems/cache/rubyforge-1.0.1.gem b/vendor/gems/cache/rubyforge-1.0.1.gem new file mode 100644 index 0000000000000000000000000000000000000000..4ef604dcd51481a0d779d2bf30edbc5e2a1bded7 GIT binary patch literal 16384 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 literal 0 HcmV?d00001 diff --git a/vendor/gems/gems/hoe-1.8.2/History.txt b/vendor/gems/gems/hoe-1.8.2/History.txt new file mode 100644 index 0000000..1ee0d69 --- /dev/null +++ b/vendor/gems/gems/hoe-1.8.2/History.txt @@ -0,0 +1,280 @@ +=== 1.8.2 / 2008-10-24: + +* 1 minor enhancement: + + * Now asks Inline for known inlined classes if you package w/ INLINE=1. + +=== 1.8.1 / 2008-10-22 + +* 1 bug fix: + + * Fixes for windows compatibility from Luis Lavena. + +=== 1.8.0 / 2008-10-09 + +* 5 minor enhancements: + + * Added Hoe.add_include_dirs to make setting up rake deps easier. + * Removed unused optional group arg in sow. + * Added testlib variable so you can specify what test library to use. + * Added deps:list to help you review dependent projects. + * Added deps:email to help you communicate with dependent projects. + * Added deps:fetch to help you search through dependent projects. + +=== 1.7.0 / 2008-06-30 + +* 3 minor enhancements: + + * Use rdoc 2.x gem if available. Eric likes his backslashes. + * Added extra_dev_deps for new rubygems developer dependencies. + * Switched hoe to dev dep. Fork off, bitches. + * Finally got a sane test that does something. Hey... it's a start. + +=== 1.6.0 / 2008-06-18 + +* 1 minor enhancement + + * blog categories! Defaults to array with project's name. Thanks Aaron! + +=== 1.5.3 / 2008-05-20 + +* 1 Bug Fix + + * hoe really really needs better tests. I suck. :/ + +=== 1.5.2 / 2008-05-20 + +* 4 Minor Enhancements: + + * Added multiruby_skip attribute for 'rake multi' version invalidation. + * Improved error messages when files are missing. + * Added rubygems post_install_message accessor. Thanks to Dr. Nic. + * Cleaned up alternative_name... I didn't get it. + +* 1 Bug Fix: + + * Removed require of rake/contrib/sshpublisher to fix 1.9. + +=== 1.5.1 / 2008-03-04 + +* 2 Minor Enhancements: + + * Removed install/uninstall tasks. Too buggy. Gems do a better job. + * Added cleaning of rbc files to default list + +* 5 Bug Fixes: + + * Correctly deal with errors intuiting history and readme files. Thanks Aaron! + * Fixed rdoc title. Thanks, Sander! + * Fixed sow to match new Rakefile and History format. Thanks, me! + * Moved test/unit to the front for rake test. Fixes use of miniunit. + * Renamed shadowed variable. + +=== 1.5.0 / 2008-01-30 + +* 9 Minor Enhancements: + + * Added autopopulation of changes from History.txt. + * Added autopopulation of urls from History.txt. + * Added autopopulation of description from History.txt + * Added autopopulation of summary from description. + * Added description_sections to declare what sections of readme to use. + * Added summary_sentences to declare how many sentences you want in summary. + * Added developer(name, email) to cleanly populate both author/email arrays. + * author and email now default to "doofus". + * author and email warn that they'll blow up on 2008-04-01. + +=== 1.4.0 / 2007-12-20 + +* 1 Major Enhancement: + + * rake package now supports INLINE=1 and FORCE_PLATFORM=whatever. + * Supports ruby_inline extensions. + * Contributed by Luis Lavena. Thanks Luis! + +=== 1.3.0 / 2007-08-13 + +* 1 Major Enhancement: + + * Hoe now builds signed gems automatically. Run the generate_key task to + automatically create a signing key. + +* 4 Minor Enhancements: + + * Extended rdoc pattern to include ext dirs. + * Fixed dependency adding for versionless dependencies. + * Added NODOT env var to disable RDoc diagram generation. + * The config_hoe task automatically merges in new config entries. + +=== 1.2.2 / 2007-07-23 + +* 2 Minor Enhancements: + + * Added exclude parameter for check_manifest filtering to .hoerc. + * Documented .hoerc stuffs. + +* 1 Bug Fix: + + * Various (untested) fixes for windows compatibility. + +=== 1.2.1 / 2007-05-21 + +* 8 Minor Enhancements: + + * Allow for spaces in filenames in manifest. Thanks to Aaron Patterson. + * Allow rsync flags to be set. + * Allow rdoc destination directory to be set. + * Deal with bad line-endings. Stupid windoze users... :( + * Added WINDOZE check for diff.exe and look for gdiff first. + * Use gdiff if available, diff otherwise. Allows to work on borked Solaris. + * Move RDoc to attr* from big 'ol chunk at the top of the class. + * Basic conversion of history/urls from rdoc to markdown. + +* 1 Bug Fix: + + * Fixed executables regexp to /^bin/. + +=== 1.2.0 / 2007-02-13 + +* 4 Minor Enhancements: + + * Added more support for ext dirs. + * Added a simple config file (yaml). Use 'rake config_hoe' to edit. + * Added post_blog task (thanks Aaron!), configured via config_hoe. + * Announce task now posts to your blogs and/or publishes API + depending on config. + +=== 1.1.7 / 2007-01-10 + +* 5 Minor Enhancements: + + * extra_deps is now self-healing, and ensures no (direct) cycles. + * cleans check_manifest for CVS projects. + * rubyforge changes for config. + * Now uses rsync for publish_docs. YAY for fast! + * Bug #7193 fix spelling of 'synopsys'. Submitted by Jacob Atzen. + +=== 1.1.6 / 2006-11-29 + +* 1 Bug Fix: + + * Fix release to work correctly with need_zip and need_tar. + +=== 1.1.5 / 2006-11-29 + +* 2 Minor Enhancements: + + * Reduced check_manifest dependencies to just diff for windows. + * Don't use default author in summary, description or changes. + +=== 1.1.4 / 2006-11-12 + +* 3 Minor Enhancements: + + * Added need_tar and need_zip to customize package requirements. Stupid windoze. + * Extended spec_extras to take procs as values. Passes in named parameter. + * Removed test from require_paths. I thought I already parameterized this. :/ + +=== 1.1.3 / 2006-11-09 + +* 6 Minor Enhancements: + + * Added test_deps, now you can automatically discover test dependency ommisions. + * Added ext support! Build C extensions with hoe! + * Gemspec uses test_all.rb or result of test_globs. Tweak those tests. + * Now uses https to login to rubyforge. Rubyforge crackers beware! + * Fixed doco and automated updating of it. + * Added rdoc_pattern. Go doco go! + +=== 1.1.2 / 2006-10-22 + +* 4 Minor Enhancements: + + * Added -d and -t flags to sow to make dev or trunk subdirs for p4 + and svn projects. + * Added install_gem to further test gem builds. + * Added test_globs to customize your test file list. + * Removed demo.rb from clean_globs. I'm torn on this one. + +* 1 Bug Fix: + + * Fixed bug in install rule. + +=== 1.1.1 / 2006-10-11 + +* 2 Bug Fixes: + + * Fixed minor problem with subject of email. + * Fixed problem in test. + +=== 1.1.0 / 2006-10-04 + +* 1 Major Enhancement: + + * Added sow, a command-line tool for quickly creating new projects. + +* 1 Minor Enhancement: + + * Added check_manifest task + +=== 1.0.5 / 2006-10-03 + +* 8 Minor Enhancements: + + * Doco cleanup. + * Removed Manifest.txt from rdoc and added title. + * Added changeset support. + * Added spec_extras for easy gemspec attribute setting. + * Added release_notes, changeset setting for releases. + * Added paragraphs_of utility method. + * Added email and rubyforge news announcement tasks. + * Url attribute may now be an array of urls. + +=== 1.0.4 / 2006-09-23 + +* 1 Bug Fix: + + * Damnit... I messed up. There is no rubygems gem to be dependent upon. Duh. + +=== 1.0.3 / 2006-09-23 + +* 9 Minor Enhancements: + + * Added debug_gem rule. + * Added lots of doco. + * Added proper deps to hoe for other's gems, and + rake/rubyforge/rubygems for hoe. + * Added ridocs to generate ri locally for testing. + * Added support for multiple authors. + * Rdoc now includes any top level .txt files. + * Renamed deploy to release. + * Renamed upload to publish_docs. + * publish_docs is now smart about subprojects and missing subdirectories. + +* 1 Bug Fix: + + * Fixed include paths. + +=== 1.0.2 / 2006-09-20 + +* 2 Minor Enhancements: + + * Wee little tests. + * Fixed up gemspec's require_paths. + +=== 1.0.1 / 2006-09-20 + +* 5 Minor Enhancements: + + * Finally got deployment straightened out. Maybe. Some might be on + rubyforge.org. + * Added default description and summary. + * Added dependency mechanism. + * Improved gemspec debugging. + * Swapped gem with tgz in deploy... we'd rather screw up on tgz + +=== 1.0.0 / 2006-09-19 + +* 1 Major Enhancement: + + * Birthday! diff --git a/vendor/gems/gems/hoe-1.8.2/Manifest.txt b/vendor/gems/gems/hoe-1.8.2/Manifest.txt new file mode 100644 index 0000000..5893d70 --- /dev/null +++ b/vendor/gems/gems/hoe-1.8.2/Manifest.txt @@ -0,0 +1,7 @@ +History.txt +Manifest.txt +README.txt +Rakefile +bin/sow +lib/hoe.rb +test/test_hoe.rb diff --git a/vendor/gems/gems/hoe-1.8.2/README.txt b/vendor/gems/gems/hoe-1.8.2/README.txt new file mode 100644 index 0000000..f7721f3 --- /dev/null +++ b/vendor/gems/gems/hoe-1.8.2/README.txt @@ -0,0 +1,95 @@ += Hoe + +* http://rubyforge.org/projects/seattlerb/ +* http://seattlerb.rubyforge.org/hoe/ +* mailto:ryand-ruby@zenspider.com + +== DESCRIPTION: + +Hoe is a simple rake/rubygems helper for project Rakefiles. It +generates all the usual tasks for projects including rdoc generation, +testing, packaging, and deployment. + +Tasks Provided: + +* announce - Create news email file and post to rubyforge. +* audit - Run ZenTest against the package. +* check_manifest - Verify the manifest. +* clean - Clean up all the extras. +* config_hoe - Create a fresh ~/.hoerc file. +* debug_gem - Show information about the gem. +* default - Run the default tasks. +* deps:email - Print a contact list for gems dependent on this gem +* deps:fetch - Fetch all the dependent gems of this gem into tarballs +* deps:list - List all the dependent gems of this gem +* docs - Build the docs HTML Files +* email - Generate email announcement file. +* gem - Build the gem file hoe-1.8.0.gem +* generate_key - Generate a key for signing your gems. +* install_gem - Install the package as a gem. +* multi - Run the test suite using multiruby. +* package - Build all the packages +* post_blog - Post announcement to blog. +* post_news - Post announcement to rubyforge. +* publish_docs - Publish RDoc to RubyForge. +* release - Package and upload the release to rubyforge. +* ridocs - Generate ri locally for testing. +* tasks - Generate a list of tasks for doco. +* test - Run the test suite. +* test_deps - Show which test files fail when run alone. + +See class rdoc for help. Hint: ri Hoe + +== FEATURES/PROBLEMS: + +* Provides 'sow' for quick project directory creation. +* Make making and maintaining Rakefiles fun and easy. + +== SYNOPSIS: + + % sow [group] project + +or + + require 'hoe' + + Hoe.new(projectname, version) do |p| + # ... project specific data ... + end + + # ... project specific tasks ... + +== REQUIREMENTS: + +* rake +* rubyforge +* rubygems + +== INSTALL: + +* sudo gem install hoe + +== LICENSE: + +(The MIT License) + +Copyright (c) Ryan Davis, Zen Spider Software + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/gems/gems/hoe-1.8.2/Rakefile b/vendor/gems/gems/hoe-1.8.2/Rakefile new file mode 100644 index 0000000..d6309d3 --- /dev/null +++ b/vendor/gems/gems/hoe-1.8.2/Rakefile @@ -0,0 +1,28 @@ +# -*- ruby -*- + +require './lib/hoe.rb' + +Hoe.new("hoe", Hoe::VERSION) do |hoe| + hoe.rubyforge_name = "seattlerb" + + hoe.developer("Ryan Davis", "ryand-ruby@zenspider.com") + + hoe.blog_categories << "Seattle.rb" << "Ruby" +end + +desc "Generate a list of tasks for doco. RDOC=1 for commented output" +task :tasks do + tasks = `rake -T`.scan(/rake (\w+)\s+# (.*)/) + tasks.reject! { |t,d| t =~ /^(clobber|tasks|re(package|docs))/ } + max = tasks.map { |x,y| x.size }.max + + tasks.each do |t,d| + if ENV['RDOC'] then + puts "# %-#{max+2}s %s" % [t + "::", d] + else + puts "* %-#{max}s - %s" % [t, d] + end + end +end + +# vim: syntax=Ruby diff --git a/vendor/gems/gems/hoe-1.8.2/bin/sow b/vendor/gems/gems/hoe-1.8.2/bin/sow new file mode 100755 index 0000000..42dbbc4 --- /dev/null +++ b/vendor/gems/gems/hoe-1.8.2/bin/sow @@ -0,0 +1,74 @@ +#!/usr/bin/env ruby -ws + +$t ||= false +$d ||= false + +if defined? $h then + puts "usage: #{File.dirname($0)} [-d|-t] project" + puts " -t = add project to subdir under 'trunk'" + puts " -d = add project to subdir under 'dev'" +end + +abort "You must specify only one of -t or -d" if $t and $d + +project = ARGV.shift + +# prevents false positives on my tag reporter +X = 'FI' + 'X' + +abort "You must supply a project name on the commandline" unless project +abort "Project #{project} seems to exist" if test ?d, project +puts "creating project #{project}" + +case project +when /_/ then + file_name = project + project = project.capitalize.gsub(/_([a-z])/) {$1.upcase} + klass = project +else + file_name = project.gsub(/([A-Z])/, '_\1').downcase.sub(/^_/, '') + klass = project.capitalize.gsub(/_([a-z])/) {$1.upcase} +end + +Dir.mkdir project +Dir.chdir project do + + if $d then + Dir.mkdir "dev" + Dir.chdir "dev" + elsif $t then + Dir.mkdir "trunk" + Dir.chdir "trunk" + end + + %w(bin lib test).each do |path| + Dir.mkdir path + end + + files = { + "History.txt" => "=== 1.0.0 / #{Time.new.strftime("%Y-%m-%d")}\n\n* 1 major enhancement\n\n * Birthday!\n\n", + "README.txt" => "= #{project}\n\n* #{X} (url)\n\n== DESCRIPTION:\n\n#{X} (describe your package)\n\n== FEATURES/PROBLEMS:\n\n* #{X} (list of features or problems)\n\n== SYNOPSIS:\n\n #{X} (code sample of usage)\n\n== REQUIREMENTS:\n\n* #{X} (list of requirements)\n\n== INSTALL:\n\n* #{X} (sudo gem install, anything else)\n\n== LICENSE:\n\n(The MIT License)\n\nCopyright (c) #{Time.new.strftime("%Y")} #{X}\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", + "Manifest.txt" => "", + "bin/#{file_name}" => "", + "lib/#{file_name}.rb" => "class #{klass}\n VERSION = '1.0.0'\nend", + "test/test_#{file_name}.rb" => "", + "Rakefile" => "# -*- ruby -*-\n\nrequire 'rubygems'\nrequire 'hoe'\nrequire './lib/#{file_name}.rb'\n\nHoe.new('#{project}', #{klass}::VERSION) do |p|\n # p.rubyforge_name = '#{project}x' # if different than lowercase project name\n # p.developer('#{X}', '#{X}@example.com')\nend\n\n# vim: syntax=Ruby\n" + } + + files["Manifest.txt"] = files.keys.sort.join("\n") + + files.each do |file, content| + File.open(file, "w") do |f| + f.write content + end + end +end + +WINDOZE = /mswin|mingw/ =~ RUBY_PLATFORM + +puts "... done, now go fix all occurrences of '#{X}'" +if WINDOZE then + puts `findstr /N /S /C:#{X} #{project}\\*` +else + puts `find #{project} -type f | xargs grep -n #{X}`.gsub(/\A|\n/, "\n ") +end diff --git a/vendor/gems/gems/hoe-1.8.2/lib/hoe.rb b/vendor/gems/gems/hoe-1.8.2/lib/hoe.rb new file mode 100644 index 0000000..9c492e5 --- /dev/null +++ b/vendor/gems/gems/hoe-1.8.2/lib/hoe.rb @@ -0,0 +1,1030 @@ +# -*- ruby -*- + +require 'rubygems' +require 'rake' +require 'rake/gempackagetask' +require 'rake/rdoctask' +require 'rake/testtask' +require 'rbconfig' +require 'rubyforge' +require 'yaml' + +begin + gem 'rdoc' +rescue Gem::LoadError +end + +## +# hoe - a tool to help rake +# +# Hoe is a simple rake/rubygems helper for project Rakefiles. It +# generates all the usual tasks for projects including rdoc generation, +# testing, packaging, and deployment. +# +# == Using Hoe +# +# === Basics +# +# Use this as a minimal starting point: +# +# require 'hoe' +# +# Hoe.new("project_name", '1.0.0') do |p| +# p.rubyforge_name = "rf_project" +# # add other details here +# end +# +# # add other tasks here +# +# === Tasks Provided: +# +# announce:: Create news email file and post to rubyforge. +# audit:: Run ZenTest against the package. +# check_manifest:: Verify the manifest. +# clean:: Clean up all the extras. +# config_hoe:: Create a fresh ~/.hoerc file. +# debug_gem:: Show information about the gem. +# default:: Run the default tasks. +# deps:email:: Print a contact list for gems dependent on this gem +# deps:fetch:: Fetch all the dependent gems of this gem into tarballs +# deps:list:: List all the dependent gems of this gem +# docs:: Build the docs HTML Files +# email:: Generate email announcement file. +# gem:: Build the gem file hoe-1.8.0.gem +# generate_key:: Generate a key for signing your gems. +# install_gem:: Install the package as a gem. +# multi:: Run the test suite using multiruby. +# package:: Build all the packages +# post_blog:: Post announcement to blog. +# post_news:: Post announcement to rubyforge. +# publish_docs:: Publish RDoc to RubyForge. +# release:: Package and upload the release to rubyforge. +# ridocs:: Generate ri locally for testing. +# tasks:: Generate a list of tasks for doco. +# test:: Run the test suite. +# test_deps:: Show which test files fail when run alone. +# +# === Extra Configuration Options: +# +# Run +config_hoe+ to generate a new ~/.hoerc file. The file is a +# YAML formatted config file with the following settings: +# +# exclude:: A regular expression of files to exclude from +# +check_manifest+. +# publish_on_announce:: Run +publish_docs+ when you run +release+. +# signing_key_file:: Signs your gems with this private key. +# signing_cert_file:: Signs your gem with this certificate. +# blogs:: An array of hashes of blog settings. +# +# Run +config_hoe+ and see ~/.hoerc for examples. +# +# === Signing Gems: +# +# Run the 'generate_key' task. This will: +# +# 1. Configure your ~/.hoerc. +# 2. Generate a signing key and certificate. +# 3. Install the private key and public certificate files into ~/.gem. +# 4. Upload the certificate to RubyForge. +# +# Hoe will now generate signed gems when the package task is run. If you have +# multiple machines you build gems on, be sure to install your key and +# certificate on each machine. +# +# Keep your private key secret! Keep your private key safe! +# +# To make sure your gems are signed run: +# +# rake package; tar tf pkg/yourproject-1.2.3.gem +# +# If your gem is signed you will see: +# +# data.tar.gz +# data.tar.gz.sig +# metadata.gz +# metadata.gz.sig +# +# === Platform awareness +# +# Hoe allows bundling of pre-compiled extensions in the +package+ task. +# +# To create a package for your current platform: +# +# rake package INLINE=1 +# +# This will force Hoe analize your +Inline+ already compiled +# extensions and include them in your gem. +# +# If somehow you need to force a specific platform: +# +# rake package INLINE=1 FORCE_PLATFORM=mswin32 +# +# This will set the +Gem::Specification+ platform to the one indicated in +# +FORCE_PLATFORM+ (instead of default Gem::Platform::CURRENT) +# + +class Hoe + VERSION = '1.8.2' + GEMURL = URI.parse 'http://gems.rubyforge.org' # for namespace :deps below + + ruby_prefix = Config::CONFIG['prefix'] + sitelibdir = Config::CONFIG['sitelibdir'] + + ## + # Used to specify a custom install location (for rake install). + + PREFIX = ENV['PREFIX'] || ruby_prefix + + ## + # Used to add extra flags to RUBY_FLAGS. + + RUBY_DEBUG = ENV['RUBY_DEBUG'] + + default_ruby_flags = "-w -I#{%w(lib ext bin test).join(File::PATH_SEPARATOR)}" + + (RUBY_DEBUG ? " #{RUBY_DEBUG}" : '') + + ## + # Used to specify flags to ruby [has smart default]. + + RUBY_FLAGS = ENV['RUBY_FLAGS'] || default_ruby_flags + + ## + # Used to add flags to test_unit (e.g., -n test_borked). + + FILTER = ENV['FILTER'] # for tests (eg FILTER="-n test_blah") + + # :stopdoc: + + RUBYLIB = if PREFIX == ruby_prefix then + sitelibdir + else + File.join(PREFIX, sitelibdir[ruby_prefix.size..-1]) + end + + DLEXT = Config::CONFIG['DLEXT'] + + WINDOZE = /mswin|mingw/ =~ RUBY_PLATFORM unless defined? WINDOZE + + DIFF = if WINDOZE + 'diff.exe' + else + if system("gdiff", __FILE__, __FILE__) + 'gdiff' # solaris and kin suck + else + 'diff' + end + end unless defined? DIFF + + # :startdoc: + + ## + # *Recommended*: The author(s) of the package. (can be array) + # Really. Set this or we'll tease you. + + attr_accessor :author + + ## + # Populated automatically from the manifest. List of executables. + + attr_accessor :bin_files # :nodoc: + + ## + # *Optional*: An array of the project's blog categories. Defaults to project name. + + attr_accessor :blog_categories + + ## + # Optional: A description of the release's latest changes. Auto-populates. + + attr_accessor :changes + + ## + # Optional: An array of file patterns to delete on clean. + + attr_accessor :clean_globs + + ## + # Optional: A description of the project. Auto-populates. + + attr_accessor :description + + ## + # Optional: What sections from the readme to use for auto-description. Defaults to %w(description). + + attr_accessor :description_sections + + ## + # *Recommended*: The author's email address(es). (can be array) + + attr_accessor :email + + ## + # Optional: An array of rubygem dependencies. + + attr_accessor :extra_deps + + ## + # Optional: An array of rubygem developer dependencies. + + attr_accessor :extra_dev_deps + + ## + # Populated automatically from the manifest. List of library files. + + attr_accessor :lib_files # :nodoc: + + ## + # Optional: Array of incompatible versions for multiruby filtering. Used as a regex. + + attr_accessor :multiruby_skip + + ## + # *MANDATORY*: The name of the release. + + attr_accessor :name + + ## + # Optional: Should package create a tarball? [default: true] + + attr_accessor :need_tar + + ## + # Optional: Should package create a zipfile? [default: false] + + attr_accessor :need_zip + + ## + # Optional: A post-install message to be displayed when gem is installed. + + attr_accessor :post_install_message + + ## + # Optional: A regexp to match documentation files against the manifest. + + attr_accessor :rdoc_pattern + + ## + # Optional: Name of RDoc destination directory on Rubyforge. [default: +name+] + + attr_accessor :remote_rdoc_dir + + ## + # Optional: Flags for RDoc rsync. [default: "-av --delete"] + + attr_accessor :rsync_args + + ## + # Optional: The name of the rubyforge project. [default: name.downcase] + + attr_accessor :rubyforge_name + + ## + # The Gem::Specification. + + attr_accessor :spec # :nodoc: + + ## + # Optional: A hash of extra values to set in the gemspec. Value may be a proc. + + attr_accessor :spec_extras + + ## + # Optional: A short summary of the project. Auto-populates. + + attr_accessor :summary + + ## + # Optional: Number of sentences from description for summary. Defaults to 1. + + attr_accessor :summary_sentences + + ## + # Populated automatically from the manifest. List of tests. + + attr_accessor :test_files # :nodoc: + + ## + # Optional: An array of test file patterns [default: test/**/test_*.rb] + + attr_accessor :test_globs + + ## + # Optional: What test library to require [default: test/unit] + + attr_accessor :testlib + + ## + # Optional: The url(s) of the project. (can be array). Auto-populates. + + attr_accessor :url + + ## + # *MANDATORY*: The version. Don't hardcode! use a constant in the project. + + attr_accessor :version + + ## + # Add extra dirs to both $: and RUBY_FLAGS (for test runs) + + def self.add_include_dirs(*dirs) + dirs = dirs.flatten + $:.unshift(*dirs) + s = File::PATH_SEPARATOR + Hoe::RUBY_FLAGS.sub!(/-I/, "-I#{dirs.join(s)}#{s}") + end + + def normalize_deps deps + Array(deps).map { |o| String === o ? [o] : o } + end + + def missing name + warn "** #{name} is missing or in the wrong format for auto-intuiting." + warn " run `sow blah` and look at its text files" + end + + def initialize(name, version) # :nodoc: + self.name = name + self.version = version + + # Defaults + self.author = [] + self.clean_globs = %w(diff diff.txt email.txt ri deps .source_index + *.gem *~ **/*~ *.rbc **/*.rbc) + self.description_sections = %w(description) + self.blog_categories = [name] + self.email = [] + self.extra_deps = [] + self.extra_dev_deps = [] + self.multiruby_skip = [] + self.need_tar = true + self.need_zip = false + self.rdoc_pattern = /^(lib|bin|ext)|txt$/ + self.remote_rdoc_dir = name + self.rsync_args = '-av --delete' + self.rubyforge_name = name.downcase + self.spec_extras = {} + self.summary_sentences = 1 + self.test_globs = ['test/**/test_*.rb'] + self.testlib = 'test/unit' + self.post_install_message = nil + + yield self if block_given? + + # Intuit values: + + readme = File.read("README.txt").split(/^(=+ .*)$/)[1..-1] rescue '' + unless readme.empty? then + sections = readme.map { |s| + s =~ /^=/ ? s.strip.downcase.chomp(':').split.last : s.strip + } + sections = Hash[*sections] + desc = sections.values_at(*description_sections).join("\n\n") + summ = desc.split(/\.\s+/).first(summary_sentences).join(". ") + + self.description ||= desc + self.summary ||= summ + self.url ||= readme[1].gsub(/^\* /, '').split(/\n/).grep(/\S+/) + else + missing 'README.txt' + end + + self.changes ||= begin + h = File.read("History.txt") + h.split(/^(===.*)/)[1..2].join.strip + rescue + missing 'History.txt' + '' + end + + %w(email author).each do |field| + value = self.send(field) + if value.nil? or value.empty? then + if Time.now < Time.local(2008, 4, 1) then + warn "Hoe #{field} value not set - Fix by 2008-04-01!" + self.send "#{field}=", "doofus" + else + abort "Hoe #{field} value not set. aborting" + end + end + end + + hoe_deps = { + 'rake' => ">= #{RAKEVERSION}", + 'rubyforge' => ">= #{::RubyForge::VERSION}", + } + + self.extra_deps = normalize_deps extra_deps + self.extra_dev_deps = normalize_deps extra_dev_deps + + if name == 'hoe' then + hoe_deps.each do |pkg, vers| + extra_deps << [pkg, vers] + end + else + extra_dev_deps << ['hoe', ">= #{VERSION}"] unless hoe_deps.has_key? name + end + + define_tasks + end + + def developer name, email + self.author << name + self.email << email + end + + def with_config # :nodoc: + rc = File.expand_path("~/.hoerc") + exists = File.exist? rc + config = exists ? YAML.load_file(rc) : {} + yield(config, rc) + end + + def define_tasks # :nodoc: + desc 'Run the default tasks.' + task :default => :test + + desc 'Run the test suite. Use FILTER to add to the command line.' + task :test do + run_tests + end + + desc 'Show which test files fail when run alone.' + task :test_deps do + tests = Dir["test/**/test_*.rb"] + Dir["test/**/*_test.rb"] + + paths = ['bin', 'lib', 'test'].join(File::PATH_SEPARATOR) + null_dev = WINDOZE ? '> NUL 2>&1' : '&> /dev/null' + + tests.each do |test| + if not system "ruby -I#{paths} #{test} #{null_dev}" then + puts "Dependency Issues: #{test}" + end + end + end + + desc 'Run the test suite using multiruby.' + task :multi do + run_tests :multi + end + + ############################################################ + # Packaging and Installing + + signing_key = nil + cert_chain = [] + + with_config do |config, path| + break unless config['signing_key_file'] and config['signing_cert_file'] + key_file = File.expand_path config['signing_key_file'].to_s + signing_key = key_file if File.exist? key_file + + cert_file = File.expand_path config['signing_cert_file'].to_s + cert_chain << cert_file if File.exist? cert_file + end + + self.spec = Gem::Specification.new do |s| + s.name = name + s.version = version + s.summary = summary + case author + when Array + s.authors = author + else + s.author = author + end + s.email = email + s.homepage = Array(url).first + s.rubyforge_project = rubyforge_name + + s.description = description + + extra_deps.each do |dep| + s.add_dependency(*dep) + end + + extra_dev_deps.each do |dep| + s.add_development_dependency(*dep) + end + + s.files = File.read("Manifest.txt").delete("\r").split(/\n/) + s.executables = s.files.grep(/^bin/) { |f| File.basename(f) } + + s.bindir = "bin" + dirs = Dir['{lib,ext}'] + s.require_paths = dirs unless dirs.empty? + + s.rdoc_options = ['--main', 'README.txt'] + s.extra_rdoc_files = s.files.grep(/txt$/) + s.has_rdoc = true + + s.post_install_message = post_install_message + + if test ?f, "test/test_all.rb" then + s.test_file = "test/test_all.rb" + else + s.test_files = Dir[*test_globs] + end + + if signing_key and cert_chain then + s.signing_key = signing_key + s.cert_chain = cert_chain + end + + ############################################################ + # Allow automatic inclusion of compiled extensions + if ENV['INLINE'] then + s.platform = ENV['FORCE_PLATFORM'] || Gem::Platform::CURRENT + + # Try collecting Inline extensions for +name+ + if defined?(Inline) then + directory 'lib/inline' + + Inline.registered_inline_classes.each do |cls| + name = cls.name # TODO: what about X::Y::Z? + # name of the extension is CamelCase + alternate_name = if name =~ /[A-Z]/ then + name.gsub(/([A-Z])/, '_\1').downcase.sub(/^_/, '') + elsif name =~ /_/ then + name.capitalize.gsub(/_([a-z])/) { $1.upcase } + end + + extensions = Dir.chdir(Inline::directory) { + Dir["Inline_{#{name},#{alternate_name}}_*.#{DLEXT}"] + } + + extensions.each do |ext| + # add the inlined extension to the spec files + s.files += ["lib/inline/#{ext}"] + + # include the file in the tasks + file "lib/inline/#{ext}" => ["lib/inline"] do + cp File.join(Inline::directory, ext), "lib/inline" + end + end + end + end + end + + # Do any extra stuff the user wants + spec_extras.each do |msg, val| + case val + when Proc + val.call(s.send(msg)) + else + s.send "#{msg}=", val + end + end + end + + desc 'Show information about the gem.' + task :debug_gem do + puts spec.to_ruby + end + + self.lib_files = spec.files.grep(/^(lib|ext)/) + self.bin_files = spec.files.grep(/^bin/) + self.test_files = spec.files.grep(/^test/) + + Rake::GemPackageTask.new spec do |pkg| + pkg.need_tar = @need_tar + pkg.need_zip = @need_zip + end + + desc 'Install the package as a gem.' + task :install_gem => [:clean, :package] do + gem = Dir['pkg/*.gem'].first + sh "#{'sudo ' unless WINDOZE}gem install --local #{gem}" + end + + desc 'Package and upload the release to rubyforge.' + task :release => [:clean, :package] do |t| + v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z" + abort "Versions don't match #{v} vs #{version}" if v != version + pkg = "pkg/#{name}-#{version}" + + if $DEBUG then + puts "release_id = rf.add_release #{rubyforge_name.inspect}, #{name.inspect}, #{version.inspect}, \"#{pkg}.tgz\"" + puts "rf.add_file #{rubyforge_name.inspect}, #{name.inspect}, release_id, \"#{pkg}.gem\"" + end + + rf = RubyForge.new.configure + puts "Logging in" + rf.login + + c = rf.userconfig + c["release_notes"] = description if description + c["release_changes"] = changes if changes + c["preformatted"] = true + + files = [(@need_tar ? "#{pkg}.tgz" : nil), + (@need_zip ? "#{pkg}.zip" : nil), + "#{pkg}.gem"].compact + + puts "Releasing #{name} v. #{version}" + rf.add_release rubyforge_name, name, version, *files + end + + ############################################################ + # Doco + + Rake::RDocTask.new(:docs) do |rd| + rd.main = "README.txt" + rd.options << '-d' if + `which dot` =~ /\/dot/ unless ENV['NODOT'] unless WINDOZE + rd.rdoc_dir = 'doc' + files = spec.files.grep(rdoc_pattern) + files -= ['Manifest.txt'] + rd.rdoc_files.push(*files) + + title = "#{name}-#{version} Documentation" + title = "#{rubyforge_name}'s " + title if rubyforge_name != name + + rd.options << "-t #{title}" + end + + desc 'Generate ri locally for testing.' + task :ridocs => :clean do + sh %q{ rdoc --ri -o ri . } + end + + desc 'Publish RDoc to RubyForge.' + task :publish_docs => [:clean, :docs] do + config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml"))) + host = "#{config["username"]}@rubyforge.org" + + remote_dir = "/var/www/gforge-projects/#{rubyforge_name}/#{remote_rdoc_dir}" + local_dir = 'doc' + + sh %{rsync #{rsync_args} #{local_dir}/ #{host}:#{remote_dir}} + end + + # no doco for this one + task :publish_on_announce do + with_config do |config, _| + Rake::Task['publish_docs'].invoke if config["publish_on_announce"] + end + end + + ############################################################ + # Dependencies: + + namespace :deps do + require 'zlib' # HACK for rubygems 1.3.0 + require 'rubygems/remote_fetcher' + + @@index = nil + + def self.get_source_index + return @@index if @@index + + dump = unless File.exist? '.source_index' then + url = GEMURL + "Marshal.#{Gem.marshal_version}.Z" + dump = Gem::RemoteFetcher.fetcher.fetch_path url + dump = Gem.inflate dump + open '.source_index', 'wb' do |io| io.write dump end + dump + else + open '.source_index', 'rb' do |io| io.read end + end + + @@index = Marshal.load dump + end + + def self.get_latest_gems + @@cache ||= get_source_index.latest_specs + end + + def self.get_gems_by_name + @@by_name ||= Hash[*get_latest_gems.map { |gem| + [gem.name, gem, gem.full_name, gem] + }.flatten] + end + + def self.dependent_upon name + get_latest_gems.find_all { |gem| + gem.dependencies.any? { |dep| dep.name == name } + } + end + + + desc "List all the dependent gems of this gem" + task :list do + gems = self.get_gems_by_name + gem = gems[self.name] + + abort "Couldn't find gem: #{self.name}" unless gem + + deps = self.dependent_upon self.name + max = deps.map { |s| s.full_name.size }.max + + puts " dependents:" + unless deps.empty? then + deps.sort_by { |spec| spec.full_name }.each do |spec| + vers = spec.dependencies.find {|s| s.name == name }.requirement_list + puts " %-*s - %s" % [max, spec.full_name, vers.join(", ")] + end + else + puts " none" + end + end + + desc "Print a contact list for gems dependent on this gem" + task :email do + gems = self.get_gems_by_name + gem = gems[self.name] + + abort "Couldn't find gem: #{self.name}" unless gem + + deps = self.dependent_upon self.name + + email = deps.map { |s| s.email }.flatten.sort.uniq + email = email.map { |s| s.split(/,\s*/) }.flatten.sort.uniq + + email.map! { |s| # don't you people realize how easy this is? + s.gsub(/ at | _at_ |\s*(atmark|@nospam@|-at?-|@at?@||\[at?\]|\(at?\))\s*/i, '@').gsub(/\s*(dot|\[d(ot)?\]|\.dot\.)\s*/i, '.').gsub(/\s+com$/, '.com') + } + + bad, good = email.partition { |e| e !~ /^[\w.+-]+\@[\w.+-]+$/ } + + warn "Rejecting #{bad.size} email. I couldn't unmunge them." unless + bad.empty? + + puts good.join(", ") + end + + desc "Fetch all the dependent gems of this gem into tarballs" + task :fetch do + gems = self.get_gems_by_name + gem = gems[self.name] + deps = self.dependent_upon self.name + + mkdir "deps" unless File.directory? "deps" + Dir.chdir "deps" do + begin + deps.sort_by { |spec| spec.full_name }.each do |spec| + full_name = spec.full_name + tgz_name = "#{full_name}.tgz" + gem_name = "#{full_name}.gem" + + next if File.exist? tgz_name + FileUtils.rm_rf [full_name, gem_name] + + begin + warn "downloading #{full_name}" + Gem::RemoteFetcher.fetcher.download(spec, GEMURL, Dir.pwd) + FileUtils.mv "cache/#{gem_name}", '.' + rescue Gem::RemoteFetcher::FetchError + warn " failed" + next + end + + warn "converting #{gem_name} to tarball" + + system "gem unpack #{gem_name} 2> /dev/null" + system "gem spec -l #{gem_name} > #{full_name}/gemspec.rb" + system "tar zmcf #{tgz_name} #{full_name}" + FileUtils.rm_rf [full_name, gem_name, "cache"] + end + ensure + FileUtils.rm_rf "cache" + end + end + end + end + + ############################################################ + # Misc/Maintenance: + + desc 'Run ZenTest against the package.' + task :audit do + libs = %w(lib test ext).join(File::PATH_SEPARATOR) + sh "zentest -I=#{libs} #{spec.files.grep(/^(lib|test)/).join(' ')}" + end + + desc 'Clean up all the extras.' + task :clean => [ :clobber_docs, :clobber_package ] do + clean_globs.each do |pattern| + files = Dir[pattern] + rm_rf files, :verbose => true unless files.empty? + end + end + + desc 'Create a fresh ~/.hoerc file.' + task :config_hoe do + with_config do |config, path| + default_config = { + "exclude" => /tmp$|CVS|\.svn/, + "publish_on_announce" => false, + "signing_key_file" => "~/.gem/gem-private_key.pem", + "signing_cert_file" => "~/.gem/gem-public_cert.pem", + "blogs" => [ { + "user" => "user", + "url" => "url", + "extra_headers" => { + "mt_convert_breaks" => "markdown" + }, + "blog_id" => "blog_id", + "password"=>"password", + } ], + } + File.open(path, "w") do |f| + YAML.dump(default_config.merge(config), f) + end + + editor = ENV['EDITOR'] || 'vi' + system "#{editor} #{path}" if ENV['SHOW_EDITOR'] != 'no' + end + end + + desc 'Generate email announcement file.' + task :email do + require 'rubyforge' + subject, title, body, urls = announcement + + File.open("email.txt", "w") do |mail| + mail.puts "Subject: [ANN] #{subject}" + mail.puts + mail.puts title + mail.puts + mail.puts urls + mail.puts + mail.puts body + mail.puts + mail.puts urls + end + puts "Created email.txt" + end + + desc 'Post announcement to blog.' + task :post_blog do + require 'xmlrpc/client' + + with_config do |config, path| + break unless config['blogs'] + + subject, title, body, urls = announcement + body += "\n\n#{urls}" + + config['blogs'].each do |site| + server = XMLRPC::Client.new2(site['url']) + content = site['extra_headers'].merge(:title => title, + :description => body, + :categories => blog_categories) + + result = server.call('metaWeblog.newPost', + site['blog_id'], + site['user'], + site['password'], + content, + true) + end + end + end + + desc 'Post announcement to rubyforge.' + task :post_news do + require 'rubyforge' + subject, title, body, urls = announcement + + rf = RubyForge.new.configure + rf.login + rf.post_news(rubyforge_name, subject, "#{title}\n\n#{body}") + puts "Posted to rubyforge" + end + + desc 'Create news email file and post to rubyforge.' + task :announce => [:email, :post_news, :post_blog, :publish_on_announce ] + + desc 'Verify the manifest.' + task :check_manifest => :clean do + f = "Manifest.tmp" + require 'find' + files = [] + with_config do |config, _| + exclusions = config["exclude"] + abort "exclude entry missing from .hoerc. Aborting." if exclusions.nil? + Find.find '.' do |path| + next unless File.file? path + next if path =~ exclusions + files << path[2..-1] + end + files = files.sort.join "\n" + File.open f, 'w' do |fp| fp.puts files end + system "#{DIFF} -du Manifest.txt #{f}" + rm f + end + end + + desc 'Generate a key for signing your gems.' + task :generate_key do + email = spec.email + abort "No email in your gemspec" if email.nil? or email.empty? + + key_file = with_config { |config, _| config['signing_key_file'] } + cert_file = with_config { |config, _| config['signing_cert_file'] } + + if key_file.nil? or cert_file.nil? then + ENV['SHOW_EDITOR'] ||= 'no' + Rake::Task['config_hoe'].invoke + + key_file = with_config { |config, _| config['signing_key_file'] } + cert_file = with_config { |config, _| config['signing_cert_file'] } + end + + key_file = File.expand_path key_file + cert_file = File.expand_path cert_file + + unless File.exist? key_file or File.exist? cert_file then + sh "gem cert --build #{email}" + mv "gem-private_key.pem", key_file, :verbose => true + mv "gem-public_cert.pem", cert_file, :verbose => true + + puts "Installed key and certificate." + + rf = RubyForge.new.configure + rf.login + + cert_package = "#{rubyforge_name}-certificates" + + begin + rf.lookup 'package', cert_package + rescue + rf.create_package rubyforge_name, cert_package + end + + begin + rf.lookup('release', cert_package)['certificates'] + rf.add_file rubyforge_name, cert_package, 'certificates', cert_file + rescue + rf.add_release rubyforge_name, cert_package, 'certificates', cert_file + end + + puts "Uploaded certificate to release \"certificates\" in package #{cert_package}" + else + puts "Keys already exist." + end + end + + end # end define + + def announcement # :nodoc: + changes = self.changes.rdoc_to_markdown + subject = "#{name} #{version} Released" + title = "#{name} version #{version} has been released!" + body = "#{description}\n\nChanges:\n\n#{changes}".rdoc_to_markdown + urls = Array(url).map { |s| "* <#{s.strip.rdoc_to_markdown}>" }.join("\n") + + return subject, title, body, urls + end + + def run_tests(multi=false) # :nodoc: + msg = multi ? :sh : :ruby + cmd = if test ?f, 'test/test_all.rb' then + "#{RUBY_FLAGS} test/test_all.rb #{FILTER}" + else + tests = ["rubygems", self.testlib] + + test_globs.map { |g| Dir.glob(g) }.flatten + tests.map! {|f| %Q(require "#{f}")} + "#{RUBY_FLAGS} -e '#{tests.join("; ")}' #{FILTER}" + end + + excludes = multiruby_skip.join(":") + ENV['EXCLUDED_VERSIONS'] = excludes + cmd = "multiruby #{cmd}" if multi + + send msg, cmd + end + + ## + # Reads a file at +path+ and spits out an array of the +paragraphs+ specified. + # + # changes = p.paragraphs_of('History.txt', 0..1).join("\n\n") + # summary, *description = p.paragraphs_of('README.txt', 3, 3..8) + + def paragraphs_of(path, *paragraphs) + File.read(path).delete("\r").split(/\n\n+/).values_at(*paragraphs) + end +end + +# :enddoc: + +class ::Rake::SshDirPublisher # :nodoc: + attr_reader :host, :remote_dir, :local_dir +end + +class String + def rdoc_to_markdown + self.gsub(/^mailto:/, '').gsub(/^(=+)/) { "#" * $1.size } + end +end + +if $0 == __FILE__ then + out = `rake -T | egrep -v "redocs|repackage|clobber|trunk"` + if ARGV.empty? then + # # default:: Run the default tasks. + puts out.gsub(/(\s*)\#/, '::\1').gsub(/^rake /, '# ') + else + # * default - Run the default tasks. + puts out.gsub(/\#/, '-').gsub(/^rake /, '* ') + end +end diff --git a/vendor/gems/gems/hoe-1.8.2/test/test_hoe.rb b/vendor/gems/gems/hoe-1.8.2/test/test_hoe.rb new file mode 100644 index 0000000..d859278 --- /dev/null +++ b/vendor/gems/gems/hoe-1.8.2/test/test_hoe.rb @@ -0,0 +1,97 @@ + +require 'test/unit/testcase' +require 'hoe' + +$rakefile = nil # shuts up a warning in rdoctask.rb + +class TestHoe < Test::Unit::TestCase + def setup + Rake.application.clear + end + + ## + # Yes, these tests suck, but it is damn hard to test this since + # everything is forked out. + + def test_basics + boring = %w(clobber_docs clobber_package gem redocs repackage) + expected = %w(audit + announce + check_manifest + clean + config_hoe + debug_gem + default + deps:email + deps:fetch + deps:list + docs + email + generate_key + install_gem + multi + package + post_blog + post_news + publish_docs + release + ridocs + test + test_deps) + expected += boring + + spec = Hoe.new('blah', '1.0.0') do |h| + h.developer("name", "email") + end + + assert_equal ["name"], spec.author + assert_equal ["email"], spec.email + + tasks = Rake.application.tasks + public_tasks = tasks.reject { |t| t.comment.nil? }.map { |t| t.name }.sort + + assert_equal expected.sort, public_tasks + end + + def test_possibly_better + t = Gem::Specification::TODAY + hoe = Hoe.new("blah", '1.2.3') do |h| + h.developer 'author', 'email' + end + + files = File.read("Manifest.txt").split(/\n/) + + spec = hoe.spec + + assert_equal 'blah', spec.name + assert_equal '1.2.3', spec.version.to_s + assert_equal '>= 0', spec.required_rubygems_version.to_s + + assert_equal ['author'], spec.authors + assert_equal t, spec.date + assert_equal 'sow', spec.default_executable + assert_match(/Hoe.*Rakefiles/, spec.description) + assert_equal ['email'], spec.email + assert_equal ['sow'], spec.executables + assert_equal files.grep(/txt$/), spec.extra_rdoc_files + assert_equal files, spec.files + assert_equal true, spec.has_rdoc + assert_equal "http://rubyforge.org/projects/seattlerb/", spec.homepage + assert_equal ['--main', 'README.txt'], spec.rdoc_options + assert_equal ['lib'], spec.require_paths + assert_equal 'blah', spec.rubyforge_project + assert_equal Gem::RubyGemsVersion, spec.rubygems_version + assert_match(/^Hoe.*Rakefiles$/, spec.summary) + assert_equal files.grep(/^test/), spec.test_files + + deps = spec.dependencies + + assert_equal 1, deps.size + + dep = deps.first + + assert_equal 'hoe', dep.name + assert_equal :development, dep.type + assert_equal ">= #{Hoe::VERSION}", dep.version_requirements.to_s + end +end diff --git a/vendor/gems/gems/rake-0.8.3/CHANGES b/vendor/gems/gems/rake-0.8.3/CHANGES new file mode 100644 index 0000000..ce3ab9f --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/CHANGES @@ -0,0 +1,400 @@ + += Rake Changelog + +== Version 0.8.3 + +* Enhanced the system directory detection in windows. We now check + HOMEDRIVE/HOMEPATH and USERPROFILE if APPDATA isn't found. (Patch + supplied by James Tucker). Rake no long aborts if it can't find the + directory. + +* Added fix to handle ruby installations in directories with spaces in + their name. + +== Version 0.8.2 + +* Fixed bug in package task so that it will include the subdir + directory in the package for testing. (Bug found by Adam Majer) + +* Added ENV var to rakefile to prevent OS X from including extended + attribute junk in a tar file. (Bug found by Adam Majer) + +* Fixed filename dependency order bug in test_inspect_pending and + test_to_s_pending. (Bug found by Adam Majer) + +* Fixed check for file utils options to make them immune to the + symbol/string differences. (Patch supplied by Edwin Pratomo) + +* Fixed bug with rules involving multiple source (Patch supplied by + Emanuel Indermühle) + +* Switched from getoptlong to optparse (patches supplied by Edwin + Pratomo) + +* The -T option will now attempt to dynamically sense the size of the + terminal. RAKE_COLUMNS will override any dynamic sensing. + +* FileList#clone and FileList#dup have better sematics w.r.t. taint + and freeze. + +* Added ability clear prerequisites, and/or actions from an existing + task. + +* Added the ability to reenable a task to be invoked a second time. + +* Changed RDoc test task to have no default template. This makes it + easier for the tempate to pick up the template from the environment. + +* Changed from using Mutex to Monitor. Evidently Mutex causes thread + join errors when Ruby is compiled with -disable-pthreads. (Patch + supplied by Ittay Dror) + +* Fixed bug in makefile parser that had problems with extra spaces in + file task names. (Patch supplied by Ittay Dror) + +* Added a performance patch for reading large makefile dependency + files. (Patch supplied by Ittay Dror) + +* Default values for task arguments can easily be specified with the + :with_defaults method. (Idea for default argument merging supplied + by (Adam Q. Salter) + +* The -T output will only self-truncate if the output is a tty. + However, if RAKE_COLUMNS is explicitly set, it will be honored in + any case. (Patch provided by Gavin Stark). + +* Numerous fixes for running under windows. A big thanks to Bheeshmar + Redheendran for spending a good part of the afternoon at the + Lonestar Ruby Conference to help me work out these issues. + +== Version 0.8.1 + +* Removed requires on parsedate.rb (in Ftptools) +* Removed ftools from rake.rb. Made it options in sys.rb + +== Version 0.8.0 + +* Added task parameters (e.g. "rake build[version7]") +* Made task parameters passable to prerequisites. +* Comments are limited to 80 columns or so (suggested by Jamis Buck). +* Added -D to display full comments (suggested by Jamis Buck). +* The rake program will set the status value used in any explicit + exit(n) calls. (patch provided by Stephen Touset) +* Fixed error in functional tests that were not including session (and + silently skipping the functionl tests. +* Removed --usage and make -h the same as -H. +* Make a prettier inspect for tasks. + +== Version 0.7.3 + +* Added existing and existing! methods to FileList +* FileLists now claim to be Arrays (via is_a?) to get better support + from the FileUtil module. +* Added init and top_level for custom rake applications. + +== Version 0.7.2 + +* Error messages are now send to stderr rather than stdout (from + Payton Quackenbush). +* Better error handling on invalid command line arguments (from Payton + Quackenbush). +* Added rcov task and updated unit testing for better code coverage. +* Fixed some bugs where the application object was going to the global + appliation instead of using its own data. +* Added square and curly bracket patterns to FileList#include (Tilman + Sauerbeck). +* Added plain filename support to rule dependents (suggested by Nobu + Nakada). +* Added pathmap support to rule dependents. +* Added a 'tasks' method to a namespace to get a list of tasks + associated with the namespace. +* Fixed the method name leak from FileUtils (bug found by Glenn + Vanderburg). +* Added rake_extension to handle detection of extension collisions. +* Added test for noop, bad_option and verbose flags to sh command. +* Removed dependency on internal fu_xxx functions from FileUtils. +* Added a 'shame' task to the Rakefile. +* Added tar_command and zip_command options to the Package task. +* Added a description to the gem task in GemPackageTask. +* Fixed a bug when rules have multiple prerequisites (patch by Joel + VanderWerf) +* Added a protected 'require "rubygems"' to test/test_application to + unbreak cruisecontrol.rb. +* Added the handful of RakeFileUtils to the private method as well. +* Added block based exclusion. +* The clean task will no longer delete 'core' if it is a directory. +* Removed rake_dup. Now we just simply rescue a bad dup. +* Refactored the FileList reject logic to remove duplication. +* Removed if __FILE__ at the end of the rake.rb file. + +== Version 0.7.1 + +* Added optional filter parameter to the --tasks command line option. +* Added flatten to allow rule transform procs to return lists of + prereqs (Joel VanderWerf provided patch). +* Added pathmap to String and FileList. +* The -r option will now load .rake files (but a straight require + doesn't yet). NOTE: This is experimental ... it may be + discontinued. +* The -f option without a value will disable the search for a + Rakefile. The assumption is that the -r files are adequate. +* Fixed the safe_ln function to fall back to cp in more error + scenarios. + +== Version 0.7.0 + +* Added Rake.original_dir to return the original starting directory of + the rake application. +* Added safe_ln support for openAFS (from Ludvig Omholt). +* Added --trace reminder on short exception messages (David Heinemeier + Hansson suggestion). +* Added multitask declaration that executes prerequisites in + parallel. (Doug Young providied an initial implementation). +* Fixed missing_const hack to be compatible with Rails. (Jamis Buck + supplied test case). +* Made the RDoc task default to internal (in-process) RDoc formatting. + The old behavior is still available by setting the +external+ flag + to true. +* Rakefiles are now loaded with the expanded path to prevent + accidental polution from the Ruby load path. +* The +namespace+ command now returns a NameSpace object that can be + used to lookup tasks defined in that namespace. This allows for + better anonymous namespace behavior. +* Task objects my now be used in prerequisite lists directly. + +== Version 0.6.1 + +* Rebuilt 0.6.0 gem without signing. + +== Version 0.6.0 + +* Fixed file creation bug in the unit tests (caused infinite loop on + windows). +* Fixed bug where session based functional tests were run under + windows. +* Fixed bug in directory tasks so that updating a directory will not + retrigger file tasks depending on the directory (see + FileCreationTask and EarlyTime). +* Added egrep to FileList +* ruby command now runs same ruby version as rake. +* Added investigation to task object. (suggested by Martin Fowler) +* Added ruby_opts to the test task to allow arbitrary ruby options to + be passed to the test script. (Greg Fast) +* Fixed the test loader to ignore options. (Greg Fast) +* Moved Task, FileTask, FileCreationTask and RakeApp into the Rake + module namespace. Old style namespace behavior can be invoked via + the --classic-namespace option. (requested by Kelly Felkins). +* GemTask is now sensitive to the gem platform (Masao Mutoh). +* A non-existing file prerequisite will no longer cause an exception + (Philipp Neubeck). +* Multiple prerequisites on Rake rules now allowed (initial patch + supplied by Stuart Jansen). + +== Version 0.5.4 + +* Added double quotes to the test runner. +* Added .svn to default ignore list. +* Updated FileList#include to support nested arrays and filelists. + +== Version 0.5.3 + +* Added support for importing Rakefile and other dependencies. +* Fixed bug so that now rules can chain off of existing tasks as well + as existing files. +* Fixed verbose flag bug in the testing task. Shortened some failure + messages. +* Make FileUtils methods private at the top level module to avoid + accidental method leaking into other objects. +* Added test loader option to test task. "testrb" is no longer the + default test loader. It is now eating syntax errors that should + halt the unit tests. +* Revamped FileList so that it works more like and array (addressed + flatten bug). Added many tests around file list. +* Added +ext+ method to both String and FileList. + +== Version 0.5.0 + +* Fixed documentation that was lacking the Rake module name (Tilman + Sauerbeck). +* Added tar.gz and tar.bz2 support to package task (Tilman Sauerbeck). +* Recursive rules are now supported (Tilman Sauerbeck). +* Added warning option for the Test Task (requested by Eric Hodel). +* The jamis rdoc template is only used if it exists. +* Added fix for Ruby 1.8.2 test/unit and rails problem. +* Added contributed rake man file (Jani Monoses). +* Added Brian Candler's fix for problems in --trace and --dry-run + mode. + +== Version 0.4.15 + +* Fixed a bug that prevented the TESTOPTS flag from working with the + revised for 1.8.2 test task. +* Updated the docs on --trace to indicate that it also enables a full + backtrace on errors. + +== Version 0.4.14 + +* Modified the TestTask to workaround the Ruby 1.8.2 change in + autoexecuting unit tests. + +== Version 0.4.13 + +* Fixed the dry-run flag so it is operating again. +* Multiple arguments to sh and ruby commands will not be interpreted + by the shell (patch provided by Jonathan Paisley). + +== Version 0.4.12 + +* Added --silent (-s) to suppress the (in directory) rake message. + +== Version 0.4.11 + +* Changed the "don't know how to rake" message (finally) +* Changes references to a literal "Rakefile" to reference the global + variable $rakefile (which contains the actual name of the rakefile). + +== Version 0.4.10 + +* Added block support to the "sh" command, allowing users to take + special actions on the result of the system call. E.g. + + sh "shell_command" do |ok, res| + puts "Program returned #{res.exitstatus}" if ! ok + end + +== Version 0.4.9 + +* Switched to Jamis Buck's RDoc template. +* Removed autorequire from Rake's gem spec. This prevents the Rake + libraries from loading while using rails. + +== Version 0.4.8 + +* Added support for .rb versions of Rakefile. +* Removed \\\n's from test task. +* Fixed Ruby 1.9 compatibility issue with FileList. + +== Version 0.4.7 + +* Fixed problem in FileList that caused Ruby 1.9 to go into infinite + recursion. Since to_a was removed from Object, it does not need to + added back into the list of methods to rewrite in FileList. (Thanks + to Kent Sibilev for pointing this out). + +== Version 0.4.6 +* Removed test version of ln in FileUtils that prevented safe_ln from + using ln. + +== Version 0.4.5 +* Upgraded comments in TestTask. +* FileList to_s and inspect now automatically resolve pending changes. +* FileList#exclude properly returns the FileList. + +== Version 0.4.4 +* Fixed initialization problem with @comment. +* Now using multi -r technique in TestTask. Switch Rakefile back to + using the built-in test task macros because the rake runtime is no + longer needed. +* Added 'TEST=filename' and 'TESTOPTS=options' to the Test Task + macros. +* Allow a +test_files+ attribute in test tasks. This allows more + flexibility in specifying test files. + +== Version 0.4.3 +* Fixed Comment leakage. + +== Version 0.4.2 +* Added safe_ln that falls back to a copy if a file link is not supported. +* Package builder now uses safe_ln. + +== Version 0.4.1 +* Task comments are now additive, combined with "/". +* Works with (soon to be released) rubygems 0.6.2 (or 0.7.0) + +== Version 0.4.0 +* FileList now uses deferred loading. The file system is not searched + until the first call that needs the file names. +* VAR=VALUE options are now accepted on the command line and are + treated like environment variables. The values may be tested in a + Rakefile by referencing ENV['VAR']. +* File.mtime is now used (instead of File.new().mtime). + +== Version 0.3.2.x + +* Removed some hidden dependencies on rubygems. Tests now will test + gems only if they are installed. +* Removed Sys from some example files. I believe that is that last + reference to Sys outside of the contrib area. +* Updated all copyright notices to include 2004. + +== Version 0.3.2 + +* GEM Installation now works with the application stub. + +== Version 0.3.1 + +* FileLists now automatically ignore CVS, .bak, ! +* GEM Installation now works. + +== Version 0.3.0 + +Promoted 0.2.10. + +== Version 0.2.10 +General + +* Added title to Rake's rdocs +* Contrib packages are no longer included in the documentation. + +RDoc Issues + +* Removed default for the '--main' option +* Fixed rendering of the rdoc options +* Fixed clean/clobber confusion with rerdoc +* 'title' attribute added + +Package Task Library Issues + +* Version (or explicit :noversion) is required. +* +package_file+ attribute is now writable + +FileList Issues + +* Dropped bang version of exclude. Now using ant-like include/exclude semantics. +* Enabled the "yield self" idiom in FileList#initialize. + +== Version 0.2.9 + +This version contains numerous changes as the RubyConf.new(2003) +presentation was being prepared. The changes include: + +* The monolithic rubyapp task library is in the process of being + dropped in favor of lighter weight task libraries. + +== Version 0.2.7 + +* Added "desc" for task descriptions. +* -T will now display tasks with descriptions. +* -P will display tasks and prerequisites. +* Dropped the Sys module in favor of the 1.8.x FileUtils module. Sys + is still supported in the contrib area. + +== Version 0.2.6 + +* Moved to RubyForge + +== Version 0.2.5 + +* Switched to standard ruby app builder. +* Added no_match option to file matcher. + +== Version 0.2.4 + +* Fixed indir, which neglected to actually change directories. + +== Version 0.2.3 + +* Added rake module for a help target +* Added 'for_files' to Sys +* Added a $rakefile constant +* Added test for selecting proper rule with multiple targets. diff --git a/vendor/gems/gems/rake-0.8.3/MIT-LICENSE b/vendor/gems/gems/rake-0.8.3/MIT-LICENSE new file mode 100644 index 0000000..7273475 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/MIT-LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2003, 2004 Jim Weirich + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/gems/gems/rake-0.8.3/README b/vendor/gems/gems/rake-0.8.3/README new file mode 100644 index 0000000..a04fa7e --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/README @@ -0,0 +1,285 @@ += RAKE -- Ruby Make + +Supporting Rake version: 0.8.2 + +This package contains Rake, a simple ruby build program with +capabilities similar to make. + +Rake has the following features: + +* Rakefiles (rake's version of Makefiles) are completely defined in + standard Ruby syntax. No XML files to edit. No quirky Makefile + syntax to worry about (is that a tab or a space?) + +* Users can specify tasks with prerequisites. + +* Rake supports rule patterns to synthesize implicit tasks. + +* Flexible FileLists that act like arrays but know about manipulating + file names and paths. + +* A library of prepackaged tasks to make building rakefiles easier. + +== Download + +The latest version of rake can be found at + +* http://rubyforge.org/project/showfiles.php?group_id=50 + +== Source Repository + +Rake is currently hosted at github. The github web page is +http://github.com/jimweirich/rake. The public git clone URL is + +* git://github.com/jimweirich/rake.git + +== Installation + +=== Normal Installation + +You can install rake with the following command. + + % ruby install.rb + +from its distribution directory. + +=== GEM Installation + +Download and install rake with the following. + + gem install --remote rake + +=== Running the Rake Test Suite + +If you wish to run the unit and functional tests that come with Rake: + +* Install the 'session' gem in order to run the functional tests. adf + asdf asdf +* CD into the top project directory of rake. +* Type one of the following: + + rake # If you have a version of rake installed + ruby -Ilib bin/rake # If you do not have a version of rake installed. + +== Online Resources + +== Rake References + +* Rake Documentation Home: http://docs.rubyrake.org +* Rake Project Page: http://rubyforge.org/projects/rake +* Rake API Documents: http://rake.rubyforge.org +* Rake Source Code Repo: http://github.com/jimweirich/rake +* Rake Git Repo Clone URL: git://github.com/jimweirich/rake.git + +== Presentations and Articles about Rake + +* Jim Weirich's 2003 RubyConf presentation: http://onestepback.org/articles/buildingwithrake/ +* Martin Fowler's article on Rake: http://martinfowler.com/articles/rake.html + +=== Road Map + +* If you want to see how to invoke rake to build your projects, read on. +* If you want to see the format of a Rakefile, see + doc/rakefile.rdoc[http://rake.rubyforge.org/files/doc/rakefile_rdoc.html]. +* If you want to see the original announcement of rake, see + doc/rational.rdoc[http://rake.rubyforge.org/files/doc/rational_rdoc.html]. +* If you want to see a glossary of terms, see + doc/glossary.rdoc[http://rake.rubyforge.org/files/doc/glossary_rdoc.html]. + +== Simple Example + +Once installed, you can run rake as follows ... + + % rake [options ...] [VAR=VALUE ...] [tasks...] + +Type "rake --help" for an up-to-date option summary. + +Invoking rake without any options or targets causes rake to +look for a rakefile and invoke the default task in that rakefile. + +For example, given a simple rakefile like this ... + + task :default => [:test] + + task :test do + ruby "test/unittest.rb" + end + +The command + + $ rake + +will invoke the +default+ task. As +default+ satisfies its +prerequisites, the +test+ task will run the unit tests for the +package. + +== Other Make Reinvisionings ... + +Rake is a late entry in the make replacement field. Here are links to +other projects with similar (and not so similar) goals. + +* http://directory.fsf.org/bras.html -- Bras, one of earliest + implementations of "make in a scripting language". +* http://www.a-a-p.org -- Make in Python +* http://www.aromatic.com/tools/jam.txt -- JAM, Java Automated Make +* http://ant.apache.org -- The Ant project +* http://ppt.perl.org/commands/make/index.html -- Make from the Perl + Power Tools implementation. +* http://search.cpan.org/search?query=PerlBuildSystem -- The Perl Build System +* http://make.rubyforge.org -- Rant, another Ruby make tool. + +== Credits + +[Ryan Dlugosz] For the initial conversation that sparked Rake. + +[nobu.nokada@softhome.net] For the initial patch for rule support. + +[Tilman Sauerbeck ] For the recursive rule patch. + +== License + +Rake is available under an MIT-style license. + +:include: MIT-LICENSE + +== Support + +The Rake homepage is http://rake.rubyforge.org. You can find the Rake +RubyForge page at http://rubyforge.org/projects/rake. + +Feel free to submit commits or feature requests. If you send a patch, +remember to update the corresponding unit tests. If fact, I prefer +new feature to be submitted in the form of new unit tests. + +For other information, feel free to ask on the ruby-talk mailing list +(which is mirrored to comp.lang.ruby) or contact +mailto:jim@weirichhouse.org. + +---- + += Usage + +Rake is invoked from the command line using: + + % rake [options ...] [VAR=VALUE] [targets ...] + +Options are: + +[name=value] + Set the environment variable name to value + during the execution of the rake command. You can access + the value by using ENV['name']. + +[--classic-namespace (-n)] + Import the Task, FileTask, and FileCreateTask into the top-level + scope to be compatible with older versions of Rake. Alternatively + you can include the line require + 'rake/classic_namespace' in your Rakefile to get the + classic behavior. + +[--describe _pattern_ (-D)] + Describe the tasks (matching optional PATTERN), then exit. + +[--dry-run (-n)] + Do a dry run. Print the tasks invoked and executed, but do not + actually execute any of the actions. + +[--execute _code_ (-e)] + Execute some Ruby code and exit. + +[--execute-print _code_ (-p)] + Execute some Ruby code, print the result, and exit. + +[--execute-continue _code_ (-p)] + Execute some Ruby code, then continue with normal task processing. + +[--help (-H)] + Display some help text and exit. + +[--libdir _directory_ (-I)] + Add _directory_ to the list of directories searched for require. + +[--nosearch (-N)] + Do not search for a Rakefile in parent directories. + +[--prereqs (-P)] + Display a list of all tasks and their immediate prerequisites. + +[--quiet (-q)] + Do not echo commands from FileUtils. + +[--rakefile _filename_ (-f)] + Use _filename_ as the name of the rakefile. The default rakefile + names are +rakefile+ and +Rakefile+ (with +rakefile+ taking + precedence). If the rakefile is not found in the current + directory, +rake+ will search parent directories for a match. The + directory where the Rakefile is found will become the current + directory for the actions executed in the Rakefile. + +[--rakelibdir _rakelibdir_ (-R)] + Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib') + +[--require _name_ (-r)] + Require _name_ before executing the Rakefile. + +[--rules] + Trace the rules resolution. + +[--silent (-s)] + Like --quiet, but also suppresses the 'in directory' announcement. + +[--system (-g)] + Use the system wide (global) rakefiles. The project Rakefile is + ignored. By default, the system wide rakefiles are used only if no + project Rakefile is found. On Unix-like system, the system wide + rake files are located in $HOME/.rake. On a windows system they + are stored in $APPDATA/Rake. + +[--no-system (-G)] + Use the project level Rakefile, ignoring the system-wide (global) + rakefiles. + +[--tasks (-T)] + Display a list of the major tasks and their comments. Comments + are defined using the "desc" command. + +[--trace (-t)] + Turn on invoke/execute tracing. Also enable full backtrace on + errors. + +[--usage (-h)] + Display a usage message and exit. + +[--verbose (-v)] + Echo the Sys commands to standard output. + +[--version (-V)] + Display the program version and exit. + +In addition, any command line option of the form +VAR=VALUE will be added to the environment hash +ENV and may be tested in the Rakefile. + +--- + += Rakefile Format + +See doc/rakefile.rdoc[http://rake.rubyforge.org/files/doc/rakefile_rdoc.html] +for details on the Rakefile format. + +--- + += Other stuff + +Author:: Jim Weirich +Requires:: Ruby 1.8.0 or later +License:: Copyright 2003, 2004 by Jim Weirich. + Released under an MIT-style license. See the LICENSE file + included in the distribution. + +== Warranty + +This software is provided "as is" and without any express or +implied warranties, including, without limitation, the implied +warranties of merchantibility and fitness for a particular +purpose. diff --git a/vendor/gems/gems/rake-0.8.3/Rakefile b/vendor/gems/gems/rake-0.8.3/Rakefile new file mode 100644 index 0000000..2e26efb --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/Rakefile @@ -0,0 +1,418 @@ +# Rakefile for rake -*- ruby -*- + +# Copyright 2003, 2004, 2005 by Jim Weirich (jim@weirichhouse.org) +# All rights reserved. + +# This file may be distributed under an MIT style license. See +# MIT-LICENSE for details. + +begin + require 'rubygems' + require 'rake/gempackagetask' +rescue Exception + nil +end +require 'rake/clean' +require 'rake/testtask' +require 'rake/rdoctask' + +CLEAN.include('**/*.o', '*.dot', '**/.*.rbc') +CLOBBER.include('doc/example/main', 'testdata') +CLOBBER.include('test/data/**/temp_*') +CLOBBER.include('test/data/chains/play.*') +CLOBBER.include('test/data/file_creation_task/build') +CLOBBER.include('test/data/file_creation_task/src') +CLOBBER.include('TAGS') +CLOBBER.include('coverage', 'rcov_aggregate') + +# Prevent OS X from including extended attribute junk in the tar output +ENV['COPY_EXTENDED_ATTRIBUTES_DISABLE'] = 'true' + +def announce(msg='') + STDERR.puts msg +end + +# Determine the current version of the software + +if `ruby -Ilib ./bin/rake --version` =~ /rake, version ([0-9.]+)$/ + CURRENT_VERSION = $1 +else + CURRENT_VERSION = "0.0.0" +end + +$package_version = CURRENT_VERSION + +SRC_RB = FileList['lib/**/*.rb'] + +# The default task is run if rake is given no explicit arguments. + +desc "Default Task" +task :default => :test_all + +# Test Tasks --------------------------------------------------------- +task :dbg do |t| + puts "Arguments are: #{t.args.join(', ')}" +end + +# Common Abbreviations ... + +task :ta => :test_all +task :tf => :test_functional +task :tu => :test_units +task :tc => :test_contribs +task :test => :test_units + +Rake::TestTask.new(:test_all) do |t| + t.test_files = FileList[ + 'test/test*.rb', + 'test/contrib/test*.rb', + 'test/fun*.rb' + ] + t.warning = true + t.verbose = false +end + +Rake::TestTask.new(:test_units) do |t| + t.test_files = FileList['test/test*.rb'] + t.warning = true + t.verbose = false +end + +Rake::TestTask.new(:test_functional) do |t| + t.test_files = FileList['test/fun*.rb'] + t.warning = true + t.verbose = false +end + +Rake::TestTask.new(:test_contribs) do |t| + t.test_files = FileList['test/contrib/test*.rb'] + t.warning = true + t.verbose = false +end + +begin + require 'rcov/rcovtask' + + Rcov::RcovTask.new do |t| + t.libs << "test" + dot_rakes = + t.rcov_opts = [ + '-xRakefile', '-xrakefile', '-xpublish.rf', + '-xlib/rake/contrib', '-x/Library', + '--text-report', + '--sort coverage' + ] + FileList['rakelib/*.rake'].pathmap("-x%p") + t.test_files = FileList[ + 'test/test*.rb', 'test/functional.rb' + ] + t.output_dir = 'coverage' + t.verbose = true + end +rescue LoadError + puts "RCov is not available" +end + +directory 'testdata' +[:test_all, :test_units, :test_contribs, :test_functional].each do |t| + task t => ['testdata'] +end + +# CVS Tasks ---------------------------------------------------------- + +# Install rake using the standard install.rb script. + +desc "Install the application" +task :install do + ruby "install.rb" +end + +# Create a task to build the RDOC documentation tree. + +rd = Rake::RDocTask.new("rdoc") { |rdoc| + rdoc.rdoc_dir = 'html' +# rdoc.template = 'kilmer' +# rdoc.template = 'css2' + rdoc.template = 'doc/jamis.rb' + rdoc.title = "Rake -- Ruby Make" + rdoc.options << '--line-numbers' << '--inline-source' << + '--main' << 'README' << + '--title' << 'Rake -- Ruby Make' + rdoc.rdoc_files.include('README', 'MIT-LICENSE', 'TODO', 'CHANGES') + rdoc.rdoc_files.include('lib/**/*.rb', 'doc/**/*.rdoc') + rdoc.rdoc_files.exclude(/\bcontrib\b/) +} + +# ==================================================================== +# Create a task that will package the Rake software into distributable +# tar, zip and gem files. + +PKG_FILES = FileList[ + 'install.rb', + '[A-Z]*', + 'bin/**/*', + 'lib/**/*.rb', + 'test/**/*.rb', + 'test/**/*.rf', + 'test/**/*.mf', + 'test/**/Rakefile', + 'test/**/subdir', + 'doc/**/*' +] +PKG_FILES.exclude('doc/example/*.o') +PKG_FILES.exclude(%r{doc/example/main$}) + +if ! defined?(Gem) + puts "Package Target requires RubyGEMs" +else + SPEC = Gem::Specification.new do |s| + + #### Basic information. + + s.name = 'rake' + s.version = $package_version + s.summary = "Ruby based make-like utility." + s.description = <<-EOF + Rake is a Make-like program implemented in Ruby. Tasks + and dependencies are specified in standard Ruby syntax. + EOF + + #### Dependencies and requirements. + + #s.add_dependency('log4r', '> 1.0.4') + #s.requirements << "" + + #### Which files are to be included in this gem? Everything! (Except CVS directories.) + + s.files = PKG_FILES.to_a + + #### C code extensions. + + #s.extensions << "ext/rmagic/extconf.rb" + + #### Load-time details: library and application (you will need one or both). + + s.require_path = 'lib' # Use these for libraries. + + s.bindir = "bin" # Use these for applications. + s.executables = ["rake"] + s.default_executable = "rake" + + #### Documentation and testing. + + s.has_rdoc = true + s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$/ }.to_a + s.rdoc_options = rd.options + + #### Author and project details. + + s.author = "Jim Weirich" + s.email = "jim@weirichhouse.org" + s.homepage = "http://rake.rubyforge.org" + s.rubyforge_project = "rake" +# if ENV['CERT_DIR'] +# s.signing_key = File.join(ENV['CERT_DIR'], 'gem-private_key.pem') +# s.cert_chain = [File.join(ENV['CERT_DIR'], 'gem-public_cert.pem')] +# end + end + + package_task = Rake::GemPackageTask.new(SPEC) do |pkg| + pkg.need_zip = true + pkg.need_tar = true + end + + file "rake.gemspec" => ["Rakefile", "lib/rake.rb"] do |t| + require 'yaml' + open(t.name, "w") { |f| f.puts SPEC.to_yaml } + end + + desc "Create a stand-alone gemspec" + task :gemspec => "rake.gemspec" +end + +# Misc tasks ========================================================= + +def count_lines(filename) + lines = 0 + codelines = 0 + open(filename) { |f| + f.each do |line| + lines += 1 + next if line =~ /^\s*$/ + next if line =~ /^\s*#/ + codelines += 1 + end + } + [lines, codelines] +end + +def show_line(msg, lines, loc) + printf "%6s %6s %s\n", lines.to_s, loc.to_s, msg +end + +desc "Count lines in the main rake file" +task :lines do + total_lines = 0 + total_code = 0 + show_line("File Name", "LINES", "LOC") + SRC_RB.each do |fn| + lines, codelines = count_lines(fn) + show_line(fn, lines, codelines) + total_lines += lines + total_code += codelines + end + show_line("TOTAL", total_lines, total_code) +end + +# Define an optional publish target in an external file. If the +# publish.rf file is not found, the publish targets won't be defined. + +load "publish.rf" if File.exist? "publish.rf" + +# Support Tasks ------------------------------------------------------ + +RUBY_FILES = FileList['**/*.rb'].exclude('pkg') + +desc "Look for TODO and FIXME tags in the code" +task :todo do + RUBY_FILES.egrep(/#.*(FIXME|TODO|TBD)/) +end + +desc "Look for Debugging print lines" +task :dbg do + RUBY_FILES.egrep(/\bDBG|\bbreakpoint\b/) +end + +desc "List all ruby files" +task :rubyfiles do + puts RUBY_FILES + puts FileList['bin/*'].exclude('bin/*.rb') +end +task :rf => :rubyfiles + +desc "Create a TAGS file" +task :tags => "TAGS" + +TAGS = 'xctags -e' + +file "TAGS" => RUBY_FILES do + puts "Makings TAGS" + sh "#{TAGS} #{RUBY_FILES}", :verbose => false +end + +# -------------------------------------------------------------------- +# Creating a release + +def plugin(plugin_name) + require "rake/plugins/#{plugin_name}" +end + +task :noop +#plugin "release_manager" + +desc "Make a new release" +task :release, :rel, :reuse, :reltest, + :needs => [ + :prerelease, + :clobber, + :test_all, + :update_version, + :package, + :tag + ] do + announce + announce "**************************************************************" + announce "* Release #{$package_version} Complete." + announce "* Packages ready to upload." + announce "**************************************************************" + announce +end + +# Validate that everything is ready to go for a release. +task :prerelease, :rel, :reuse, :reltest do |t, args| + $package_version = args.rel + announce + announce "**************************************************************" + announce "* Making RubyGem Release #{$package_version}" + announce "* (current version #{CURRENT_VERSION})" + announce "**************************************************************" + announce + + # Is a release number supplied? + unless args.rel + fail "Usage: rake release[X.Y.Z] [REUSE=tag_suffix]" + end + + # Is the release different than the current release. + # (or is REUSE set?) + if $package_version == CURRENT_VERSION && ! args.reuse + fail "Current version is #{$package_version}, must specify REUSE=tag_suffix to reuse version" + end + + # Are all source files checked in? + if args.reltest + announce "Release Task Testing, skipping checked-in file test" + else + announce "Checking for unchecked-in files..." + data = `svn st` + unless data =~ /^$/ + abort "svn status is not clean ... do you have unchecked-in files?" + end + announce "No outstanding checkins found ... OK" + end +end + +task :update_version, :rel, :reuse, :reltest, + :needs => [:prerelease] do |t, args| + if args.rel == CURRENT_VERSION + announce "No version change ... skipping version update" + else + announce "Updating Rake version to #{args.rel}" + open("lib/rake.rb") do |rakein| + open("lib/rake.rb.new", "w") do |rakeout| + rakein.each do |line| + if line =~ /^RAKEVERSION\s*=\s*/ + rakeout.puts "RAKEVERSION = '#{args.rel}'" + else + rakeout.puts line + end + end + end + end + mv "lib/rake.rb.new", "lib/rake.rb" + if args.reltest + announce "Release Task Testing, skipping commiting of new version" + else + sh %{svn commit -m "Updated to version #{args.rel}" lib/rake.rb} # " + end + end +end + +desc "Tag all the CVS files with the latest release number (REL=x.y.z)" +task :tag, :rel, :reuse, :reltest, + :needs => [:prerelease] do |t, args| + reltag = "REL_#{args.rel.gsub(/\./, '_')}" + reltag << args.reuse.gsub(/\./, '_') if args.reuse + announce "Tagging Repository with [#{reltag}]" + if args.reltest + announce "Release Task Testing, skipping CVS tagging" + else + sh %{svn copy svn+ssh://rubyforge.org/var/svn/rake/trunk svn+ssh://rubyforge.org/var/svn/rake/tags/#{reltag} -m 'Commiting release #{reltag}'} ###' + end +end + +desc "Install the jamis RDoc template" +task :install_jamis_template do + require 'rbconfig' + dest_dir = File.join(Config::CONFIG['rubylibdir'], "rdoc/generators/template/html") + fail "Unabled to write to #{dest_dir}" unless File.writable?(dest_dir) + install "doc/jamis.rb", dest_dir, :verbose => true +end + +# Require experimental XForge/Metaproject support. + +load 'xforge.rf' if File.exist?('xforge.rf') + +desc "Where is the current directory. This task displays\nthe current rake directory" +task :where_am_i do + puts Rake.original_dir +end diff --git a/vendor/gems/gems/rake-0.8.3/TODO b/vendor/gems/gems/rake-0.8.3/TODO new file mode 100644 index 0000000..bd8a969 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/TODO @@ -0,0 +1,20 @@ += Rake Project -- To Do List + +Send suggestions for this list to mailto:jim@weirichhouse.org or on +the rake-devel@rubyforge.org mailing list. + +=== To Do +* Need a nice API for accessing tasks in namespaces, namespaces in an app, etc. +* Provide a way to disable -w warning mode. +* Define a set of default rules that work in the absense of any Rakefile +* What about cyclic dependencies? +* Java support utilities +* Installation support utilities + * Check out installpkg.rb +* Autogenerate Dependencies +* Rules should apply to existing tasks if no actions are defined. +* How to create multiple package tasks without task name collision? +* Trap "ln -s" commands that fail and use "cp" instead (SMB mounted + drives have problems with "ln -s". + +(moved DONE list to CHANGES file) diff --git a/vendor/gems/gems/rake-0.8.3/bin/rake b/vendor/gems/gems/rake-0.8.3/bin/rake new file mode 100755 index 0000000..c9e95da --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/bin/rake @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby + +#-- +# Copyright (c) 2003, 2004, 2005, 2006, 2007 Jim Weirich +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +#++ + +begin + require 'rake' +rescue LoadError + require 'rubygems' + require 'rake' +end +Rake.application.run diff --git a/vendor/gems/gems/rake-0.8.3/doc/example/Rakefile1 b/vendor/gems/gems/rake-0.8.3/doc/example/Rakefile1 new file mode 100644 index 0000000..39f8bcc --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/example/Rakefile1 @@ -0,0 +1,38 @@ +# Example Rakefile -*- ruby -*- + +task :default => [:main] + +file "a.o" => ["a.c"] do |t| + src = t.name.sub(/\.o$/, '.c') + sh "gcc #{src} -c -o #{t.name}" +end + +file "b.o" => ["b.c"] do |t| + src = t.name.sub(/\.o$/, '.c') + sh "gcc #{src} -c -o #{t.name}" +end + +file "main.o" => ["main.c"] do |t| + src = t.name.sub(/\.o$/, '.c') + sh "gcc #{src} -c -o #{t.name}" +end + +OBJFILES = ["a.o", "b.o", "main.o"] +task :obj => OBJFILES + +file "main" => OBJFILES do |t| + sh "gcc -o #{t.name} main.o a.o b.o" +end + +task :clean do + rm_f FileList['*.o'] + Dir['*~'].each { |fn| rm_f fn } +end + +task :clobber => [:clean] do + rm_f "main" +end + +task :run => ["main"] do + sh "./main" +end diff --git a/vendor/gems/gems/rake-0.8.3/doc/example/Rakefile2 b/vendor/gems/gems/rake-0.8.3/doc/example/Rakefile2 new file mode 100644 index 0000000..35310ec --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/example/Rakefile2 @@ -0,0 +1,35 @@ +# Example Rakefile -*- ruby -*- +# Using the power of Ruby + +task :default => [:main] + +def ext(fn, newext) + fn.sub(/\.[^.]+$/, newext) +end + +SRCFILES = Dir['*.c'] +OBJFILES = SRCFILES.collect { |fn| ext(fn,".o") } + +OBJFILES.each do |objfile| + srcfile = ext(objfile, ".c") + file objfile => [srcfile] do |t| + sh "gcc #{srcfile} -c -o #{t.name}" + end +end + +file "main" => OBJFILES do |t| + sh "gcc -o #{t.name} main.o a.o b.o" +end + +task :clean do + rm_f FileList['*.o'] + Dir['*~'].each { |fn| rm_f fn } +end + +task :clobber => [:clean] do + rm_f "main" +end + +task :run => ["main"] do + sh "./main" +end diff --git a/vendor/gems/gems/rake-0.8.3/doc/example/a.c b/vendor/gems/gems/rake-0.8.3/doc/example/a.c new file mode 100644 index 0000000..620e6f8 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/example/a.c @@ -0,0 +1,6 @@ +#include + +void a() +{ + printf ("In function a\n"); +} diff --git a/vendor/gems/gems/rake-0.8.3/doc/example/b.c b/vendor/gems/gems/rake-0.8.3/doc/example/b.c new file mode 100644 index 0000000..9b24aa1 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/example/b.c @@ -0,0 +1,6 @@ +#include + +void b() +{ + printf ("In function b\n"); +} diff --git a/vendor/gems/gems/rake-0.8.3/doc/example/main.c b/vendor/gems/gems/rake-0.8.3/doc/example/main.c new file mode 100644 index 0000000..a04558a --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/example/main.c @@ -0,0 +1,11 @@ +#include + +extern void a(); +extern void b(); + +int main () +{ + a(); + b(); + return 0; +} diff --git a/vendor/gems/gems/rake-0.8.3/doc/glossary.rdoc b/vendor/gems/gems/rake-0.8.3/doc/glossary.rdoc new file mode 100644 index 0000000..0ca1869 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/glossary.rdoc @@ -0,0 +1,51 @@ += Glossary + +[action] + Code to be executed in order to perform a task. Actions in a + rakefile are specified in a code block (usually delimited by + +do+/+end+ pairs. + +[execute] + When a task is executed, all of its actions are performed, in + the order they were defined. Note that unlike + invoke, execute always executes the actions + (without invoking or executing the prerequisites). + +[file task (FileTask)] + A file task is a task whose purpose is to create a file + (which has the same name as the task). When invoked, a file + task will only execute if one or more of the following + conditions are true. + + 1. The associated file does not exist. + 2. A prerequisite has a later time stamp than the existing file. + + Because normal Tasks always have the current time as + timestamp, a FileTask that has a normal Task prerequisite + will always execute. + +[invoke] + When a task is invoked, first we check to see if it has been + invoked before. if it has been, then nothing else is done. + If this is the first time its been invoked, then we invoke + each of its prerequisites. Finally, we check to see if we + need to execute the actions of this task by calling + needed?. Finally, if the task is needed, we execute + its actions. + + NOTE: Currently prerequisites are invoked even if the task is + not needed. This may change in the future. + +[prerequisites] + Every task has a set (possiblity empty) of prerequisites. A + prerequisite P to Task T is itself a task that must be invoked + before Task T. + +[rule] + A rule is a recipe for synthesizing a task when no task is + explicitly defined. Rules generally synthesize file tasks. + +[task (Task)] + Basic unit of work in a rakefile. A task has a name, a set of + prerequisites and a list of actions to be performed. + diff --git a/vendor/gems/gems/rake-0.8.3/doc/jamis.rb b/vendor/gems/gems/rake-0.8.3/doc/jamis.rb new file mode 100644 index 0000000..c7439d8 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/jamis.rb @@ -0,0 +1,591 @@ +module RDoc +module Page + +FONTS = "\"Bitstream Vera Sans\", Verdana, Arial, Helvetica, sans-serif" + +STYLE = < pre { + padding: 0.5em; + border: 1px dotted black; + background: #FFE; +} + +CSS + +XHTML_PREAMBLE = %{ + +} + +HEADER = XHTML_PREAMBLE + < + + %title% + + + + + + + +ENDHEADER + +FILE_PAGE = < + + + + +
File
%short_name%
+ + + + + + + + + +
Path:%full_path% +IF:cvsurl +  (CVS) +ENDIF:cvsurl +
Modified:%dtm_modified%
+
+ +
+HTML + +################################################################### + +CLASS_PAGE = < + %classmod%
%full_name% + + + + + + +IF:parent + + + + +ENDIF:parent +
In: +START:infiles +HREF:full_path_url:full_path: +IF:cvsurl + (CVS) +ENDIF:cvsurl +END:infiles +
Parent: +IF:par_url + +ENDIF:par_url +%parent% +IF:par_url + +ENDIF:par_url +
+ + + +HTML + +################################################################### + +METHOD_LIST = < +IF:diagram +
+ %diagram% +
+ENDIF:diagram + +IF:description +

%description%
+ENDIF:description + +IF:requires +
Required Files
+
    +START:requires +
  • HREF:aref:name:
  • +END:requires +
+ENDIF:requires + +IF:toc +
Contents
+ +ENDIF:toc + +IF:methods +
Methods
+
    +START:methods +
  • HREF:aref:name:
  • +END:methods +
+ENDIF:methods + +IF:includes +
Included Modules
+
    +START:includes +
  • HREF:aref:name:
  • +END:includes +
+ENDIF:includes + +START:sections +IF:sectitle + +IF:seccomment +
+%seccomment% +
+ENDIF:seccomment +ENDIF:sectitle + +IF:classlist +
Classes and Modules
+ %classlist% +ENDIF:classlist + +IF:constants +
Constants
+ +START:constants + + + + + +IF:desc + + + + +ENDIF:desc +END:constants +
%name%=%value%
 %desc%
+ENDIF:constants + +IF:attributes +
Attributes
+ +START:attributes + + + + + +END:attributes +
+IF:rw +[%rw%] +ENDIF:rw + %name%%a_desc%
+ENDIF:attributes + +IF:method_list +START:method_list +IF:methods +
%type% %category% methods
+START:methods +
+
+IF:callseq + %callseq% +ENDIF:callseq +IFNOT:callseq + %name%%params% +ENDIF:callseq +IF:codeurl +[ source ] +ENDIF:codeurl +
+IF:m_desc +
+ %m_desc% +
+ENDIF:m_desc +IF:aka +
+ This method is also aliased as +START:aka + %name% +END:aka +
+ENDIF:aka +IF:sourcecode +
+ +
+
+%sourcecode%
+
+
+
+ENDIF:sourcecode +
+END:methods +ENDIF:methods +END:method_list +ENDIF:method_list +END:sections + +HTML + +FOOTER = < + +ENDFOOTER + +BODY = HEADER + < + +
+ #{METHOD_LIST} +
+ + #{FOOTER} +ENDBODY + +########################## Source code ########################## + +SRC_PAGE = XHTML_PREAMBLE + < +%title% + + + + +
%code%
+ + +HTML + +########################## Index ################################ + +FR_INDEX_BODY = < + + + + + + + +
+START:entries +%name%
+END:entries +
+ +HTML + +CLASS_INDEX = FILE_INDEX +METHOD_INDEX = FILE_INDEX + +INDEX = XHTML_PREAMBLE + < + + %title% + + + + + + + + + +IF:inline_source + +ENDIF:inline_source +IFNOT:inline_source + + + + +ENDIF:inline_source + + <body bgcolor="white"> + Click <a href="html/index.html">here</a> for a non-frames + version of this page. + </body> + + + + +HTML + +end +end + + diff --git a/vendor/gems/gems/rake-0.8.3/doc/proto_rake.rdoc b/vendor/gems/gems/rake-0.8.3/doc/proto_rake.rdoc new file mode 100644 index 0000000..39b9b88 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/proto_rake.rdoc @@ -0,0 +1,127 @@ += Original Prototype Rake + +This is the original 100 line prototype rake program. + +--- + #!/usr/bin/env ruby + + require 'ftools' + + class Task + TASKS = Hash.new + + attr_reader :prerequisites + + def initialize(task_name) + @name = task_name + @prerequisites = [] + @actions = [] + end + + def enhance(deps=nil, &block) + @prerequisites |= deps if deps + @actions << block if block_given? + self + end + + def name + @name.to_s + end + + def invoke + @prerequisites.each { |n| Task[n].invoke } + execute if needed? + end + + def execute + return if @triggered + @triggered = true + @actions.collect { |act| result = act.call(self) }.last + end + + def needed? + true + end + + def timestamp + Time.now + end + + class << self + def [](task_name) + TASKS[intern(task_name)] or fail "Don't know how to rake #{task_name}" + end + + def define_task(args, &block) + case args + when Hash + fail "Too Many Target Names: #{args.keys.join(' ')}" if args.size > 1 + fail "No Task Name Given" if args.size < 1 + task_name = args.keys[0] + deps = args[task_name] + else + task_name = args + deps = [] + end + deps = deps.collect {|d| intern(d) } + get(task_name).enhance(deps, &block) + end + + def get(task_name) + name = intern(task_name) + TASKS[name] ||= self.new(name) + end + + def intern(task_name) + (Symbol === task_name) ? task_name : task_name.intern + end + end + end + + class FileTask < Task + def needed? + return true unless File.exist?(name) + latest_prereq = @prerequisites.collect{|n| Task[n].timestamp}.max + return false if latest_prereq.nil? + timestamp < latest_prereq + end + + def timestamp + File.new(name.to_s).mtime + end + end + + def task(args, &block) + Task.define_task(args, &block) + end + + def file(args, &block) + FileTask.define_task(args, &block) + end + + def sys(cmd) + puts cmd + system(cmd) or fail "Command Failed: [#{cmd}]" + end + + def rake + begin + here = Dir.pwd + while ! File.exist?("Rakefile") + Dir.chdir("..") + fail "No Rakefile found" if Dir.pwd == here + here = Dir.pwd + end + puts "(in #{Dir.pwd})" + load "./Rakefile" + ARGV.push("default") if ARGV.size == 0 + ARGV.each { |task_name| Task[task_name].invoke } + rescue Exception => ex + puts "rake aborted ... #{ex.message}" + puts ex.backtrace.find {|str| str =~ /Rakefile/ } || "" + end + end + + if __FILE__ == $0 then + rake + end diff --git a/vendor/gems/gems/rake-0.8.3/doc/rake.1.gz b/vendor/gems/gems/rake-0.8.3/doc/rake.1.gz new file mode 100644 index 0000000000000000000000000000000000000000..02af4de4b50404e7a74f9495a78d3a2d4c42a312 GIT binary patch literal 1369 zcmV-f1*ZBRiwFph;1ogv19D+&WiBxQomSg!+eQ$5=T{8!5~-EwxImG@NZdHF0;}~! zkmNQ&-G?PPG&iPpnY~zHzrJUeq$~@0C~6qCyfb@d=FFK{r*|*tKYd+rJE7Ut*@x8$ zO@Ek@GP*3orz8c$M`^61Mi{YS$7Vv;XIHZc*-HDmpo~e>HRYnQ(R;i*iYW870 zzq#JOaXkHHLL1TIsuiLO4XPSn(sm8Ge*js(aWX zek1NV4OhFO^oA*tvJtt_c0#2NcS<&_az2Spsj3D-3u#4GGgWPa0Ag2KTD5}Uq9Be~x)ajms`tg`})3`Reb~yyLdQzvh;arw7-%htx@Vl`hS>3cHqa5<;HNH>95OMfS* zBs!kYRv(u0MNs76OO>#(@1+hZ3o0mCIB(dVB*_o7gbzqzOQYca(h?M7flIoitHC&q zI?Z)R*m2!bfpf(Lcu9z?LwAHJXz8<-Y^$93mJ(fS`gCowSmG#roE$)47m$*pPa}DL<_Qw$obcC$ot8v%i$+VnY$PrlMeMc zBQx*7Netf)y3t=S{TOq6hcdx`r$WZ{#bAv!7ThpI?i+9)J6C8@+EJ_m><1@6L=z%H zkq(Ok@!;<;6YNleb-W1~r;9}t=bAr}k2GN;g=-t#H4>_IaUx>2K_GYK`!`#}2rJ|C zu3UtXix_w1{JDWGHX^7*Vqrr>_N02$1rpQHa)}PbftAQm<`{#B1IaaE6+S{hY1HdY zlqz(+UL@0LVcMzjYJYi;rfQs=YqT9k3dWFbkOqI_+`AxW5w|Of?ocYOn}a7{G`#?d zv`q~T;(m-y8@9IFgz;i6vqGA;m-F}M^W|`HK2GK;uRTiZ4N^t6EDMuYK|oc%FJqSq z5L`f6yL6Q9J@?bOjzxv$?qINMAps!dP8$hM184{|4CnyZ>DoT8Z?Rt=_hS$`(1{9N z0^}sv6qv&p_F%{vvN<5@>n^)m-w!NxBQgv+I?(tXis@5)`*D6b8&Jw|g88I))UP0O zP)g6)+pC-N+y3HcYR1X3SA2h-aT!GW)bT?ci_gj(RAI--rNpT8MNY71u}5mF;|hQl zEq7VHL`MhW+m~QXX%AIz067Hc_&f-({-2yX6UO5J%#D+^H!93>n4||j>dFN!+)?yo z_kwx+N0N#BA>s_6KJ@4iw0g?W?<*a1oI#e)ogcy1Q@g*@Z5mwUv&3NPAhMrW6+o8+_hafRYFDR%G6u>Nu%nh^hg2oFt)={xe)9N7xvas>O4 z8J@_q+x5lGvU^&$klWTsY<8^XmVT2P`je%Rn6o!uHTpCe#`!k$%K718 bpixj|znYOw5kTV8VZrjh-^fVx). + + task :name => [:prereq1, :prereq2] + +NOTE: Although this syntax looks a little funky, it is legal +Ruby. We are constructing a hash where the key is :name and the value +for that key is the list of prerequisites. It is equivalent to the +following ... + + hash = Hash.new + hash[:name] = [:prereq1, :prereq2] + task(hash) + +=== Tasks with Actions + +Actions are defined by passing a block to the +task+ method. Any Ruby +code can be placed in the block. The block may reference the task +object via the block paramter.. + + task :name => [:prereq1, :prereq2] do |t| + # actions (may reference t) + end + +=== Multiple Definitions + +A task may be specified more than once. Each specification adds its +prerequisites and actions to the existing definition. This allows one +part of a rakefile to specify the actions and a different rakefile +(perhaps separately generated) to specify the dependencies. + +For example, the following is equivalent to the single task +specification given above. + + task :name + task :name => [:prereq1] + task :name => [:prereq2] + task :name do |t| + # actions + end + +== File Tasks + +Some tasks are designed to create a file from one or more other files. +Tasks that generate these files may be skipped if the file already +exists. File tasks are used to specify file creation tasks. + +File tasks are declared using the +file+ method (instead of the +task+ +method). In addition, file tasks are usually named with a string +rather than a symbol. + +The following file task creates a executable program (named +prog+) +given two object files name a.o and b.o. The tasks +for creating a.o and b.o are not shown. + + file "prog" => ["a.o", "b.o"] do |t| + sh "cc -o #{t.name} #{t.prerequisites.join(' ')}" + end + +== Directory Tasks + +It is common to need to create directories upon demand. The ++directory+ convenience method is a short-hand for creating a FileTask +that creates the directory. For example, the following declaration +... + + directory "testdata/examples/doc" + +is equivalent to ... + + file "testdata" do |t| mkdir t.name end + file "testdata/examples" do |t| mkdir t.name end + file "testdata/examples/doc" do |t| mkdir t.name end + +The +directory+ method does not accept prerequisites or actions, but +both prerequisites and actions can be added later. For example ... + + directory "testdata" + file "testdata" => ["otherdata"] + file "testdata" do + cp Dir["standard_data/*.data"], "testdata" + end + +== Tasks with Parallel Prerequisites + +Rake allows parallel execution of prerequisites using the following syntax: + + multitask :copy_files => [:copy_src, :copy_doc, :copy_bin] do + puts "All Copies Complete" + end + +In this example, +copy_files+ is a normal rake task. Its actions are +executed whereever all of its prerequisites are done. The big +difference is that the prerequisites (+copy_src+, +copy_bin+ and ++copy_doc+) are executed in parallel. Each of the prerequisites are +run in their own Ruby thread, possibly allowing faster overall runtime. + +=== Secondary Prerequisites + +If any of the primary prerequites of a multitask have common secondary +prerequisites, all of the primary/parallel prerequisites will wait +until the common prerequisites have been run. + +For example, if the copy_xxx tasks have the +following prerequisites: + + task :copy_src => [:prep_for_copy] + task :copy_bin => [:prep_for_copy] + task :copy_doc => [:prep_for_copy] + +Then the +prep_for_copy+ task is run before starting all the copies in +parallel. Once +prep_for_copy+ is complete, +copy_src+, +copy_bin+, +and +copy_doc+ are all run in parallel. Note that +prep_for_copy+ is +run only once, even though it is referenced in multiple threads. + +=== Thread Safety + +The Rake internal data structures are thread-safe with respect +to the multitask parallel execution, so there is no need for the user +to do extra synchronization for Rake's benefit. However, if there are +user data structures shared between the parallel prerequisites, the +user must do whatever is necessary to prevent race conditions. + +== Tasks with Arguments + +Prior to version 0.8.0, rake was only able to handle command line +arguments of the form NAME=VALUE that were passed into Rake via the +ENV hash. Many folks had asked for some kind of simple command line +arguments, perhaps using "--" to separate regular task names from +argument values on the command line. The problem is that there was no +easy way to associate positional arguments on the command line with +different tasks. Suppose both tasks :a and :b expect a command line +argument: does the first value go with :a? What if :b is run first? +Should it then get the first command line argument. + +Rake 0.8.0 solves this problem by explicitly passing values directly +to the tasks that need them. For example, if I had a release task +that required a version number, I could say: + + rake release[0.8.2] + +And the string "0.8.2" will be passed to the :release task. Multiple +arguments can be passed by separating them with a comma, for example: + + rake name[john,doe] + +Just a few words of caution. The rake task name and its arguments +need to be a single command line argument to rake. This generally +means no spaces. If spaces are needed, then the entire rake + +argument string should be quoted. Something like this: + + rake "name[billy bob, smith]" + +(Quoting rules vary between operating systems and shells, so make sure +you consult the proper docs for your OS/shell). + +=== Tasks that Expect Parameters + +Parameters are only given to tasks that are setup to expect them. In +order to handle named parameters, the task declaration syntax for +tasks has been extended slightly. + +For example, a task that needs a first name and last name might be +declared as: + + task :name, [:first_name, :last_name] + +The first argument is still the name of the task (:name in this case). +The next to argumements are the names of the parameters expected by +:name in an array (:first_name and :last_name in the example). + +To access the values of the paramters, the block defining the task +behaviour can now accept a second parameter: + + task :name, [:first_name, :last_name] do |t, args| + puts "First name is #{args.first_name}" + puts "Last name is #{args.last_name}" + end + +The first argument of the block "t" is always bound to the current +task object. The second argument "args" is an open-struct like object +that allows access to the task arguments. Extra command line +arguments to a task are ignored. Missing command line arguments are +given the nil value. + +If you wish to specify default values for the arguments, you can use +the with_defaults method in the task body. Here is the above example +where we specify default values for the first and last names: + + task :name, [:first_name, :last_name] do |t, args| + args.with_defaults(:first_name => "John", :last_name => "Dough") + puts "First name is #{args.first_name}" + puts "Last name is #{args.last_name}" + end + +=== Tasks that Expect Parameters and Have Prerequisites + +Tasks that use parameters have a slightly different format for +prerequisites. Use the :needs keyword to specify the +prerequisites for tasks with arguments. For example: + + task :name, [:first_name, :last_name] => [:pre_name] do |t, args| + args.with_defaults(:first_name => "John", :last_name => "Dough") + puts "First name is #{args.first_name}" + puts "Last name is #{args.last_name}" + end + +=== Deprecated Task Parameters Format + +There is an older format for declaring task parameters that omitted +the task array and used the :needs keyword to introduce the +dependencies. That format is still supported for compatibility, but +is not recommended for use. + +== Accessing Task Programatically + +Sometimes it is useful to manipulate tasks programatically in a +Rakefile. To find a task object, use the :[] operator on the +Rake::Task. + +=== Programmatic Task Example + +For example, the following Rakefile defines two tasks. The :doit task +simply prints a simple "DONE" message. The :dont class will lookup +the doit class and remove (clear) all of its prerequisites and +actions. + + task :doit do + puts "DONE" + end + + task :dont do + Rake::Task[:doit].clear + end + +Running this example: + + $ rake doit + (in /Users/jim/working/git/rake/x) + DONE + $ rake dont doit + (in /Users/jim/working/git/rake/x) + $ + +The ability to programmatically manipulate tasks gives rake very +powerful meta-programming capabilities w.r.t. task execution, but +should be used with cation. + +== Rules + +When a file is named as a prerequisite, but does not have a file task +defined for it, Rake will attempt to synthesize a task by looking at a +list of rules supplied in the Rakefile. + +Suppose we were trying to invoke task "mycode.o", but no task is +defined for it. But the rakefile has a rule that look like this ... + + rule '.o' => ['.c'] do |t| + sh "cc #{t.source} -c -o #{t.name}" + end + +This rule will synthesize any task that ends in ".o". It has a +prerequisite a source file with an extension of ".c" must exist. If +Rake is able to find a file named "mycode.c", it will automatically +create a task that builds "mycode.o" from "mycode.c". + +If the file "mycode.c" does not exist, rake will attempt +to recursively synthesize a rule for it. + +When a task is synthesized from a rule, the +source+ attribute of the +task is set to the matching source file. This allows us to write +rules with actions that reference the source file. + +=== Advanced Rules + +Any regular expression may be used as the rule pattern. Additionally, +a proc may be used to calculate the name of the source file. This +allows for complex patterns and sources. + +The following rule is equivalent to the example above. + + rule( /\.o$/ => [ + proc {|task_name| task_name.sub(/\.[^.]+$/, '.c') } + ]) do |t| + sh "cc #{t.source} -c -o #{t.name}" + end + +NOTE: Because of a _quirk_ in Ruby syntax, parenthesis are +required on *rule* when the first argument is a regular expression. + +The following rule might be used for Java files ... + + rule '.java' => [ + proc { |tn| tn.sub(/\.class$/, '.java').sub(/^classes\//, 'src/') } + ] do |t| + java_compile(t.source, t.name) + end + +NOTE: +java_compile+ is a hypothetical method that invokes the +java compiler. + +== Importing Dependencies + +Any ruby file (including other rakefiles) can be included with a +standard Ruby +require+ command. The rules and declarations in the +required file are just added to the definitions already accumulated. + +Because the files are loaded _before_ the rake targets are evaluated, +the loaded files must be "ready to go" when the rake command is +invoked. This make generated dependency files difficult to use. By +the time rake gets around to updating the dependencies file, it is too +late to load it. + +The +import+ command addresses this by specifying a file to be loaded +_after_ the main rakefile is loaded, but _before_ any targets on the +command line are specified. In addition, if the file name matches an +explicit task, that task is invoked before loading the file. This +allows dependency files to be generated and used in a single rake +command invocation. + +=== Example: + + require 'rake/loaders/makefile' + + file ".depends.mf" => [SRC_LIST] do |t| + sh "makedepend -f- -- #{CFLAGS} -- #{t.prerequisites} > #{t.name}" + end + + import ".depends.mf" + +If ".depends" does not exist, or is out of date w.r.t. the source +files, a new ".depends" file is generated using +makedepend+ before +loading. + +== Comments + +Standard Ruby comments (beginning with "#") can be used anywhere it is +legal in Ruby source code, including comments for tasks and rules. +However, if you wish a task to be described using the "-T" switch, +then you need to use the +desc+ command to describe the task. + +=== Example: + + desc "Create a distribution package" + task :package => [ ... ] do ... end + +The "-T" switch (or "--tasks" if you like to spell things out) will +display a list of tasks that have a defined comment. If you use ++desc+ to describe your major tasks, you have a semi-automatic way of +generating a summary of your Rake file. + + traken$ rake -T + (in /home/.../rake) + rake clean # Remove any temporary products. + rake clobber # Remove any generated file. + rake clobber_rdoc # Remove rdoc products + rake contrib_test # Run tests for contrib_test + rake default # Default Task + rake install # Install the application + rake lines # Count lines in the main rake file + rake rdoc # Build the rdoc HTML Files + rake rerdoc # Force a rebuild of the RDOC files + rake test # Run tests + rake testall # Run all test targets + +Only tasks with descriptions will be displayed with the "-T" switch. +Use "-P" (or "--prereqs") to get a list of all tasks and their +prerequisites. + +== Namespaces + +As projects grow (and along with it, the number of tasks), it is +common for task names to begin to clash. For example, if you might +have a main program and a set of sample programs built by a single +Rakefile. By placing the tasks related to the main program in one +namespace, and the tasks for building the sample programs in a +different namespace, the task names will not will not interfer with +each other. + +For example: + + namespace "main" + task :build do + # Build the main program + end + end + + namespace "samples" do + task :build do + # Build the sample programs + end + end + + task :build => ["main:build", "samples:build"] + +Referencing a task in a separate namespace can be achieved by +prefixing the task name with the namespace and a colon +(e.g. "main:build" refers to the :build task in the +main+ namespace). +Nested namespaces are supported, so + +Note that the name given in the +task+ command is always the unadorned +task name without any namespace prefixes. The +task+ command always +defines a task in the current namespace. + +=== FileTasks + +File task names are not scoped by the namespace command. Since the +name of a file task is the name of an actual file in the file system, +it makes little sense to include file task names in name space. +Directory tasks (created by the +directory+ command) are a type of +file task and are also not affected by namespaces. + +=== Name Resolution + +When looking up a task name, rake will start with the current +namespace and attempt to find the name there. If it fails to find a +name in the current namespace, it will search the parent namespaces +until a match is found (or an error occurs if there is no match). + +The "rake" namespace is a special implicit namespace that refers to +the toplevel names. + +If a task name begins with a "^" character, the name resolution will +start in the parent namespace. Multiple "^" characters are allowed. + +Here is an example file with multiple :run tasks and how various names +resolve in different locations. + + task :run + + namespace "one" do + task :run + + namespace "two" do + task :run + + # :run => "one:two:run" + # "two:run" => "one:two:run" + # "one:two:run" => "one:two:run" + # "one:run" => "one:run" + # "^run" => "one:run" + # "^^run" => "rake:run" (the top level task) + # "rake:run" => "rake:run" (the top level task) + end + + # :run => "one:run" + # "two:run" => "one:two:run" + # "^run" => "rake:run" + end + + # :run => "rake:run" + # "one:run" => "one:run" + # "one:two:run" => "one:two:run" + +== FileLists + +FileLists are the way Rake manages lists of files. You can treat a +FileList as an array of strings for the most part, but FileLists +support some additional operations. + +=== Creating a FileList + +Creating a file list is easy. Just give it the list of file names: + + fl = FileList['file1.rb', file2.rb'] + +Or give it a glob pattern: + + fl = FileList['*.rb'] + +== Odds and Ends + +=== do/end verses { } + +Blocks may be specified with either a +do+/+end+ pair, or with curly +braces in Ruby. We _strongly_ recommend using +do+/+end+ to specify the +actions for tasks and rules. Because the rakefile idiom tends to +leave off parenthesis on the task/file/rule methods, unusual +ambiguities can arise when using curly braces. + +For example, suppose that the method +object_files+ returns a list of +object files in a project. Now we use +object_files+ as the +prerequistes in a rule specified with actions in curly braces. + + # DON'T DO THIS! + file "prog" => object_files { + # Actions are expected here (but it doesn't work)! + } + +Because curly braces have a higher precedence than +do+/+end+, the +block is associated with the +object_files+ method rather than the ++file+ method. + +This is the proper way to specify the task ... + + # THIS IS FINE + file "prog" => object_files do + # Actions go here + end + +---- + +== See + +* README -- Main documentation for Rake. diff --git a/vendor/gems/gems/rake-0.8.3/doc/rational.rdoc b/vendor/gems/gems/rake-0.8.3/doc/rational.rdoc new file mode 100644 index 0000000..f741e65 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/rational.rdoc @@ -0,0 +1,151 @@ += Why rake? + +Ok, let me state from the beginning that I never intended to write this +code. I'm not convinced it is useful, and I'm not convinced anyone +would even be interested in it. All I can say is that Why's onion truck +must by been passing through the Ohio valley. + +What am I talking about? ... A Ruby version of Make. + +See, I can sense you cringing already, and I agree. The world certainly +doesn't need yet another reworking of the "make" program. I mean, we +already have "ant". Isn't that enough? + +It started yesterday. I was helping a coworker fix a problem in one of +the Makefiles we use in our project. Not a particularly tough problem, +but during the course of the conversation I began lamenting some of the +shortcomings of make. In particular, in one of my makefiles I wanted to +determine the name of a file dynamically and had to resort to some +simple scripting (in Ruby) to make it work. "Wouldn't it be nice if you +could just use Ruby inside a Makefile" I said. + +My coworker (a recent convert to Ruby) agreed, but wondered what it +would look like. So I sketched the following on the whiteboard... + + "What if you could specify the make tasks in Ruby, like this ..." + + task "build" do + java_compile(...args, etc ...) + end + + "The task function would register "build" as a target to be made, + and the block would be the action executed whenever the build + system determined that it was time to do the build target." + +We agreed that would be cool, but writing make from scratch would be WAY +too much work. And that was the end of that! + +... Except I couldn't get the thought out of my head. What exactly +would be needed to make the about syntax work as a make file? Hmmm, you +would need to register the tasks, you need some way of specifying +dependencies between tasks, and some way of kicking off the process. +Hey! What if we did ... and fifteen minutes later I had a working +prototype of Ruby make, complete with dependencies and actions. + +I showed the code to my coworker and we had a good laugh. It was just +about a page worth of code that reproduced an amazing amount of the +functionality of make. We were both truely stunned with the power of +Ruby. + +But it didn't do everything make did. In particular, it didn't have +timestamp based file dependencies (where a file is rebuilt if any of its +prerequisite files have a later timestamp). Obviously THAT would be a +pain to add and so Ruby Make would remain an interesting experiment. + +... Except as I walked back to my desk, I started thinking about what +file based dependecies would really need. Rats! I was hooked again, +and by adding a new class and two new methods, file/timestamp +dependencies were implemented. + +Ok, now I was really hooked. Last night (during CSI!) I massaged the +code and cleaned it up a bit. The result is a bare-bones replacement +for make in exactly 100 lines of code. + +For the curious, you can see it at ... +* doc/proto_rake.rdoc + +Oh, about the name. When I wrote the example Ruby Make task on my +whiteboard, my coworker exclaimed "Oh! I have the perfect name: Rake ... +Get it? Ruby-Make. Rake!" He said he envisioned the tasks as leaves +and Rake would clean them up ... or something like that. Anyways, the +name stuck. + +Some quick examples ... + +A simple task to delete backup files ... + + task :clean do + Dir['*~'].each {|fn| rm fn rescue nil} + end + +Note that task names are symbols (they are slightly easier to type +than quoted strings ... but you may use quoted string if you would +rather). Rake makes the methods of the FileUtils module directly +available, so we take advantage of the rm command. Also note +the use of "rescue nil" to trap and ignore errors in the rm +command. + +To run it, just type "rake clean". Rake will automatically find a +Rakefile in the current directory (or above!) and will invoke the +targets named on the command line. If there are no targets explicitly +named, rake will invoke the task "default". + +Here's another task with dependencies ... + + task :clobber => [:clean] do + rm_r "tempdir" + end + +Task :clobber depends upon task :clean, so :clean will be run before +:clobber is executed. + +Files are specified by using the "file" command. It is similar to the +task command, except that the task name represents a file, and the task +will be run only if the file doesn't exist, or if its modification time +is earlier than any of its prerequisites. + +Here is a file based dependency that will compile "hello.cc" to +"hello.o". + + file "hello.cc" + file "hello.o" => ["hello.cc"] do |t| + srcfile = t.name.sub(/\.o$/, ".cc") + sh %{g++ #{srcfile} -c -o #{t.name}} + end + +I normally specify file tasks with string (rather than symbols). Some +file names can't be represented by symbols. Plus it makes the +distinction between them more clear to the casual reader. + +Currently writing a task for each and every file in the project would be +tedious at best. I envision a set of libraries to make this job +easier. For instance, perhaps something like this ... + + require 'rake/ctools' + Dir['*.c'].each do |fn| + c_source_file(fn) + end + +where "c_source_file" will create all the tasks need to compile all the +C source files in a directory. Any number of useful libraries could be +created for rake. + +That's it. There's no documentation (other than whats in this +message). Does this sound interesting to anyone? If so, I'll continue +to clean it up and write it up and publish it on RAA. Otherwise, I'll +leave it as an interesting excerise and a tribute to the power of Ruby. + +Why /might/ rake be interesting to Ruby programmers. I don't know, +perhaps ... + +* No weird make syntax (only weird Ruby syntax :-) +* No need to edit or read XML (a la ant) +* Platform independent build scripts. +* Will run anywhere Ruby exists, so no need to have "make" installed. + If you stay away from the "sys" command and use things like + 'ftools', you can have a perfectly platform independent + build script. Also rake is only 100 lines of code, so it can + easily be packaged along with the rest of your code. + +So ... Sorry for the long rambling message. Like I said, I never +intended to write this code at all. diff --git a/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.4.14.rdoc b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.4.14.rdoc new file mode 100644 index 0000000..b2f1f84 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.4.14.rdoc @@ -0,0 +1,23 @@ += Rake 0.4.14 Released + +== Changes + +Version 0.4.14 is a compatibility fix to allow Rake's test task to +work under Ruby 1.8.2. A change in the Test::Unit autorun feature +prevented Rake from running any tests. This release fixes the +problem. + +Rake 0.4.14 is the recommended release for anyone using Ruby 1.8.2. + +== What is Rake + +Rake is a build tool similar to the make program in many ways. But +instead of cryptic make recipes, Rake uses standard Ruby code to +declare tasks and dependencies. You have the full power of a modern +scripting language built right into your build tool. + +== Availability + +Home Page:: http://rake.rubyforge.org/ +Download:: http://rubyforge.org/project/showfiles.php?group_id=50 + diff --git a/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.4.15.rdoc b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.4.15.rdoc new file mode 100644 index 0000000..1d8afd9 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.4.15.rdoc @@ -0,0 +1,35 @@ += Rake 0.4.15 Released + +== Changes + +Version 0.4.15 is a bug fix update for the Ruby 1.8.2 compatibility +changes. This release includes: + +* Fixed a bug that prevented the TESTOPTS flag from working with the + revised for 1.8.2 test task. + +* Updated the docs on --trace to indicate that it also enables a full + backtrace on errors. + +* Several fixes for new warnings generated. + +== Mini-Roadmap + +I will continue to issue Rake updates in the 0.4.xx series as new +Ruby-1.8.2 issues become manifest. Once the codebase stabilizes, I +will release a 0.5.0 version incorporating all the changes. If you +are not using Ruby-1.8.2 and wish to avoid version churn, I recommend +staying with a release prior to Rake-0.4.14. + +== What is Rake + +Rake is a build tool similar to the make program in many ways. But +instead of cryptic make recipes, Rake uses standard Ruby code to +declare tasks and dependencies. You have the full power of a modern +scripting language built right into your build tool. + +== Availability + +Home Page:: http://rake.rubyforge.org/ +Download:: http://rubyforge.org/project/showfiles.php?group_id=50 + diff --git a/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.5.0.rdoc b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.5.0.rdoc new file mode 100644 index 0000000..6b49d2a --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.5.0.rdoc @@ -0,0 +1,53 @@ += Rake 0.5.0 Released + +It has been a long time in coming, but we finally have a new version +of Rake available. + +== Changes + +* Fixed bug where missing intermediate file dependencies could cause + an abort with --trace or --dry-run. (Brian Candler) + +* Recursive rules are now supported (Tilman Sauerbeck). + +* Added tar.gz and tar.bz2 support to package task (Tilman Sauerbeck). + +* Added warning option for the Test Task (requested by Eric Hodel). + +* The jamis rdoc template is only used if it exists. + +* Added fix for Ruby 1.8.2 test/unit and rails problem. + +* Added contributed rake man file. (Jani Monoses) + +* Fixed documentation that was lacking the Rake module name (Tilman + Sauerbeck). + +== What is Rake + +Rake is a build tool similar to the make program in many ways. But +instead of cryptic make recipes, Rake uses standard Ruby code to +declare tasks and dependencies. You have the full power of a modern +scripting language built right into your build tool. + +== Availability + +The easiest way to get and install rake is via RubyGems ... + + gem install rake (you may need root/admin privileges) + +Otherwise, you can get it from the more traditional places: + +Home Page:: http://rake.rubyforge.org/ +Download:: http://rubyforge.org/project/showfiles.php?group_id=50 + +== Thanks + +Lots of people provided input to this release. Thanks to Tilman +Sauerbeck for numerous patches, documentation fixes and suggestions. +And for also pushing me to get this release out. Also, thanks to +Brian Candler for the finding and fixing --trace/dry-run fix. That +was an obscure bug. Also to Eric Hodel for some good suggestions. + +-- Jim Weirich + diff --git a/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.5.3.rdoc b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.5.3.rdoc new file mode 100644 index 0000000..be2919f --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.5.3.rdoc @@ -0,0 +1,78 @@ += Rake 0.5.0 Released + +Although it has only been two weeks since the last release, we have +enough updates to the Rake program to make it time for another +release. + +== Changes + +Here are the changes for version 0.5.3 ... + +* FileLists have been extensively changed so that they mimic the + behavior of real arrays even more closely. In particular, + operations on FileLists that return a new collection (e.g. collect, + reject) will now return a FileList rather than an array. In + addition, several places where FileLists were not properly expanded + before use have been fixed. + +* A method (+ext+) to simplify the handling of file extensions was + added to String and to Array. + +* The 'testrb' script in test/unit tends to silently swallow syntax + errors in test suites. Because of that, the default test loader is + now a rake-provided script. You can still use 'testrb' by setting + the loader flag in the test task to :testrb. (See the API documents + for TestTask for all the loader flag values). + +* FileUtil methods (e.g. cp, mv, install) are now declared to be + private. This will cut down on the interference with user defined + methods of the same name. + +* Fixed the verbose flag in the TestTask so that the test code is + controlled by the flag. Also shortened up some failure messages. + (Thanks to Tobias Luetke for the suggestion). + +* Rules will now properly detect a task that can generate a source + file. Previously rules would only consider source files that were + already present. + +* Added an +import+ command that allows Rake to dynamically import + dependendencies into a running Rake session. The +import+ command + can run tasks to update the dependency file before loading them. + Dependency files can be in rake or make format, allowing rake to + work with tools designed to generate dependencies for make. + +== What is Rake + +Rake is a build tool similar to the make program in many ways. But +instead of cryptic make recipes, Rake uses standard Ruby code to +declare tasks and dependencies. You have the full power of a modern +scripting language built right into your build tool. + +== Availability + +The easiest way to get and install rake is via RubyGems ... + + gem install rake (you may need root/admin privileges) + +Otherwise, you can get it from the more traditional places: + +Home Page:: http://rake.rubyforge.org/ +Download:: http://rubyforge.org/project/showfiles.php?group_id=50 + +== Thanks + +As usual, it was input from users that drove a alot of these changes. +Thanks to ... + +* Brian Gernhardt for the rules fix (especially for the patience to + explain the problem to me until I got what he was talking about). +* Stefan Lang for pointing out problems in the dark corners of the + FileList implementation. +* Alexey Verkhovsky pointing out the silently swallows syntax errors + in tests. +* Tobias Luetke for beautifying the test task output. +* Sam Roberts for some of the ideas behind dependency loading. + +-- Jim Weirich + diff --git a/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.5.4.rdoc b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.5.4.rdoc new file mode 100644 index 0000000..38dfbdd --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.5.4.rdoc @@ -0,0 +1,46 @@ += Rake 0.5.4 Released + +Time for some minor bug fixes and small enhancements + +== Changes + +Here are the changes for version 0.5.3 ... + +* Added double quotes to the test runner. This allows the location of + the tests (and runner) to be in a directory path that contains + spaces (e.g. "C:/Program Files/ruby/bin"). + +* Added .svn to default ignore list. Now subversion project metadata + is automatically ignored by Rake's FileList. + +* Updated FileList#include to support nested arrays and filelists. + FileLists are flat lists of file names. Using a FileList in an + include will flatten out the nested file names. + +== What is Rake + +Rake is a build tool similar to the make program in many ways. But +instead of cryptic make recipes, Rake uses standard Ruby code to +declare tasks and dependencies. You have the full power of a modern +scripting language built right into your build tool. + +== Availability + +The easiest way to get and install rake is via RubyGems ... + + gem install rake (you may need root/admin privileges) + +Otherwise, you can get it from the more traditional places: + +Home Page:: http://rake.rubyforge.org/ +Download:: http://rubyforge.org/project/showfiles.php?group_id=50 + +== Thanks + +As usual, it was input from users that drove a alot of these changes. +Thanks to ... + +* Tilman Sauerbeck for the nested FileList suggestion. +* Josh Knowles for pointing out the spaces in directory name problem. + +-- Jim Weirich diff --git a/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.6.0.rdoc b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.6.0.rdoc new file mode 100644 index 0000000..340c07b --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.6.0.rdoc @@ -0,0 +1,141 @@ += Rake 0.6.0 Released + +Its time for some long requested enhancements and lots of bug fixes +... And a whole new web page. + +== New Web Page + +The primary documentation for rake has moved from the RubyForge based +wiki to its own Hieraki based web site. Constant spam on the wiki +made it a difficult to keep clean. The new site will be easier to +update and organize. + +Check out the new documentation at: http://docs.rubyrake.org + +We will be adding new documentation to the site as time goes on. + +In addition to the new docs page, make sure you check out Martin +Fowlers article on rake at http://martinfowler.com/articles/rake.html + +== Changes + +=== New Features + +* Multiple prerequisites on Rake rules now allowed. However, keep the + following in mind: + + 1. All the prerequisites of a rule must be available before a rule + is triggered, where "enabled" means (a) an existing file, (b) a + defined rule, or (c) another rule which also must be + trigger-able. + 2. Rules are checked in order of definition, so it is important to + order your rules properly. If a file can be created by two + different rules, put the more specific rule first (otherwise the + more general rule will trigger first and the specific one will + never be triggered). + 3. The source method now returns the name of the first + prerequisite listed in the rule. sources returns the + names of all the rule prerequisites, ordered as they are defined + in the rule. If the task has other prerequisites not defined in + the rule (but defined in an explicit task definition), then they + will _not_ be included in the sources list. + +* FileLists may now use the egrep command. This popular enhancement + is now a core part of the FileList object. If you want to get a + list of all your to-dos, fixmes and TBD comments, add the following + to your Rakefile. + + desc "Look for TODO and FIXME tags in the code" + task :todo do + FileList['**/*.rb'].egrep /#.*(FIXME|TODO|TBD)/ + end + +* The investigation method was added to task object to dump + out some important values. This makes it a bit easier to debug Rake + tasks. + + For example, if you are having problems with a particular task, just + print it out: + + task :huh do + puts Rake::Task['huh'].investigation + end + +* The Rake::TestTask class now supports a "ruby_opts" option to pass + arbitrary ruby options to a test subprocess. + +=== Some Incompatibilities + +* When using the ruby command to start a Ruby subprocess, the + Ruby interpreter that is currently running rake is used by default. + This makes it easier to use rake in an environment with multiple + ruby installation. (Previously, the first ruby command found in the + PATH was used). + + If you wish to chose a different Ruby interpreter, you can + explicitly choose the interpreter via the sh command. + +* The major rake classes (Task, FileTask, FileCreationTask, RakeApp) + have been moved out of the toplevel scope and are now accessible as + Rake::Task, Rake::FileTask, Rake::FileCreationTask and + Rake::Application. If your Rakefile + directly references any one of these tasks, you may: + + 1. Update your Rakefile to use the new classnames + 2. Use the --classic-namespace option on the rake command to get the + old behavior, + 3. Add require 'rake/classic_namespace' to the + Rakefile to get the old behavior. + + rake will print a rather annoying warning whenever a + deprecated class name is referenced without enabling classic + namespace. + +=== Bug Fixes + +* Several unit tests and functional tests were fixed to run better + under windows. + +* Directory tasks are now a specialized version of a File task. A + directory task will only be triggered if it doesn't exist. It will + not be triggered if it is out of date w.r.t. any of its + prerequisites. + +* Fixed a bug in the Rake::GemPackageTask class so that the gem now + properly contains the platform name. + +* Fixed a bug where a prerequisite on a file task would cause + an exception if the prerequisite did not exist. + +== What is Rake + +Rake is a build tool similar to the make program in many ways. But +instead of cryptic make recipes, Rake uses standard Ruby code to +declare tasks and dependencies. You have the full power of a modern +scripting language built right into your build tool. + +== Availability + +The easiest way to get and install rake is via RubyGems ... + + gem install rake (you may need root/admin privileges) + +Otherwise, you can get it from the more traditional places: + +Home Page:: http://rake.rubyforge.org/ +Download:: http://rubyforge.org/project/showfiles.php?group_id=50 + +== Thanks + +As usual, it was input from users that drove a alot of these changes. +The following people either contributed patches, made suggestions or +made otherwise helpful comments. Thanks to ... + +* Greg Fast (better ruby_opt test options) +* Kelly Felkins (requested by better namespace support) +* Martin Fowler (suggested Task.investigation) +* Stuart Jansen (send initial patch for multiple prerequisites). +* Masao Mutch (better support for non-ruby Gem platforms) +* Philipp Neubeck (patch for file task exception fix) + +-- Jim Weirich diff --git a/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.7.0.rdoc b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.7.0.rdoc new file mode 100644 index 0000000..9c07c7f --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.7.0.rdoc @@ -0,0 +1,119 @@ += Rake 0.7.0 Released + +These changes for Rake have been brewing for a long time. Here they +are, I hope you enjoy them. + +== Changes + +=== New Features + +* Name space support for task names (see below). + +* Prerequisites can be executed in parallel (see below). + +* Added safe_ln support for openAFS (via Ludvig Omholt). + +* RDoc defaults to internal (in-process) invocation. The old behavior + is still available by setting the +external+ flag to true. + +* Rakefiles are now loaded with the expanded path to prevent + accidental polution from the Ruby load path. + +* Task objects my now be used in prerequisite lists directly. + +* Task objects (in addition to task names) may now be included in the + prerequisite list of a task. + +* Internals cleanup and refactoring. + +=== Bug Fixes + +* Compatibility fixes for Ruby 1.8.4 FileUtils changes. + +=== Namespaces + +Tasks can now be nested inside their own namespaces. Tasks within one +namespace will not accidently interfer with tasks named in a different +namespace. + +For example: + + namespace "main" do + task :build do + # Build the main program + end + end + + namespace "samples" do + task :build do + # Build the sample programs + end + end + + task :build_all => ["main:build", "samples:build"] + +Even though both tasks are named :build, they are separate tasks in +their own namespaces. The :build_all task (defined in the toplevel +namespace) references both build tasks in its prerequisites. + +You may invoke each of the individual build tasks with the following +commands: + + rake main:build + rake samples:build + +Or invoke both via the :build_all command: + + rake build_all + +Namespaces may be nested arbitrarily. Since the name of file tasks +correspond to the name of a file in the external file system, +FileTasks are not affected by the namespaces. + +See the Rakefile format documentation (in the Rake API documents) for +more information. + +=== Parallel Tasks + +Sometimes you have several tasks that can be executed in parallel. By +specifying these tasks as prerequisites to a +multitask+ task. + +In the following example the tasks copy_src, copy_doc and copy_bin +will all execute in parallel in their own thread. + + multitask :copy_files => [:copy_src, :copy_doc, :copy_bin] do + puts "All Copies Complete" + end + +== What is Rake + +Rake is a build tool similar to the make program in many ways. But +instead of cryptic make recipes, Rake uses standard Ruby code to +declare tasks and dependencies. You have the full power of a modern +scripting language built right into your build tool. + +== Availability + +The easiest way to get and install rake is via RubyGems ... + + gem install rake (you may need root/admin privileges) + +Otherwise, you can get it from the more traditional places: + +Home Page:: http://rake.rubyforge.org/ +Download:: http://rubyforge.org/project/showfiles.php?group_id=50 + +== Thanks + +As usual, it was input from users that drove a alot of these changes. +The following people either contributed patches, made suggestions or +made otherwise helpful comments. Thanks to ... + +* Doug Young (inspriation for the parallel task) + +* David Heinemeier Hansson (for --trace message enhancement and for + pushing for namespace support). + +* Ludvig Omholt (for the openAFS fix) + +-- Jim Weirich diff --git a/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.7.1.rdoc b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.7.1.rdoc new file mode 100644 index 0000000..c17088e --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.7.1.rdoc @@ -0,0 +1,59 @@ += Rake 0.7.1 Released + +Version 0.7.1 supplies a bug fix and a few minor enhancements. + +== Changes + +=== Bug Fixes in 0.7.1 + +* Changes in the exception reported for the FileUtils.ln caused + safe_ln to fail with a NotImplementedError. Rake 0.7.1 will now + catch that error or any StandardError and properly fall back to + using +cp+. + +=== New Features in 0.7.1 + +* You can filter the results of the --task option by supplying an + optional regular expression. This allows the user to easily find a + particular task name in a long list of possible names. + +* Transforming procs in a rule may now return a list of prerequisites. + This allows more flexible rule formation. + +* FileList and String now support a +pathmap+ melthod that makes the + transforming paths a bit easier. See the API docs for +pathmap+ for + details. + +* The -f option without a value will disable the search for a + Rakefile. This allows the Rakefile to be defined entirely in a + library (and loaded with the -r option). The current working + directory is not changed when this is done. + +== What is Rake + +Rake is a build tool similar to the make program in many ways. But +instead of cryptic make recipes, Rake uses standard Ruby code to +declare tasks and dependencies. You have the full power of a modern +scripting language built right into your build tool. + +== Availability + +The easiest way to get and install rake is via RubyGems ... + + gem install rake (you may need root/admin privileges) + +Otherwise, you can get it from the more traditional places: + +Home Page:: http://rake.rubyforge.org/ +Download:: http://rubyforge.org/project/showfiles.php?group_id=50 + +== Thanks + +As usual, it was input from users that drove a alot of these changes. +The following people either contributed patches, made suggestions or +made otherwise helpful comments. Thanks to ... + +* James Britt and Assaph Mehr for reporting and helping to debug the + safe_ln issue. + +-- Jim Weirich diff --git a/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.7.2.rdoc b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.7.2.rdoc new file mode 100644 index 0000000..2cc86be --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.7.2.rdoc @@ -0,0 +1,121 @@ += Rake 0.7.2 Released + +Version 0.7.2 supplies a bug fix and a few minor enhancements. In +particular, the new version fixes an incompatibility with the soon to +be released Ruby 1.8.6. We strongly recommend upgrading to Rake 0.7.2 +in order to be compatible with the new version of Ruby. + +== Changes + +=== Bug Fixes in 0.7.2 + +There are quite a number of bug fixes in the new 0.7.2 version of +Rake: + +* Removed dependency on internal fu_xxx functions from FileUtils. + +* Error messages are now send to stderr rather than stdout (from + Payton Quackenbush). + +* Better error handling on invalid command line arguments (from Payton + Quackenbush). + +* Fixed some bugs where the application object was going to the global + appliation instead of using its own data. + +* Fixed the method name leak from FileUtils (bug found by Glenn + Vanderburg). + +* Added test for noop, bad_option and verbose flags to sh command. + +* Added a description to the gem task in GemPackageTask. + +* Fixed a bug when rules have multiple prerequisites (patch by Joel + VanderWerf) + +* Added the handful of RakeFileUtils to the private method as well. + +=== New Features in 0.7.2 + +The following new features are available in Rake version 0.7.2: + +* Added square and curly bracket patterns to FileList#include (Tilman + Sauerbeck). + +* FileLists can now pass a block to FileList#exclude to exclude files + based on calculated values. + +* Added plain filename support to rule dependents (suggested by Nobu + Nakada). + +* Added pathmap support to rule dependents. In other words, if a + pathmap format (beginning with a '%') is given as a Rake rule + dependent, then the name of the depend will be the name of the + target with the pathmap format applied. + +* Added a 'tasks' method to a namespace to get a list of tasks + associated with the namespace. + +* Added tar_command and zip_command options to the Package task. + +* The clean task will no longer delete 'core' if it is a directory. + +=== Internal Rake Improvements + +The following changes will are mainly internal improvements and +refactorings and have little effect on the end user. But they may be +of interest to the general public. + +* Added rcov task and updated unit testing for better code coverage. + +* Added a 'shame' task to the Rakefile. + +* Added rake_extension to handle detection of extension collisions. + +* Added a protected 'require "rubygems"' to test/test_application to + unbreak cruisecontrol.rb. + +* Removed rake_dup. Now we just simply rescue a bad dup. + +* Refactored the FileList reject logic to remove duplication. + +* Removed if __FILE__ at the end of the rake.rb file. + +== What is Rake + +Rake is a build tool similar to the make program in many ways. But +instead of cryptic make recipes, Rake uses standard Ruby code to +declare tasks and dependencies. You have the full power of a modern +scripting language built right into your build tool. + +== Availability + +The easiest way to get and install rake is via RubyGems ... + + gem install rake (you may need root/admin privileges) + +Otherwise, you can get it from the more traditional places: + +Home Page:: http://rake.rubyforge.org/ +Download:: http://rubyforge.org/project/showfiles.php?group_id=50 + +== Thanks + +As usual, it was input from users that drove a alot of these changes. +The following people either contributed patches, made suggestions or +made otherwise helpful comments. Thanks to ... + +* Payton Quackenbush -- For several error handling improvements. + +* Glenn Vanderburg -- For finding and fixing the method name leak from + FileUtils. + +* Joel VanderWerf -- for finding and fixing a bug in the handling of + multiple prerequisites. + +* Tilman Sauerbeck -- For some enhancing FileList to support more + advanced file globbing. + +* Nobu Nakada -- For suggesting plain file name support to rule dependents. + +-- Jim Weirich diff --git a/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.7.3.rdoc b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.7.3.rdoc new file mode 100755 index 0000000..39e91bb --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.7.3.rdoc @@ -0,0 +1,47 @@ += Rake 0.7.3 Released + +Rake version 0.7.3 is a minor release that includes some refactoring to better +support custom Rake applications. + +== Changes + +=== New Features in Version 0.7.3 + +* Added the +init+ and +top_level+ methods to make the creation of custom Rake applications a bit easier. E.g. + + gem 'rake', ">= 0.7.3" + require 'rake' + + Rake.application.init('myrake') + + task :default do + something_interesting + end + + Rake.application.top_level + +== What is Rake + +Rake is a build tool similar to the make program in many ways. But instead of +cryptic make recipes, Rake uses standard Ruby code to declare tasks and +dependencies. You have the full power of a modern scripting language built +right into your build tool. + +== Availability + +The easiest way to get and install rake is via RubyGems ... + + gem install rake (you may need root/admin privileges) + +Otherwise, you can get it from the more traditional places: + +Home Page:: http://rake.rubyforge.org/ +Download:: http://rubyforge.org/project/showfiles.php?group_id=50 + +== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +-- Jim Weirich diff --git a/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.8.0.rdoc b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.8.0.rdoc new file mode 100644 index 0000000..05e5877 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.8.0.rdoc @@ -0,0 +1,114 @@ += Rake 0.8.0/0.8.1 Released + +Rake version 0.8.0 is a new release of rake that includes serveral new +features. + +== Changes + +=== New Features in Version 0.8.0 + +* Tasks can now receive command line parameters. See the examples + below for more details. + +* Comments are limited to 80 columns on output, but full comments can + be seen by using the -D parameter. (feature suggested by Jamis + Buck). + +* Explicit exit(n) calls will now set the exit status to n. (patch + provided by Stephen Touset). + +* Rake is now compatible with Ruby 1.9. + +Version 0.8.1 is a minor update that includes additional Ruby 1.9 +compatibility fixes. + +== What is Rake + +Rake is a build tool similar to the make program in many ways. But +instead of cryptic make recipes, Rake uses standard Ruby code to +declare tasks and dependencies. You have the full power of a modern +scripting language built right into your build tool. + +== Availability + +The easiest way to get and install rake is via RubyGems ... + + gem install rake (you may need root/admin privileges) + +Otherwise, you can get it from the more traditional places: + +Home Page:: http://rake.rubyforge.org/ +Download:: http://rubyforge.org/project/showfiles.php?group_id=50 + +== Task Argument Examples + +Prior to version 0.8.0, rake was only able to handle command line +arguments of the form NAME=VALUE that were passed into Rake via the +ENV hash. Many folks had asked for some kind of simple command line +arguments, perhaps using "--" to separate regular task names from +argument values on the command line. The problem is that there was no +easy way to associate positional arguments on the command line with +different tasks. Suppose both tasks :a and :b expect a command line +argument: does the first value go with :a? What if :b is run first? +Should it then get the first command line argument. + +Rake 0.8.0 solves this problem by explicitly passing values directly +to the tasks that need them. For example, if I had a release task +that required a version number, I could say: + + rake release[0.8.0] + +And the string "0.8.0" will be passed to the :release task. Multiple +arguments can be passed by separating them with a comma, for example: + + rake name[john,doe] + +Just a few words of caution. The rake task name and its arguments +need to be a single command line argument to rake. This generally +means no spaces. If spaces are needed, then the entire rake + +argument string should be quoted. Something like this: + + rake "name[billy bob, smith]" + +(Quoting rules vary between operating systems and shells, so make sure +you consult the proper docs for your OS/shell). + +=== Tasks that Expect Parameters + +Parameters are only given to tasks that are setup to expect them. In +order to handle named parameters, the task declaration syntax for +tasks has been extended slightly. + +For example, a task that needs a first name and last name might be +declared as: + + task :name, :first_name, :last_name + +The first argument is still the name of the task (:name in this case). +The next to argumements are the names of the parameters expected by +:name (:first_name and :last_name in the example). + +To access the values of the paramters, the block defining the task +behaviour can now accept a second parameter: + + task :name, :first_name, :last_name do |t, args| + puts "First name is #{args.first_name}" + puts "Last name is #{args.last_name}" + end + +The first argument of the block "t" is always bound to the current +task object. The second argument "args" is an open-struct like object +that allows access to the task arguments. Extra command line +arguments to a task are ignored. Missing command line arguments are +given the nil value. + +== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Jamis Buck (for comment formatting suggestions) +* Stephen Touset (for exit status patch). + +-- Jim Weirich diff --git a/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.8.2.rdoc b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.8.2.rdoc new file mode 100644 index 0000000..cfb9941 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.8.2.rdoc @@ -0,0 +1,165 @@ += Rake 0.8.2 Released + +Rake version 0.8.2 is a new release of rake that includes a number of +new features and numerous bug fixes. + +== Changes + +=== New Features in Version 0.8.2 + +* Switched from getoptlong to optparse (patches supplied by Edwin + Pratomo). + +* The -T option will now attempt to dynamically sense the size of the + terminal. The -T output will only self-truncate if the output is a + tty. However, if RAKE_COLUMNS is explicitly set, it will be honored + in any case. (Patch provided by Gavin Stark). + +* The following public methods have been added to rake task objects: + + * task.clear -- Clear both the prerequisites and actions of the + target rake task. + * task.clear_prerequisites -- Clear all the existing prerequisites + from the target rake task. + * task.clear_actions -- Clear all the existing actions from the + target rake task. + * task.reenable -- Re-enable a task, allowing its actions to be + executed again if the task is invoked. + +* Changed RDoc test task to have no default template. This makes it + easier for the tempate to pick up the template from the environment. + +* Default values for task arguments can easily be specified with the + :with_defaults method. (Idea for default argument merging supplied + by (Adam Q. Salter) + +=== Bug Fixes in Version 0.8.2 + +* Fixed bug in package task so that it will include the subdir + directory in the package for testing. (Bug found by Adam Majer) + +* Fixed filename dependency order bug in test_inspect_pending and + test_to_s_pending. (Bug found by Adam Majer) + +* Fixed check for file utils options to make them immune to the + symbol/string differences. (Patch supplied by Edwin Pratomo) + +* Fixed bug with rules involving multiple source, where only the first + dependency of a rule has any effect (Patch supplied by Emanuel + Indermühle) + +* FileList#clone and FileList#dup have better sematics w.r.t. taint + and freeze. + +* Changed from using Mutex to Monitor. Evidently Mutex causes thread + join errors when Ruby is compiled with -disable-pthreads. (Patch + supplied by Ittay Dror) + +* Fixed bug in makefile parser that had problems with extra spaces in + file task names. (Patch supplied by Ittay Dror) + +== Other changes in Version 0.8.2 + +* Added ENV var to rake's own Rakefile to prevent OS X from including + extended attribute junk in the rake package tar file. (Bug found by + Adam Majer) + +* Added a performance patch for reading large makefile dependency + files. (Patch supplied by Ittay Dror) + +== What is Rake + +Rake is a build tool similar to the make program in many ways. But +instead of cryptic make recipes, Rake uses standard Ruby code to +declare tasks and dependencies. You have the full power of a modern +scripting language built right into your build tool. + +== Availability + +The easiest way to get and install rake is via RubyGems ... + + gem install rake (you may need root/admin privileges) + +Otherwise, you can get it from the more traditional places: + +Home Page:: http://rake.rubyforge.org/ +Download:: http://rubyforge.org/project/showfiles.php?group_id=50 + +== Task Argument Examples + +Prior to version 0.8.0, rake was only able to handle command line +arguments of the form NAME=VALUE that were passed into Rake via the +ENV hash. Many folks had asked for some kind of simple command line +arguments, perhaps using "--" to separate regular task names from +argument values on the command line. The problem is that there was no +easy way to associate positional arguments on the command line with +different tasks. Suppose both tasks :a and :b expect a command line +argument: does the first value go with :a? What if :b is run first? +Should it then get the first command line argument. + +Rake 0.8.0 solves this problem by explicitly passing values directly +to the tasks that need them. For example, if I had a release task +that required a version number, I could say: + + rake release[0.8.2] + +And the string "0.8.2" will be passed to the :release task. Multiple +arguments can be passed by separating them with a comma, for example: + + rake name[john,doe] + +Just a few words of caution. The rake task name and its arguments +need to be a single command line argument to rake. This generally +means no spaces. If spaces are needed, then the entire rake + +argument string should be quoted. Something like this: + + rake "name[billy bob, smith]" + +(Quoting rules vary between operating systems and shells, so make sure +you consult the proper docs for your OS/shell). + +=== Tasks that Expect Parameters + +Parameters are only given to tasks that are setup to expect them. In +order to handle named parameters, the task declaration syntax for +tasks has been extended slightly. + +For example, a task that needs a first name and last name might be +declared as: + + task :name, :first_name, :last_name + +The first argument is still the name of the task (:name in this case). +The next to argumements are the names of the parameters expected by +:name (:first_name and :last_name in the example). + +To access the values of the paramters, the block defining the task +behaviour can now accept a second parameter: + + task :name, :first_name, :last_name do |t, args| + puts "First name is #{args.first_name}" + puts "Last name is #{args.last_name}" + end + +The first argument of the block "t" is always bound to the current +task object. The second argument "args" is an open-struct like object +that allows access to the task arguments. Extra command line +arguments to a task are ignored. Missing command line arguments are +given the nil value. + +== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Edwin Pratomo +* Gavin Stark +* Adam Q. Salter +* Adam Majer +* Emanuel Indermühle +* Ittay Dror +* Bheeshmar Redheendran (for spending an afternoon with me debugging + windows issues) + +-- Jim Weirich diff --git a/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.8.3.rdoc b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.8.3.rdoc new file mode 100644 index 0000000..fefc8c0 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/doc/release_notes/rake-0.8.3.rdoc @@ -0,0 +1,112 @@ += Rake 0.8.3 Released + +Rake version 0.8.3 is a bug-fix release of rake. + +== Changes + +=== Bug Fixes in Version 0.8.3 + +* Enhanced the system directory detection in windows. We now check + HOMEDRIVE/HOMEPATH and USERPROFILE if APPDATA isn't found. (Patch + supplied by James Tucker). Rake no long aborts if it can't find the + directory. + +* Added fix to handle ruby installations in directories with spaces in + their name. + +== What is Rake + +Rake is a build tool similar to the make program in many ways. But +instead of cryptic make recipes, Rake uses standard Ruby code to +declare tasks and dependencies. You have the full power of a modern +scripting language built right into your build tool. + +== Availability + +The easiest way to get and install rake is via RubyGems ... + + gem install rake (you may need root/admin privileges) + +Otherwise, you can get it from the more traditional places: + +Home Page:: http://rake.rubyforge.org/ +Download:: http://rubyforge.org/project/showfiles.php?group_id=50 + +== Task Argument Examples + +Prior to version 0.8.0, rake was only able to handle command line +arguments of the form NAME=VALUE that were passed into Rake via the +ENV hash. Many folks had asked for some kind of simple command line +arguments, perhaps using "--" to separate regular task names from +argument values on the command line. The problem is that there was no +easy way to associate positional arguments on the command line with +different tasks. Suppose both tasks :a and :b expect a command line +argument: does the first value go with :a? What if :b is run first? +Should it then get the first command line argument. + +Rake 0.8.0 solves this problem by explicitly passing values directly +to the tasks that need them. For example, if I had a release task +that required a version number, I could say: + + rake release[0.8.3] + +And the string "0.8.3" will be passed to the :release task. Multiple +arguments can be passed by separating them with a comma, for example: + + rake name[john,doe] + +Just a few words of caution. The rake task name and its arguments +need to be a single command line argument to rake. This generally +means no spaces. If spaces are needed, then the entire rake + +argument string should be quoted. Something like this: + + rake "name[billy bob, smith]" + +(Quoting rules vary between operating systems and shells, so make sure +you consult the proper docs for your OS/shell). + +=== Tasks that Expect Parameters + +Parameters are only given to tasks that are setup to expect them. In +order to handle named parameters, the task declaration syntax for +tasks has been extended slightly. + +For example, a task that needs a first name and last name might be +declared as: + + task :name, :first_name, :last_name + +The first argument is still the name of the task (:name in this case). +The next to argumements are the names of the parameters expected by +:name (:first_name and :last_name in the example). + +To access the values of the paramters, the block defining the task +behaviour can now accept a second parameter: + + task :name, :first_name, :last_name do |t, args| + puts "First name is #{args.first_name}" + puts "Last name is #{args.last_name}" + end + +The first argument of the block "t" is always bound to the current +task object. The second argument "args" is an open-struct like object +that allows access to the task arguments. Extra command line +arguments to a task are ignored. Missing command line arguments are +given the nil value. + +== Thanks + +As usual, it was input from users that drove a alot of these changes. The +following people either contributed patches, made suggestions or made +otherwise helpful comments. Thanks to ... + +* Edwin Pratomo +* Gavin Stark +* Adam Q. Salter +* Adam Majer +* Emanuel Indermühle +* Ittay Dror +* Bheeshmar Redheendran (for spending an afternoon with me debugging + windows issues) + +-- Jim Weirich diff --git a/vendor/gems/gems/rake-0.8.3/install.rb b/vendor/gems/gems/rake-0.8.3/install.rb new file mode 100644 index 0000000..2d0dc61 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/install.rb @@ -0,0 +1,88 @@ +require 'rbconfig' +require 'find' +require 'ftools' + +include Config + +$ruby = CONFIG['ruby_install_name'] + +## +# Install a binary file. We patch in on the way through to +# insert a #! line. If this is a Unix install, we name +# the command (for example) 'rake' and let the shebang line +# handle running it. Under windows, we add a '.rb' extension +# and let file associations to their stuff +# + +def installBIN(from, opfile) + + tmp_dir = nil + for t in [".", "/tmp", "c:/temp", $bindir] + stat = File.stat(t) rescue next + if stat.directory? and stat.writable? + tmp_dir = t + break + end + end + + fail "Cannot find a temporary directory" unless tmp_dir + tmp_file = File.join(tmp_dir, "_tmp") + + File.open(from) do |ip| + File.open(tmp_file, "w") do |op| + ruby = File.join($realbindir, $ruby) + op.puts "#!#{ruby} -w" + op.write ip.read + end + end + + opfile += ".rb" if CONFIG["target_os"] =~ /mswin/i + File::install(tmp_file, File.join($bindir, opfile), 0755, true) + File::unlink(tmp_file) +end + +$sitedir = CONFIG["sitelibdir"] +unless $sitedir + version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"] + $libdir = File.join(CONFIG["libdir"], "ruby", version) + $sitedir = $:.find {|x| x =~ /site_ruby/} + if !$sitedir + $sitedir = File.join($libdir, "site_ruby") + elsif $sitedir !~ Regexp.quote(version) + $sitedir = File.join($sitedir, version) + end +end + +$bindir = CONFIG["bindir"] + +$realbindir = $bindir + +bindir = CONFIG["bindir"] +if (destdir = ENV['DESTDIR']) + $bindir = destdir + $bindir + $sitedir = destdir + $sitedir + + File::makedirs($bindir) + File::makedirs($sitedir) +end + +rake_dest = File.join($sitedir, "rake") +File::makedirs(rake_dest, true) +File::chmod(0755, rake_dest) + +# The library files + +files = Dir.chdir('lib') { Dir['**/*.rb'] } + +for fn in files + fn_dir = File.dirname(fn) + target_dir = File.join($sitedir, fn_dir) + if ! File.exist?(target_dir) + File.makedirs(target_dir) + end + File::install(File.join('lib', fn), File.join($sitedir, fn), 0644, true) +end + +# and the executable + +installBIN("bin/rake", "rake") diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake.rb b/vendor/gems/gems/rake-0.8.3/lib/rake.rb new file mode 100755 index 0000000..313e169 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake.rb @@ -0,0 +1,2468 @@ +#!/usr/bin/env ruby + +#-- + +# Copyright (c) 2003, 2004, 2005, 2006, 2007 Jim Weirich +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +#++ +# +# = Rake -- Ruby Make +# +# This is the main file for the Rake application. Normally it is referenced +# as a library via a require statement, but it can be distributed +# independently as an application. + +RAKEVERSION = '0.8.3' + +require 'rbconfig' +require 'fileutils' +require 'singleton' +require 'monitor' +require 'optparse' +require 'ostruct' + +require 'rake/win32' + +###################################################################### +# Rake extensions to Module. +# +class Module + # Check for an existing method in the current class before extending. IF + # the method already exists, then a warning is printed and the extension is + # not added. Otherwise the block is yielded and any definitions in the + # block will take effect. + # + # Usage: + # + # class String + # rake_extension("xyz") do + # def xyz + # ... + # end + # end + # end + # + def rake_extension(method) + if instance_methods.include?(method.to_s) || instance_methods.include?(method.to_sym) + $stderr.puts "WARNING: Possible conflict with Rake extension: #{self}##{method} already exists" + else + yield + end + end +end # module Module + + +###################################################################### +# User defined methods to be added to String. +# +class String + rake_extension("ext") do + # Replace the file extension with +newext+. If there is no extenson on + # the string, append the new extension to the end. If the new extension + # is not given, or is the empty string, remove any existing extension. + # + # +ext+ is a user added method for the String class. + def ext(newext='') + return self.dup if ['.', '..'].include? self + if newext != '' + newext = (newext =~ /^\./) ? newext : ("." + newext) + end + dup.sub!(%r(([^/\\])\.[^./\\]*$)) { $1 + newext } || self + newext + end + end + + rake_extension("pathmap") do + # Explode a path into individual components. Used by +pathmap+. + def pathmap_explode + head, tail = File.split(self) + return [self] if head == self + return [tail] if head == '.' || tail == '/' + return [head, tail] if head == '/' + return head.pathmap_explode + [tail] + end + protected :pathmap_explode + + # Extract a partial path from the path. Include +n+ directories from the + # front end (left hand side) if +n+ is positive. Include |+n+| + # directories from the back end (right hand side) if +n+ is negative. + def pathmap_partial(n) + dirs = File.dirname(self).pathmap_explode + partial_dirs = + if n > 0 + dirs[0...n] + elsif n < 0 + dirs.reverse[0...-n].reverse + else + "." + end + File.join(partial_dirs) + end + protected :pathmap_partial + + # Preform the pathmap replacement operations on the given path. The + # patterns take the form 'pat1,rep1;pat2,rep2...'. + def pathmap_replace(patterns, &block) + result = self + patterns.split(';').each do |pair| + pattern, replacement = pair.split(',') + pattern = Regexp.new(pattern) + if replacement == '*' && block_given? + result = result.sub(pattern, &block) + elsif replacement + result = result.sub(pattern, replacement) + else + result = result.sub(pattern, '') + end + end + result + end + protected :pathmap_replace + + # Map the path according to the given specification. The specification + # controls the details of the mapping. The following special patterns are + # recognized: + # + # * %p -- The complete path. + # * %f -- The base file name of the path, with its file extension, + # but without any directories. + # * %n -- The file name of the path without its file extension. + # * %d -- The directory list of the path. + # * %x -- The file extension of the path. An empty string if there + # is no extension. + # * %X -- Everything *but* the file extension. + # * %s -- The alternate file separater if defined, otherwise use + # the standard file separator. + # * %% -- A percent sign. + # + # The %d specifier can also have a numeric prefix (e.g. '%2d'). If the + # number is positive, only return (up to) +n+ directories in the path, + # starting from the left hand side. If +n+ is negative, return (up to) + # |+n+| directories from the right hand side of the path. + # + # Examples: + # + # 'a/b/c/d/file.txt'.pathmap("%2d") => 'a/b' + # 'a/b/c/d/file.txt'.pathmap("%-2d") => 'c/d' + # + # Also the %d, %p, $f, $n, %x, and %X operators can take a + # pattern/replacement argument to perform simple string substititions on a + # particular part of the path. The pattern and replacement are speparated + # by a comma and are enclosed by curly braces. The replacement spec comes + # after the % character but before the operator letter. (e.g. + # "%{old,new}d"). Muliple replacement specs should be separated by + # semi-colons (e.g. "%{old,new;src,bin}d"). + # + # Regular expressions may be used for the pattern, and back refs may be + # used in the replacement text. Curly braces, commas and semi-colons are + # excluded from both the pattern and replacement text (let's keep parsing + # reasonable). + # + # For example: + # + # "src/org/onestepback/proj/A.java".pathmap("%{^src,bin}X.class") + # + # returns: + # + # "bin/org/onestepback/proj/A.class" + # + # If the replacement text is '*', then a block may be provided to perform + # some arbitrary calculation for the replacement. + # + # For example: + # + # "/path/to/file.TXT".pathmap("%X%{.*,*}x") { |ext| + # ext.downcase + # } + # + # Returns: + # + # "/path/to/file.txt" + # + def pathmap(spec=nil, &block) + return self if spec.nil? + result = '' + spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag| + case frag + when '%f' + result << File.basename(self) + when '%n' + result << File.basename(self).ext + when '%d' + result << File.dirname(self) + when '%x' + result << $1 if self =~ /[^\/](\.[^.]+)$/ + when '%X' + if self =~ /^(.*[^\/])(\.[^.]+)$/ + result << $1 + else + result << self + end + when '%p' + result << self + when '%s' + result << (File::ALT_SEPARATOR || File::SEPARATOR) + when '%-' + # do nothing + when '%%' + result << "%" + when /%(-?\d+)d/ + result << pathmap_partial($1.to_i) + when /^%\{([^}]*)\}(\d*[dpfnxX])/ + patterns, operator = $1, $2 + result << pathmap('%' + operator).pathmap_replace(patterns, &block) + when /^%/ + fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'" + else + result << frag + end + end + result + end + end +end # class String + +############################################################################## +module Rake + + # Errors ----------------------------------------------------------- + + # Error indicating an ill-formed task declaration. + class TaskArgumentError < ArgumentError + end + + # Error indicating a recursion overflow error in task selection. + class RuleRecursionOverflowError < StandardError + def initialize(*args) + super + @targets = [] + end + + def add_target(target) + @targets << target + end + + def message + super + ": [" + @targets.reverse.join(' => ') + "]" + end + end + + # -------------------------------------------------------------------------- + # Rake module singleton methods. + # + class << self + # Current Rake Application + def application + @application ||= Rake::Application.new + end + + # Set the current Rake application object. + def application=(app) + @application = app + end + + # Return the original directory where the Rake application was started. + def original_dir + application.original_dir + end + + end + + # ########################################################################## + # Mixin for creating easily cloned objects. + # + module Cloneable + # Clone an object by making a new object and setting all the instance + # variables to the same values. + def dup + sibling = self.class.new + instance_variables.each do |ivar| + value = self.instance_variable_get(ivar) + new_value = value.clone rescue value + sibling.instance_variable_set(ivar, new_value) + end + sibling.taint if tainted? + sibling + end + + def clone + sibling = dup + sibling.freeze if frozen? + sibling + end + end + + #################################################################### + # TaskAguments manage the arguments passed to a task. + # + class TaskArguments + include Enumerable + + attr_reader :names + + # Create a TaskArgument object with a list of named arguments + # (given by :names) and a set of associated values (given by + # :values). :parent is the parent argument object. + def initialize(names, values, parent=nil) + @names = names + @parent = parent + @hash = {} + names.each_with_index { |name, i| + @hash[name.to_sym] = values[i] unless values[i].nil? + } + end + + # Create a new argument scope using the prerequisite argument + # names. + def new_scope(names) + values = names.collect { |n| self[n] } + self.class.new(names, values, self) + end + + # Find an argument value by name or index. + def [](index) + lookup(index.to_sym) + end + + # Specify a hash of default values for task arguments. Use the + # defaults only if there is no specific value for the given + # argument. + def with_defaults(defaults) + @hash = defaults.merge(@hash) + end + + def each(&block) + @hash.each(&block) + end + + def method_missing(sym, *args, &block) + lookup(sym.to_sym) + end + + def to_hash + @hash + end + + def to_s + @hash.inspect + end + + def inspect + to_s + end + + protected + + def lookup(name) + if @hash.has_key?(name) + @hash[name] + elsif ENV.has_key?(name.to_s) + ENV[name.to_s] + elsif ENV.has_key?(name.to_s.upcase) + ENV[name.to_s.upcase] + elsif @parent + @parent.lookup(name) + end + end + end + + EMPTY_TASK_ARGS = TaskArguments.new([], []) + + #################################################################### + # InvocationChain tracks the chain of task invocations to detect + # circular dependencies. + class InvocationChain + def initialize(value, tail) + @value = value + @tail = tail + end + + def member?(obj) + @value == obj || @tail.member?(obj) + end + + def append(value) + if member?(value) + fail RuntimeError, "Circular dependency detected: #{to_s} => #{value}" + end + self.class.new(value, self) + end + + def to_s + "#{prefix}#{@value}" + end + + def self.append(value, chain) + chain.append(value) + end + + private + + def prefix + "#{@tail.to_s} => " + end + + class EmptyInvocationChain + def member?(obj) + false + end + def append(value) + InvocationChain.new(value, self) + end + def to_s + "TOP" + end + end + + EMPTY = EmptyInvocationChain.new + + end # class InvocationChain + +end # module Rake + +module Rake + + # ######################################################################### + # A Task is the basic unit of work in a Rakefile. Tasks have associated + # actions (possibly more than one) and a list of prerequisites. When + # invoked, a task will first ensure that all of its prerequisites have an + # opportunity to run and then it will execute its own actions. + # + # Tasks are not usually created directly using the new method, but rather + # use the +file+ and +task+ convenience methods. + # + class Task + # List of prerequisites for a task. + attr_reader :prerequisites + + # List of actions attached to a task. + attr_reader :actions + + # Application owning this task. + attr_accessor :application + + # Comment for this task. Restricted to a single line of no more than 50 + # characters. + attr_reader :comment + + # Full text of the (possibly multi-line) comment. + attr_reader :full_comment + + # Array of nested namespaces names used for task lookup by this task. + attr_reader :scope + + # Return task name + def to_s + name + end + + def inspect + "<#{self.class} #{name} => [#{prerequisites.join(', ')}]>" + end + + # List of sources for task. + attr_writer :sources + def sources + @sources ||= [] + end + + # First source from a rule (nil if no sources) + def source + @sources.first if defined?(@sources) + end + + # Create a task named +task_name+ with no actions or prerequisites. Use + # +enhance+ to add actions and prerequisites. + def initialize(task_name, app) + @name = task_name.to_s + @prerequisites = [] + @actions = [] + @already_invoked = false + @full_comment = nil + @comment = nil + @lock = Monitor.new + @application = app + @scope = app.current_scope + @arg_names = nil + end + + # Enhance a task with prerequisites or actions. Returns self. + def enhance(deps=nil, &block) + @prerequisites |= deps if deps + @actions << block if block_given? + self + end + + # Name of the task, including any namespace qualifiers. + def name + @name.to_s + end + + # Name of task with argument list description. + def name_with_args # :nodoc: + if arg_description + "#{name}#{arg_description}" + else + name + end + end + + # Argument description (nil if none). + def arg_description # :nodoc: + @arg_names ? "[#{(arg_names || []).join(',')}]" : nil + end + + # Name of arguments for this task. + def arg_names + @arg_names || [] + end + + # Reenable the task, allowing its tasks to be executed if the task + # is invoked again. + def reenable + @already_invoked = false + end + + # Clear the existing prerequisites and actions of a rake task. + def clear + clear_prerequisites + clear_actions + self + end + + # Clear the existing prerequisites of a rake task. + def clear_prerequisites + prerequisites.clear + self + end + + # Clear the existing actions on a rake task. + def clear_actions + actions.clear + self + end + + # Invoke the task if it is needed. Prerequites are invoked first. + def invoke(*args) + task_args = TaskArguments.new(arg_names, args) + invoke_with_call_chain(task_args, InvocationChain::EMPTY) + end + + # Same as invoke, but explicitly pass a call chain to detect + # circular dependencies. + def invoke_with_call_chain(task_args, invocation_chain) # :nodoc: + new_chain = InvocationChain.append(self, invocation_chain) + @lock.synchronize do + if application.options.trace + puts "** Invoke #{name} #{format_trace_flags}" + end + return if @already_invoked + @already_invoked = true + invoke_prerequisites(task_args, new_chain) + execute(task_args) if needed? + end + end + protected :invoke_with_call_chain + + # Invoke all the prerequisites of a task. + def invoke_prerequisites(task_args, invocation_chain) # :nodoc: + @prerequisites.each { |n| + prereq = application[n, @scope] + prereq_args = task_args.new_scope(prereq.arg_names) + prereq.invoke_with_call_chain(prereq_args, invocation_chain) + } + end + + # Format the trace flags for display. + def format_trace_flags + flags = [] + flags << "first_time" unless @already_invoked + flags << "not_needed" unless needed? + flags.empty? ? "" : "(" + flags.join(", ") + ")" + end + private :format_trace_flags + + # Execute the actions associated with this task. + def execute(args=nil) + args ||= EMPTY_TASK_ARGS + if application.options.dryrun + puts "** Execute (dry run) #{name}" + return + end + if application.options.trace + puts "** Execute #{name}" + end + application.enhance_with_matching_rule(name) if @actions.empty? + @actions.each do |act| + case act.arity + when 1 + act.call(self) + else + act.call(self, args) + end + end + end + + # Is this task needed? + def needed? + true + end + + # Timestamp for this task. Basic tasks return the current time for their + # time stamp. Other tasks can be more sophisticated. + def timestamp + @prerequisites.collect { |p| application[p].timestamp }.max || Time.now + end + + # Add a description to the task. The description can consist of an option + # argument list (enclosed brackets) and an optional comment. + def add_description(description) + return if ! description + comment = description.strip + add_comment(comment) if comment && ! comment.empty? + end + + # Writing to the comment attribute is the same as adding a description. + def comment=(description) + add_description(description) + end + + # Add a comment to the task. If a comment alread exists, separate + # the new comment with " / ". + def add_comment(comment) + if @full_comment + @full_comment << " / " + else + @full_comment = '' + end + @full_comment << comment + if @full_comment =~ /\A([^.]+?\.)( |$)/ + @comment = $1 + else + @comment = @full_comment + end + end + private :add_comment + + # Set the names of the arguments for this task. +args+ should be + # an array of symbols, one for each argument name. + def set_arg_names(args) + @arg_names = args.map { |a| a.to_sym } + end + + # Return a string describing the internal state of a task. Useful for + # debugging. + def investigation + result = "------------------------------\n" + result << "Investigating #{name}\n" + result << "class: #{self.class}\n" + result << "task needed: #{needed?}\n" + result << "timestamp: #{timestamp}\n" + result << "pre-requisites: \n" + prereqs = @prerequisites.collect {|name| application[name]} + prereqs.sort! {|a,b| a.timestamp <=> b.timestamp} + prereqs.each do |p| + result << "--#{p.name} (#{p.timestamp})\n" + end + latest_prereq = @prerequisites.collect{|n| application[n].timestamp}.max + result << "latest-prerequisite time: #{latest_prereq}\n" + result << "................................\n\n" + return result + end + + # ---------------------------------------------------------------- + # Rake Module Methods + # + class << self + + # Clear the task list. This cause rake to immediately forget all the + # tasks that have been assigned. (Normally used in the unit tests.) + def clear + Rake.application.clear + end + + # List of all defined tasks. + def tasks + Rake.application.tasks + end + + # Return a task with the given name. If the task is not currently + # known, try to synthesize one from the defined rules. If no rules are + # found, but an existing file matches the task name, assume it is a file + # task with no dependencies or actions. + def [](task_name) + Rake.application[task_name] + end + + # TRUE if the task name is already defined. + def task_defined?(task_name) + Rake.application.lookup(task_name) != nil + end + + # Define a task given +args+ and an option block. If a rule with the + # given name already exists, the prerequisites and actions are added to + # the existing task. Returns the defined task. + def define_task(*args, &block) + Rake.application.define_task(self, *args, &block) + end + + # Define a rule for synthesizing tasks. + def create_rule(*args, &block) + Rake.application.create_rule(*args, &block) + end + + # Apply the scope to the task name according to the rules for + # this kind of task. Generic tasks will accept the scope as + # part of the name. + def scope_name(scope, task_name) + (scope + [task_name]).join(':') + end + + end # class << Rake::Task + end # class Rake::Task + + + # ######################################################################### + # A FileTask is a task that includes time based dependencies. If any of a + # FileTask's prerequisites have a timestamp that is later than the file + # represented by this task, then the file must be rebuilt (using the + # supplied actions). + # + class FileTask < Task + + # Is this file task needed? Yes if it doesn't exist, or if its time stamp + # is out of date. + def needed? + return true unless File.exist?(name) + return true if out_of_date?(timestamp) + false + end + + # Time stamp for file task. + def timestamp + if File.exist?(name) + File.mtime(name.to_s) + else + Rake::EARLY + end + end + + private + + # Are there any prerequisites with a later time than the given time stamp? + def out_of_date?(stamp) + @prerequisites.any? { |n| application[n].timestamp > stamp} + end + + # ---------------------------------------------------------------- + # Task class methods. + # + class << self + # Apply the scope to the task name according to the rules for this kind + # of task. File based tasks ignore the scope when creating the name. + def scope_name(scope, task_name) + task_name + end + end + end # class Rake::FileTask + + # ######################################################################### + # A FileCreationTask is a file task that when used as a dependency will be + # needed if and only if the file has not been created. Once created, it is + # not re-triggered if any of its dependencies are newer, nor does trigger + # any rebuilds of tasks that depend on it whenever it is updated. + # + class FileCreationTask < FileTask + # Is this file task needed? Yes if it doesn't exist. + def needed? + ! File.exist?(name) + end + + # Time stamp for file creation task. This time stamp is earlier + # than any other time stamp. + def timestamp + Rake::EARLY + end + end + + # ######################################################################### + # Same as a regular task, but the immediate prerequisites are done in + # parallel using Ruby threads. + # + class MultiTask < Task + def invoke_prerequisites(args, invocation_chain) + threads = @prerequisites.collect { |p| + Thread.new(p) { |r| application[r].invoke_with_call_chain(args, invocation_chain) } + } + threads.each { |t| t.join } + end + end +end # module Rake + +# ########################################################################### +# Task Definition Functions ... + +# Declare a basic task. +# +# Example: +# task :clobber => [:clean] do +# rm_rf "html" +# end +# +def task(*args, &block) + Rake::Task.define_task(*args, &block) +end + + +# Declare a file task. +# +# Example: +# file "config.cfg" => ["config.template"] do +# open("config.cfg", "w") do |outfile| +# open("config.template") do |infile| +# while line = infile.gets +# outfile.puts line +# end +# end +# end +# end +# +def file(*args, &block) + Rake::FileTask.define_task(*args, &block) +end + +# Declare a file creation task. +# (Mainly used for the directory command). +def file_create(args, &block) + Rake::FileCreationTask.define_task(args, &block) +end + +# Declare a set of files tasks to create the given directories on demand. +# +# Example: +# directory "testdata/doc" +# +def directory(dir) + Rake.each_dir_parent(dir) do |d| + file_create d do |t| + mkdir_p t.name if ! File.exist?(t.name) + end + end +end + +# Declare a task that performs its prerequisites in parallel. Multitasks does +# *not* guarantee that its prerequisites will execute in any given order +# (which is obvious when you think about it) +# +# Example: +# multitask :deploy => [:deploy_gem, :deploy_rdoc] +# +def multitask(args, &block) + Rake::MultiTask.define_task(args, &block) +end + +# Create a new rake namespace and use it for evaluating the given block. +# Returns a NameSpace object that can be used to lookup tasks defined in the +# namespace. +# +# E.g. +# +# ns = namespace "nested" do +# task :run +# end +# task_run = ns[:run] # find :run in the given namespace. +# +def namespace(name=nil, &block) + Rake.application.in_namespace(name, &block) +end + +# Declare a rule for auto-tasks. +# +# Example: +# rule '.o' => '.c' do |t| +# sh %{cc -o #{t.name} #{t.source}} +# end +# +def rule(*args, &block) + Rake::Task.create_rule(*args, &block) +end + +# Describe the next rake task. +# +# Example: +# desc "Run the Unit Tests" +# task :test => [:build] +# runtests +# end +# +def desc(description) + Rake.application.last_description = description +end + +# Import the partial Rakefiles +fn+. Imported files are loaded _after_ the +# current file is completely loaded. This allows the import statement to +# appear anywhere in the importing file, and yet allowing the imported files +# to depend on objects defined in the importing file. +# +# A common use of the import statement is to include files containing +# dependency declarations. +# +# See also the --rakelibdir command line option. +# +# Example: +# import ".depend", "my_rules" +# +def import(*fns) + fns.each do |fn| + Rake.application.add_import(fn) + end +end + +# ########################################################################### +# This a FileUtils extension that defines several additional commands to be +# added to the FileUtils utility functions. +# +module FileUtils + RUBY = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name']). + sub(/.*\s.*/m, '"\&"') + + OPT_TABLE['sh'] = %w(noop verbose) + OPT_TABLE['ruby'] = %w(noop verbose) + + # Run the system command +cmd+. If multiple arguments are given the command + # is not run with the shell (same semantics as Kernel::exec and + # Kernel::system). + # + # Example: + # sh %{ls -ltr} + # + # sh 'ls', 'file with spaces' + # + # # check exit status after command runs + # sh %{grep pattern file} do |ok, res| + # if ! ok + # puts "pattern not found (status = #{res.exitstatus})" + # end + # end + # + def sh(*cmd, &block) + options = (Hash === cmd.last) ? cmd.pop : {} + unless block_given? + show_command = cmd.join(" ") + show_command = show_command[0,42] + "..." + # TODO code application logic heref show_command.length > 45 + block = lambda { |ok, status| + ok or fail "Command failed with status (#{status.exitstatus}): [#{show_command}]" + } + end + if RakeFileUtils.verbose_flag == :default + options[:verbose] = false + else + options[:verbose] ||= RakeFileUtils.verbose_flag + end + options[:noop] ||= RakeFileUtils.nowrite_flag + rake_check_options options, :noop, :verbose + rake_output_message cmd.join(" ") if options[:verbose] + unless options[:noop] + res = rake_system(*cmd) + block.call(res, $?) + end + end + + def rake_system(*cmd) + if Rake::Win32.windows? + Rake::Win32.rake_system(*cmd) + else + system(*cmd) + end + end + private :rake_system + + # Run a Ruby interpreter with the given arguments. + # + # Example: + # ruby %{-pe '$_.upcase!' 1 then + sh(*([RUBY] + args + [options]), &block) + else + sh("#{RUBY} #{args.first}", options, &block) + end + end + + LN_SUPPORTED = [true] + + # Attempt to do a normal file link, but fall back to a copy if the link + # fails. + def safe_ln(*args) + unless LN_SUPPORTED[0] + cp(*args) + else + begin + ln(*args) + rescue StandardError, NotImplementedError => ex + LN_SUPPORTED[0] = false + cp(*args) + end + end + end + + # Split a file path into individual directory names. + # + # Example: + # split_all("a/b/c") => ['a', 'b', 'c'] + # + def split_all(path) + head, tail = File.split(path) + return [tail] if head == '.' || tail == '/' + return [head, tail] if head == '/' + return split_all(head) + [tail] + end +end + +# ########################################################################### +# RakeFileUtils provides a custom version of the FileUtils methods that +# respond to the verbose and nowrite commands. +# +module RakeFileUtils + include FileUtils + + class << self + attr_accessor :verbose_flag, :nowrite_flag + end + RakeFileUtils.verbose_flag = :default + RakeFileUtils.nowrite_flag = false + + $fileutils_verbose = true + $fileutils_nowrite = false + + FileUtils::OPT_TABLE.each do |name, opts| + default_options = [] + if opts.include?(:verbose) || opts.include?("verbose") + default_options << ':verbose => RakeFileUtils.verbose_flag' + end + if opts.include?(:noop) || opts.include?("noop") + default_options << ':noop => RakeFileUtils.nowrite_flag' + end + + next if default_options.empty? + module_eval(<<-EOS, __FILE__, __LINE__ + 1) + def #{name}( *args, &block ) + super( + *rake_merge_option(args, + #{default_options.join(', ')} + ), &block) + end + EOS + end + + # Get/set the verbose flag controlling output from the FileUtils utilities. + # If verbose is true, then the utility method is echoed to standard output. + # + # Examples: + # verbose # return the current value of the verbose flag + # verbose(v) # set the verbose flag to _v_. + # verbose(v) { code } # Execute code with the verbose flag set temporarily to _v_. + # # Return to the original value when code is done. + def verbose(value=nil) + oldvalue = RakeFileUtils.verbose_flag + RakeFileUtils.verbose_flag = value unless value.nil? + if block_given? + begin + yield + ensure + RakeFileUtils.verbose_flag = oldvalue + end + end + RakeFileUtils.verbose_flag + end + + # Get/set the nowrite flag controlling output from the FileUtils utilities. + # If verbose is true, then the utility method is echoed to standard output. + # + # Examples: + # nowrite # return the current value of the nowrite flag + # nowrite(v) # set the nowrite flag to _v_. + # nowrite(v) { code } # Execute code with the nowrite flag set temporarily to _v_. + # # Return to the original value when code is done. + def nowrite(value=nil) + oldvalue = RakeFileUtils.nowrite_flag + RakeFileUtils.nowrite_flag = value unless value.nil? + if block_given? + begin + yield + ensure + RakeFileUtils.nowrite_flag = oldvalue + end + end + oldvalue + end + + # Use this function to prevent protentially destructive ruby code from + # running when the :nowrite flag is set. + # + # Example: + # + # when_writing("Building Project") do + # project.build + # end + # + # The following code will build the project under normal conditions. If the + # nowrite(true) flag is set, then the example will print: + # DRYRUN: Building Project + # instead of actually building the project. + # + def when_writing(msg=nil) + if RakeFileUtils.nowrite_flag + puts "DRYRUN: #{msg}" if msg + else + yield + end + end + + # Merge the given options with the default values. + def rake_merge_option(args, defaults) + if Hash === args.last + defaults.update(args.last) + args.pop + end + args.push defaults + args + end + private :rake_merge_option + + # Send the message to the default rake output (which is $stderr). + def rake_output_message(message) + $stderr.puts(message) + end + private :rake_output_message + + # Check that the options do not contain options not listed in +optdecl+. An + # ArgumentError exception is thrown if non-declared options are found. + def rake_check_options(options, *optdecl) + h = options.dup + optdecl.each do |name| + h.delete name + end + raise ArgumentError, "no such option: #{h.keys.join(' ')}" unless h.empty? + end + private :rake_check_options + + extend self +end + +# ########################################################################### +# Include the FileUtils file manipulation functions in the top level module, +# but mark them private so that they don't unintentionally define methods on +# other objects. + +include RakeFileUtils +private(*FileUtils.instance_methods(false)) +private(*RakeFileUtils.instance_methods(false)) + +###################################################################### +module Rake + + # ######################################################################### + # A FileList is essentially an array with a few helper methods defined to + # make file manipulation a bit easier. + # + # FileLists are lazy. When given a list of glob patterns for possible files + # to be included in the file list, instead of searching the file structures + # to find the files, a FileList holds the pattern for latter use. + # + # This allows us to define a number of FileList to match any number of + # files, but only search out the actual files when then FileList itself is + # actually used. The key is that the first time an element of the + # FileList/Array is requested, the pending patterns are resolved into a real + # list of file names. + # + class FileList + + include Cloneable + + # == Method Delegation + # + # The lazy evaluation magic of FileLists happens by implementing all the + # array specific methods to call +resolve+ before delegating the heavy + # lifting to an embedded array object (@items). + # + # In addition, there are two kinds of delegation calls. The regular kind + # delegates to the @items array and returns the result directly. Well, + # almost directly. It checks if the returned value is the @items object + # itself, and if so will return the FileList object instead. + # + # The second kind of delegation call is used in methods that normally + # return a new Array object. We want to capture the return value of these + # methods and wrap them in a new FileList object. We enumerate these + # methods in the +SPECIAL_RETURN+ list below. + + # List of array methods (that are not in +Object+) that need to be + # delegated. + ARRAY_METHODS = (Array.instance_methods - Object.instance_methods).map { |n| n.to_s } + + # List of additional methods that must be delegated. + MUST_DEFINE = %w[to_a inspect] + + # List of methods that should not be delegated here (we define special + # versions of them explicitly below). + MUST_NOT_DEFINE = %w[to_a to_ary partition *] + + # List of delegated methods that return new array values which need + # wrapping. + SPECIAL_RETURN = %w[ + map collect sort sort_by select find_all reject grep + compact flatten uniq values_at + + - & | + ] + + DELEGATING_METHODS = (ARRAY_METHODS + MUST_DEFINE - MUST_NOT_DEFINE).collect{ |s| s.to_s }.sort.uniq + + # Now do the delegation. + DELEGATING_METHODS.each_with_index do |sym, i| + if SPECIAL_RETURN.include?(sym) + ln = __LINE__+1 + class_eval %{ + def #{sym}(*args, &block) + resolve + result = @items.send(:#{sym}, *args, &block) + FileList.new.import(result) + end + }, __FILE__, ln + else + ln = __LINE__+1 + class_eval %{ + def #{sym}(*args, &block) + resolve + result = @items.send(:#{sym}, *args, &block) + result.object_id == @items.object_id ? self : result + end + }, __FILE__, ln + end + end + + # Create a file list from the globbable patterns given. If you wish to + # perform multiple includes or excludes at object build time, use the + # "yield self" pattern. + # + # Example: + # file_list = FileList.new('lib/**/*.rb', 'test/test*.rb') + # + # pkg_files = FileList.new('lib/**/*') do |fl| + # fl.exclude(/\bCVS\b/) + # end + # + def initialize(*patterns) + @pending_add = [] + @pending = false + @exclude_patterns = DEFAULT_IGNORE_PATTERNS.dup + @exclude_procs = DEFAULT_IGNORE_PROCS.dup + @exclude_re = nil + @items = [] + patterns.each { |pattern| include(pattern) } + yield self if block_given? + end + + # Add file names defined by glob patterns to the file list. If an array + # is given, add each element of the array. + # + # Example: + # file_list.include("*.java", "*.cfg") + # file_list.include %w( math.c lib.h *.o ) + # + def include(*filenames) + # TODO: check for pending + filenames.each do |fn| + if fn.respond_to? :to_ary + include(*fn.to_ary) + else + @pending_add << fn + end + end + @pending = true + self + end + alias :add :include + + # Register a list of file name patterns that should be excluded from the + # list. Patterns may be regular expressions, glob patterns or regular + # strings. In addition, a block given to exclude will remove entries that + # return true when given to the block. + # + # Note that glob patterns are expanded against the file system. If a file + # is explicitly added to a file list, but does not exist in the file + # system, then an glob pattern in the exclude list will not exclude the + # file. + # + # Examples: + # FileList['a.c', 'b.c'].exclude("a.c") => ['b.c'] + # FileList['a.c', 'b.c'].exclude(/^a/) => ['b.c'] + # + # If "a.c" is a file, then ... + # FileList['a.c', 'b.c'].exclude("a.*") => ['b.c'] + # + # If "a.c" is not a file, then ... + # FileList['a.c', 'b.c'].exclude("a.*") => ['a.c', 'b.c'] + # + def exclude(*patterns, &block) + patterns.each do |pat| + @exclude_patterns << pat + end + if block_given? + @exclude_procs << block + end + resolve_exclude if ! @pending + self + end + + + # Clear all the exclude patterns so that we exclude nothing. + def clear_exclude + @exclude_patterns = [] + @exclude_procs = [] + calculate_exclude_regexp if ! @pending + self + end + + # Define equality. + def ==(array) + to_ary == array + end + + # Return the internal array object. + def to_a + resolve + @items + end + + # Return the internal array object. + def to_ary + to_a + end + + # Lie about our class. + def is_a?(klass) + klass == Array || super(klass) + end + alias kind_of? is_a? + + # Redefine * to return either a string or a new file list. + def *(other) + result = @items * other + case result + when Array + FileList.new.import(result) + else + result + end + end + + # Resolve all the pending adds now. + def resolve + if @pending + @pending = false + @pending_add.each do |fn| resolve_add(fn) end + @pending_add = [] + resolve_exclude + end + self + end + + def calculate_exclude_regexp + ignores = [] + @exclude_patterns.each do |pat| + case pat + when Regexp + ignores << pat + when /[*?]/ + Dir[pat].each do |p| ignores << p end + else + ignores << Regexp.quote(pat) + end + end + if ignores.empty? + @exclude_re = /^$/ + else + re_str = ignores.collect { |p| "(" + p.to_s + ")" }.join("|") + @exclude_re = Regexp.new(re_str) + end + end + + def resolve_add(fn) + case fn + when %r{[*?\[\{]} + add_matching(fn) + else + self << fn + end + end + private :resolve_add + + def resolve_exclude + calculate_exclude_regexp + reject! { |fn| exclude?(fn) } + self + end + private :resolve_exclude + + # Return a new FileList with the results of running +sub+ against each + # element of the oringal list. + # + # Example: + # FileList['a.c', 'b.c'].sub(/\.c$/, '.o') => ['a.o', 'b.o'] + # + def sub(pat, rep) + inject(FileList.new) { |res, fn| res << fn.sub(pat,rep) } + end + + # Return a new FileList with the results of running +gsub+ against each + # element of the original list. + # + # Example: + # FileList['lib/test/file', 'x/y'].gsub(/\//, "\\") + # => ['lib\\test\\file', 'x\\y'] + # + def gsub(pat, rep) + inject(FileList.new) { |res, fn| res << fn.gsub(pat,rep) } + end + + # Same as +sub+ except that the oringal file list is modified. + def sub!(pat, rep) + each_with_index { |fn, i| self[i] = fn.sub(pat,rep) } + self + end + + # Same as +gsub+ except that the original file list is modified. + def gsub!(pat, rep) + each_with_index { |fn, i| self[i] = fn.gsub(pat,rep) } + self + end + + # Apply the pathmap spec to each of the included file names, returning a + # new file list with the modified paths. (See String#pathmap for + # details.) + def pathmap(spec=nil) + collect { |fn| fn.pathmap(spec) } + end + + # Return a new array with String#ext method applied to each + # member of the array. + # + # This method is a shortcut for: + # + # array.collect { |item| item.ext(newext) } + # + # +ext+ is a user added method for the Array class. + def ext(newext='') + collect { |fn| fn.ext(newext) } + end + + + # Grep each of the files in the filelist using the given pattern. If a + # block is given, call the block on each matching line, passing the file + # name, line number, and the matching line of text. If no block is given, + # a standard emac style file:linenumber:line message will be printed to + # standard out. + def egrep(pattern) + each do |fn| + open(fn) do |inf| + count = 0 + inf.each do |line| + count += 1 + if pattern.match(line) + if block_given? + yield fn, count, line + else + puts "#{fn}:#{count}:#{line}" + end + end + end + end + end + end + + # Return a new file list that only contains file names from the current + # file list that exist on the file system. + def existing + select { |fn| File.exist?(fn) } + end + + # Modify the current file list so that it contains only file name that + # exist on the file system. + def existing! + resolve + @items = @items.select { |fn| File.exist?(fn) } + self + end + + # FileList version of partition. Needed because the nested arrays should + # be FileLists in this version. + def partition(&block) # :nodoc: + resolve + result = @items.partition(&block) + [ + FileList.new.import(result[0]), + FileList.new.import(result[1]), + ] + end + + # Convert a FileList to a string by joining all elements with a space. + def to_s + resolve + self.join(' ') + end + + # Add matching glob patterns. + def add_matching(pattern) + Dir[pattern].each do |fn| + self << fn unless exclude?(fn) + end + end + private :add_matching + + # Should the given file name be excluded? + def exclude?(fn) + calculate_exclude_regexp unless @exclude_re + fn =~ @exclude_re || @exclude_procs.any? { |p| p.call(fn) } + end + + DEFAULT_IGNORE_PATTERNS = [ + /(^|[\/\\])CVS([\/\\]|$)/, + /(^|[\/\\])\.svn([\/\\]|$)/, + /\.bak$/, + /~$/ + ] + DEFAULT_IGNORE_PROCS = [ + proc { |fn| fn =~ /(^|[\/\\])core$/ && ! File.directory?(fn) } + ] +# @exclude_patterns = DEFAULT_IGNORE_PATTERNS.dup + + def import(array) + @items = array + self + end + + class << self + # Create a new file list including the files listed. Similar to: + # + # FileList.new(*args) + def [](*args) + new(*args) + end + end + end # FileList +end + +module Rake + class << self + + # Yield each file or directory component. + def each_dir_parent(dir) # :nodoc: + old_length = nil + while dir != '.' && dir.length != old_length + yield(dir) + old_length = dir.length + dir = File.dirname(dir) + end + end + end +end # module Rake + +# Alias FileList to be available at the top level. +FileList = Rake::FileList + +# ########################################################################### +module Rake + + # Default Rakefile loader used by +import+. + class DefaultLoader + def load(fn) + Kernel.load(File.expand_path(fn)) + end + end + + # EarlyTime is a fake timestamp that occurs _before_ any other time value. + class EarlyTime + include Comparable + include Singleton + + def <=>(other) + -1 + end + + def to_s + "" + end + end + + EARLY = EarlyTime.instance +end # module Rake + +# ########################################################################### +# Extensions to time to allow comparisons with an early time class. +# +class Time + alias rake_original_time_compare :<=> + def <=>(other) + if Rake::EarlyTime === other + - other.<=>(self) + else + rake_original_time_compare(other) + end + end +end # class Time + +module Rake + + #################################################################### + # The NameSpace class will lookup task names in the the scope + # defined by a +namespace+ command. + # + class NameSpace + + # Create a namespace lookup object using the given task manager + # and the list of scopes. + def initialize(task_manager, scope_list) + @task_manager = task_manager + @scope = scope_list.dup + end + + # Lookup a task named +name+ in the namespace. + def [](name) + @task_manager.lookup(name, @scope) + end + + # Return the list of tasks defined in this namespace. + def tasks + @task_manager.tasks + end + end # NameSpace + + + #################################################################### + # The TaskManager module is a mixin for managing tasks. + module TaskManager + # Track the last comment made in the Rakefile. + attr_accessor :last_description + alias :last_comment :last_description # Backwards compatibility + + def initialize + super + @tasks = Hash.new + @rules = Array.new + @scope = Array.new + @last_description = nil + end + + def create_rule(*args, &block) + pattern, arg_names, deps = resolve_args(args) + pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern + @rules << [pattern, deps, block] + end + + def define_task(task_class, *args, &block) + task_name, arg_names, deps = resolve_args(args) + task_name = task_class.scope_name(@scope, task_name) + deps = [deps] unless deps.respond_to?(:to_ary) + deps = deps.collect {|d| d.to_s } + task = intern(task_class, task_name) + task.set_arg_names(arg_names) unless arg_names.empty? + task.add_description(@last_description) + @last_description = nil + task.enhance(deps, &block) + task + end + + # Lookup a task. Return an existing task if found, otherwise + # create a task of the current type. + def intern(task_class, task_name) + @tasks[task_name.to_s] ||= task_class.new(task_name, self) + end + + # Find a matching task for +task_name+. + def [](task_name, scopes=nil) + task_name = task_name.to_s + self.lookup(task_name, scopes) or + enhance_with_matching_rule(task_name) or + synthesize_file_task(task_name) or + fail "Don't know how to build task '#{task_name}'" + end + + def synthesize_file_task(task_name) + return nil unless File.exist?(task_name) + define_task(Rake::FileTask, task_name) + end + + # Resolve the arguments for a task/rule. Returns a triplet of + # [task_name, arg_name_list, prerequisites]. + def resolve_args(args) + if args.last.is_a?(Hash) + deps = args.pop + resolve_args_with_dependencies(args, deps) + else + resolve_args_without_dependencies(args) + end + end + + # Resolve task arguments for a task or rule when there are no + # dependencies declared. + # + # The patterns recognized by this argument resolving function are: + # + # task :t + # task :t, [:a] + # task :t, :a (deprecated) + # + def resolve_args_without_dependencies(args) + task_name = args.shift + if args.size == 1 && args.first.respond_to?(:to_ary) + arg_names = args.first.to_ary + else + arg_names = args + end + [task_name, arg_names, []] + end + private :resolve_args_without_dependencies + + # Resolve task arguments for a task or rule when there are + # dependencies declared. + # + # The patterns recognized by this argument resolving function are: + # + # task :t => [:d] + # task :t, [a] => [:d] + # task :t, :needs => [:d] (deprecated) + # task :t, :a, :needs => [:d] (deprecated) + # + def resolve_args_with_dependencies(args, hash) # :nodoc: + fail "Task Argument Error" if hash.size != 1 + key, value = hash.map { |k, v| [k,v] }.first + if args.empty? + task_name = key + arg_names = [] + deps = value + elsif key == :needs + task_name = args.shift + arg_names = args + deps = value + else + task_name = args.shift + arg_names = key + deps = value + end + deps = [deps] unless deps.respond_to?(:to_ary) + [task_name, arg_names, deps] + end + private :resolve_args_with_dependencies + + # If a rule can be found that matches the task name, enhance the + # task with the prerequisites and actions from the rule. Set the + # source attribute of the task appropriately for the rule. Return + # the enhanced task or nil of no rule was found. + def enhance_with_matching_rule(task_name, level=0) + fail Rake::RuleRecursionOverflowError, + "Rule Recursion Too Deep" if level >= 16 + @rules.each do |pattern, extensions, block| + if md = pattern.match(task_name) + task = attempt_rule(task_name, extensions, block, level) + return task if task + end + end + nil + rescue Rake::RuleRecursionOverflowError => ex + ex.add_target(task_name) + fail ex + end + + # List of all defined tasks in this application. + def tasks + @tasks.values.sort_by { |t| t.name } + end + + # Clear all tasks in this application. + def clear + @tasks.clear + @rules.clear + end + + # Lookup a task, using scope and the scope hints in the task name. + # This method performs straight lookups without trying to + # synthesize file tasks or rules. Special scope names (e.g. '^') + # are recognized. If no scope argument is supplied, use the + # current scope. Return nil if the task cannot be found. + def lookup(task_name, initial_scope=nil) + initial_scope ||= @scope + task_name = task_name.to_s + if task_name =~ /^rake:/ + scopes = [] + task_name = task_name.sub(/^rake:/, '') + elsif task_name =~ /^(\^+)/ + scopes = initial_scope[0, initial_scope.size - $1.size] + task_name = task_name.sub(/^(\^+)/, '') + else + scopes = initial_scope + end + lookup_in_scope(task_name, scopes) + end + + # Lookup the task name + def lookup_in_scope(name, scope) + n = scope.size + while n >= 0 + tn = (scope[0,n] + [name]).join(':') + task = @tasks[tn] + return task if task + n -= 1 + end + nil + end + private :lookup_in_scope + + # Return the list of scope names currently active in the task + # manager. + def current_scope + @scope.dup + end + + # Evaluate the block in a nested namespace named +name+. Create + # an anonymous namespace if +name+ is nil. + def in_namespace(name) + name ||= generate_name + @scope.push(name) + ns = NameSpace.new(self, @scope) + yield(ns) + ns + ensure + @scope.pop + end + + private + + # Generate an anonymous namespace name. + def generate_name + @seed ||= 0 + @seed += 1 + "_anon_#{@seed}" + end + + def trace_rule(level, message) + puts "#{" "*level}#{message}" if Rake.application.options.trace_rules + end + + # Attempt to create a rule given the list of prerequisites. + def attempt_rule(task_name, extensions, block, level) + sources = make_sources(task_name, extensions) + prereqs = sources.collect { |source| + trace_rule level, "Attempting Rule #{task_name} => #{source}" + if File.exist?(source) || Rake::Task.task_defined?(source) + trace_rule level, "(#{task_name} => #{source} ... EXIST)" + source + elsif parent = enhance_with_matching_rule(source, level+1) + trace_rule level, "(#{task_name} => #{source} ... ENHANCE)" + parent.name + else + trace_rule level, "(#{task_name} => #{source} ... FAIL)" + return nil + end + } + task = FileTask.define_task({task_name => prereqs}, &block) + task.sources = prereqs + task + end + + # Make a list of sources from the list of file name extensions / + # translation procs. + def make_sources(task_name, extensions) + extensions.collect { |ext| + case ext + when /%/ + task_name.pathmap(ext) + when %r{/} + ext + when /^\./ + task_name.ext(ext) + when String + ext + when Proc + if ext.arity == 1 + ext.call(task_name) + else + ext.call + end + else + fail "Don't know how to handle rule dependent: #{ext.inspect}" + end + }.flatten + end + + end # TaskManager + + ###################################################################### + # Rake main application object. When invoking +rake+ from the + # command line, a Rake::Application object is created and run. + # + class Application + include TaskManager + + # The name of the application (typically 'rake') + attr_reader :name + + # The original directory where rake was invoked. + attr_reader :original_dir + + # Name of the actual rakefile used. + attr_reader :rakefile + + # List of the top level task names (task names from the command line). + attr_reader :top_level_tasks + + DEFAULT_RAKEFILES = ['rakefile', 'Rakefile', 'rakefile.rb', 'Rakefile.rb'].freeze + + # Initialize a Rake::Application object. + def initialize + super + @name = 'rake' + @rakefiles = DEFAULT_RAKEFILES.dup + @rakefile = nil + @pending_imports = [] + @imported = [] + @loaders = {} + @default_loader = Rake::DefaultLoader.new + @original_dir = Dir.pwd + @top_level_tasks = [] + add_loader('rb', DefaultLoader.new) + add_loader('rf', DefaultLoader.new) + add_loader('rake', DefaultLoader.new) + @tty_output = STDOUT.tty? + end + + # Run the Rake application. The run method performs the following three steps: + # + # * Initialize the command line options (+init+). + # * Define the tasks (+load_rakefile+). + # * Run the top level tasks (+run_tasks+). + # + # If you wish to build a custom rake command, you should call +init+ on your + # application. The define any tasks. Finally, call +top_level+ to run your top + # level tasks. + def run + standard_exception_handling do + init + load_rakefile + top_level + end + end + + # Initialize the command line parameters and app name. + def init(app_name='rake') + standard_exception_handling do + @name = app_name + collect_tasks handle_options + end + end + + # Find the rakefile and then load it and any pending imports. + def load_rakefile + standard_exception_handling do + raw_load_rakefile + end + end + + # Run the top level tasks of a Rake application. + def top_level + standard_exception_handling do + if options.show_tasks + display_tasks_and_comments + elsif options.show_prereqs + display_prerequisites + else + top_level_tasks.each { |task_name| invoke_task(task_name) } + end + end + end + + # Add a loader to handle imported files ending in the extension + # +ext+. + def add_loader(ext, loader) + ext = ".#{ext}" unless ext =~ /^\./ + @loaders[ext] = loader + end + + # Application options from the command line + def options + @options ||= OpenStruct.new + end + + # private ---------------------------------------------------------------- + + def invoke_task(task_string) + name, args = parse_task_string(task_string) + t = self[name] + t.invoke(*args) + end + + def parse_task_string(string) + if string =~ /^([^\[]+)(\[(.*)\])$/ + name = $1 + args = $3.split(/\s*,\s*/) + else + name = string + args = [] + end + [name, args] + end + + # Provide standard execption handling for the given block. + def standard_exception_handling + begin + yield + rescue SystemExit => ex + # Exit silently with current status + exit(ex.status) + rescue SystemExit, OptionParser::InvalidOption => ex + # Exit silently + exit(1) + rescue Exception => ex + # Exit with error message + $stderr.puts "rake aborted!" + $stderr.puts ex.message + if options.trace + $stderr.puts ex.backtrace.join("\n") + else + $stderr.puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || "" + $stderr.puts "(See full trace by running task with --trace)" + end + exit(1) + end + end + + # True if one of the files in RAKEFILES is in the current directory. + # If a match is found, it is copied into @rakefile. + def have_rakefile + @rakefiles.each do |fn| + if File.exist?(fn) || fn == '' + return fn + end + end + return nil + end + + # True if we are outputting to TTY, false otherwise + def tty_output? + @tty_output + end + + # Override the detected TTY output state (mostly for testing) + def tty_output=( tty_output_state ) + @tty_output = tty_output_state + end + + # We will truncate output if we are outputting to a TTY or if we've been + # given an explicit column width to honor + def truncate_output? + tty_output? || ENV['RAKE_COLUMNS'] + end + + # Display the tasks and dependencies. + def display_tasks_and_comments + displayable_tasks = tasks.select { |t| + t.comment && t.name =~ options.show_task_pattern + } + if options.full_description + displayable_tasks.each do |t| + puts "rake #{t.name_with_args}" + t.full_comment.split("\n").each do |line| + puts " #{line}" + end + puts + end + else + width = displayable_tasks.collect { |t| t.name_with_args.length }.max || 10 + max_column = truncate_output? ? terminal_width - name.size - width - 7 : nil + displayable_tasks.each do |t| + printf "#{name} %-#{width}s # %s\n", + t.name_with_args, max_column ? truncate(t.comment, max_column) : t.comment + end + end + end + + def terminal_width + if ENV['RAKE_COLUMNS'] + result = ENV['RAKE_COLUMNS'].to_i + else + result = unix? ? dynamic_width : 80 + end + (result < 10) ? 80 : result + rescue + 80 + end + + # Calculate the dynamic width of the + def dynamic_width + @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput) + end + + def dynamic_width_stty + %x{stty size 2>/dev/null}.split[1].to_i + end + + def dynamic_width_tput + %x{tput cols 2>/dev/null}.to_i + end + + def unix? + RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i + end + + def windows? + Win32.windows? + end + + def truncate(string, width) + if string.length <= width + string + else + ( string[0, width-3] || "" ) + "..." + end + end + + # Display the tasks and prerequisites + def display_prerequisites + tasks.each do |t| + puts "rake #{t.name}" + t.prerequisites.each { |pre| puts " #{pre}" } + end + end + + # A list of all the standard options used in rake, suitable for + # passing to OptionParser. + def standard_rake_options + [ + ['--classic-namespace', '-C', "Put Task and FileTask in the top level namespace", + lambda { |value| + require 'rake/classic_namespace' + options.classic_namespace = true + } + ], + ['--describe', '-D [PATTERN]', "Describe the tasks (matching optional PATTERN), then exit.", + lambda { |value| + options.show_tasks = true + options.full_description = true + options.show_task_pattern = Regexp.new(value || '') + } + ], + ['--dry-run', '-n', "Do a dry run without executing actions.", + lambda { |value| + verbose(true) + nowrite(true) + options.dryrun = true + options.trace = true + } + ], + ['--execute', '-e CODE', "Execute some Ruby code and exit.", + lambda { |value| + eval(value) + exit + } + ], + ['--execute-print', '-p CODE', "Execute some Ruby code, print the result, then exit.", + lambda { |value| + puts eval(value) + exit + } + ], + ['--execute-continue', '-E CODE', + "Execute some Ruby code, then continue with normal task processing.", + lambda { |value| eval(value) } + ], + ['--libdir', '-I LIBDIR', "Include LIBDIR in the search path for required modules.", + lambda { |value| $:.push(value) } + ], + ['--prereqs', '-P', "Display the tasks and dependencies, then exit.", + lambda { |value| options.show_prereqs = true } + ], + ['--quiet', '-q', "Do not log messages to standard output.", + lambda { |value| verbose(false) } + ], + ['--rakefile', '-f [FILE]', "Use FILE as the rakefile.", + lambda { |value| + value ||= '' + @rakefiles.clear + @rakefiles << value + } + ], + ['--rakelibdir', '--rakelib', '-R RAKELIBDIR', + "Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')", + lambda { |value| options.rakelib = value.split(':') } + ], + ['--require', '-r MODULE', "Require MODULE before executing rakefile.", + lambda { |value| + begin + require value + rescue LoadError => ex + begin + rake_require value + rescue LoadError => ex2 + raise ex + end + end + } + ], + ['--rules', "Trace the rules resolution.", + lambda { |value| options.trace_rules = true } + ], + ['--no-search', '--nosearch', '-N', "Do not search parent directories for the Rakefile.", + lambda { |value| options.nosearch = true } + ], + ['--silent', '-s', "Like --quiet, but also suppresses the 'in directory' announcement.", + lambda { |value| + verbose(false) + options.silent = true + } + ], + ['--system', '-g', + "Using system wide (global) rakefiles (usually '~/.rake/*.rake').", + lambda { |value| options.load_system = true } + ], + ['--no-system', '--nosystem', '-G', + "Use standard project Rakefile search paths, ignore system wide rakefiles.", + lambda { |value| options.ignore_system = true } + ], + ['--tasks', '-T [PATTERN]', "Display the tasks (matching optional PATTERN) with descriptions, then exit.", + lambda { |value| + options.show_tasks = true + options.show_task_pattern = Regexp.new(value || '') + options.full_description = false + } + ], + ['--trace', '-t', "Turn on invoke/execute tracing, enable full backtrace.", + lambda { |value| + options.trace = true + verbose(true) + } + ], + ['--verbose', '-v', "Log message to standard output (default).", + lambda { |value| verbose(true) } + ], + ['--version', '-V', "Display the program version.", + lambda { |value| + puts "rake, version #{RAKEVERSION}" + exit + } + ] + ] + end + + # Read and handle the command line options. + def handle_options + options.rakelib = ['rakelib'] + + opts = OptionParser.new + opts.banner = "rake [-f rakefile] {options} targets..." + opts.separator "" + opts.separator "Options are ..." + + opts.on_tail("-h", "--help", "-H", "Display this help message.") do + puts opts + exit + end + + standard_rake_options.each { |args| opts.on(*args) } + parsed_argv = opts.parse(ARGV) + + # If class namespaces are requested, set the global options + # according to the values in the options structure. + if options.classic_namespace + $show_tasks = options.show_tasks + $show_prereqs = options.show_prereqs + $trace = options.trace + $dryrun = options.dryrun + $silent = options.silent + end + parsed_argv + end + + # Similar to the regular Ruby +require+ command, but will check + # for *.rake files in addition to *.rb files. + def rake_require(file_name, paths=$LOAD_PATH, loaded=$") + return false if loaded.include?(file_name) + paths.each do |path| + fn = file_name + ".rake" + full_path = File.join(path, fn) + if File.exist?(full_path) + load full_path + loaded << fn + return true + end + end + fail LoadError, "Can't find #{file_name}" + end + + def find_rakefile_location + here = Dir.pwd + while ! (fn = have_rakefile) + Dir.chdir("..") + if Dir.pwd == here || options.nosearch + return nil + end + here = Dir.pwd + end + [fn, here] + ensure + Dir.chdir(Rake.original_dir) + end + + def raw_load_rakefile # :nodoc: + rakefile, location = find_rakefile_location + if (! options.ignore_system) && + (options.load_system || rakefile.nil?) && + system_dir && File.directory?(system_dir) + puts "(in #{Dir.pwd})" unless options.silent + glob("#{system_dir}/*.rake") do |name| + add_import name + end + else + fail "No Rakefile found (looking for: #{@rakefiles.join(', ')})" if + rakefile.nil? + @rakefile = rakefile + Dir.chdir(location) + puts "(in #{Dir.pwd})" unless options.silent + $rakefile = @rakefile if options.classic_namespace + load File.expand_path(@rakefile) if @rakefile && @rakefile != '' + options.rakelib.each do |rlib| + glob("#{rlib}/*.rake") do |name| + add_import name + end + end + end + load_imports + end + + def glob(path, &block) + Dir[path.gsub("\\", '/')].each(&block) + end + private :glob + + # The directory path containing the system wide rakefiles. + def system_dir + @system_dir ||= + begin + if ENV['RAKE_SYSTEM'] + ENV['RAKE_SYSTEM'] + elsif Win32.windows? + Win32.win32_system_dir + else + standard_system_dir + end + end + end + + # The standard directory containing system wide rake files. + def standard_system_dir #:nodoc: + File.join(File.expand_path('~'), '.rake') + end + private :standard_system_dir + + # Collect the list of tasks on the command line. If no tasks are + # given, return a list containing only the default task. + # Environmental assignments are processed at this time as well. + def collect_tasks(argv) + @top_level_tasks = [] + argv.each do |arg| + if arg =~ /^(\w+)=(.*)$/ + ENV[$1] = $2 + else + @top_level_tasks << arg unless arg =~ /^-/ + end + end + @top_level_tasks.push("default") if @top_level_tasks.size == 0 + end + + # Add a file to the list of files to be imported. + def add_import(fn) + @pending_imports << fn + end + + # Load the pending list of imported files. + def load_imports + while fn = @pending_imports.shift + next if @imported.member?(fn) + if fn_task = lookup(fn) + fn_task.invoke + end + ext = File.extname(fn) + loader = @loaders[ext] || @default_loader + loader.load(fn) + @imported << fn + end + end + + # Warn about deprecated use of top level constant names. + def const_warning(const_name) + @const_warning ||= false + if ! @const_warning + $stderr.puts %{WARNING: Deprecated reference to top-level constant '#{const_name}' } + + %{found at: #{rakefile_location}} # ' + $stderr.puts %{ Use --classic-namespace on rake command} + $stderr.puts %{ or 'require "rake/classic_namespace"' in Rakefile} + end + @const_warning = true + end + + def rakefile_location + begin + fail + rescue RuntimeError => ex + ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || "" + end + end + end +end + + +class Module + # Rename the original handler to make it available. + alias :rake_original_const_missing :const_missing + + # Check for deprecated uses of top level (i.e. in Object) uses of + # Rake class names. If someone tries to reference the constant + # name, display a warning and return the proper object. Using the + # --classic-namespace command line option will define these + # constants in Object and avoid this handler. + def const_missing(const_name) + case const_name + when :Task + Rake.application.const_warning(const_name) + Rake::Task + when :FileTask + Rake.application.const_warning(const_name) + Rake::FileTask + when :FileCreationTask + Rake.application.const_warning(const_name) + Rake::FileCreationTask + when :RakeApp + Rake.application.const_warning(const_name) + Rake::Application + else + rake_original_const_missing(const_name) + end + end +end diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/classic_namespace.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/classic_namespace.rb new file mode 100644 index 0000000..feb7569 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/classic_namespace.rb @@ -0,0 +1,8 @@ +# The following classes used to be in the top level namespace. +# Loading this file enables compatibility with older Rakefile that +# referenced Task from the top level. + +Task = Rake::Task +FileTask = Rake::FileTask +FileCreationTask = Rake::FileCreationTask +RakeApp = Rake::Application diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/clean.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/clean.rb new file mode 100644 index 0000000..4ee2c5a --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/clean.rb @@ -0,0 +1,33 @@ +#!/usr/bin/env ruby + +# The 'rake/clean' file defines two file lists (CLEAN and CLOBBER) and +# two rake tasks (:clean and :clobber). +# +# [:clean] Clean up the project by deleting scratch files and backup +# files. Add files to the CLEAN file list to have the :clean +# target handle them. +# +# [:clobber] Clobber all generated and non-source files in a project. +# The task depends on :clean, so all the clean files will +# be deleted as well as files in the CLOBBER file list. +# The intent of this task is to return a project to its +# pristine, just unpacked state. + +require 'rake' + +CLEAN = Rake::FileList["**/*~", "**/*.bak", "**/core"] +CLEAN.clear_exclude.exclude { |fn| + fn.pathmap("%f") == 'core' && File.directory?(fn) +} + +desc "Remove any temporary products." +task :clean do + CLEAN.each { |fn| rm_r fn rescue nil } +end + +CLOBBER = Rake::FileList.new + +desc "Remove any generated file." +task :clobber => [:clean] do + CLOBBER.each { |fn| rm_r fn rescue nil } +end diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/compositepublisher.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/compositepublisher.rb new file mode 100644 index 0000000..d771ccc --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/compositepublisher.rb @@ -0,0 +1,24 @@ +#!/usr/bin/env ruby + +module Rake + + # Manage several publishers as a single entity. + class CompositePublisher + def initialize + @publishers = [] + end + + # Add a publisher to the composite. + def add(pub) + @publishers << pub + end + + # Upload all the individual publishers. + def upload + @publishers.each { |p| p.upload } + end + end + +end + + diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/ftptools.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/ftptools.rb new file mode 100644 index 0000000..4cd02f3 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/ftptools.rb @@ -0,0 +1,153 @@ +#!/usr/bin/env ruby + +# = Tools for FTP uploading. +# +# This file is still under development and is not released for general +# use. + +require 'date' +require 'net/ftp' + +module Rake # :nodoc: + + #################################################################### + # Note: Not released for general use. + class FtpFile + attr_reader :name, :size, :owner, :group, :time + + def self.date + @date_class ||= Date + end + + def self.time + @time_class ||= Time + end + + def initialize(path, entry) + @path = path + @mode, line, @owner, @group, size, d1, d2, d3, @name = entry.split(' ') + @size = size.to_i + @time = determine_time(d1, d2, d3) + end + + def path + File.join(@path, @name) + end + + def directory? + @mode[0] == ?d + end + + def mode + parse_mode(@mode) + end + + def symlink? + @mode[0] == ?l + end + + private # -------------------------------------------------------- + + def parse_mode(m) + result = 0 + (1..9).each do |i| + result = 2*result + ((m[i]==?-) ? 0 : 1) + end + result + end + + def determine_time(d1, d2, d3) + now = self.class.time.now + if /:/ =~ d3 + h, m = d3.split(':') + result = Time.parse("#{d1} #{d2} #{now.year} #{d3}") + if result > now + result = Time.parse("#{d1} #{d2} #{now.year-1} #{d3}") + end + else + result = Time.parse("#{d1} #{d2} #{d3}") + end + result +# elements = ParseDate.parsedate("#{d1} #{d2} #{d3}") +# if elements[0].nil? +# today = self.class.date.today +# if elements[1] > today.month +# elements[0] = today.year - 1 +# else +# elements[0] = today.year +# end +# end +# elements = elements.collect { |el| el.nil? ? 0 : el } +# Time.mktime(*elements[0,7]) + end + end + + #################################################################### + # Manage the uploading of files to an FTP account. + class FtpUploader + + # Log uploads to standard output when true. + attr_accessor :verbose + + class << FtpUploader + # Create an uploader and pass it to the given block as +up+. + # When the block is complete, close the uploader. + def connect(path, host, account, password) + up = self.new(path, host, account, password) + begin + yield(up) + ensure + up.close + end + end + end + + # Create an FTP uploader targetting the directory +path+ on +host+ + # using the given account and password. +path+ will be the root + # path of the uploader. + def initialize(path, host, account, password) + @created = Hash.new + @path = path + @ftp = Net::FTP.new(host, account, password) + makedirs(@path) + @ftp.chdir(@path) + end + + # Create the directory +path+ in the uploader root path. + def makedirs(path) + route = [] + File.split(path).each do |dir| + route << dir + current_dir = File.join(route) + if @created[current_dir].nil? + @created[current_dir] = true + puts "Creating Directory #{current_dir}" if @verbose + @ftp.mkdir(current_dir) rescue nil + end + end + end + + # Upload all files matching +wildcard+ to the uploader's root + # path. + def upload_files(wildcard) + Dir[wildcard].each do |fn| + upload(fn) + end + end + + # Close the uploader. + def close + @ftp.close + end + + private # -------------------------------------------------------- + + # Upload a single file to the uploader's root path. + def upload(file) + puts "Uploading #{file}" if @verbose + dir = File.dirname(file) + makedirs(dir) + @ftp.putbinaryfile(file, file) unless File.directory?(file) + end + end +end diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/publisher.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/publisher.rb new file mode 100644 index 0000000..6e80eb7 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/publisher.rb @@ -0,0 +1,75 @@ +#!/usr/bin/env ruby + +# Copyright 2003, 2004 by Jim Weirich (jim@weirichhouse.org) +# All rights reserved. + +# Permission is granted for use, copying, modification, distribution, +# and distribution of modified versions of this work as long as the +# above copyright notice is included. + +# Configuration information about an upload host system. +# * name :: Name of host system. +# * webdir :: Base directory for the web information for the +# application. The application name (APP) is appended to +# this directory before using. +# * pkgdir :: Directory on the host system where packages can be +# placed. +HostInfo = Struct.new(:name, :webdir, :pkgdir) + +# Manage several publishers as a single entity. +class CompositePublisher + def initialize + @publishers = [] + end + + # Add a publisher to the composite. + def add(pub) + @publishers << pub + end + + # Upload all the individual publishers. + def upload + @publishers.each { |p| p.upload } + end +end + +# Publish an entire directory to an existing remote directory using +# SSH. +class SshDirPublisher + def initialize(host, remote_dir, local_dir) + @host = host + @remote_dir = remote_dir + @local_dir = local_dir + end + + def upload + run %{scp -rq #{@local_dir}/* #{@host}:#{@remote_dir}} + end +end + +# Publish an entire directory to a fresh remote directory using SSH. +class SshFreshDirPublisher < SshDirPublisher + def upload + run %{ssh #{@host} rm -rf #{@remote_dir}} rescue nil + run %{ssh #{@host} mkdir #{@remote_dir}} + super + end +end + +# Publish a list of files to an existing remote directory. +class SshFilePublisher + # Create a publisher using the give host information. + def initialize(host, remote_dir, local_dir, *files) + @host = host + @remote_dir = remote_dir + @local_dir = local_dir + @files = files + end + + # Upload the local directory to the remote directory. + def upload + @files.each do |fn| + run %{scp -q #{@local_dir}/#{fn} #{@host}:#{@remote_dir}} + end + end +end diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/rubyforgepublisher.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/rubyforgepublisher.rb new file mode 100644 index 0000000..a91265f --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/rubyforgepublisher.rb @@ -0,0 +1,18 @@ +#!/usr/bin/env ruby + +require 'rake/contrib/sshpublisher' + +module Rake + + class RubyForgePublisher < SshDirPublisher + attr_reader :project, :proj_id, :user + + def initialize(projname, user) + super( + "#{user}@rubyforge.org", + "/var/www/gforge-projects/#{projname}", + "html") + end + end + +end diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/sshpublisher.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/sshpublisher.rb new file mode 100644 index 0000000..d77fcc3 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/sshpublisher.rb @@ -0,0 +1,47 @@ +#!/usr/bin/env ruby + +require 'rake/contrib/compositepublisher' + +module Rake + + # Publish an entire directory to an existing remote directory using + # SSH. + class SshDirPublisher + def initialize(host, remote_dir, local_dir) + @host = host + @remote_dir = remote_dir + @local_dir = local_dir + end + + def upload + sh %{scp -rq #{@local_dir}/* #{@host}:#{@remote_dir}} + end + end + + # Publish an entire directory to a fresh remote directory using SSH. + class SshFreshDirPublisher < SshDirPublisher + def upload + sh %{ssh #{@host} rm -rf #{@remote_dir}} rescue nil + sh %{ssh #{@host} mkdir #{@remote_dir}} + super + end + end + + # Publish a list of files to an existing remote directory. + class SshFilePublisher + # Create a publisher using the give host information. + def initialize(host, remote_dir, local_dir, *files) + @host = host + @remote_dir = remote_dir + @local_dir = local_dir + @files = files + end + + # Upload the local directory to the remote directory. + def upload + @files.each do |fn| + sh %{scp -q #{@local_dir}/#{fn} #{@host}:#{@remote_dir}} + end + end + end +end diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/sys.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/sys.rb new file mode 100644 index 0000000..06ac9e9 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/contrib/sys.rb @@ -0,0 +1,209 @@ +#!/usr/bin/env ruby + +#-- +# Copyright (c) 2003, 2004 Jim Weirich +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +#++ +# +begin + require 'ftools' +rescue LoadError +end +require 'rbconfig' + +###################################################################### +# Sys provides a number of file manipulation tools for the convenience +# of writing Rakefiles. All commands in this module will announce +# their activity on standard output if the $verbose flag is set +# ($verbose = true is the default). You can control this by globally +# setting $verbose or by using the +verbose+ and +quiet+ methods. +# +# Sys has been deprecated in favor of the FileUtils module available +# in Ruby 1.8. +# +module Sys + RUBY = Config::CONFIG['ruby_install_name'] + + # Install all the files matching +wildcard+ into the +dest_dir+ + # directory. The permission mode is set to +mode+. + def install(wildcard, dest_dir, mode) + Dir[wildcard].each do |fn| + File.install(fn, dest_dir, mode, $verbose) + end + end + + # Run the system command +cmd+. + def run(cmd) + log cmd + system(cmd) or fail "Command Failed: [#{cmd}]" + end + + # Run a Ruby interpreter with the given arguments. + def ruby(*args) + run "#{RUBY} #{args.join(' ')}" + end + + # Copy a single file from +file_name+ to +dest_file+. + def copy(file_name, dest_file) + log "Copying file #{file_name} to #{dest_file}" + File.copy(file_name, dest_file) + end + + # Copy all files matching +wildcard+ into the directory +dest_dir+. + def copy_files(wildcard, dest_dir) + for_matching_files(wildcard, dest_dir) { |from, to| copy(from, to) } + end + + # Link +file_name+ to +dest_file+. + def link(file_name, dest_file) + log "Linking file #{file_name} to #{dest_file}" + File.link(file_name, dest_file) + end + + # Link all files matching +wildcard+ into the directory +dest_dir+. + def link_files(wildcard, dest_dir) + for_matching_files(wildcard, dest_dir) { |from, to| link(from, to) } + end + + # Symlink +file_name+ to +dest_file+. + def symlink(file_name, dest_file) + log "Symlinking file #{file_name} to #{dest_file}" + File.symlink(file_name, dest_file) + end + + # Symlink all files matching +wildcard+ into the directory +dest_dir+. + def symlink_files(wildcard, dest_dir) + for_matching_files(wildcard, dest_dir) { |from, to| link(from, to) } + end + + # Remove all files matching +wildcard+. If a matching file is a + # directory, it must be empty to be removed. used +delete_all+ to + # recursively delete directories. + def delete(*wildcards) + wildcards.each do |wildcard| + Dir[wildcard].each do |fn| + if File.directory?(fn) + log "Deleting directory #{fn}" + Dir.delete(fn) + else + log "Deleting file #{fn}" + File.delete(fn) + end + end + end + end + + # Recursively delete all files and directories matching +wildcard+. + def delete_all(*wildcards) + wildcards.each do |wildcard| + Dir[wildcard].each do |fn| + next if ! File.exist?(fn) + if File.directory?(fn) + Dir["#{fn}/*"].each do |subfn| + next if subfn=='.' || subfn=='..' + delete_all(subfn) + end + log "Deleting directory #{fn}" + Dir.delete(fn) + else + log "Deleting file #{fn}" + File.delete(fn) + end + end + end + end + + # Make the directories given in +dirs+. + def makedirs(*dirs) + dirs.each do |fn| + log "Making directory #{fn}" + File.makedirs(fn) + end + end + + # Make +dir+ the current working directory for the duration of + # executing the given block. + def indir(dir) + olddir = Dir.pwd + Dir.chdir(dir) + yield + ensure + Dir.chdir(olddir) + end + + # Split a file path into individual directory names. + # + # For example: + # split_all("a/b/c") => ['a', 'b', 'c'] + def split_all(path) + head, tail = File.split(path) + return [tail] if head == '.' || tail == '/' + return [head, tail] if head == '/' + return split_all(head) + [tail] + end + + # Write a message to standard out if $verbose is enabled. + def log(msg) + print " " if $trace && $verbose + puts msg if $verbose + end + + # Perform a block with $verbose disabled. + def quiet(&block) + with_verbose(false, &block) + end + + # Perform a block with $verbose enabled. + def verbose(&block) + with_verbose(true, &block) + end + + # Perform a block with each file matching a set of wildcards. + def for_files(*wildcards) + wildcards.each do |wildcard| + Dir[wildcard].each do |fn| + yield(fn) + end + end + end + + extend(self) + + private # ---------------------------------------------------------- + + def for_matching_files(wildcard, dest_dir) + Dir[wildcard].each do |fn| + dest_file = File.join(dest_dir, fn) + parent = File.dirname(dest_file) + makedirs(parent) if ! File.directory?(parent) + yield(fn, dest_file) + end + end + + def with_verbose(v) + oldverbose = $verbose + $verbose = v + yield + ensure + $verbose = oldverbose + end + +end diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/gempackagetask.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/gempackagetask.rb new file mode 100644 index 0000000..a4e5cd1 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/gempackagetask.rb @@ -0,0 +1,103 @@ +#!/usr/bin/env ruby + +# Define a package task library to aid in the definition of GEM +# packages. + +require 'rubygems' +require 'rake' +require 'rake/packagetask' +require 'rubygems/user_interaction' +require 'rubygems/builder' + +begin + Gem.manage_gems +rescue NoMethodError => ex + # Using rubygems prior to 0.6.1 +end + +module Rake + + # Create a package based upon a Gem spec. Gem packages, as well as + # zip files and tar/gzipped packages can be produced by this task. + # + # In addition to the Rake targets generated by PackageTask, a + # GemPackageTask will also generate the following tasks: + # + # ["package_dir/name-version.gem"] + # Create a Ruby GEM package with the given name and version. + # + # Example using a Ruby GEM spec: + # + # require 'rubygems' + # + # spec = Gem::Specification.new do |s| + # s.platform = Gem::Platform::RUBY + # s.summary = "Ruby based make-like utility." + # s.name = 'rake' + # s.version = PKG_VERSION + # s.requirements << 'none' + # s.require_path = 'lib' + # s.autorequire = 'rake' + # s.files = PKG_FILES + # s.description = < [:gem] + desc "Build the gem file #{gem_file}" + task :gem => ["#{package_dir}/#{gem_file}"] + file "#{package_dir}/#{gem_file}" => [package_dir] + @gem_spec.files do + when_writing("Creating GEM") { + Gem::Builder.new(gem_spec).build + verbose(true) { + mv gem_file, "#{package_dir}/#{gem_file}" + } + } + end + end + + def gem_file + if @gem_spec.platform == Gem::Platform::RUBY + "#{package_name}.gem" + else + "#{package_name}-#{@gem_spec.platform}.gem" + end + end + + end +end diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/loaders/makefile.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/loaders/makefile.rb new file mode 100644 index 0000000..9ade098 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/loaders/makefile.rb @@ -0,0 +1,35 @@ +#!/usr/bin/env ruby + +module Rake + + # Makefile loader to be used with the import file loader. + class MakefileLoader + + # Load the makefile dependencies in +fn+. + def load(fn) + open(fn) do |mf| + lines = mf.read + lines.gsub!(/#[^\n]*\n/m, "") + lines.gsub!(/\\\n/, ' ') + lines.split("\n").each do |line| + process_line(line) + end + end + end + + private + + # Process one logical line of makefile data. + def process_line(line) + file_tasks, args = line.split(':') + return if args.nil? + dependents = args.split + file_tasks.strip.split.each do |file_task| + file file_task => dependents + end + end + end + + # Install the handler + Rake.application.add_loader('mf', MakefileLoader.new) +end diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/packagetask.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/packagetask.rb new file mode 100644 index 0000000..4b0775d --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/packagetask.rb @@ -0,0 +1,185 @@ +#!/usr/bin/env ruby + +# Define a package task libarary to aid in the definition of +# redistributable package files. + +require 'rake' +require 'rake/tasklib' + +module Rake + + # Create a packaging task that will package the project into + # distributable files (e.g zip archive or tar files). + # + # The PackageTask will create the following targets: + # + # [:package] + # Create all the requested package files. + # + # [:clobber_package] + # Delete all the package files. This target is automatically + # added to the main clobber target. + # + # [:repackage] + # Rebuild the package files from scratch, even if they are not out + # of date. + # + # ["package_dir/name-version.tgz"] + # Create a gzipped tar package (if need_tar is true). + # + # ["package_dir/name-version.tar.gz"] + # Create a gzipped tar package (if need_tar_gz is true). + # + # ["package_dir/name-version.tar.bz2"] + # Create a bzip2'd tar package (if need_tar_bz2 is true). + # + # ["package_dir/name-version.zip"] + # Create a zip package archive (if need_zip is true). + # + # Example: + # + # Rake::PackageTask.new("rake", "1.2.3") do |p| + # p.need_tar = true + # p.package_files.include("lib/**/*.rb") + # end + # + class PackageTask < TaskLib + # Name of the package (from the GEM Spec). + attr_accessor :name + + # Version of the package (e.g. '1.3.2'). + attr_accessor :version + + # Directory used to store the package files (default is 'pkg'). + attr_accessor :package_dir + + # True if a gzipped tar file (tgz) should be produced (default is false). + attr_accessor :need_tar + + # True if a gzipped tar file (tar.gz) should be produced (default is false). + attr_accessor :need_tar_gz + + # True if a bzip2'd tar file (tar.bz2) should be produced (default is false). + attr_accessor :need_tar_bz2 + + # True if a zip file should be produced (default is false) + attr_accessor :need_zip + + # List of files to be included in the package. + attr_accessor :package_files + + # Tar command for gzipped or bzip2ed archives. The default is 'tar'. + attr_accessor :tar_command + + # Zip command for zipped archives. The default is 'zip'. + attr_accessor :zip_command + + # Create a Package Task with the given name and version. + def initialize(name=nil, version=nil) + init(name, version) + yield self if block_given? + define unless name.nil? + end + + # Initialization that bypasses the "yield self" and "define" step. + def init(name, version) + @name = name + @version = version + @package_files = Rake::FileList.new + @package_dir = 'pkg' + @need_tar = false + @need_tar_gz = false + @need_tar_bz2 = false + @need_zip = false + @tar_command = 'tar' + @zip_command = 'zip' + end + + # Create the tasks defined by this task library. + def define + fail "Version required (or :noversion)" if @version.nil? + @version = nil if :noversion == @version + + desc "Build all the packages" + task :package + + desc "Force a rebuild of the package files" + task :repackage => [:clobber_package, :package] + + desc "Remove package products" + task :clobber_package do + rm_r package_dir rescue nil + end + + task :clobber => [:clobber_package] + + [ + [need_tar, tgz_file, "z"], + [need_tar_gz, tar_gz_file, "z"], + [need_tar_bz2, tar_bz2_file, "j"] + ].each do |(need, file, flag)| + if need + task :package => ["#{package_dir}/#{file}"] + file "#{package_dir}/#{file}" => [package_dir_path] + package_files do + chdir(package_dir) do + sh %{env} + sh %{#{@tar_command} #{flag}cvf #{file} #{package_name}} + end + end + end + end + + if need_zip + task :package => ["#{package_dir}/#{zip_file}"] + file "#{package_dir}/#{zip_file}" => [package_dir_path] + package_files do + chdir(package_dir) do + sh %{#{@zip_command} -r #{zip_file} #{package_name}} + end + end + end + + directory package_dir + + file package_dir_path => @package_files do + mkdir_p package_dir rescue nil + @package_files.each do |fn| + f = File.join(package_dir_path, fn) + fdir = File.dirname(f) + mkdir_p(fdir) if !File.exist?(fdir) + if File.directory?(fn) + mkdir_p(f) + else + rm_f f + safe_ln(fn, f) + end + end + end + self + end + + def package_name + @version ? "#{@name}-#{@version}" : @name + end + + def package_dir_path + "#{package_dir}/#{package_name}" + end + + def tgz_file + "#{package_name}.tgz" + end + + def tar_gz_file + "#{package_name}.tar.gz" + end + + def tar_bz2_file + "#{package_name}.tar.bz2" + end + + def zip_file + "#{package_name}.zip" + end + end + +end diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/rake_test_loader.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/rake_test_loader.rb new file mode 100644 index 0000000..8d7dad3 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/rake_test_loader.rb @@ -0,0 +1,5 @@ +#!/usr/bin/env ruby + +# Load the test files from the command line. + +ARGV.each { |f| load f unless f =~ /^-/ } diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/rdoctask.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/rdoctask.rb new file mode 100644 index 0000000..6cfbda1 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/rdoctask.rb @@ -0,0 +1,147 @@ +#!/usr/bin/env ruby + +require 'rake' +require 'rake/tasklib' + +module Rake + + # Create a documentation task that will generate the RDoc files for + # a project. + # + # The RDocTask will create the following targets: + # + # [rdoc] + # Main task for this RDOC task. + # + # [:clobber_rdoc] + # Delete all the rdoc files. This target is automatically + # added to the main clobber target. + # + # [:rerdoc] + # Rebuild the rdoc files from scratch, even if they are not out + # of date. + # + # Simple Example: + # + # Rake::RDocTask.new do |rd| + # rd.main = "README.rdoc" + # rd.rdoc_files.include("README.rdoc", "lib/**/*.rb") + # end + # + # You may wish to give the task a different name, such as if you are + # generating two sets of documentation. For instance, if you want to have a + # development set of documentation including private methods: + # + # Rake::RDocTask.new(:rdoc_dev) do |rd| + # rd.main = "README.doc" + # rd.rdoc_files.include("README.rdoc", "lib/**/*.rb") + # rd.options << "--all" + # end + # + # The tasks would then be named :rdoc_dev, :clobber_rdoc_dev, and + # :rerdoc_dev. + # + class RDocTask < TaskLib + # Name of the main, top level task. (default is :rdoc) + attr_accessor :name + + # Name of directory to receive the html output files. (default is "html") + attr_accessor :rdoc_dir + + # Title of RDoc documentation. (default is none) + attr_accessor :title + + # Name of file to be used as the main, top level file of the + # RDoc. (default is none) + attr_accessor :main + + # Name of template to be used by rdoc. (defaults to rdoc's default) + attr_accessor :template + + # List of files to be included in the rdoc generation. (default is []) + attr_accessor :rdoc_files + + # List of options to be passed rdoc. (default is []) + attr_accessor :options + + # Run the rdoc process as an external shell (default is false) + attr_accessor :external + + # Create an RDoc task named rdoc. Default task name is +rdoc+. + def initialize(name=:rdoc) # :yield: self + @name = name + @rdoc_files = Rake::FileList.new + @rdoc_dir = 'html' + @main = nil + @title = nil + @template = nil + @external = false + @options = [] + yield self if block_given? + define + end + + # Create the tasks defined by this task lib. + def define + if name.to_s != "rdoc" + desc "Build the RDOC HTML Files" + end + + desc "Build the #{name} HTML Files" + task name + + desc "Force a rebuild of the RDOC files" + task "re#{name}" => ["clobber_#{name}", name] + + desc "Remove rdoc products" + task "clobber_#{name}" do + rm_r rdoc_dir rescue nil + end + + task :clobber => ["clobber_#{name}"] + + directory @rdoc_dir + task name => [rdoc_target] + file rdoc_target => @rdoc_files + [Rake.application.rakefile] do + rm_r @rdoc_dir rescue nil + args = option_list + @rdoc_files + if @external + argstring = args.join(' ') + sh %{ruby -Ivendor vender/rd #{argstring}} + else + require 'rdoc/rdoc' + RDoc::RDoc.new.document(args) + end + end + self + end + + def option_list + result = @options.dup + result << "-o" << @rdoc_dir + result << "--main" << quote(main) if main + result << "--title" << quote(title) if title + result << "-T" << quote(template) if template + result + end + + def quote(str) + if @external + "'#{str}'" + else + str + end + end + + def option_string + option_list.join(' ') + end + + private + + def rdoc_target + "#{rdoc_dir}/index.html" + end + + end +end diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/ruby182_test_unit_fix.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/ruby182_test_unit_fix.rb new file mode 100755 index 0000000..f02c787 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/ruby182_test_unit_fix.rb @@ -0,0 +1,23 @@ +module Test + module Unit + module Collector + class Dir + undef collect_file + def collect_file(name, suites, already_gathered) + # loadpath = $:.dup + dir = File.dirname(File.expand_path(name)) + $:.unshift(dir) unless $:.first == dir + if(@req) + @req.require(name) + else + require(name) + end + find_test_cases(already_gathered).each{|t| add_suite(suites, t.suite)} + ensure + # $:.replace(loadpath) + $:.delete_at $:.rindex(dir) + end + end + end + end +end diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/runtest.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/runtest.rb new file mode 100644 index 0000000..3f1d205 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/runtest.rb @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'test/unit/assertions' + +module Rake + include Test::Unit::Assertions + + def run_tests(pattern='test/test*.rb', log_enabled=false) + Dir["#{pattern}"].each { |fn| + puts fn if log_enabled + begin + load fn + rescue Exception => ex + puts "Error in #{fn}: #{ex.message}" + puts ex.backtrace + assert false + end + } + end + + extend self +end diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/tasklib.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/tasklib.rb new file mode 100644 index 0000000..c7fd981 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/tasklib.rb @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby + +require 'rake' + +module Rake + + # Base class for Task Libraries. + class TaskLib + include Cloneable + + # Make a symbol by pasting two strings together. + # + # NOTE: DEPRECATED! This method is kinda stupid. I don't know why + # I didn't just use string interpolation. But now other task + # libraries depend on this so I can't remove it without breaking + # other people's code. So for now it stays for backwards + # compatibility. BUT DON'T USE IT. + def paste(a,b) # :nodoc: + (a.to_s + b.to_s).intern + end + end + +end diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/testtask.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/testtask.rb new file mode 100644 index 0000000..79154e4 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/testtask.rb @@ -0,0 +1,161 @@ +#!/usr/bin/env ruby + +# Define a task library for running unit tests. + +require 'rake' +require 'rake/tasklib' + +module Rake + + # Create a task that runs a set of tests. + # + # Example: + # + # Rake::TestTask.new do |t| + # t.libs << "test" + # t.test_files = FileList['test/test*.rb'] + # t.verbose = true + # end + # + # If rake is invoked with a "TEST=filename" command line option, + # then the list of test files will be overridden to include only the + # filename specified on the command line. This provides an easy way + # to run just one test. + # + # If rake is invoked with a "TESTOPTS=options" command line option, + # then the given options are passed to the test process after a + # '--'. This allows Test::Unit options to be passed to the test + # suite. + # + # Examples: + # + # rake test # run tests normally + # rake test TEST=just_one_file.rb # run just one test file. + # rake test TESTOPTS="-v" # run in verbose mode + # rake test TESTOPTS="--runner=fox" # use the fox test runner + # + class TestTask < TaskLib + + # Name of test task. (default is :test) + attr_accessor :name + + # List of directories to added to $LOAD_PATH before running the + # tests. (default is 'lib') + attr_accessor :libs + + # True if verbose test output desired. (default is false) + attr_accessor :verbose + + # Test options passed to the test suite. An explicit + # TESTOPTS=opts on the command line will override this. (default + # is NONE) + attr_accessor :options + + # Request that the tests be run with the warning flag set. + # E.g. warning=true implies "ruby -w" used to run the tests. + attr_accessor :warning + + # Glob pattern to match test files. (default is 'test/test*.rb') + attr_accessor :pattern + + # Style of test loader to use. Options are: + # + # * :rake -- Rake provided test loading script (default). + # * :testrb -- Ruby provided test loading script. + # * :direct -- Load tests using command line loader. + # + attr_accessor :loader + + # Array of commandline options to pass to ruby when running test loader. + attr_accessor :ruby_opts + + # Explicitly define the list of test files to be included in a + # test. +list+ is expected to be an array of file names (a + # FileList is acceptable). If both +pattern+ and +test_files+ are + # used, then the list of test files is the union of the two. + def test_files=(list) + @test_files = list + end + + # Create a testing task. + def initialize(name=:test) + @name = name + @libs = ["lib"] + @pattern = nil + @options = nil + @test_files = nil + @verbose = false + @warning = false + @loader = :rake + @ruby_opts = [] + yield self if block_given? + @pattern = 'test/test*.rb' if @pattern.nil? && @test_files.nil? + define + end + + # Create the tasks defined by this task lib. + def define + lib_path = @libs.join(File::PATH_SEPARATOR) + desc "Run tests" + (@name==:test ? "" : " for #{@name}") + task @name do + run_code = '' + RakeFileUtils.verbose(@verbose) do + run_code = + case @loader + when :direct + "-e 'ARGV.each{|f| load f}'" + when :testrb + "-S testrb #{fix}" + when :rake + rake_loader + end + @ruby_opts.unshift( "-I#{lib_path}" ) + @ruby_opts.unshift( "-w" ) if @warning + ruby @ruby_opts.join(" ") + + " \"#{run_code}\" " + + file_list.collect { |fn| "\"#{fn}\"" }.join(' ') + + " #{option_list}" + end + end + self + end + + def option_list # :nodoc: + ENV['TESTOPTS'] || @options || "" + end + + def file_list # :nodoc: + if ENV['TEST'] + FileList[ ENV['TEST'] ] + else + result = [] + result += @test_files.to_a if @test_files + result += FileList[ @pattern ].to_a if @pattern + FileList[result] + end + end + + def fix # :nodoc: + case RUBY_VERSION + when '1.8.2' + find_file 'rake/ruby182_test_unit_fix' + else + nil + end || '' + end + + def rake_loader # :nodoc: + find_file('rake/rake_test_loader') or + fail "unable to find rake test loader" + end + + def find_file(fn) # :nodoc: + $LOAD_PATH.each do |path| + file_path = File.join(path, "#{fn}.rb") + return file_path if File.exist? file_path + end + nil + end + + end +end diff --git a/vendor/gems/gems/rake-0.8.3/lib/rake/win32.rb b/vendor/gems/gems/rake-0.8.3/lib/rake/win32.rb new file mode 100644 index 0000000..eadc585 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/lib/rake/win32.rb @@ -0,0 +1,54 @@ +module Rake + + # Win 32 interface methods for Rake. Windows specific functionality + # will be placed here to collect that knowledge in one spot. + module Win32 + + # Error indicating a problem in locating the home directory on a + # Win32 system. + class Win32HomeError < RuntimeError + end + + class << self + # True if running on a windows system. + def windows? + Config::CONFIG['host_os'] =~ /mswin/ + end + + # Run a command line on windows. + def rake_system(*cmd) + if cmd.size == 1 + system("call #{cmd}") + else + system(*cmd) + end + end + + # The standard directory containing system wide rake files on + # Win 32 systems. Try the following environment variables (in + # order): + # + # * APPDATA + # * HOMEDRIVE + HOMEPATH + # * USERPROFILE + # + # If the above are not defined, the return nil. + def win32_system_dir #:nodoc: + win32_shared_path = ENV['APPDATA'] + if win32_shared_path.nil? && ENV['HOMEDRIVE'] && ENV['HOMEPATH'] + win32_shared_path = ENV['HOMEDRIVE'] + ENV['HOMEPATH'] + end + win32_shared_path ||= ENV['USERPROFILE'] + raise Win32HomeError, "Unable to determine home path environment variable." if + win32_shared_path.nil? or win32_shared_path.empty? + normalize(File.join(win32_shared_path, 'Rake')) + end + + # Normalize a win32 path so that the slashes are all forward slashes. + def normalize(path) + path.gsub(/\\/, '/') + end + + end + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/capture_stdout.rb b/vendor/gems/gems/rake-0.8.3/test/capture_stdout.rb new file mode 100644 index 0000000..8b664ad --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/capture_stdout.rb @@ -0,0 +1,26 @@ +#!/usr/bin/env ruby + +require 'stringio' + +# Mix-in for capturing standard output. +module CaptureStdout + def capture_stdout + s = StringIO.new + oldstdout = $stdout + $stdout = s + yield + s.string + ensure + $stdout = oldstdout + end + + def capture_stderr + s = StringIO.new + oldstderr = $stderr + $stderr = s + yield + s.string + ensure + $stderr = oldstderr + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/check_expansion.rb b/vendor/gems/gems/rake-0.8.3/test/check_expansion.rb new file mode 100644 index 0000000..659cf71 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/check_expansion.rb @@ -0,0 +1,5 @@ +if ARGV[0] != ARGV[1] + exit 1 +else + exit 0 +end diff --git a/vendor/gems/gems/rake-0.8.3/test/contrib/test_sys.rb b/vendor/gems/gems/rake-0.8.3/test/contrib/test_sys.rb new file mode 100644 index 0000000..37a5dc9 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/contrib/test_sys.rb @@ -0,0 +1,47 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'test/filecreation' +require 'rake/contrib/sys' + +class TestSys < Test::Unit::TestCase + include FileCreation + +# def test_delete +# create_file("testdata/a") +# Sys.delete_all("testdata/a") +# assert ! File.exist?("testdata/a") +# end + +# def test_copy +# create_file("testdata/a") +# Sys.copy("testdata/a", "testdata/b") +# assert File.exist?("testdata/b") +# end + +# def test_for_files +# test_files = ["testdata/a.pl", "testdata/c.pl", "testdata/b.rb"] +# test_files.each { |fn| create_file(fn) } +# list = [] +# Sys.for_files("testdata/*.pl", "testdata/*.rb") { |fn| +# list << fn +# } +# assert_equal test_files.sort, list.sort +# end + +# def test_indir +# here = Dir.pwd +# Sys.makedirs("testdata/dir") +# assert_equal "#{here}/testdata/dir", Sys.indir("testdata/dir") { Dir.pwd } +# assert_equal here, Dir.pwd +# end + + def test_split_all + assert_equal ['a'], Sys.split_all('a') + assert_equal ['..'], Sys.split_all('..') + assert_equal ['/'], Sys.split_all('/') + assert_equal ['a', 'b'], Sys.split_all('a/b') + assert_equal ['/', 'a', 'b'], Sys.split_all('/a/b') + assert_equal ['..', 'a', 'b'], Sys.split_all('../a/b') + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/data/chains/Rakefile b/vendor/gems/gems/rake-0.8.3/test/data/chains/Rakefile new file mode 100644 index 0000000..31bdc25 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/data/chains/Rakefile @@ -0,0 +1,15 @@ +# -*- ruby -*- + +task :default => "play.app" + +file "play.scpt" => "base" do |t| + cp t.prerequisites.first, t.name +end + +rule ".app" => ".scpt" do |t| + cp t.source, t.name +end + +file 'base' do + touch 'base' +end diff --git a/vendor/gems/gems/rake-0.8.3/test/data/default/Rakefile b/vendor/gems/gems/rake-0.8.3/test/data/default/Rakefile new file mode 100644 index 0000000..22ed5e0 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/data/default/Rakefile @@ -0,0 +1,19 @@ +#!/usr/bin/env ruby + +if ENV['TESTTOPSCOPE'] + puts "TOPSCOPE" +end + +task :default do + puts "DEFAULT" +end + +task :other => [:default] do + puts "OTHER" +end + +task :task_scope do + if ENV['TESTTASKSCOPE'] + puts "TASKSCOPE" + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/data/dryrun/Rakefile b/vendor/gems/gems/rake-0.8.3/test/data/dryrun/Rakefile new file mode 100644 index 0000000..0a68a0d --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/data/dryrun/Rakefile @@ -0,0 +1,22 @@ +# + +task :default => ["temp_main"] + +file "temp_main" => [:all_apps] do touch "temp_main" end + +task :all_apps => [:one, :two] +task :one => ["temp_one"] +task :two => ["temp_two"] + +file "temp_one" do |t| + touch "temp_one" +end +file "temp_two" do |t| + touch "temp_two" +end + +task :clean do + ["temp_one", "temp_two", "temp_main"].each do |file| + rm_f file + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/data/file_creation_task/Rakefile b/vendor/gems/gems/rake-0.8.3/test/data/file_creation_task/Rakefile new file mode 100644 index 0000000..94641b6 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/data/file_creation_task/Rakefile @@ -0,0 +1,33 @@ +#!/usr/bin/env ruby + +N = 2 + +task :default => :run + +BUILD_DIR = 'build' +task :clean do + rm_rf 'build' + rm_rf 'src' +end + +task :run + +TARGET_DIR = 'build/copies' + +FileList['src/*'].each do |src| + directory TARGET_DIR + target = File.join TARGET_DIR, File.basename(src) + file target => [src, TARGET_DIR] do + cp src, target + # sleep 3 if src !~ /foo#{N-1}$/ # I'm commenting out this sleep, it doesn't seem to do anything. + end + task :run => target +end + +task :prep => :clean do + mkdir_p 'src' + N.times do |n| + puts "DBG: Touching src/foo#{n}" + touch "src/foo#{n}" + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/data/imports/Rakefile b/vendor/gems/gems/rake-0.8.3/test/data/imports/Rakefile new file mode 100644 index 0000000..6a60f61 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/data/imports/Rakefile @@ -0,0 +1,19 @@ +# -*- ruby -*- + +require 'rake/loaders/makefile' + +task :default + +task :other do + puts "OTHER" +end + +file "dynamic_deps" do |t| + open(t.name, "w") do |f| f.puts "puts 'DYNAMIC'" end +end + +import "dynamic_deps" +import "static_deps" +import "static_deps" +import "deps.mf" +puts "FIRST" diff --git a/vendor/gems/gems/rake-0.8.3/test/data/imports/deps.mf b/vendor/gems/gems/rake-0.8.3/test/data/imports/deps.mf new file mode 100644 index 0000000..04643d0 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/data/imports/deps.mf @@ -0,0 +1 @@ +default: other diff --git a/vendor/gems/gems/rake-0.8.3/test/data/multidesc/Rakefile b/vendor/gems/gems/rake-0.8.3/test/data/multidesc/Rakefile new file mode 100644 index 0000000..5342481 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/data/multidesc/Rakefile @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +task :b + +desc "A" +task :a + +desc "B" +task :b + +desc "A2" +task :a + +task :c + +desc "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +task :d diff --git a/vendor/gems/gems/rake-0.8.3/test/data/namespace/Rakefile b/vendor/gems/gems/rake-0.8.3/test/data/namespace/Rakefile new file mode 100644 index 0000000..6de98ed --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/data/namespace/Rakefile @@ -0,0 +1,57 @@ +#!/usr/bin/env ruby + +desc "copy" +task :copy do + puts "COPY" +end + +namespace "nest" do + desc "nest copy" + task :copy do + puts "NEST COPY" + end + task :xx => :copy +end + +anon_ns = namespace do + desc "anonymous copy task" + task :copy do + puts "ANON COPY" + end +end + +desc "Top level task to run the anonymous version of copy" +task :anon => anon_ns[:copy] + +namespace "very" do + namespace "nested" do + task "run" => "rake:copy" + end +end + +namespace "a" do + desc "Run task in the 'a' namespace" + task "run" do + puts "IN A" + end +end + +namespace "b" do + desc "Run task in the 'b' namespace" + task "run" => "a:run" do + puts "IN B" + end +end + +namespace "file1" do + file "xyz.rb" do + puts "XYZ1" + end +end + +namespace "file2" do + file "xyz.rb" do + puts "XYZ2" + end +end + diff --git a/vendor/gems/gems/rake-0.8.3/test/data/rakelib/test1.rb b/vendor/gems/gems/rake-0.8.3/test/data/rakelib/test1.rb new file mode 100644 index 0000000..bb1c419 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/data/rakelib/test1.rb @@ -0,0 +1,3 @@ +task :default do + puts "TEST1" +end diff --git a/vendor/gems/gems/rake-0.8.3/test/data/rbext/rakefile.rb b/vendor/gems/gems/rake-0.8.3/test/data/rbext/rakefile.rb new file mode 100644 index 0000000..670604d --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/data/rbext/rakefile.rb @@ -0,0 +1,3 @@ +task :default do + puts "OK" +end diff --git a/vendor/gems/gems/rake-0.8.3/test/data/sample.mf b/vendor/gems/gems/rake-0.8.3/test/data/sample.mf new file mode 100644 index 0000000..0ce672c --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/data/sample.mf @@ -0,0 +1,12 @@ +# Comments +a: a1 a2 a3 a4 +b: b1 b2 b3 \ + b4 b5 b6\ +# Mid: Comment +b7 + + a : a5 a6 a7 +c: c1 +d: d1 d2 \ + +e f : e1 f1 diff --git a/vendor/gems/gems/rake-0.8.3/test/data/statusreturn/Rakefile b/vendor/gems/gems/rake-0.8.3/test/data/statusreturn/Rakefile new file mode 100644 index 0000000..6802305 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/data/statusreturn/Rakefile @@ -0,0 +1,8 @@ +#!/usr/bin/env ruby + +task :exit5 do + exit(5) +end + +task :normal do +end diff --git a/vendor/gems/gems/rake-0.8.3/test/data/unittest/Rakefile b/vendor/gems/gems/rake-0.8.3/test/data/unittest/Rakefile new file mode 100644 index 0000000..9c3b8ac --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/data/unittest/Rakefile @@ -0,0 +1 @@ +# Empty Rakefile for Unit Test diff --git a/vendor/gems/gems/rake-0.8.3/test/filecreation.rb b/vendor/gems/gems/rake-0.8.3/test/filecreation.rb new file mode 100644 index 0000000..7a8bc87 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/filecreation.rb @@ -0,0 +1,32 @@ +#!/usr/bin/env ruby + +module FileCreation + OLDFILE = "testdata/old" + NEWFILE = "testdata/new" + + def create_timed_files(oldfile, *newfiles) + return if File.exist?(oldfile) && newfiles.all? { |newfile| File.exist?(newfile) } + old_time = create_file(oldfile) + newfiles.each do |newfile| + while create_file(newfile) <= old_time + sleep(0.1) + File.delete(newfile) rescue nil + end + end + end + + def create_dir(dirname) + FileUtils.mkdir_p(dirname) unless File.exist?(dirname) + File.stat(dirname).mtime + end + + def create_file(name) + create_dir(File.dirname(name)) + FileUtils.touch(name) unless File.exist?(name) + File.stat(name).mtime + end + + def delete_file(name) + File.delete(name) rescue nil + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/functional.rb b/vendor/gems/gems/rake-0.8.3/test/functional.rb new file mode 100644 index 0000000..6a5c602 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/functional.rb @@ -0,0 +1,15 @@ +#!/usr/bin/env ruby + +begin + require 'rubygems' + gem 'session' + require 'session' +rescue LoadError + puts "UNABLE TO RUN FUNCTIONAL TESTS" + puts "No Session Found (gem install session)" +end + +if defined?(Session) + puts "RUNNING WITH SESSIONS" + require 'test/session_functional' +end diff --git a/vendor/gems/gems/rake-0.8.3/test/in_environment.rb b/vendor/gems/gems/rake-0.8.3/test/in_environment.rb new file mode 100644 index 0000000..fb02eba --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/in_environment.rb @@ -0,0 +1,30 @@ +module InEnvironment + private + + # Create an environment for a test. At the completion of the yielded + # block, the environment is restored to its original conditions. + def in_environment(settings) + original_settings = set_env(settings) + yield + ensure + set_env(original_settings) + end + + # Set the environment according to the settings hash. + def set_env(settings) # :nodoc: + result = {} + settings.each do |k, v| + result[k] = ENV[k] + if k == 'PWD' + result[k] = Dir.pwd + Dir.chdir(v) + elsif v.nil? + ENV.delete(k) + else + ENV[k] = v + end + end + result + end + +end diff --git a/vendor/gems/gems/rake-0.8.3/test/rake_test_setup.rb b/vendor/gems/gems/rake-0.8.3/test/rake_test_setup.rb new file mode 100644 index 0000000..74b28e1 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/rake_test_setup.rb @@ -0,0 +1,10 @@ +# Common setup for all test files. + +begin + require 'rubygems' + gem 'flexmock' +rescue LoadError + # got no gems +end + +require 'flexmock/test_unit' diff --git a/vendor/gems/gems/rake-0.8.3/test/reqfile.rb b/vendor/gems/gems/rake-0.8.3/test/reqfile.rb new file mode 100644 index 0000000..5372544 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/reqfile.rb @@ -0,0 +1,3 @@ +# For --require testing + +TESTING_REQUIRE << 1 diff --git a/vendor/gems/gems/rake-0.8.3/test/reqfile2.rb b/vendor/gems/gems/rake-0.8.3/test/reqfile2.rb new file mode 100644 index 0000000..6599390 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/reqfile2.rb @@ -0,0 +1,3 @@ +# For --require testing + +TESTING_REQUIRE << 2 diff --git a/vendor/gems/gems/rake-0.8.3/test/session_functional.rb b/vendor/gems/gems/rake-0.8.3/test/session_functional.rb new file mode 100644 index 0000000..bf4635a --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/session_functional.rb @@ -0,0 +1,337 @@ +#!/usr/bin/env ruby + +begin + require 'rubygems' +rescue LoadError => ex +end +require 'test/unit' +require 'fileutils' +require 'session' +require 'test/in_environment' + +# Version 2.1.9 of session has a bug where the @debug instance +# variable is not initialized, causing warning messages. This snippet +# of code fixes that problem. +module Session + class AbstractSession + alias old_initialize initialize + def initialize(*args) + @debug = nil + old_initialize(*args) + end + end +end + +class FunctionalTest < Test::Unit::TestCase + include InEnvironment + + RUBY_COMMAND = 'ruby' + + def setup + @rake_path = File.expand_path("bin/rake") + lib_path = File.expand_path("lib") + @ruby_options = "-I#{lib_path} -I." + @verbose = ! ENV['VERBOSE'].nil? + if @verbose + puts + puts + puts "--------------------------------------------------------------------" + puts name + puts "--------------------------------------------------------------------" + end + end + + def test_rake_default + Dir.chdir("test/data/default") do rake end + assert_match(/^DEFAULT$/, @out) + assert_status + end + + def test_rake_error_on_bad_task + Dir.chdir("test/data/default") do rake "xyz" end + assert_match(/rake aborted/, @err) + assert_status(1) + end + + def test_env_availabe_at_top_scope + Dir.chdir("test/data/default") do rake "TESTTOPSCOPE=1" end + assert_match(/^TOPSCOPE$/, @out) + assert_status + end + + def test_env_availabe_at_task_scope + Dir.chdir("test/data/default") do rake "TESTTASKSCOPE=1 task_scope" end + assert_match(/^TASKSCOPE$/, @out) + assert_status + end + + def test_multi_desc + in_environment( + 'RAKE_COLUMNS' => "80", + "PWD" => "test/data/multidesc" + ) do + rake "-T" + end + assert_match %r{^rake a *# A / A2 *$}, @out + assert_match %r{^rake b *# B *$}, @out + assert_no_match %r{^rake c}, @out + assert_match %r{^rake d *# x{65}\.\.\.$}, @out + end + + def test_long_description + in_environment("PWD" => "test/data/multidesc") do + rake "--describe" + end + assert_match %r{^rake a\n *A / A2 *$}m, @out + assert_match %r{^rake b\n *B *$}m, @out + assert_match %r{^rake d\n *x{80}}m, @out + assert_no_match %r{^rake c\n}m, @out + end + + def test_rbext + in_environment("PWD" => "test/data/rbext") do + rake "-N" + end + assert_match %r{^OK$}, @out + end + + def test_system + in_environment('RAKE_SYSTEM' => 'test/data/sys') do + rake '-g', "sys1" + end + assert_match %r{^SYS1}, @out + end + + def test_system_excludes_rakelib_files_too + in_environment('RAKE_SYSTEM' => 'test/data/sys') do + rake '-g', "sys1", '-T', 'extra' + end + assert_no_match %r{extra:extra}, @out + end + + def test_by_default_rakelib_files_are_include + in_environment('RAKE_SYSTEM' => 'test/data/sys') do + rake '-T', 'extra' + end + assert_match %r{extra:extra}, @out + end + + def test_implicit_system + in_environment('RAKE_SYSTEM' => File.expand_path('test/data/sys'), "PWD" => "/") do + rake "sys1", "--trace" + end + assert_match %r{^SYS1}, @out + end + + def test_no_system + in_environment('RAKE_SYSTEM' => 'test/data/sys') do + rake '-G', "sys1" + end + assert_match %r{^Don't know how to build task}, @err # emacs wart: ' + end + + def test_nosearch_with_rakefile_uses_local_rakefile + in_environment("PWD" => "test/data/default") do + rake "--nosearch" + end + assert_match %r{^DEFAULT}, @out + end + + def test_nosearch_without_rakefile_finds_system + in_environment( + "PWD" => "test/data/nosearch", + "RAKE_SYSTEM" => File.expand_path("test/data/sys") + ) do + rake "--nosearch", "sys1" + end + assert_match %r{^SYS1}, @out + end + + def test_nosearch_without_rakefile_and_no_system_fails + in_environment("PWD" => "test/data/nosearch", "RAKE_SYSTEM" => "not_exist") do + rake "--nosearch" + end + assert_match %r{^No Rakefile found}, @err + end + + def test_dry_run + in_environment("PWD" => "test/data/default") do rake "-n", "other" end + assert_match %r{Execute \(dry run\) default}, @out + assert_match %r{Execute \(dry run\) other}, @out + assert_no_match %r{DEFAULT}, @out + assert_no_match %r{OTHER}, @out + end + + # Test for the trace/dry_run bug found by Brian Chandler + def test_dry_run_bug + in_environment("PWD" => "test/data/dryrun") do + rake + end + FileUtils.rm_f "test/data/dryrun/temp_one" + in_environment("PWD" => "test/data/dryrun") do + rake "--dry-run" + end + assert_no_match(/No such file/, @out) + assert_status + end + + # Test for the trace/dry_run bug found by Brian Chandler + def test_trace_bug + in_environment("PWD" => "test/data/dryrun") do + rake + end + FileUtils.rm_f "test/data/dryrun/temp_one" + in_environment("PWD" => "test/data/dryrun") do + rake "--trace" + end + assert_no_match(/No such file/, @out) + assert_status + end + + def test_imports + open("test/data/imports/static_deps", "w") do |f| + f.puts 'puts "STATIC"' + end + FileUtils.rm_f "test/data/imports/dynamic_deps" + in_environment("PWD" => "test/data/imports") do + rake + end + assert File.exist?("test/data/imports/dynamic_deps"), + "'dynamic_deps' file should exist" + assert_match(/^FIRST$\s+^DYNAMIC$\s+^STATIC$\s+^OTHER$/, @out) + assert_status + FileUtils.rm_f "test/data/imports/dynamic_deps" + FileUtils.rm_f "test/data/imports/static_deps" + end + + def test_rules_chaining_to_file_task + remove_chaining_files + in_environment("PWD" => "test/data/chains") do + rake + end + assert File.exist?("test/data/chains/play.app"), + "'play.app' file should exist" + assert_status + remove_chaining_files + end + + def test_file_creation_task + in_environment("PWD" => "test/data/file_creation_task") do + rake "prep" + rake "run" + rake "run" + end + assert(@err !~ /^cp src/, "Should not recopy data") + end + + def test_dash_f_with_no_arg_foils_rakefile_lookup + rake "-I test/data/rakelib -rtest1 -f" + assert_match(/^TEST1$/, @out) + end + + def test_dot_rake_files_can_be_loaded_with_dash_r + rake "-I test/data/rakelib -rtest2 -f" + assert_match(/^TEST2$/, @out) + end + + def test_can_invoke_task_in_toplevel_namespace + in_environment("PWD" => "test/data/namespace") do + rake "copy" + end + assert_match(/^COPY$/, @out) + end + + def test_can_invoke_task_in_nested_namespace + in_environment("PWD" => "test/data/namespace") do + rake "nest:copy" + assert_match(/^NEST COPY$/, @out) + end + end + + def test_tasks_can_reference_task_in_same_namespace + in_environment("PWD" => "test/data/namespace") do + rake "nest:xx" + assert_match(/^NEST COPY$/m, @out) + end + end + + def test_tasks_can_reference_task_in_other_namespaces + in_environment("PWD" => "test/data/namespace") do + rake "b:run" + assert_match(/^IN A\nIN B$/m, @out) + end + end + + def test_anonymous_tasks_can_be_invoked_indirectly + in_environment("PWD" => "test/data/namespace") do + rake "anon" + assert_match(/^ANON COPY$/m, @out) + end + end + + def test_rake_namespace_refers_to_toplevel + in_environment("PWD" => "test/data/namespace") do + rake "very:nested:run" + assert_match(/^COPY$/m, @out) + end + end + + def test_file_task_are_not_scoped_by_namespaces + in_environment("PWD" => "test/data/namespace") do + rake "xyz.rb" + assert_match(/^XYZ1\nXYZ2$/m, @out) + end + end + + def test_rake_returns_status_error_values + in_environment("PWD" => "test/data/statusreturn") do + rake "exit5" + assert_status(5) + end + end + + def test_rake_returns_no_status_error_on_normal_exit + in_environment("PWD" => "test/data/statusreturn") do + rake "normal" + assert_status(0) + end + end + + private + + def remove_chaining_files + %w(play.scpt play.app base).each do |fn| + FileUtils.rm_f File.join("test/data/chains", fn) + end + end + + class << self + def format_command + @format_command ||= lambda { |ruby_options, rake_path, options| + "ruby #{ruby_options} #{rake_path} #{options}" + } + end + + def format_command=(fmt_command) + @format_command = fmt_command + end + end + + def rake(*option_list) + options = option_list.join(' ') + shell = Session::Shell.new + command = self.class.format_command[@ruby_options, @rake_path, options] + puts "COMMAND: [#{command}]" if @verbose + @out, @err = shell.execute command + @status = shell.exit_status + puts "STATUS: [#{@status}]" if @verbose + puts "OUTPUT: [#{@out}]" if @verbose + puts "ERROR: [#{@err}]" if @verbose + puts "PWD: [#{Dir.pwd}]" if @verbose + shell.close + end + + def assert_status(expected_status=0) + assert_equal expected_status, @status + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/shellcommand.rb b/vendor/gems/gems/rake-0.8.3/test/shellcommand.rb new file mode 100755 index 0000000..58db8a0 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/shellcommand.rb @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby + +exit((ARGV[0] || "0").to_i) diff --git a/vendor/gems/gems/rake-0.8.3/test/test_application.rb b/vendor/gems/gems/rake-0.8.3/test/test_application.rb new file mode 100644 index 0000000..d9b281e --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_application.rb @@ -0,0 +1,694 @@ +#!/usr/bin/env ruby + +begin + require 'rubygems' +rescue LoadError + # got no gems +end + +require 'test/unit' +require 'rake' +require 'test/rake_test_setup' +require 'test/capture_stdout' +require 'test/in_environment' + +TESTING_REQUIRE = [ ] + +###################################################################### +class TestApplication < Test::Unit::TestCase + include CaptureStdout + include InEnvironment + + def setup + @app = Rake::Application.new + @app.options.rakelib = [] + end + + def test_constant_warning + err = capture_stderr do @app.instance_eval { const_warning("Task") } end + assert_match(/warning/i, err) + assert_match(/deprecated/i, err) + assert_match(/Task/i, err) + end + + def test_display_tasks + @app.options.show_task_pattern = // + @app.last_description = "COMMENT" + @app.define_task(Rake::Task, "t") + out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end + assert_match(/^rake t/, out) + assert_match(/# COMMENT/, out) + end + + def test_display_tasks_with_long_comments + in_environment('RAKE_COLUMNS' => '80') do + @app.options.show_task_pattern = // + @app.last_description = "1234567890" * 8 + @app.define_task(Rake::Task, "t") + out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end + assert_match(/^rake t/, out) + assert_match(/# 12345678901234567890123456789012345678901234567890123456789012345\.\.\./, out) + end + end + + def test_display_tasks_with_task_name_wider_than_tty_display + in_environment('RAKE_COLUMNS' => '80') do + @app.options.show_task_pattern = // + description = "something short" + task_name = "task name" * 80 + @app.last_description = "something short" + @app.define_task(Rake::Task, task_name ) + out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end + # Ensure the entire task name is output and we end up showing no description + assert_match(/rake #{task_name} # .../, out) + end + end + + def test_display_tasks_with_very_long_task_name_to_a_non_tty_shows_name_and_comment + @app.options.show_task_pattern = // + @app.tty_output = false + description = "something short" + task_name = "task name" * 80 + @app.last_description = "something short" + @app.define_task(Rake::Task, task_name ) + out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end + # Ensure the entire task name is output and we end up showing no description + assert_match(/rake #{task_name} # #{description}/, out) + end + + def test_display_tasks_with_long_comments_to_a_non_tty_shows_entire_comment + @app.options.show_task_pattern = // + @app.tty_output = false + @app.last_description = "1234567890" * 8 + @app.define_task(Rake::Task, "t") + out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end + assert_match(/^rake t/, out) + assert_match(/# #{@app.last_description}/, out) + end + + def test_display_tasks_with_long_comments_to_a_non_tty_with_columns_set_truncates_comments + in_environment("RAKE_COLUMNS" => '80') do + @app.options.show_task_pattern = // + @app.tty_output = false + @app.last_description = "1234567890" * 8 + @app.define_task(Rake::Task, "t") + out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end + assert_match(/^rake t/, out) + assert_match(/# 12345678901234567890123456789012345678901234567890123456789012345\.\.\./, out) + end + end + + def test_display_tasks_with_full_descriptions + @app.options.show_task_pattern = // + @app.options.full_description = true + @app.last_description = "COMMENT" + @app.define_task(Rake::Task, "t") + out = capture_stdout do @app.instance_eval { display_tasks_and_comments } end + assert_match(/^rake t$/, out) + assert_match(/^ {4}COMMENT$/, out) + end + + def test_finding_rakefile + assert_match(/[Rr]akefile/, @app.instance_eval { have_rakefile }) + end + + def test_not_finding_rakefile + @app.instance_eval { @rakefiles = ['NEVER_FOUND'] } + assert( ! @app.instance_eval do have_rakefile end ) + assert_nil @app.rakefile + end + + def test_load_rakefile + in_environment("PWD" => "test/data/unittest") do + @app.instance_eval do + handle_options + options.silent = true + load_rakefile + end + assert_equal "rakefile", @app.rakefile.downcase + assert_match(%r(unittest$), Dir.pwd) + end + end + + def test_load_rakefile_from_subdir + in_environment("PWD" => "test/data/unittest/subdir") do + @app.instance_eval do + handle_options + options.silent = true + load_rakefile + end + assert_equal "rakefile", @app.rakefile.downcase + assert_match(%r(unittest$), Dir.pwd) + end + end + + def test_load_rakefile_not_found + in_environment("PWD" => "/", "RAKE_SYSTEM" => 'not_exist') do + @app.instance_eval do + handle_options + options.silent = true + end + ex = assert_raise(RuntimeError) do + @app.instance_eval do raw_load_rakefile end + end + assert_match(/no rakefile found/i, ex.message) + end + end + + def test_load_from_system_rakefile + in_environment('RAKE_SYSTEM' => 'test/data/sys') do + @app.options.rakelib = [] + @app.instance_eval do + handle_options + options.silent = true + options.load_system = true + load_rakefile + end + assert_equal "test/data/sys", @app.system_dir + assert_nil @app.rakefile + end + end + + def test_load_from_system_rakefile_on_unix + flexmock(@app, :windows? => false, + :win32_system_dir => nil, + :load => nil) + flexmock(File).should_receive(:expand_path).with("~").and_return("/HOME") + flexmock(File).should_receive(:expand_path).and_return { |fn| fn } + + in_environment('RAKE_SYSTEM' => nil) do + @app.options.rakelib = [] + @app.instance_eval do + handle_options + options.silent = true + options.load_system = true + load_rakefile + end + assert_equal "/HOME/.rake", @app.system_dir + end + end + + def test_windows + assert ! (@app.windows? && @app.unix?) + end + + def test_load_from_system_rakefile_on_windows + flexmock(Rake::Win32, :windows? => true) + flexmock(@app, :standard_system_dir => "XX") + flexmock(@app).should_receive(:directory?).with("/AD/Rake").and_return(true) + flexmock(@app).should_receive(:load).and_return(nil) + in_environment('RAKE_SYSTEM' => nil, 'APPDATA' => '/AD') do + @app.options.rakelib = [] + @app.instance_eval do + handle_options + options.silent = true + options.load_system = true + load_rakefile + end + assert_equal "/AD/Rake", @app.system_dir + end + end + + def test_loading_imports + mock = flexmock("loader") + mock.should_receive(:load).with("x.dummy").once + @app.instance_eval do + add_loader("dummy", mock) + add_import("x.dummy") + load_imports + end + end + + def test_building_imported_files_on_demand + mock = flexmock("loader") + mock.should_receive(:load).with("x.dummy").once + mock.should_receive(:make_dummy).with_no_args.once + @app.instance_eval do + intern(Rake::Task, "x.dummy").enhance do mock.make_dummy end + add_loader("dummy", mock) + add_import("x.dummy") + load_imports + end + end + + def test_good_run + ran = false + ARGV.clear + ARGV << '--rakelib=""' + @app.options.silent = true + @app.instance_eval do + intern(Rake::Task, "default").enhance { ran = true } + end + in_environment("PWD" => "test/data/default") do + @app.run + end + assert ran + end + + def test_display_task_run + ran = false + ARGV.clear + ARGV << '-f' << '-s' << '--tasks' << '--rakelib=""' + @app.last_description = "COMMENT" + @app.define_task(Rake::Task, "default") + out = capture_stdout { @app.run } + assert @app.options.show_tasks + assert ! ran + assert_match(/rake default/, out) + assert_match(/# COMMENT/, out) + end + + def test_display_prereqs + ran = false + ARGV.clear + ARGV << '-f' << '-s' << '--prereqs' << '--rakelib=""' + @app.last_description = "COMMENT" + t = @app.define_task(Rake::Task, "default") + t.enhance([:a, :b]) + @app.define_task(Rake::Task, "a") + @app.define_task(Rake::Task, "b") + out = capture_stdout { @app.run } + assert @app.options.show_prereqs + assert ! ran + assert_match(/rake a$/, out) + assert_match(/rake b$/, out) + assert_match(/rake default\n( *(a|b)\n){2}/m, out) + end + + def test_bad_run + @app.intern(Rake::Task, "default").enhance { fail } + ARGV.clear + ARGV << '-f' << '-s' << '--rakelib=""' + assert_raise(SystemExit) { + err = capture_stderr { @app.run } + assert_match(/see full trace/, err) + } + ensure + ARGV.clear + end + + def test_bad_run_with_trace + @app.intern(Rake::Task, "default").enhance { fail } + ARGV.clear + ARGV << '-f' << '-s' << '-t' + assert_raise(SystemExit) { + err = capture_stderr { capture_stdout { @app.run } } + assert_no_match(/see full trace/, err) + } + ensure + ARGV.clear + end + + def test_run_with_bad_options + @app.intern(Rake::Task, "default").enhance { fail } + ARGV.clear + ARGV << '-f' << '-s' << '--xyzzy' + assert_raise(SystemExit) { + err = capture_stderr { capture_stdout { @app.run } } + } + ensure + ARGV.clear + end +end + + +###################################################################### +class TestApplicationOptions < Test::Unit::TestCase + include CaptureStdout + + def setup + clear_argv + RakeFileUtils.verbose_flag = false + RakeFileUtils.nowrite_flag = false + TESTING_REQUIRE.clear + end + + def teardown + clear_argv + RakeFileUtils.verbose_flag = false + RakeFileUtils.nowrite_flag = false + end + + def clear_argv + while ! ARGV.empty? + ARGV.pop + end + end + + def test_default_options + opts = command_line + assert_nil opts.classic_namespace + assert_nil opts.dryrun + assert_nil opts.full_description + assert_nil opts.ignore_system + assert_nil opts.load_system + assert_nil opts.nosearch + assert_equal ['rakelib'], opts.rakelib + assert_nil opts.show_prereqs + assert_nil opts.show_task_pattern + assert_nil opts.show_tasks + assert_nil opts.silent + assert_nil opts.trace + assert_equal ['rakelib'], opts.rakelib + assert ! RakeFileUtils.verbose_flag + assert ! RakeFileUtils.nowrite_flag + end + + def test_dry_run + flags('--dry-run', '-n') do |opts| + assert opts.dryrun + assert opts.trace + assert RakeFileUtils.verbose_flag + assert RakeFileUtils.nowrite_flag + end + end + + def test_describe + flags('--describe') do |opts| + assert opts.full_description + assert opts.show_tasks + assert_equal(//.to_s, opts.show_task_pattern.to_s) + end + end + + def test_describe_with_pattern + flags('--describe=X') do |opts| + assert opts.full_description + assert opts.show_tasks + assert_equal(/X/.to_s, opts.show_task_pattern.to_s) + end + end + + def test_execute + $xyzzy = 0 + flags('--execute=$xyzzy=1', '-e $xyzzy=1') do |opts| + assert_equal 1, $xyzzy + assert_equal :exit, @exit + $xyzzy = 0 + end + end + + def test_execute_and_continue + $xyzzy = 0 + flags('--execute-continue=$xyzzy=1', '-E $xyzzy=1') do |opts| + assert_equal 1, $xyzzy + assert_not_equal :exit, @exit + $xyzzy = 0 + end + end + + def test_execute_and_print + $xyzzy = 0 + flags('--execute-print=$xyzzy="pugh"', '-p $xyzzy="pugh"') do |opts| + assert_equal 'pugh', $xyzzy + assert_equal :exit, @exit + assert_match(/^pugh$/, @out) + $xyzzy = 0 + end + end + + def test_help + flags('--help', '-H', '-h') do |opts| + assert_match(/\Arake/, @out) + assert_match(/\boptions\b/, @out) + assert_match(/\btargets\b/, @out) + assert_equal :exit, @exit + assert_equal :exit, @exit + end + end + + def test_libdir + flags(['--libdir', 'xx'], ['-I', 'xx'], ['-Ixx']) do |opts| + $:.include?('xx') + end + ensure + $:.delete('xx') + end + + def test_rakefile + flags(['--rakefile', 'RF'], ['--rakefile=RF'], ['-f', 'RF'], ['-fRF']) do |opts| + assert_equal ['RF'], @app.instance_eval { @rakefiles } + end + end + + def test_rakelib + flags(['--rakelibdir', 'A:B:C'], ['--rakelibdir=A:B:C'], ['-R', 'A:B:C'], ['-RA:B:C']) do |opts| + assert_equal ['A', 'B', 'C'], opts.rakelib + end + end + + def test_require + flags(['--require', 'test/reqfile'], '-rtest/reqfile2', '-rtest/reqfile3') do |opts| + end + assert TESTING_REQUIRE.include?(1) + assert TESTING_REQUIRE.include?(2) + assert TESTING_REQUIRE.include?(3) + assert_equal 3, TESTING_REQUIRE.size + end + + def test_missing_require + ex = assert_raises(LoadError) do + flags(['--require', 'test/missing']) do |opts| + end + end + assert_match(/no such file/, ex.message) + assert_match(/test\/missing/, ex.message) + end + + def test_prereqs + flags('--prereqs', '-P') do |opts| + assert opts.show_prereqs + end + end + + def test_quiet + flags('--quiet', '-q') do |opts| + assert ! RakeFileUtils.verbose_flag + assert ! opts.silent + end + end + + def test_no_search + flags('--nosearch', '--no-search', '-N') do |opts| + assert opts.nosearch + end + end + + def test_silent + flags('--silent', '-s') do |opts| + assert ! RakeFileUtils.verbose_flag + assert opts.silent + end + end + + def test_system + flags('--system', '-g') do |opts| + assert opts.load_system + end + end + + def test_no_system + flags('--no-system', '-G') do |opts| + assert opts.ignore_system + end + end + + def test_trace + flags('--trace', '-t') do |opts| + assert opts.trace + assert RakeFileUtils.verbose_flag + assert ! RakeFileUtils.nowrite_flag + end + end + + def test_trace_rules + flags('--rules') do |opts| + assert opts.trace_rules + end + end + + def test_tasks + flags('--tasks', '-T') do |opts| + assert opts.show_tasks + assert_equal(//.to_s, opts.show_task_pattern.to_s) + end + flags(['--tasks', 'xyz'], ['-Txyz']) do |opts| + assert opts.show_tasks + assert_equal(/xyz/, opts.show_task_pattern) + end + end + + def test_verbose + flags('--verbose', '-V') do |opts| + assert RakeFileUtils.verbose_flag + assert ! opts.silent + end + end + + def test_version + flags('--version', '-V') do |opts| + assert_match(/\bversion\b/, @out) + assert_match(/\b#{RAKEVERSION}\b/, @out) + assert_equal :exit, @exit + end + end + + def test_classic_namespace + flags(['--classic-namespace'], ['-C', '-T', '-P', '-n', '-s', '-t']) do |opts| + assert opts.classic_namespace + assert_equal opts.show_tasks, $show_tasks + assert_equal opts.show_prereqs, $show_prereqs + assert_equal opts.trace, $trace + assert_equal opts.dryrun, $dryrun + assert_equal opts.silent, $silent + end + end + + def test_bad_option + capture_stderr do + ex = assert_raise(OptionParser::InvalidOption) do + flags('--bad-option') + end + if ex.message =~ /^While/ # Ruby 1.9 error message + assert_match(/while parsing/i, ex.message) + else # Ruby 1.8 error message + assert_match(/(invalid|unrecognized) option/i, ex.message) + assert_match(/--bad-option/, ex.message) + end + end + end + + def test_task_collection + command_line("a", "b") + assert_equal ["a", "b"], @tasks.sort + end + + def test_default_task_collection + command_line() + assert_equal ["default"], @tasks + end + + def test_environment_definition + ENV.delete('TESTKEY') + command_line("a", "TESTKEY=12") + assert_equal ["a"], @tasks.sort + assert '12', ENV['TESTKEY'] + end + + private + + def flags(*sets) + sets.each do |set| + ARGV.clear + @out = capture_stdout { + @exit = catch(:system_exit) { opts = command_line(*set) } + } + yield(@app.options) if block_given? + end + end + + def command_line(*options) + options.each do |opt| ARGV << opt end + @app = Rake::Application.new + def @app.exit(*args) + throw :system_exit, :exit + end + @app.instance_eval do + collect_tasks handle_options + end + @tasks = @app.top_level_tasks + @app.options + end +end + +class TestTaskArgumentParsing < Test::Unit::TestCase + def setup + @app = Rake::Application.new + end + + def test_name_only + name, args = @app.parse_task_string("name") + assert_equal "name", name + assert_equal [], args + end + + def test_empty_args + name, args = @app.parse_task_string("name[]") + assert_equal "name", name + assert_equal [], args + end + + def test_one_argument + name, args = @app.parse_task_string("name[one]") + assert_equal "name", name + assert_equal ["one"], args + end + + def test_two_arguments + name, args = @app.parse_task_string("name[one,two]") + assert_equal "name", name + assert_equal ["one", "two"], args + end + + def test_can_handle_spaces_between_args + name, args = @app.parse_task_string("name[one, two,\tthree , \tfour]") + assert_equal "name", name + assert_equal ["one", "two", "three", "four"], args + end + + def test_keeps_embedded_spaces + name, args = @app.parse_task_string("name[a one ana, two]") + assert_equal "name", name + assert_equal ["a one ana", "two"], args + end + +end + +class TestTaskArgumentParsing < Test::Unit::TestCase + include InEnvironment + + def test_terminal_width_using_env + app = Rake::Application.new + in_environment('RAKE_COLUMNS' => '1234') do + assert_equal 1234, app.terminal_width + end + end + + def test_terminal_width_using_stty + app = Rake::Application.new + flexmock(app, + :unix? => true, + :dynamic_width_stty => 1235, + :dynamic_width_tput => 0) + in_environment('RAKE_COLUMNS' => nil) do + assert_equal 1235, app.terminal_width + end + end + + def test_terminal_width_using_tput + app = Rake::Application.new + flexmock(app, + :unix? => true, + :dynamic_width_stty => 0, + :dynamic_width_tput => 1236) + in_environment('RAKE_COLUMNS' => nil) do + assert_equal 1236, app.terminal_width + end + end + + def test_terminal_width_using_hardcoded_80 + app = Rake::Application.new + flexmock(app, :unix? => false) + in_environment('RAKE_COLUMNS' => nil) do + assert_equal 80, app.terminal_width + end + end + + def test_terminal_width_with_failure + app = Rake::Application.new + flexmock(app).should_receive(:unix?).and_throw(RuntimeError) + in_environment('RAKE_COLUMNS' => nil) do + assert_equal 80, app.terminal_width + end + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_clean.rb b/vendor/gems/gems/rake-0.8.3/test/test_clean.rb new file mode 100644 index 0000000..da04ad1 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_clean.rb @@ -0,0 +1,14 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'rake/clean' + +class TestClean < Test::Unit::TestCase + include Rake + def test_clean + assert Task['clean'], "Should define clean" + assert Task['clobber'], "Should define clobber" + assert Task['clobber'].prerequisites.include?("clean"), + "Clobber should require clean" + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_definitions.rb b/vendor/gems/gems/rake-0.8.3/test/test_definitions.rb new file mode 100644 index 0000000..fe6d42c --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_definitions.rb @@ -0,0 +1,82 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'fileutils' +require 'rake' +require 'test/filecreation' + +###################################################################### +class TestDefinitions < Test::Unit::TestCase + include Rake + EXISTINGFILE = "testdata/existing" + + def setup + Task.clear + end + + def test_task + done = false + task :one => [:two] do done = true end + task :two + task :three => [:one, :two] + check_tasks(:one, :two, :three) + assert done, "Should be done" + end + + def test_file_task + done = false + file "testdata/one" => "testdata/two" do done = true end + file "testdata/two" + file "testdata/three" => ["testdata/one", "testdata/two"] + check_tasks("testdata/one", "testdata/two", "testdata/three") + assert done, "Should be done" + end + + def check_tasks(n1, n2, n3) + t = Task[n1] + assert Task === t, "Should be a Task" + assert_equal n1.to_s, t.name + assert_equal [n2.to_s], t.prerequisites.collect{|n| n.to_s} + t.invoke + t2 = Task[n2] + assert_equal FileList[], t2.prerequisites + t3 = Task[n3] + assert_equal [n1.to_s, n2.to_s], t3.prerequisites.collect{|n|n.to_s} + end + + def test_incremental_definitions + runs = [] + task :t1 => [:t2] do runs << "A"; 4321 end + task :t1 => [:t3] do runs << "B"; 1234 end + task :t1 => [:t3] + task :t2 + task :t3 + Task[:t1].invoke + assert_equal ["A", "B"], runs + assert_equal ["t2", "t3"], Task[:t1].prerequisites + end + + def test_missing_dependencies + task :x => ["testdata/missing"] + assert_raises(RuntimeError) { Task[:x].invoke } + end + + def test_implicit_file_dependencies + runs = [] + create_existing_file + task :y => [EXISTINGFILE] do |t| runs << t.name end + Task[:y].invoke + assert_equal runs, ['y'] + end + + private # ---------------------------------------------------------- + + def create_existing_file + Dir.mkdir File.dirname(EXISTINGFILE) unless + File.exist?(File.dirname(EXISTINGFILE)) + open(EXISTINGFILE, "w") do |f| f.puts "HI" end unless + File.exist?(EXISTINGFILE) + end + +end + diff --git a/vendor/gems/gems/rake-0.8.3/test/test_earlytime.rb b/vendor/gems/gems/rake-0.8.3/test/test_earlytime.rb new file mode 100644 index 0000000..e63bd54 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_earlytime.rb @@ -0,0 +1,35 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'rake' + +class TestEarlyTime < Test::Unit::TestCase + def test_create + early = Rake::EarlyTime.instance + time = Time.mktime(1970, 1, 1, 0, 0, 0) + assert early <= Time.now + assert early < Time.now + assert early != Time.now + assert Time.now > early + assert Time.now >= early + assert Time.now != early + end + + def test_equality + early = Rake::EarlyTime.instance + assert_equal early, early, "two early times should be equal" + end + + def test_original_time_compare_is_not_messed_up + t1 = Time.mktime(1970, 1, 1, 0, 0, 0) + t2 = Time.now + assert t1 < t2 + assert t2 > t1 + assert t1 == t1 + assert t2 == t2 + end + + def test_to_s + assert_equal "", Rake::EARLY.to_s + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_extension.rb b/vendor/gems/gems/rake-0.8.3/test/test_extension.rb new file mode 100644 index 0000000..4a5784c --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_extension.rb @@ -0,0 +1,63 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'rake' +require 'stringio' + +###################################################################### +class TestExtension < Test::Unit::TestCase + + module Redirect + def error_redirect + old_err = $stderr + result = StringIO.new + $stderr = result + yield + result + ensure + $stderr = old_err + end + end + + class Sample + extend Redirect + + def duplicate_method + :original + end + + OK_ERRS = error_redirect do + rake_extension("a") do + def ok_method + end + end + end + + + DUP_ERRS = error_redirect do + rake_extension("duplicate_method") do + def duplicate_method + :override + end + end + end + end + + def test_methods_actually_exist + sample = Sample.new + sample.ok_method + sample.duplicate_method + end + + def test_no_warning_when_defining_ok_method + assert_equal "", Sample::OK_ERRS.string + end + + def test_extension_complains_when_a_method_that_is_present + assert_match(/warning:/i, Sample::DUP_ERRS.string) + assert_match(/already exists/i, Sample::DUP_ERRS.string) + assert_match(/duplicate_method/i, Sample::DUP_ERRS.string) + assert_equal :original, Sample.new.duplicate_method + end + +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_file_creation_task.rb b/vendor/gems/gems/rake-0.8.3/test/test_file_creation_task.rb new file mode 100644 index 0000000..1544e14 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_file_creation_task.rb @@ -0,0 +1,62 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'fileutils' +require 'rake' +require 'test/filecreation' + +###################################################################### +class TestFileCreationTask < Test::Unit::TestCase + include Rake + include FileCreation + + DUMMY_DIR = 'testdata/dummy_dir' + + def setup + Task.clear + end + + def teardown + FileUtils.rm_rf DUMMY_DIR + end + + def test_file_needed + create_dir DUMMY_DIR + fc_task = Task[DUMMY_DIR] + assert_equal DUMMY_DIR, fc_task.name + FileUtils.rm_rf fc_task.name + assert fc_task.needed?, "file should be needed" + FileUtils.mkdir fc_task.name + assert_equal nil, fc_task.prerequisites.collect{|n| Task[n].timestamp}.max + assert ! fc_task.needed?, "file should not be needed" + end + + def test_directory + directory DUMMY_DIR + fc_task = Task[DUMMY_DIR] + assert_equal DUMMY_DIR, fc_task.name + assert FileCreationTask === fc_task + end + + def test_no_retriggers_on_filecreate_task + create_timed_files(OLDFILE, NEWFILE) + t1 = Rake.application.intern(FileCreationTask, OLDFILE).enhance([NEWFILE]) + t2 = Rake.application.intern(FileCreationTask, NEWFILE) + assert ! t2.needed?, "Should not need to build new file" + assert ! t1.needed?, "Should not need to rebuild old file because of new" + end + + def test_no_retriggers_on_file_task + create_timed_files(OLDFILE, NEWFILE) + t1 = Rake.application.intern(FileCreationTask, OLDFILE).enhance([NEWFILE]) + t2 = Rake.application.intern(FileCreationTask, NEWFILE) + assert ! t2.needed?, "Should not need to build new file" + assert ! t1.needed?, "Should not need to rebuild old file because of new" + end + + def test_very_early_timestamp + t1 = Rake.application.intern(FileCreationTask, OLDFILE) + assert t1.timestamp < Time.now + assert t1.timestamp < Time.now - 1000000 + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_file_task.rb b/vendor/gems/gems/rake-0.8.3/test/test_file_task.rb new file mode 100644 index 0000000..383ee0d --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_file_task.rb @@ -0,0 +1,139 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'fileutils' +require 'rake' +require 'test/filecreation' + +###################################################################### +class TestFileTask < Test::Unit::TestCase + include Rake + include FileCreation + + def setup + Task.clear + @runs = Array.new + FileUtils.rm_f NEWFILE + FileUtils.rm_f OLDFILE + end + + def test_file_need + name = "testdata/dummy" + file name + ftask = Task[name] + assert_equal name.to_s, ftask.name + File.delete(ftask.name) rescue nil + assert ftask.needed?, "file should be needed" + open(ftask.name, "w") { |f| f.puts "HI" } + assert_equal nil, ftask.prerequisites.collect{|n| Task[n].timestamp}.max + assert ! ftask.needed?, "file should not be needed" + File.delete(ftask.name) rescue nil + end + + def test_file_times_new_depends_on_old + create_timed_files(OLDFILE, NEWFILE) + + t1 = Rake.application.intern(FileTask, NEWFILE).enhance([OLDFILE]) + t2 = Rake.application.intern(FileTask, OLDFILE) + assert ! t2.needed?, "Should not need to build old file" + assert ! t1.needed?, "Should not need to rebuild new file because of old" + end + + def test_file_times_old_depends_on_new + create_timed_files(OLDFILE, NEWFILE) + + t1 = Rake.application.intern(FileTask,OLDFILE).enhance([NEWFILE]) + t2 = Rake.application.intern(FileTask, NEWFILE) + assert ! t2.needed?, "Should not need to build new file" + preq_stamp = t1.prerequisites.collect{|t| Task[t].timestamp}.max + assert_equal t2.timestamp, preq_stamp + assert t1.timestamp < preq_stamp, "T1 should be older" + assert t1.needed?, "Should need to rebuild old file because of new" + end + + def test_file_depends_on_task_depend_on_file + create_timed_files(OLDFILE, NEWFILE) + + file NEWFILE => [:obj] do |t| @runs << t.name end + task :obj => [OLDFILE] do |t| @runs << t.name end + file OLDFILE do |t| @runs << t.name end + + Task[:obj].invoke + Task[NEWFILE].invoke + assert ! @runs.include?(NEWFILE) + end + + def test_existing_file_depends_on_non_existing_file + create_file(OLDFILE) + delete_file(NEWFILE) + file NEWFILE + file OLDFILE => NEWFILE + assert_nothing_raised do Task[OLDFILE].invoke end + end + + # I have currently disabled this test. I'm not convinced that + # deleting the file target on failure is always the proper thing to + # do. I'm willing to hear input on this topic. + def ztest_file_deletes_on_failure + task :obj + file NEWFILE => [:obj] do |t| + FileUtils.touch NEWFILE + fail "Ooops" + end + assert Task[NEWFILE] + begin + Task[NEWFILE].invoke + rescue Exception + end + assert( ! File.exist?(NEWFILE), "NEWFILE should be deleted") + end + +end + +###################################################################### +class TestDirectoryTask < Test::Unit::TestCase + include Rake + + def setup + rm_rf "testdata", :verbose=>false + end + + def teardown + rm_rf "testdata", :verbose=>false + end + + def test_directory + desc "DESC" + directory "testdata/a/b/c" + assert_equal FileCreationTask, Task["testdata"].class + assert_equal FileCreationTask, Task["testdata/a"].class + assert_equal FileCreationTask, Task["testdata/a/b/c"].class + assert_nil Task["testdata"].comment + assert_equal "DESC", Task["testdata/a/b/c"].comment + assert_nil Task["testdata/a/b"].comment + verbose(false) { + Task['testdata/a/b'].invoke + } + assert File.exist?("testdata/a/b") + assert ! File.exist?("testdata/a/b/c") + end + + def test_directory_win32 + desc "WIN32 DESC" + FileUtils.mkdir_p("testdata") + Dir.chdir("testdata") do + directory 'c:/testdata/a/b/c' + assert_equal FileCreationTask, Task['c:/testdata'].class + assert_equal FileCreationTask, Task['c:/testdata/a'].class + assert_equal FileCreationTask, Task['c:/testdata/a/b/c'].class + assert_nil Task['c:/testdata'].comment + assert_equal "WIN32 DESC", Task['c:/testdata/a/b/c'].comment + assert_nil Task['c:/testdata/a/b'].comment + verbose(false) { + Task['c:/testdata/a/b'].invoke + } + assert File.exist?('c:/testdata/a/b') + assert ! File.exist?('c:/testdata/a/b/c') + end + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_filelist.rb b/vendor/gems/gems/rake-0.8.3/test/test_filelist.rb new file mode 100644 index 0000000..b6a6265 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_filelist.rb @@ -0,0 +1,618 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'rake' + +require 'test/capture_stdout' + +class TestFileList < Test::Unit::TestCase + FileList = Rake::FileList + include CaptureStdout + + def setup + create_test_data + end + + def teardown +# FileList.select_default_ignore_patterns + FileUtils.rm_rf("testdata") + end + + def test_delgating_methods_do_not_include_to_a_or_to_ary + assert ! FileList::DELEGATING_METHODS.include?("to_a"), "should not include to_a" + assert ! FileList::DELEGATING_METHODS.include?(:to_a), "should not include to_a" + assert ! FileList::DELEGATING_METHODS.include?("to_ary"), "should not include to_ary" + assert ! FileList::DELEGATING_METHODS.include?(:to_ary), "should not include to_ary" + end + + def test_create + fl = FileList.new + assert_equal 0, fl.size + end + + def test_create_with_args + fl = FileList.new("testdata/*.c", "x") + assert_equal ["testdata/abc.c", "testdata/x.c", "testdata/xyz.c", "x"].sort, + fl.sort + end + + def test_create_with_block + fl = FileList.new { |f| f.include("x") } + assert_equal ["x"], fl.resolve + end + + def test_create_with_brackets + fl = FileList["testdata/*.c", "x"] + assert_equal ["testdata/abc.c", "testdata/x.c", "testdata/xyz.c", "x"].sort, + fl.sort + end + + def test_create_with_brackets_and_filelist + fl = FileList[FileList["testdata/*.c", "x"]] + assert_equal ["testdata/abc.c", "testdata/x.c", "testdata/xyz.c", "x"].sort, + fl.sort + end + + def test_include_with_another_array + fl = FileList.new.include(["x", "y", "z"]) + assert_equal ["x", "y", "z"].sort, fl.sort + end + + def test_include_with_another_filelist + fl = FileList.new.include(FileList["testdata/*.c", "x"]) + assert_equal ["testdata/abc.c", "testdata/x.c", "testdata/xyz.c", "x"].sort, + fl.sort + end + + def test_append + fl = FileList.new + fl << "a.rb" << "b.rb" + assert_equal ['a.rb', 'b.rb'], fl + end + + def test_add_many + fl = FileList.new + fl.include %w(a d c) + fl.include('x', 'y') + assert_equal ['a', 'd', 'c', 'x', 'y'], fl + assert_equal ['a', 'd', 'c', 'x', 'y'], fl.resolve + end + + def test_add_return + f = FileList.new + g = f << "x" + assert_equal f.object_id, g.object_id + h = f.include("y") + assert_equal f.object_id, h.object_id + end + + def test_match + fl = FileList.new + fl.include('test/test*.rb') + assert fl.include?("test/test_filelist.rb") + assert fl.size > 3 + fl.each { |fn| assert_match(/\.rb$/, fn) } + end + + def test_add_matching + fl = FileList.new + fl << "a.java" + fl.include("test/*.rb") + assert_equal "a.java", fl[0] + assert fl.size > 2 + assert fl.include?("test/test_filelist.rb") + end + + def test_multiple_patterns + create_test_data + fl = FileList.new + fl.include('*.c', '*xist*') + assert_equal [], fl + fl.include('testdata/*.c', 'testdata/*xist*') + assert_equal [ + 'testdata/x.c', 'testdata/xyz.c', 'testdata/abc.c', 'testdata/existing' + ].sort, fl.sort + end + + def test_square_bracket_pattern + fl = FileList.new + fl.include("testdata/abc.[ch]") + assert fl.size == 2 + assert fl.include?("testdata/abc.c") + assert fl.include?("testdata/abc.h") + end + + def test_curly_bracket_pattern + fl = FileList.new + fl.include("testdata/abc.{c,h}") + assert fl.size == 2 + assert fl.include?("testdata/abc.c") + assert fl.include?("testdata/abc.h") + end + + def test_reject + fl = FileList.new + fl.include %w(testdata/x.c testdata/abc.c testdata/xyz.c testdata/existing) + fl.reject! { |fn| fn =~ %r{/x} } + assert_equal [ + 'testdata/abc.c', 'testdata/existing' + ], fl + end + + def test_exclude + fl = FileList['testdata/x.c', 'testdata/abc.c', 'testdata/xyz.c', 'testdata/existing'] + fl.each { |fn| touch fn, :verbose => false } + x = fl.exclude(%r{/x.+\.}) + assert_equal FileList, x.class + assert_equal %w(testdata/x.c testdata/abc.c testdata/existing), fl + assert_equal fl.object_id, x.object_id + fl.exclude('testdata/*.c') + assert_equal ['testdata/existing'], fl + fl.exclude('testdata/existing') + assert_equal [], fl + end + + def test_excluding_via_block + fl = FileList['testdata/a.c', 'testdata/b.c', 'testdata/xyz.c'] + fl.exclude { |fn| fn.pathmap('%n') == 'xyz' } + assert fl.exclude?("xyz.c"), "Should exclude xyz.c" + assert_equal ['testdata/a.c', 'testdata/b.c'], fl + end + + def test_exclude_return_on_create + fl = FileList['testdata/*'].exclude(/.*\.[hcx]$/) + assert_equal ['testdata/existing', 'testdata/cfiles'].sort, fl.sort + assert_equal FileList, fl.class + end + + def test_exclude_with_string_return_on_create + fl = FileList['testdata/*'].exclude('testdata/abc.c') + assert_equal %w(testdata/existing testdata/cfiles testdata/x.c testdata/abc.h testdata/abc.x testdata/xyz.c).sort, fl.sort + assert_equal FileList, fl.class + end + + def test_default_exclude + fl = FileList.new + fl.clear_exclude + fl.include("**/*~", "**/*.bak", "**/core") + assert fl.member?("testdata/core"), "Should include core" + assert fl.member?("testdata/x.bak"), "Should include .bak files" + end + + def test_unique + fl = FileList.new + fl << "x.c" << "a.c" << "b.rb" << "a.c" + assert_equal ['x.c', 'a.c', 'b.rb', 'a.c'], fl + fl.uniq! + assert_equal ['x.c', 'a.c', 'b.rb'], fl + end + + def test_to_string + fl = FileList.new + fl << "a.java" << "b.java" + assert_equal "a.java b.java", fl.to_s + assert_equal "a.java b.java", "#{fl}" + end + + def test_to_array + fl = FileList['a.java', 'b.java'] + assert_equal ['a.java', 'b.java'], fl.to_a + assert_equal Array, fl.to_a.class + assert_equal ['a.java', 'b.java'], fl.to_ary + assert_equal Array, fl.to_ary.class + end + + def test_to_s_pending + fl = FileList['testdata/abc.*'] + result = fl.to_s + assert_match(%r{testdata/abc\.c}, result) + assert_match(%r{testdata/abc\.h}, result) + assert_match(%r{testdata/abc\.x}, result) + assert_match(%r{(testdata/abc\..\b ?){2}}, result) + end + + def test_inspect_pending + fl = FileList['testdata/abc.*'] + result = fl.inspect + assert_match(%r{"testdata/abc\.c"}, result) + assert_match(%r{"testdata/abc\.h"}, result) + assert_match(%r{"testdata/abc\.x"}, result) + assert_match(%r|^\[("testdata/abc\..", ){2}"testdata/abc\.."\]$|, result) + end + + def test_sub + fl = FileList["testdata/*.c"] + f2 = fl.sub(/\.c$/, ".o") + assert_equal FileList, f2.class + assert_equal ["testdata/abc.o", "testdata/x.o", "testdata/xyz.o"].sort, + f2.sort + f3 = fl.gsub(/\.c$/, ".o") + assert_equal FileList, f3.class + assert_equal ["testdata/abc.o", "testdata/x.o", "testdata/xyz.o"].sort, + f3.sort + end + + def test_claim_to_be_a_kind_of_array + fl = FileList['testdata/*.c'] + assert fl.is_a?(Array) + assert fl.kind_of?(Array) + end + + def test_claim_to_be_a_kind_of_filelist + fl = FileList['testdata/*.c'] + assert fl.is_a?(FileList) + assert fl.kind_of?(FileList) + end + + def test_claim_to_be_a_filelist_instance + fl = FileList['testdata/*.c'] + assert fl.instance_of?(FileList) + end + + def test_dont_claim_to_be_an_array_instance + fl = FileList['testdata/*.c'] + assert ! fl.instance_of?(Array) + end + + def test_sub! + f = "x/a.c" + fl = FileList[f, "x/b.c"] + res = fl.sub!(/\.c$/, ".o") + assert_equal ["x/a.o", "x/b.o"].sort, fl.sort + assert_equal "x/a.c", f + assert_equal fl.object_id, res.object_id + end + + def test_sub_with_block + fl = FileList["src/org/onestepback/a.java", "src/org/onestepback/b.java"] +# The block version doesn't work the way I want it to ... +# f2 = fl.sub(%r{^src/(.*)\.java$}) { |x| "classes/" + $1 + ".class" } + f2 = fl.sub(%r{^src/(.*)\.java$}, "classes/\\1.class") + assert_equal [ + "classes/org/onestepback/a.class", + "classes/org/onestepback/b.class" + ].sort, + f2.sort + end + + def test_string_ext + assert_equal "one.net", "one.two".ext("net") + assert_equal "one.net", "one.two".ext(".net") + assert_equal "one.net", "one".ext("net") + assert_equal "one.net", "one".ext(".net") + assert_equal "one.two.net", "one.two.c".ext(".net") + assert_equal "one/two.net", "one/two.c".ext(".net") + assert_equal "one.x/two.net", "one.x/two.c".ext(".net") + assert_equal "one.x\\two.net", "one.x\\two.c".ext(".net") + assert_equal "one.x/two.net", "one.x/two".ext(".net") + assert_equal "one.x\\two.net", "one.x\\two".ext(".net") + assert_equal ".onerc.net", ".onerc.dot".ext("net") + assert_equal ".onerc.net", ".onerc".ext("net") + assert_equal ".a/.onerc.net", ".a/.onerc".ext("net") + assert_equal "one", "one.two".ext('') + assert_equal "one", "one.two".ext + assert_equal ".one", ".one.two".ext + assert_equal ".one", ".one".ext + assert_equal ".", ".".ext("c") + assert_equal "..", "..".ext("c") + end + + def test_filelist_ext + assert_equal FileList['one.c', '.one.c'], + FileList['one.net', '.one'].ext('c') + end + + def test_gsub + create_test_data + fl = FileList["testdata/*.c"] + f2 = fl.gsub(/a/, "A") + assert_equal ["testdAtA/Abc.c", "testdAtA/x.c", "testdAtA/xyz.c"].sort, + f2.sort + end + + def test_gsub! + create_test_data + f = FileList["testdata/*.c"] + f.gsub!(/a/, "A") + assert_equal ["testdAtA/Abc.c", "testdAtA/x.c", "testdAtA/xyz.c"].sort, + f.sort + end + + def test_egrep_with_output + files = FileList['test/test*.rb'] + the_line_number = __LINE__ + 1 + out = capture_stdout do files.egrep(/PUGH/) end + assert_match(/:#{the_line_number}:/, out) + end + + def test_egrep_with_block + files = FileList['test/test*.rb'] + found = false + the_line_number = __LINE__ + 1 + files.egrep(/XYZZY/) do |fn, ln, line | + assert_equal 'test/test_filelist.rb', fn + assert_equal the_line_number, ln + assert_match(/files\.egrep/, line) + found = true + end + assert found, "should have found a matching line" + end + + def test_existing + fl = FileList['testdata/abc.c', 'testdata/notthere.c'] + assert_equal ["testdata/abc.c"], fl.existing + assert fl.existing.is_a?(FileList) + end + + def test_existing! + fl = FileList['testdata/abc.c', 'testdata/notthere.c'] + result = fl.existing! + assert_equal ["testdata/abc.c"], fl + assert_equal fl.object_id, result.object_id + end + + def test_ignore_special + f = FileList['testdata/*'] + assert ! f.include?("testdata/CVS"), "Should not contain CVS" + assert ! f.include?("testdata/.svn"), "Should not contain .svn" + assert ! f.include?("testdata/.dummy"), "Should not contain dot files" + assert ! f.include?("testdata/x.bak"), "Should not contain .bak files" + assert ! f.include?("testdata/x~"), "Should not contain ~ files" + assert ! f.include?("testdata/core"), "Should not contain core files" + end + + def test_clear_ignore_patterns + f = FileList['testdata/*', 'testdata/.svn'] + f.clear_exclude + assert f.include?("testdata/abc.c") + assert f.include?("testdata/xyz.c") + assert f.include?("testdata/CVS") + assert f.include?("testdata/.svn") + assert f.include?("testdata/x.bak") + assert f.include?("testdata/x~") + end + + def test_exclude_with_alternate_file_seps + fl = FileList.new + assert fl.exclude?("x/CVS/y") + assert fl.exclude?("x\\CVS\\y") + assert fl.exclude?("x/.svn/y") + assert fl.exclude?("x\\.svn\\y") + assert fl.exclude?("x/core") + assert fl.exclude?("x\\core") + end + + def test_add_default_exclude_list + fl = FileList.new + fl.exclude(/~\d+$/) + assert fl.exclude?("x/CVS/y") + assert fl.exclude?("x\\CVS\\y") + assert fl.exclude?("x/.svn/y") + assert fl.exclude?("x\\.svn\\y") + assert fl.exclude?("x/core") + assert fl.exclude?("x\\core") + assert fl.exclude?("x/abc~1") + end + + def test_basic_array_functions + f = FileList['b', 'c', 'a'] + assert_equal 'b', f.first + assert_equal 'b', f[0] + assert_equal 'a', f.last + assert_equal 'a', f[2] + assert_equal 'a', f[-1] + assert_equal ['a', 'b', 'c'], f.sort + f.sort! + assert_equal ['a', 'b', 'c'], f + end + + def test_flatten + assert_equal ['a', 'testdata/x.c', 'testdata/xyz.c', 'testdata/abc.c'].sort, + ['a', FileList['testdata/*.c']].flatten.sort + end + + def test_clone_and_dup + a = FileList['a', 'b', 'c'] + c = a.clone + d = a.dup + a << 'd' + assert_equal ['a', 'b', 'c', 'd'], a + assert_equal ['a', 'b', 'c'], c + assert_equal ['a', 'b', 'c'], d + end + + def test_dup_and_clone_replicate_taint + a = FileList['a', 'b', 'c'] + a.taint + c = a.clone + d = a.dup + assert c.tainted?, "Clone should be tainted" + assert d.tainted?, "Dup should be tainted" + end + + def test_duped_items_will_thaw + a = FileList['a', 'b', 'c'] + a.freeze + d = a.dup + d << 'more' + assert_equal ['a', 'b', 'c', 'more'], d + end + + def test_cloned_items_stay_frozen + a = FileList['a', 'b', 'c'] + a.freeze + c = a.clone + assert_raise(TypeError, RuntimeError) do + c << 'more' + end + end + + def test_array_comparisons + fl = FileList['b', 'b'] + a = ['b', 'a'] + b = ['b', 'b'] + c = ['b', 'c'] + assert_equal( 1, fl <=> a ) + assert_equal( 0, fl <=> b ) + assert_equal( -1, fl <=> c ) + assert_equal( -1, a <=> fl ) + assert_equal( 0, b <=> fl ) + assert_equal( 1, c <=> fl ) + end + + def test_array_equality + a = FileList['a', 'b'] + b = ['a', 'b'] + assert a == b + assert b == a +# assert a.eql?(b) +# assert b.eql?(a) + assert ! a.equal?(b) + assert ! b.equal?(a) + end + + def test_enumeration_methods + a = FileList['a', 'b'] + b = a.collect { |it| it.upcase } + assert_equal ['A', 'B'], b + assert_equal FileList, b.class + + b = a.map { |it| it.upcase } + assert_equal ['A', 'B'], b + assert_equal FileList, b.class + + b = a.sort + assert_equal ['a', 'b'], b + assert_equal FileList, b.class + + b = a.sort_by { |it| it } + assert_equal ['a', 'b'], b + assert_equal FileList, b.class + + b = a.find_all { |it| it == 'b'} + assert_equal ['b'], b + assert_equal FileList, b.class + + b = a.select { |it| it.size == 1 } + assert_equal ['a', 'b'], b + assert_equal FileList, b.class + + b = a.reject { |it| it == 'b' } + assert_equal ['a'], b + assert_equal FileList, b.class + + b = a.grep(/./) + assert_equal ['a', 'b'], b + assert_equal FileList, b.class + + b = a.partition { |it| it == 'b' } + assert_equal [['b'], ['a']], b + assert_equal Array, b.class + assert_equal FileList, b[0].class + assert_equal FileList, b[1].class + + b = a.zip(['x', 'y']).to_a + assert_equal [['a', 'x'], ['b', 'y']], b + assert_equal Array, b.class + assert_equal Array, b[0].class + assert_equal Array, b[1].class + end + + def test_array_operators + a = ['a', 'b'] + b = ['c', 'd'] + f = FileList['x', 'y'] + g = FileList['w', 'z'] + + r = f + g + assert_equal ['x', 'y', 'w', 'z'], r + assert_equal FileList, r.class + + r = a + g + assert_equal ['a', 'b', 'w', 'z'], r + assert_equal Array, r.class + + r = f + b + assert_equal ['x', 'y', 'c', 'd'], r + assert_equal FileList, r.class + + r = FileList['w', 'x', 'y', 'z'] - f + assert_equal ['w', 'z'], r + assert_equal FileList, r.class + + r = FileList['w', 'x', 'y', 'z'] & f + assert_equal ['x', 'y'], r + assert_equal FileList, r.class + + r = f * 2 + assert_equal ['x', 'y', 'x', 'y'], r + assert_equal FileList, r.class + + r = f * ',' + assert_equal 'x,y', r + assert_equal String, r.class + + r = f | ['a', 'x'] + assert_equal ['a', 'x', 'y'].sort, r.sort + assert_equal FileList, r.class + end + + def test_other_array_returning_methods + f = FileList['a', nil, 'b'] + r = f.compact + assert_equal ['a', 'b'], r + assert_equal FileList, r.class + + f = FileList['a', 'b'] + r = f.concat(['x', 'y']) + assert_equal ['a', 'b', 'x', 'y'], r + assert_equal FileList, r.class + + f = FileList['a', ['b', 'c'], FileList['d', 'e']] + r = f.flatten + assert_equal ['a', 'b', 'c', 'd', 'e'], r + assert_equal FileList, r.class + + f = FileList['a', 'b', 'a'] + r = f.uniq + assert_equal ['a', 'b'], r + assert_equal FileList, r.class + + f = FileList['a', 'b', 'c', 'd'] + r = f.values_at(1,3) + assert_equal ['b', 'd'], r + assert_equal FileList, r.class + end + + def test_file_utils_can_use_filelists + cfiles = FileList['testdata/*.c'] + + cp cfiles, @cdir, :verbose => false + + assert File.exist?(File.join(@cdir, 'abc.c')) + assert File.exist?(File.join(@cdir, 'xyz.c')) + assert File.exist?(File.join(@cdir, 'x.c')) + end + + def create_test_data + verbose(false) do + + mkdir "testdata" unless File.exist? "testdata" + mkdir "testdata/CVS" rescue nil + mkdir "testdata/.svn" rescue nil + @cdir = "testdata/cfiles" + mkdir @cdir rescue nil + touch "testdata/.dummy" + touch "testdata/x.bak" + touch "testdata/x~" + touch "testdata/core" + touch "testdata/x.c" + touch "testdata/xyz.c" + touch "testdata/abc.c" + touch "testdata/abc.h" + touch "testdata/abc.x" + touch "testdata/existing" + end + end + +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_fileutils.rb b/vendor/gems/gems/rake-0.8.3/test/test_fileutils.rb new file mode 100644 index 0000000..c2ac257 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_fileutils.rb @@ -0,0 +1,250 @@ +#!/usr/bin/env ruby + +require 'rake' +require 'test/unit' +require 'test/filecreation' +require 'fileutils' +require 'stringio' + +class TestFileUtils < Test::Unit::TestCase + include FileCreation + + def setup + File.chmod(0750,"test/shellcommand.rb") + end + + def teardown + FileUtils.rm_rf("testdata") + FileUtils::LN_SUPPORTED[0] = true + end + + def test_rm_one_file + create_file("testdata/a") + FileUtils.rm_rf "testdata/a" + assert ! File.exist?("testdata/a") + end + + def test_rm_two_files + create_file("testdata/a") + create_file("testdata/b") + FileUtils.rm_rf ["testdata/a", "testdata/b"] + assert ! File.exist?("testdata/a") + assert ! File.exist?("testdata/b") + end + + def test_rm_filelist + list = Rake::FileList.new << "testdata/a" << "testdata/b" + list.each { |fn| create_file(fn) } + FileUtils.rm_r list + assert ! File.exist?("testdata/a") + assert ! File.exist?("testdata/b") + end + + def test_ln + create_dir("testdata") + open("testdata/a", "w") { |f| f.puts "TEST_LN" } + RakeFileUtils.safe_ln("testdata/a", "testdata/b", :verbose => false) + assert_equal "TEST_LN\n", open("testdata/b") { |f| f.read } + end + + class BadLink + include RakeFileUtils + attr_reader :cp_args + def initialize(klass) + @failure_class = klass + end + def cp(*args) + @cp_args = args + end + def ln(*args) + fail @failure_class, "ln not supported" + end + public :safe_ln + end + + def test_safe_ln_failover_to_cp_on_standard_error + FileUtils::LN_SUPPORTED[0] = true + c = BadLink.new(StandardError) + c.safe_ln "a", "b" + assert_equal ['a', 'b'], c.cp_args + c.safe_ln "x", "y" + assert_equal ['x', 'y'], c.cp_args + end + + def test_safe_ln_failover_to_cp_on_not_implemented_error + FileUtils::LN_SUPPORTED[0] = true + c = BadLink.new(NotImplementedError) + c.safe_ln "a", "b" + assert_equal ['a', 'b'], c.cp_args + end + + def test_safe_ln_fails_on_script_error + FileUtils::LN_SUPPORTED[0] = true + c = BadLink.new(ScriptError) + assert_raise(ScriptError) do c.safe_ln "a", "b" end + end + + def test_verbose + verbose true + assert_equal true, verbose + verbose false + assert_equal false, verbose + verbose(true) { + assert_equal true, verbose + } + assert_equal false, verbose + end + + def test_nowrite + nowrite true + assert_equal true, nowrite + nowrite false + assert_equal false, nowrite + nowrite(true){ + assert_equal true, nowrite + } + assert_equal false, nowrite + end + + def test_file_utils_methods_are_available_at_top_level + create_file("testdata/a") + rm_rf "testdata/a" + assert ! File.exist?("testdata/a") + end + + def test_fileutils_methods_dont_leak + obj = Object.new + assert_raise(NoMethodError) { obj.copy } # from FileUtils + assert_raise(NoMethodError) { obj.ruby } # from RubyFileUtils + end + + def test_sh + verbose(false) { sh %{ruby test/shellcommand.rb} } + assert true, "should not fail" + end + + def test_sh_multiple_arguments + ENV['RAKE_TEST_SH'] = 'someval' + expanded = windows? ? '%RAKE_TEST_SH%' : '$RAKE_TEST_SH' + # This one gets expanded by the shell + verbose(false) { sh %{ruby test/check_expansion.rb #{expanded} someval} } + assert true, "should not fail" + assert_raises(RuntimeError) { + # This one does not get expanded + verbose(false) { sh 'ruby', 'test/check_expansion.rb', expanded, 'someval' } + } + end + + def test_sh_failure + assert_raises(RuntimeError) { + verbose(false) { sh %{ruby test/shellcommand.rb 1} } + } + end + + def test_sh_special_handling + count = 0 + verbose(false) { + sh(%{ruby test/shellcommand.rb}) do |ok, res| + assert(ok) + assert_equal 0, res.exitstatus + count += 1 + end + sh(%{ruby test/shellcommand.rb 1}) do |ok, res| + assert(!ok) + assert_equal 1, res.exitstatus + count += 1 + end + } + assert_equal 2, count, "Block count should be 2" + end + + def test_sh_noop + verbose(false) { sh %{test/shellcommand.rb 1}, :noop=>true } + assert true, "should not fail" + end + + def test_sh_bad_option + ex = assert_raise(ArgumentError) { + verbose(false) { sh %{test/shellcommand.rb}, :bad_option=>true } + } + assert_match(/bad_option/, ex.message) + end + + def test_sh_verbose + out = redirect_stderr { + verbose(true) { + sh %{test/shellcommand.rb}, :noop=>true + } + } + assert_match(/^test\/shellcommand\.rb$/, out) + end + + def test_sh_no_verbose + out = redirect_stderr { + verbose(false) { + sh %{test/shellcommand.rb}, :noop=>true + } + } + assert_equal '', out + end + + def test_sh_default_is_no_verbose + out = redirect_stderr { + sh %{test/shellcommand.rb}, :noop=>true + } + assert_equal '', out + end + + def test_ruby + verbose(false) do + ENV['RAKE_TEST_RUBY'] = "123" + block_run = false + # This one gets expanded by the shell + env_var = windows? ? '%RAKE_TEST_RUBY%' : '$RAKE_TEST_RUBY' + ruby %{-e "exit #{env_var}"} do |ok, status| # " (emacs wart) + assert(!ok) + assert_equal 123, status.exitstatus + block_run = true + end + assert block_run, "The block must be run" + + if windows? + puts "SKIPPING test_ruby/part 2 when in windows" + else + # This one does not get expanded + block_run = false + ruby '-e', %{exit "#{env_var}".length} do |ok, status| # " (emacs wart) + assert(!ok) + assert_equal 15, status.exitstatus + block_run = true + end + assert block_run, "The block must be run" + end + end + end + + def test_split_all + assert_equal ['a'], RakeFileUtils.split_all('a') + assert_equal ['..'], RakeFileUtils.split_all('..') + assert_equal ['/'], RakeFileUtils.split_all('/') + assert_equal ['a', 'b'], RakeFileUtils.split_all('a/b') + assert_equal ['/', 'a', 'b'], RakeFileUtils.split_all('/a/b') + assert_equal ['..', 'a', 'b'], RakeFileUtils.split_all('../a/b') + end + + private + + def redirect_stderr + old_err = $stderr + $stderr = StringIO.new + yield + $stderr.string + ensure + $stderr = old_err + end + + def windows? + ! File::ALT_SEPARATOR.nil? + end + +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_ftp.rb b/vendor/gems/gems/rake-0.8.3/test/test_ftp.rb new file mode 100644 index 0000000..1576590 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_ftp.rb @@ -0,0 +1,59 @@ +#!/usr/bin/env ruby + +require 'date' +require 'time' +require 'test/unit' +require 'rake/contrib/ftptools' + +class FakeDate + def self.today + Date.new(2003,10,3) + end + def self.now + Time.local(2003,10,3,12,00,00) + end +end + + +class TestFtpFile < Test::Unit::TestCase + + def setup + Rake::FtpFile.class_eval { @date_class = FakeDate; @time_class = FakeDate } + end + + def test_general + file = Rake::FtpFile.new("here", "-rw-r--r-- 1 a279376 develop 121770 Mar 6 14:50 wiki.pl") + assert_equal "wiki.pl", file.name + assert_equal "here/wiki.pl", file.path + assert_equal "a279376", file.owner + assert_equal "develop", file.group + assert_equal 0644, file.mode + assert_equal 121770, file.size + assert_equal Time.mktime(2003,3,6,14,50,0,0), file.time + assert ! file.directory? + assert ! file.symlink? + end + + def test_far_date + file = Rake::FtpFile.new(".", "drwxr-xr-x 3 a279376 develop 4096 Nov 26 2001 vss") + assert_equal Time.mktime(2001,11,26,0,0,0,0), file.time + end + + def test_close_date + file = Rake::FtpFile.new(".", "drwxr-xr-x 3 a279376 develop 4096 Nov 26 15:35 vss") + assert_equal Time.mktime(2002,11,26,15,35,0,0), file.time + end + + def test_directory + file = Rake::FtpFile.new(".", "drwxrwxr-x 9 a279376 develop 4096 Mar 13 14:32 working") + assert file.directory? + assert !file.symlink? + end + + def test_symlink + file = Rake::FtpFile.new(".", "lrwxrwxrwx 1 a279376 develop 64 Mar 26 2002 xtrac -> /home/a279376/working/ics/development/java/com/fmr/fwp/ics/xtrac") + assert_equal 'xtrac', file.name + assert file.symlink? + assert !file.directory? + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_invocation_chain.rb b/vendor/gems/gems/rake-0.8.3/test/test_invocation_chain.rb new file mode 100644 index 0000000..0558066 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_invocation_chain.rb @@ -0,0 +1,75 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'rake' + +###################################################################### +class TestAnEmptyInvocationChain < Test::Unit::TestCase + + def setup + @empty = Rake::InvocationChain::EMPTY + end + + def test_should_be_able_to_add_members + assert_nothing_raised do + @empty.append("A") + end + end + + def test_to_s + assert_equal "TOP", @empty.to_s + end +end + +###################################################################### +class TestAnInvocationChainWithOneMember < Test::Unit::TestCase + def setup + @empty = Rake::InvocationChain::EMPTY + @first_member = "A" + @chain = @empty.append(@first_member) + end + + def test_should_report_first_member_as_a_member + assert @chain.member?(@first_member) + end + + def test_should_fail_when_adding_original_member + ex = assert_raise RuntimeError do + @chain.append(@first_member) + end + assert_match(/circular +dependency/i, ex.message) + assert_match(/A.*=>.*A/, ex.message) + end + + def test_to_s + assert_equal "TOP => A", @chain.to_s + end + +end + +###################################################################### +class TestAnInvocationChainWithMultipleMember < Test::Unit::TestCase + def setup + @first_member = "A" + @second_member = "B" + ch = Rake::InvocationChain::EMPTY.append(@first_member) + @chain = ch.append(@second_member) + end + + def test_should_report_first_member_as_a_member + assert @chain.member?(@first_member) + end + + def test_should_report_second_member_as_a_member + assert @chain.member?(@second_member) + end + + def test_should_fail_when_adding_original_member + ex = assert_raise RuntimeError do + @chain.append(@first_member) + end + assert_match(/A.*=>.*B.*=>.*A/, ex.message) + end +end + + diff --git a/vendor/gems/gems/rake-0.8.3/test/test_makefile_loader.rb b/vendor/gems/gems/rake-0.8.3/test/test_makefile_loader.rb new file mode 100644 index 0000000..25e2ee3 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_makefile_loader.rb @@ -0,0 +1,25 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'rake' +require 'rake/loaders/makefile' + +class TestMakefileLoader < Test::Unit::TestCase + include Rake + + def test_parse + Task.clear + loader = Rake::MakefileLoader.new + loader.load("test/data/sample.mf") + %w(a b c d).each do |t| + assert Task.task_defined?(t), "#{t} should be a defined task" + end + assert_equal %w(a1 a2 a3 a4 a5 a6 a7).sort, Task['a'].prerequisites.sort + assert_equal %w(b1 b2 b3 b4 b5 b6 b7).sort, Task['b'].prerequisites.sort + assert_equal %w(c1).sort, Task['c'].prerequisites.sort + assert_equal %w(d1 d2).sort, Task['d'].prerequisites.sort + assert_equal %w(e1 f1).sort, Task['e'].prerequisites.sort + assert_equal %w(e1 f1).sort, Task['f'].prerequisites.sort + assert_equal 6, Task.tasks.size + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_multitask.rb b/vendor/gems/gems/rake-0.8.3/test/test_multitask.rb new file mode 100644 index 0000000..ee9be77 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_multitask.rb @@ -0,0 +1,45 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'rake' + +###################################################################### +class TestMultiTask < Test::Unit::TestCase + include Rake + + def setup + Task.clear + @runs = Array.new + end + + def test_running_multitasks + task :a do 3.times do |i| @runs << "A#{i}"; sleep 0.01; end end + task :b do 3.times do |i| @runs << "B#{i}"; sleep 0.01; end end + multitask :both => [:a, :b] + Task[:both].invoke + assert_equal 6, @runs.size + assert @runs.index("A0") < @runs.index("A1") + assert @runs.index("A1") < @runs.index("A2") + assert @runs.index("B0") < @runs.index("B1") + assert @runs.index("B1") < @runs.index("B2") + end + + def test_all_multitasks_wait_on_slow_prerequisites + task :slow do 3.times do |i| @runs << "S#{i}"; sleep 0.05 end end + task :a => [:slow] do 3.times do |i| @runs << "A#{i}"; sleep 0.01 end end + task :b => [:slow] do 3.times do |i| @runs << "B#{i}"; sleep 0.01 end end + multitask :both => [:a, :b] + Task[:both].invoke + assert_equal 9, @runs.size + assert @runs.index("S0") < @runs.index("S1") + assert @runs.index("S1") < @runs.index("S2") + assert @runs.index("S2") < @runs.index("A0") + assert @runs.index("S2") < @runs.index("B0") + assert @runs.index("A0") < @runs.index("A1") + assert @runs.index("A1") < @runs.index("A2") + assert @runs.index("B0") < @runs.index("B1") + assert @runs.index("B1") < @runs.index("B2") + end +end + + diff --git a/vendor/gems/gems/rake-0.8.3/test/test_namespace.rb b/vendor/gems/gems/rake-0.8.3/test/test_namespace.rb new file mode 100644 index 0000000..4ad0295 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_namespace.rb @@ -0,0 +1,36 @@ +#!/usr/bin/env ruby + +begin + require 'rubygems' +rescue LoadError + # got no gems +end + +require 'test/unit' +require 'flexmock/test_unit' +require 'rake' + +class TestNameSpace < Test::Unit::TestCase + + def test_namespace_creation + mgr = flexmock("TaskManager") + ns = Rake::NameSpace.new(mgr, []) + assert_not_nil ns + end + + def test_namespace_lookup + mgr = flexmock("TaskManager") + mgr.should_receive(:lookup).with(:t, ["a"]). + and_return(:dummy).once + ns = Rake::NameSpace.new(mgr, ["a"]) + assert_equal :dummy, ns[:t] + end + + def test_namespace_reports_tasks_it_owns + mgr = flexmock("TaskManager") + mgr.should_receive(:tasks).with(). + and_return([:x, :y, :z]).once + ns = Rake::NameSpace.new(mgr, ["a"]) + assert_equal [:x, :y, :z], ns.tasks + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_package_task.rb b/vendor/gems/gems/rake-0.8.3/test/test_package_task.rb new file mode 100644 index 0000000..72aac5f --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_package_task.rb @@ -0,0 +1,116 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'rake/packagetask' + +class TestPackageTask < Test::Unit::TestCase + include Rake + + def test_create + pkg = Rake::PackageTask.new("pkgr", "1.2.3") { |p| + p.package_files << "install.rb" + p.package_files.include( + '[A-Z]*', + 'bin/**/*', + 'lib/**/*.rb', + 'test/**/*.rb', + 'doc/**/*', + 'build/rubyapp.rb', + '*.blurb') + p.package_files.exclude(/\bCVS\b/) + p.package_files.exclude(/~$/) + p.package_dir = 'pkg' + p.need_tar = true + p.need_tar_gz = true + p.need_tar_bz2 = true + p.need_zip = true + } + assert_equal "pkg", pkg.package_dir + assert pkg.package_files.include?("bin/rake") + assert "pkgr", pkg.name + assert "1.2.3", pkg.version + assert Task[:package] + assert Task['pkg/pkgr-1.2.3.tgz'] + assert Task['pkg/pkgr-1.2.3.tar.gz'] + assert Task['pkg/pkgr-1.2.3.tar.bz2'] + assert Task['pkg/pkgr-1.2.3.zip'] + assert Task["pkg/pkgr-1.2.3"] + assert Task[:clobber_package] + assert Task[:repackage] + end + + def test_missing_version + assert_raises(RuntimeError) { + pkg = Rake::PackageTask.new("pkgr") { |p| } + } + end + + def test_no_version + pkg = Rake::PackageTask.new("pkgr", :noversion) { |p| } + assert "pkgr", pkg.send(:package_name) + end + + def test_clone + pkg = Rake::PackageTask.new("x", :noversion) + p2 = pkg.clone + pkg.package_files << "y" + p2.package_files << "x" + assert_equal ["y"], pkg.package_files + assert_equal ["x"], p2.package_files + end +end + + +begin + require 'rubygems' + require 'rake/gempackagetask' +rescue Exception + puts "WARNING: RubyGems not installed" +end + +if ! defined?(Gem) + puts "WARNING: Unable to test GemPackaging ... requires RubyGems" +else + class TestGemPackageTask < Test::Unit::TestCase + def test_gem_package + gem = Gem::Specification.new do |g| + g.name = "pkgr" + g.version = "1.2.3" + g.files = FileList["x"].resolve + end + pkg = Rake::GemPackageTask.new(gem) do |p| + p.package_files << "y" + end + assert_equal ["x", "y"], pkg.package_files + assert_equal "pkgr-1.2.3.gem", pkg.gem_file + end + + def test_gem_package_with_current_platform + gem = Gem::Specification.new do |g| + g.name = "pkgr" + g.version = "1.2.3" + g.files = FileList["x"].resolve + g.platform = Gem::Platform::CURRENT + end + pkg = Rake::GemPackageTask.new(gem) do |p| + p.package_files << "y" + end + assert_equal ["x", "y"], pkg.package_files + assert_match(/^pkgr-1\.2\.3-(\S+)\.gem$/, pkg.gem_file) + end + + def test_gem_package_with_ruby_platform + gem = Gem::Specification.new do |g| + g.name = "pkgr" + g.version = "1.2.3" + g.files = FileList["x"].resolve + g.platform = Gem::Platform::RUBY + end + pkg = Rake::GemPackageTask.new(gem) do |p| + p.package_files << "y" + end + assert_equal ["x", "y"], pkg.package_files + assert_equal "pkgr-1.2.3.gem", pkg.gem_file + end + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_pathmap.rb b/vendor/gems/gems/rake-0.8.3/test/test_pathmap.rb new file mode 100644 index 0000000..2231150 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_pathmap.rb @@ -0,0 +1,209 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'rake' + +# ==================================================================== +class TestPathMap < Test::Unit::TestCase + + def test_returns_self_with_no_args + assert_equal "abc.rb", "abc.rb".pathmap + end + + def test_s_returns_file_separator + sep = File::ALT_SEPARATOR || File::SEPARATOR + assert_equal sep, "abc.rb".pathmap("%s") + assert_equal sep, "".pathmap("%s") + assert_equal "a#{sep}b", "a/b".pathmap("%d%s%f") + end + + def test_f_returns_basename + assert_equal "abc.rb", "abc.rb".pathmap("%f") + assert_equal "abc.rb", "this/is/a/dir/abc.rb".pathmap("%f") + assert_equal "abc.rb", "/this/is/a/dir/abc.rb".pathmap("%f") + end + + def test_n_returns_basename_without_extension + assert_equal "abc", "abc.rb".pathmap("%n") + assert_equal "abc", "abc".pathmap("%n") + assert_equal "abc", "this/is/a/dir/abc.rb".pathmap("%n") + assert_equal "abc", "/this/is/a/dir/abc.rb".pathmap("%n") + assert_equal "abc", "/this/is/a/dir/abc".pathmap("%n") + end + + def test_d_returns_dirname + assert_equal ".", "abc.rb".pathmap("%d") + assert_equal "/", "/abc".pathmap("%d") + assert_equal "this/is/a/dir", "this/is/a/dir/abc.rb".pathmap("%d") + assert_equal "/this/is/a/dir", "/this/is/a/dir/abc.rb".pathmap("%d") + end + + def test_9d_returns_partial_dirname + assert_equal "this/is", "this/is/a/dir/abc.rb".pathmap("%2d") + assert_equal "this", "this/is/a/dir/abc.rb".pathmap("%1d") + assert_equal ".", "this/is/a/dir/abc.rb".pathmap("%0d") + assert_equal "dir", "this/is/a/dir/abc.rb".pathmap("%-1d") + assert_equal "a/dir", "this/is/a/dir/abc.rb".pathmap("%-2d") + assert_equal "this/is/a/dir", "this/is/a/dir/abc.rb".pathmap("%100d") + assert_equal "this/is/a/dir", "this/is/a/dir/abc.rb".pathmap("%-100d") + end + + def test_x_returns_extension + assert_equal "", "abc".pathmap("%x") + assert_equal ".rb", "abc.rb".pathmap("%x") + assert_equal ".rb", "abc.xyz.rb".pathmap("%x") + assert_equal "", ".depends".pathmap("%x") + assert_equal "", "dir/.depends".pathmap("%x") + end + + def test_X_returns_everything_but_extension + assert_equal "abc", "abc".pathmap("%X") + assert_equal "abc", "abc.rb".pathmap("%X") + assert_equal "abc.xyz", "abc.xyz.rb".pathmap("%X") + assert_equal "ab.xyz", "ab.xyz.rb".pathmap("%X") + assert_equal "a.xyz", "a.xyz.rb".pathmap("%X") + assert_equal "abc", "abc.rb".pathmap("%X") + assert_equal "ab", "ab.rb".pathmap("%X") + assert_equal "a", "a.rb".pathmap("%X") + assert_equal ".depends", ".depends".pathmap("%X") + assert_equal "a/dir/.depends", "a/dir/.depends".pathmap("%X") + assert_equal "/.depends", "/.depends".pathmap("%X") + end + + def test_p_returns_entire_pathname + assert_equal "abc.rb", "abc.rb".pathmap("%p") + assert_equal "this/is/a/dir/abc.rb", "this/is/a/dir/abc.rb".pathmap("%p") + assert_equal "/this/is/a/dir/abc.rb", "/this/is/a/dir/abc.rb".pathmap("%p") + end + + def test_dash_returns_empty_string + assert_equal "", "abc.rb".pathmap("%-") + assert_equal "abc.rb", "abc.rb".pathmap("%X%-%x") + end + + def test_percent_percent_returns_percent + assert_equal "a%b", "".pathmap("a%%b") + end + + def test_undefined_percent_causes_error + ex = assert_raise(ArgumentError) { + "dir/abc.rb".pathmap("%z") + } + end + + def test_pattern_returns_substitutions + assert_equal "bin/org/osb", + "src/org/osb/Xyz.java".pathmap("%{src,bin}d") + end + + def test_pattern_can_use_backreferences + assert_equal "dir/hi/is", "dir/this/is".pathmap("%{t(hi)s,\\1}p") + end + + def test_pattern_with_star_replacement_string_uses_block + assert_equal "src/ORG/osb", + "src/org/osb/Xyz.java".pathmap("%{/org,*}d") { |d| d.upcase } + assert_equal "Xyz.java", + "src/org/osb/Xyz.java".pathmap("%{.*,*}f") { |f| f.capitalize } + end + + def test_pattern_with_no_replacement_nor_block_substitutes_empty_string + assert_equal "bc.rb", "abc.rb".pathmap("%{a}f") + end + + def test_pattern_works_with_certain_valid_operators + assert_equal "dir/xbc.rb", "dir/abc.rb".pathmap("%{a,x}p") + assert_equal "d1r", "dir/abc.rb".pathmap("%{i,1}d") + assert_equal "xbc.rb", "dir/abc.rb".pathmap("%{a,x}f") + assert_equal ".Rb", "dir/abc.rb".pathmap("%{r,R}x") + assert_equal "xbc", "dir/abc.rb".pathmap("%{a,x}n") + end + + def test_multiple_patterns + assert_equal "this/is/b/directory/abc.rb", + "this/is/a/dir/abc.rb".pathmap("%{a,b;dir,\\0ectory}p") + end + + def test_partial_directory_selection_works_with_patterns + assert_equal "this/is/a/long", + "this/is/a/really/long/path/ok.rb".pathmap("%{/really/,/}5d") + end + + def test_pattern_with_invalid_operator + ex = assert_raise(ArgumentError) do + "abc.xyz".pathmap("%{src,bin}z") + end + assert_match(/unknown.*pathmap.*spec.*z/i, ex.message) + end + + def test_works_with_windows_separators + if File::ALT_SEPARATOR + assert_equal "abc", 'dir\abc.rb'.pathmap("%n") + assert_equal 'this\is\a\dir', + 'this\is\a\dir\abc.rb'.pathmap("%d") + end + end + + def test_complex_patterns + sep = "".pathmap("%s") + assert_equal "dir/abc.rb", "dir/abc.rb".pathmap("%d/%n%x") + assert_equal "./abc.rb", "abc.rb".pathmap("%d/%n%x") + assert_equal "Your file extension is '.rb'", + "dir/abc.rb".pathmap("Your file extension is '%x'") + assert_equal "bin/org/onstepback/proj/A.class", + "src/org/onstepback/proj/A.java".pathmap("%{src,bin}d/%n.class") + assert_equal "src_work/bin/org/onstepback/proj/A.class", + "src_work/src/org/onstepback/proj/A.java".pathmap('%{\bsrc\b,bin}X.class') + assert_equal ".depends.bak", ".depends".pathmap("%X.bak") + assert_equal "d#{sep}a/b/c#{sep}file.txt", "a/b/c/d/file.txt".pathmap("%-1d%s%3d%s%f") + end +end + +class TestPathMapExplode < Test::Unit::TestCase + def setup + String.class_eval { public :pathmap_explode } + end + + def teardown + String.class_eval { protected :pathmap_explode } + end + + def test_explode + assert_equal ['a'], 'a'.pathmap_explode + assert_equal ['a', 'b'], 'a/b'.pathmap_explode + assert_equal ['a', 'b', 'c'], 'a/b/c'.pathmap_explode + assert_equal ['/', 'a'], '/a'.pathmap_explode + assert_equal ['/', 'a', 'b'], '/a/b'.pathmap_explode + assert_equal ['/', 'a', 'b', 'c'], '/a/b/c'.pathmap_explode + if File::ALT_SEPARATOR + assert_equal ['c:.', 'a'], 'c:a'.pathmap_explode + assert_equal ['c:.', 'a', 'b'], 'c:a/b'.pathmap_explode + assert_equal ['c:.', 'a', 'b', 'c'], 'c:a/b/c'.pathmap_explode + assert_equal ['c:/', 'a'], 'c:/a'.pathmap_explode + assert_equal ['c:/', 'a', 'b'], 'c:/a/b'.pathmap_explode + assert_equal ['c:/', 'a', 'b', 'c'], 'c:/a/b/c'.pathmap_explode + end + end +end + +class TestPathMapPartial < Test::Unit::TestCase + def test_pathmap_partial + @path = "1/2/file" + def @path.call(n) + pathmap_partial(n) + end + assert_equal("1", @path.call(1)) + assert_equal("1/2", @path.call(2)) + assert_equal("1/2", @path.call(3)) + assert_equal(".", @path.call(0)) + assert_equal("2", @path.call(-1)) + assert_equal("1/2", @path.call(-2)) + assert_equal("1/2", @path.call(-3)) + end +end + +class TestFileListPathMap < Test::Unit::TestCase + def test_file_list_supports_pathmap + assert_equal ['a', 'b'], FileList['dir/a.rb', 'dir/b.rb'].pathmap("%n") + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_rake.rb b/vendor/gems/gems/rake-0.8.3/test/test_rake.rb new file mode 100644 index 0000000..c995965 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_rake.rb @@ -0,0 +1,41 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'rake' + +class TestRake < Test::Unit::TestCase + def test_each_dir_parent + assert_equal ['a'], alldirs('a') + assert_equal ['a/b', 'a'], alldirs('a/b') + assert_equal ['/a/b', '/a', '/'], alldirs('/a/b') + if File.dirname("c:/foo") == "c:" + # Under Unix + assert_equal ['c:/a/b', 'c:/a', 'c:'], alldirs('c:/a/b') + assert_equal ['c:a/b', 'c:a'], alldirs('c:a/b') + else + # Under Windows + assert_equal ['c:/a/b', 'c:/a', 'c:/'], alldirs('c:/a/b') + assert_equal ['c:a/b', 'c:a'], alldirs('c:a/b') + end + end + + def alldirs(fn) + result = [] + Rake.each_dir_parent(fn) { |d| result << d } + result + end + + def test_can_override_application + old_app = Rake.application + fake_app = Object.new + Rake.application = fake_app + assert_equal fake_app, Rake.application + ensure + Rake.application = old_app + end + + def test_original_dir_reports_current_dir + assert_equal Dir.pwd, Rake.original_dir + end + +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_require.rb b/vendor/gems/gems/rake-0.8.3/test/test_require.rb new file mode 100644 index 0000000..1931b91 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_require.rb @@ -0,0 +1,33 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'rake' + +# ==================================================================== +class TestRequire < Test::Unit::TestCase + + def test_can_load_rake_library + app = Rake::Application.new + assert app.instance_eval { + rake_require("test2", ['test/data/rakelib'], []) + } + end + + def test_wont_reload_rake_library + app = Rake::Application.new + assert ! app.instance_eval { + rake_require("test2", ['test/data/rakelib'], ['test2']) + } + end + + def test_throws_error_if_library_not_found + app = Rake::Application.new + ex = assert_raise(LoadError) { + assert app.instance_eval { + rake_require("testx", ['test/data/rakelib'], []) + } + } + assert_match(/x/, ex.message) + end +end + diff --git a/vendor/gems/gems/rake-0.8.3/test/test_rules.rb b/vendor/gems/gems/rake-0.8.3/test/test_rules.rb new file mode 100644 index 0000000..5ce8e5c --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_rules.rb @@ -0,0 +1,347 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'fileutils' +require 'rake' +require 'test/filecreation' + +###################################################################### +class TestRules < Test::Unit::TestCase + include Rake + include FileCreation + + SRCFILE = "testdata/abc.c" + SRCFILE2 = "testdata/xyz.c" + FTNFILE = "testdata/abc.f" + OBJFILE = "testdata/abc.o" + FOOFILE = "testdata/foo" + DOTFOOFILE = "testdata/.foo" + + def setup + Task.clear + @runs = [] + end + + def teardown + FileList['testdata/*'].each do |f| rm_r(f, :verbose=>false) end + end + + def test_multiple_rules1 + create_file(FTNFILE) + delete_file(SRCFILE) + delete_file(OBJFILE) + rule(/\.o$/ => ['.c']) do @runs << :C end + rule(/\.o$/ => ['.f']) do @runs << :F end + t = Task[OBJFILE] + t.invoke + Task[OBJFILE].invoke + assert_equal [:F], @runs + end + + def test_multiple_rules2 + create_file(FTNFILE) + delete_file(SRCFILE) + delete_file(OBJFILE) + rule(/\.o$/ => ['.f']) do @runs << :F end + rule(/\.o$/ => ['.c']) do @runs << :C end + Task[OBJFILE].invoke + assert_equal [:F], @runs + end + + def test_create_with_source + create_file(SRCFILE) + rule(/\.o$/ => ['.c']) do |t| + @runs << t.name + assert_equal OBJFILE, t.name + assert_equal SRCFILE, t.source + end + Task[OBJFILE].invoke + assert_equal [OBJFILE], @runs + end + + def test_single_dependent + create_file(SRCFILE) + rule(/\.o$/ => '.c') do |t| + @runs << t.name + end + Task[OBJFILE].invoke + assert_equal [OBJFILE], @runs + end + + def test_rule_can_be_created_by_string + create_file(SRCFILE) + rule '.o' => ['.c'] do |t| + @runs << t.name + end + Task[OBJFILE].invoke + assert_equal [OBJFILE], @runs + end + + def test_rule_prereqs_can_be_created_by_string + create_file(SRCFILE) + rule '.o' => '.c' do |t| + @runs << t.name + end + Task[OBJFILE].invoke + assert_equal [OBJFILE], @runs + end + + def test_plain_strings_as_dependents_refer_to_files + create_file(SRCFILE) + rule '.o' => SRCFILE do |t| + @runs << t.name + end + Task[OBJFILE].invoke + assert_equal [OBJFILE], @runs + end + + def test_file_names_beginning_with_dot_can_be_tricked_into_refering_to_file + verbose(false) do + chdir("testdata") do + create_file('.foo') + rule '.o' => "./.foo" do |t| + @runs << t.name + end + Task[OBJFILE].invoke + assert_equal [OBJFILE], @runs + end + end + end + + def test_file_names_beginning_with_dot_can_be_wrapped_in_lambda + verbose(false) do + chdir("testdata") do + create_file(".foo") + rule '.o' => lambda{".foo"} do |t| + @runs << "#{t.name} - #{t.source}" + end + Task[OBJFILE].invoke + assert_equal ["#{OBJFILE} - .foo"], @runs + end + end + end + + def test_file_names_containing_percent_can_be_wrapped_in_lambda + verbose(false) do + chdir("testdata") do + create_file("foo%x") + rule '.o' => lambda{"foo%x"} do |t| + @runs << "#{t.name} - #{t.source}" + end + Task[OBJFILE].invoke + assert_equal ["#{OBJFILE} - foo%x"], @runs + end + end + end + + def test_non_extension_rule_name_refers_to_file + verbose(false) do + chdir("testdata") do + create_file("abc.c") + rule "abc" => '.c' do |t| + @runs << t.name + end + Task["abc"].invoke + assert_equal ["abc"], @runs + end + end + end + + def test_pathmap_automatically_applies_to_name + verbose(false) do + chdir("testdata") do + create_file("zzabc.c") + rule ".o" => 'zz%{x,a}n.c' do |t| + @runs << "#{t.name} - #{t.source}" + end + Task["xbc.o"].invoke + assert_equal ["xbc.o - zzabc.c"], @runs + end + end + end + + def test_plain_strings_are_just_filenames + verbose(false) do + chdir("testdata") do + create_file("plainname") + rule ".o" => 'plainname' do |t| + @runs << "#{t.name} - #{t.source}" + end + Task["xbc.o"].invoke + assert_equal ["xbc.o - plainname"], @runs + end + end + end + + def test_rule_runs_when_explicit_task_has_no_actions + create_file(SRCFILE) + create_file(SRCFILE2) + delete_file(OBJFILE) + rule '.o' => '.c' do |t| + @runs << t.source + end + file OBJFILE => [SRCFILE2] + Task[OBJFILE].invoke + assert_equal [SRCFILE], @runs + end + + def test_close_matches_on_name_do_not_trigger_rule + create_file("testdata/x.c") + rule '.o' => ['.c'] do |t| + @runs << t.name + end + assert_raises(RuntimeError) { Task['testdata/x.obj'].invoke } + assert_raises(RuntimeError) { Task['testdata/x.xyo'].invoke } + end + + def test_rule_rebuilds_obj_when_source_is_newer + create_timed_files(OBJFILE, SRCFILE) + rule(/\.o$/ => ['.c']) do + @runs << :RULE + end + Task[OBJFILE].invoke + assert_equal [:RULE], @runs + end + + def test_rule_with_two_sources_runs_if_both_sources_are_present + create_timed_files(OBJFILE, SRCFILE, SRCFILE2) + rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do + @runs << :RULE + end + Task[OBJFILE].invoke + assert_equal [:RULE], @runs + end + + def test_rule_with_two_sources_but_one_missing_does_not_run + create_timed_files(OBJFILE, SRCFILE) + delete_file(SRCFILE2) + rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do + @runs << :RULE + end + Task[OBJFILE].invoke + assert_equal [], @runs + end + + def test_rule_with_two_sources_builds_both_sources + task 'x.aa' + task 'x.bb' + rule '.a' => '.aa' do + @runs << "A" + end + rule '.b' => '.bb' do + @runs << "B" + end + rule ".c" => ['.a', '.b'] do + @runs << "C" + end + Task["x.c"].invoke + assert_equal ["A", "B", "C"], @runs.sort + end + + def test_second_rule_runs_when_first_rule_doesnt + create_timed_files(OBJFILE, SRCFILE) + delete_file(SRCFILE2) + rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do + @runs << :RULE1 + end + rule OBJFILE => [lambda{SRCFILE}] do + @runs << :RULE2 + end + Task[OBJFILE].invoke + assert_equal [:RULE2], @runs + end + + def test_second_rule_doest_run_if_first_triggers + create_timed_files(OBJFILE, SRCFILE, SRCFILE2) + rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do + @runs << :RULE1 + end + rule OBJFILE => [lambda{SRCFILE}] do + @runs << :RULE2 + end + Task[OBJFILE].invoke + assert_equal [:RULE1], @runs + end + + def test_second_rule_doest_run_if_first_triggers_with_reversed_rules + create_timed_files(OBJFILE, SRCFILE, SRCFILE2) + rule OBJFILE => [lambda{SRCFILE}] do + @runs << :RULE1 + end + rule OBJFILE => [lambda{SRCFILE}, lambda{SRCFILE2}] do + @runs << :RULE2 + end + Task[OBJFILE].invoke + assert_equal [:RULE1], @runs + end + + def test_rule_with_proc_dependent_will_trigger + ran = false + mkdir_p("testdata/src/jw") + create_file("testdata/src/jw/X.java") + rule %r(classes/.*\.class) => [ + proc { |fn| fn.pathmap("%{classes,testdata/src}d/%n.java") } + ] do |task| + assert_equal task.name, 'classes/jw/X.class' + assert_equal task.source, 'testdata/src/jw/X.java' + @runs << :RULE + end + Task['classes/jw/X.class'].invoke + assert_equal [:RULE], @runs + ensure + rm_r("testdata/src", :verbose=>false) rescue nil + end + + def test_proc_returning_lists_are_flattened_into_prereqs + ran = false + mkdir_p("testdata/flatten") + create_file("testdata/flatten/a.txt") + task 'testdata/flatten/b.data' do |t| + ran = true + touch t.name, :verbose => false + end + rule '.html' => + proc { |fn| + [ + fn.ext("txt"), + "testdata/flatten/b.data" + ] + } do |task| + end + Task['testdata/flatten/a.html'].invoke + assert ran, "Should have triggered flattened dependency" + ensure + rm_r("testdata/flatten", :verbose=>false) rescue nil + end + + def test_recursive_rules_will_work_as_long_as_they_terminate + actions = [] + create_file("testdata/abc.xml") + rule '.y' => '.xml' do actions << 'y' end + rule '.c' => '.y' do actions << 'c'end + rule '.o' => '.c' do actions << 'o'end + rule '.exe' => '.o' do actions << 'exe'end + Task["testdata/abc.exe"].invoke + assert_equal ['y', 'c', 'o', 'exe'], actions + end + + def test_recursive_rules_that_dont_terminate_will_overflow + create_file("testdata/a.a") + prev = 'a' + ('b'..'z').each do |letter| + rule ".#{letter}" => ".#{prev}" do |t| puts "#{t.name}" end + prev = letter + end + ex = assert_raises(Rake::RuleRecursionOverflowError) { + Task["testdata/a.z"].invoke + } + assert_match(/a\.z => testdata\/a.y/, ex.message) + end + + def test_rules_with_bad_dependents_will_fail + rule "a" => [ 1 ] do |t| puts t.name end + assert_raise(RuntimeError) do Task['a'].invoke end + end + +end + diff --git a/vendor/gems/gems/rake-0.8.3/test/test_task_arguments.rb b/vendor/gems/gems/rake-0.8.3/test/test_task_arguments.rb new file mode 100644 index 0000000..520a16f --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_task_arguments.rb @@ -0,0 +1,89 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'rake' + +###################################################################### +class TestTaskArguments < Test::Unit::TestCase + def teardown + ENV.delete('rev') + ENV.delete('VER') + end + + def test_empty_arg_list_is_empty + ta = Rake::TaskArguments.new([], []) + assert_equal({}, ta.to_hash) + end + + def test_multiple_values_in_args + ta = Rake::TaskArguments.new([:a, :b, :c], [:one, :two, :three]) + assert_equal({:a => :one, :b => :two, :c => :three}, ta.to_hash) + end + + def test_to_s + ta = Rake::TaskArguments.new([:a, :b, :c], [1, 2, 3]) + assert_equal ta.to_hash.inspect, ta.to_s + assert_equal ta.to_hash.inspect, ta.inspect + end + + def test_enumerable_behavior + ta = Rake::TaskArguments.new([:a, :b, :c], [1, 2 ,3]) + assert_equal [10, 20, 30], ta.collect { |k,v| v * 10 }.sort + end + + def test_named_args + ta = Rake::TaskArguments.new(["aa", "bb"], [1, 2]) + assert_equal 1, ta.aa + assert_equal 1, ta[:aa] + assert_equal 1, ta["aa"] + assert_equal 2, ta.bb + assert_nil ta.cc + end + + def test_args_knows_its_names + ta = Rake::TaskArguments.new(["aa", "bb"], [1, 2]) + assert_equal ["aa", "bb"], ta.names + end + + def test_extra_names_are_nil + ta = Rake::TaskArguments.new(["aa", "bb", "cc"], [1, 2]) + assert_nil ta.cc + end + + def test_args_can_reference_env_values + ta = Rake::TaskArguments.new(["aa"], [1]) + ENV['rev'] = "1.2" + ENV['VER'] = "2.3" + assert_equal "1.2", ta.rev + assert_equal "2.3", ta.ver + end + + def test_creating_new_argument_scopes + parent = Rake::TaskArguments.new(['p'], [1]) + child = parent.new_scope(['c', 'p']) + assert_equal({:p=>1}, child.to_hash) + assert_equal 1, child.p + assert_equal 1, child["p"] + assert_equal 1, child[:p] + assert_nil child.c + end + + def test_child_hides_parent_arg_names + parent = Rake::TaskArguments.new(['aa'], [1]) + child = Rake::TaskArguments.new(['aa'], [2], parent) + assert_equal 2, child.aa + end + + def test_default_arguments_values_can_be_merged + ta = Rake::TaskArguments.new(["aa", "bb"], [nil, "original_val"]) + ta.with_defaults({ :aa => 'default_val' }) + assert_equal 'default_val', ta[:aa] + assert_equal 'original_val', ta[:bb] + end + + def test_default_arguements_that_dont_match_names_are_ignored + ta = Rake::TaskArguments.new(["aa", "bb"], [nil, "original_val"]) + ta.with_defaults({ "cc" => "default_val" }) + assert_nil ta[:cc] + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_task_manager.rb b/vendor/gems/gems/rake-0.8.3/test/test_task_manager.rb new file mode 100644 index 0000000..07e2b7b --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_task_manager.rb @@ -0,0 +1,170 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'rake' + +class TaskManager + include Rake::TaskManager +end + +class TestTaskManager < Test::Unit::TestCase + def setup + @tm = TaskManager.new + end + + def test_create_task_manager + assert_not_nil @tm + assert_equal [], @tm.tasks + end + + def test_define_task + t = @tm.define_task(Rake::Task, :t) + assert_equal "t", t.name + assert_equal @tm, t.application + end + + def test_name_lookup + t = @tm.define_task(Rake::Task, :t) + assert_equal t, @tm[:t] + end + + def test_namespace_task_create + @tm.in_namespace("x") do + t = @tm.define_task(Rake::Task, :t) + assert_equal "x:t", t.name + end + assert_equal ["x:t"], @tm.tasks.collect { |t| t.name } + end + + def test_anonymous_namespace + anon_ns = @tm.in_namespace(nil) do + t = @tm.define_task(Rake::Task, :t) + assert_equal "_anon_1:t", t.name + end + task = anon_ns[:t] + assert_equal "_anon_1:t", task.name + end + + def test_create_filetask_in_namespace + @tm.in_namespace("x") do + t = @tm.define_task(Rake::FileTask, "fn") + assert_equal "fn", t.name + end + assert_equal ["fn"], @tm.tasks.collect { |t| t.name } + end + + def test_namespace_yields_same_namespace_as_returned + yielded_namespace = nil + returned_namespace = @tm.in_namespace("x") do |ns| + yielded_namespace = ns + end + assert_equal returned_namespace, yielded_namespace + end + + def test_name_lookup_with_implicit_file_tasks + t = @tm["README"] + assert_equal "README", t.name + assert Rake::FileTask === t + end + + def test_name_lookup_with_nonexistent_task + assert_raise(RuntimeError) { + t = @tm["DOES NOT EXIST"] + } + end + + def test_name_lookup_in_multiple_scopes + aa = nil + bb = nil + xx = @tm.define_task(Rake::Task, :xx) + top_z = @tm.define_task(Rake::Task, :z) + @tm.in_namespace("a") do + aa = @tm.define_task(Rake::Task, :aa) + mid_z = @tm.define_task(Rake::Task, :z) + @tm.in_namespace("b") do + bb = @tm.define_task(Rake::Task, :bb) + bot_z = @tm.define_task(Rake::Task, :z) + + assert_equal ["a", "b"], @tm.current_scope + + assert_equal bb, @tm["a:b:bb"] + assert_equal aa, @tm["a:aa"] + assert_equal xx, @tm["xx"] + assert_equal bot_z, @tm["z"] + assert_equal mid_z, @tm["^z"] + assert_equal top_z, @tm["^^z"] + assert_equal top_z, @tm["rake:z"] + end + + assert_equal ["a"], @tm.current_scope + + assert_equal bb, @tm["a:b:bb"] + assert_equal aa, @tm["a:aa"] + assert_equal xx, @tm["xx"] + assert_equal bb, @tm["b:bb"] + assert_equal aa, @tm["aa"] + assert_equal mid_z, @tm["z"] + assert_equal top_z, @tm["^z"] + assert_equal top_z, @tm["rake:z"] + end + + assert_equal [], @tm.current_scope + + assert_equal [], xx.scope + assert_equal ['a'], aa.scope + assert_equal ['a', 'b'], bb.scope + end + + def test_lookup_with_explicit_scopes + t1, t2, t3, s = (0...4).collect { nil } + t1 = @tm.define_task(Rake::Task, :t) + @tm.in_namespace("a") do + t2 = @tm.define_task(Rake::Task, :t) + s = @tm.define_task(Rake::Task, :s) + @tm.in_namespace("b") do + t3 = @tm.define_task(Rake::Task, :t) + end + end + assert_equal t1, @tm[:t, []] + assert_equal t2, @tm[:t, ["a"]] + assert_equal t3, @tm[:t, ["a", "b"]] + assert_equal s, @tm[:s, ["a", "b"]] + assert_equal s, @tm[:s, ["a"]] + end + + def test_correctly_scoped_prerequisites_are_invoked + values = [] + @tm = Rake::Application.new + @tm.define_task(Rake::Task, :z) do values << "top z" end + @tm.in_namespace("a") do + @tm.define_task(Rake::Task, :z) do values << "next z" end + @tm.define_task(Rake::Task, :x => :z) + end + + @tm["a:x"].invoke + assert_equal ["next z"], values + end + +end + +class TestTaskManagerArgumentResolution < Test::Unit::TestCase + def test_good_arg_patterns + assert_equal [:t, [], []], task(:t) + assert_equal [:t, [], [:x]], task(:t => :x) + assert_equal [:t, [], [:x, :y]], task(:t => [:x, :y]) + + assert_equal [:t, [:a, :b], []], task(:t, :a, :b) + assert_equal [:t, [], [:x]], task(:t, :needs => :x) + assert_equal [:t, [:a, :b], [:x]], task(:t, :a, :b, :needs => :x) + assert_equal [:t, [:a, :b], [:x, :y]], task(:t, :a, :b, :needs => [:x, :y]) + + assert_equal [:t, [:a, :b], []], task(:t, [:a, :b]) + assert_equal [:t, [:a, :b], [:x]], task(:t, [:a, :b] => :x) + assert_equal [:t, [:a, :b], [:x, :y]], task(:t, [:a, :b] => [:x, :y]) + end + + def task(*args) + tm = TaskManager.new + tm.resolve_args(args) + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_tasklib.rb b/vendor/gems/gems/rake-0.8.3/test/test_tasklib.rb new file mode 100644 index 0000000..c61fa1c --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_tasklib.rb @@ -0,0 +1,12 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'rake/tasklib' + + +class TestTaskLib < Test::Unit::TestCase + def test_paste + tl = Rake::TaskLib.new + assert_equal :ab, tl.paste(:a, :b) + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_tasks.rb b/vendor/gems/gems/rake-0.8.3/test/test_tasks.rb new file mode 100644 index 0000000..a673422 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_tasks.rb @@ -0,0 +1,371 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'fileutils' +require 'rake' +require 'test/filecreation' +require 'test/capture_stdout' + +###################################################################### +class TestTask < Test::Unit::TestCase + include CaptureStdout + include Rake + + def setup + Task.clear + end + + def test_create + arg = nil + t = task(:name) { |task| arg = task; 1234 } + assert_equal "name", t.name + assert_equal [], t.prerequisites + assert t.needed? + t.execute(0) + assert_equal t, arg + assert_nil t.source + assert_equal [], t.sources + end + + def test_inspect + t = task(:foo, :needs => [:bar, :baz]) + assert_equal " [bar, baz]>", t.inspect + end + + def test_invoke + runlist = [] + t1 = task(:t1 => [:t2, :t3]) { |t| runlist << t.name; 3321 } + t2 = task(:t2) { |t| runlist << t.name } + t3 = task(:t3) { |t| runlist << t.name } + assert_equal ["t2", "t3"], t1.prerequisites + t1.invoke + assert_equal ["t2", "t3", "t1"], runlist + end + + def test_invoke_with_circular_dependencies + runlist = [] + t1 = task(:t1 => [:t2]) { |t| runlist << t.name; 3321 } + t2 = task(:t2 => [:t1]) { |t| runlist << t.name } + assert_equal ["t2"], t1.prerequisites + assert_equal ["t1"], t2.prerequisites + ex = assert_raise RuntimeError do + t1.invoke + end + assert_match(/circular dependency/i, ex.message) + assert_match(/t1 => t2 => t1/, ex.message) + end + + def test_dry_run_prevents_actions + Rake.application.options.dryrun = true + runlist = [] + t1 = task(:t1) { |t| runlist << t.name; 3321 } + out = capture_stdout { t1.invoke } + assert_match(/execute .*t1/i, out) + assert_match(/dry run/i, out) + assert_no_match(/invoke/i, out) + assert_equal [], runlist + ensure + Rake.application.options.dryrun = false + end + + def test_tasks_can_be_traced + Rake.application.options.trace = true + t1 = task(:t1) + out = capture_stdout { + t1.invoke + } + assert_match(/invoke t1/i, out) + assert_match(/execute t1/i, out) + ensure + Rake.application.options.trace = false + end + + def test_no_double_invoke + runlist = [] + t1 = task(:t1 => [:t2, :t3]) { |t| runlist << t.name; 3321 } + t2 = task(:t2 => [:t3]) { |t| runlist << t.name } + t3 = task(:t3) { |t| runlist << t.name } + t1.invoke + assert_equal ["t3", "t2", "t1"], runlist + end + + def test_can_double_invoke_with_reenable + runlist = [] + t1 = task(:t1) { |t| runlist << t.name } + t1.invoke + t1.reenable + t1.invoke + assert_equal ["t1", "t1"], runlist + end + + def test_clear + t = task("t" => "a") { } + t.clear + assert t.prerequisites.empty?, "prerequisites should be empty" + assert t.actions.empty?, "actions should be empty" + end + + def test_clear_prerequisites + t = task("t" => ["a", "b"]) + assert_equal ['a', 'b'], t.prerequisites + t.clear_prerequisites + assert_equal [], t.prerequisites + end + + def test_clear_actions + t = task("t") { } + t.clear_actions + assert t.actions.empty?, "actions should be empty" + end + + def test_find + task :tfind + assert_equal "tfind", Task[:tfind].name + ex = assert_raises(RuntimeError) { Task[:leaves] } + assert_equal "Don't know how to build task 'leaves'", ex.message + end + + def test_defined + assert ! Task.task_defined?(:a) + task :a + assert Task.task_defined?(:a) + end + + def test_multi_invocations + runs = [] + p = proc do |t| runs << t.name end + task({:t1=>[:t2,:t3]}, &p) + task({:t2=>[:t3]}, &p) + task(:t3, &p) + Task[:t1].invoke + assert_equal ["t1", "t2", "t3"], runs.sort + end + + def test_task_list + task :t2 + task :t1 => [:t2] + assert_equal ["t1", "t2"], Task.tasks.collect {|t| t.name} + end + + def test_task_gives_name_on_to_s + task :abc + assert_equal "abc", Task[:abc].to_s + end + + def test_symbols_can_be_prerequisites + task :a => :b + assert_equal ["b"], Task[:a].prerequisites + end + + def test_strings_can_be_prerequisites + task :a => "b" + assert_equal ["b"], Task[:a].prerequisites + end + + def test_arrays_can_be_prerequisites + task :a => ["b", "c"] + assert_equal ["b", "c"], Task[:a].prerequisites + end + + def test_filelists_can_be_prerequisites + task :a => FileList.new.include("b", "c") + assert_equal ["b", "c"], Task[:a].prerequisites + end + + def test_investigation_output + t1 = task(:t1 => [:t2, :t3]) { |t| runlist << t.name; 3321 } + task(:t2) + task(:t3) + out = t1.investigation + assert_match(/class:\s*Rake::Task/, out) + assert_match(/needed:\s*true/, out) + assert_match(/pre-requisites:\s*--t2/, out) + end + + + def test_extended_comments + desc %{ + This is a comment. + + And this is the extended comment. + name -- Name of task to execute. + rev -- Software revision to use. + } + t = task(:t, :name, :rev) + assert_equal "[name,rev]", t.arg_description + assert_equal "This is a comment.", t.comment + assert_match(/^\s*name -- Name/, t.full_comment) + assert_match(/^\s*rev -- Software/, t.full_comment) + assert_match(/\A\s*This is a comment\.$/, t.full_comment) + end + + def test_multiple_comments + desc "line one" + t = task(:t) + desc "line two" + task(:t) + assert_equal "line one / line two", t.comment + end + + def test_settable_comments + t = task(:t) + t.comment = "HI" + assert_equal "HI", t.comment + end +end + +###################################################################### +class TestTaskWithArguments < Test::Unit::TestCase + include CaptureStdout + include Rake + + def setup + Task.clear + end + + def test_no_args_given + t = task :t + assert_equal [], t.arg_names + end + + def test_args_given + t = task :t, :a, :b + assert_equal [:a, :b], t.arg_names + end + + def test_name_and_needs + t = task(:t => [:pre]) + assert_equal "t", t.name + assert_equal [], t.arg_names + assert_equal ["pre"], t.prerequisites + end + + def test_name_and_explicit_needs + t = task(:t, :needs => [:pre]) + assert_equal "t", t.name + assert_equal [], t.arg_names + assert_equal ["pre"], t.prerequisites + end + + def test_name_args_and_explicit_needs + t = task(:t, :x, :y, :needs => [:pre]) + assert_equal "t", t.name + assert_equal [:x, :y], t.arg_names + assert_equal ["pre"], t.prerequisites + end + + def test_illegal_keys_in_task_name_hash + assert_raise RuntimeError do + t = task(:t, :x, :y => 1, :needs => [:pre]) + end + end + + def test_arg_list_is_empty_if_no_args_given + t = task(:t) { |tt, args| assert_equal({}, args.to_hash) } + t.invoke(1, 2, 3) + end + + def test_tasks_can_access_arguments_as_hash + t = task :t, :a, :b, :c do |tt, args| + assert_equal({:a => 1, :b => 2, :c => 3}, args.to_hash) + assert_equal 1, args[:a] + assert_equal 2, args[:b] + assert_equal 3, args[:c] + assert_equal 1, args.a + assert_equal 2, args.b + assert_equal 3, args.c + end + t.invoke(1, 2, 3) + end + + def test_actions_of_various_arity_are_ok_with_args + notes = [] + t = task(:t, :x) do + notes << :a + end + t.enhance do | | + notes << :b + end + t.enhance do |task| + notes << :c + assert_kind_of Task, task + end + t.enhance do |t2, args| + notes << :d + assert_equal t, t2 + assert_equal({:x => 1}, args.to_hash) + end + assert_nothing_raised do t.invoke(1) end + assert_equal [:a, :b, :c, :d], notes + end + + def test_arguments_are_passed_to_block + t = task(:t, :a, :b) { |tt, args| + assert_equal( { :a => 1, :b => 2 }, args.to_hash ) + } + t.invoke(1, 2) + end + + def test_extra_parameters_are_ignored + t = task(:t, :a) { |tt, args| + assert_equal 1, args.a + assert_nil args.b + } + t.invoke(1, 2) + end + + def test_arguments_are_passed_to_all_blocks + counter = 0 + t = task :t, :a + task :t do |tt, args| + assert_equal 1, args.a + counter += 1 + end + task :t do |tt, args| + assert_equal 1, args.a + counter += 1 + end + t.invoke(1) + assert_equal 2, counter + end + + def test_block_with_no_parameters_is_ok + t = task(:t) { } + t.invoke(1, 2) + end + + def test_name_with_args + desc "T" + t = task(:tt, :a, :b) + assert_equal "tt", t.name + assert_equal "T", t.comment + assert_equal "[a,b]", t.arg_description + assert_equal "tt[a,b]", t.name_with_args + assert_equal [:a, :b],t.arg_names + end + + def test_named_args_are_passed_to_prereqs + value = nil + pre = task(:pre, :rev) { |t, args| value = args.rev } + t = task(:t, :name, :rev, :needs => [:pre]) + t.invoke("bill", "1.2") + assert_equal "1.2", value + end + + def test_args_not_passed_if_no_prereq_names + pre = task(:pre) { |t, args| + assert_equal({}, args.to_hash) + assert_equal "bill", args.name + } + t = task(:t, :name, :rev, :needs => [:pre]) + t.invoke("bill", "1.2") + end + + def test_args_not_passed_if_no_arg_names + pre = task(:pre, :rev) { |t, args| + assert_equal({}, args.to_hash) + } + t = task(:t, :needs => [:pre]) + t.invoke("bill", "1.2") + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_test_task.rb b/vendor/gems/gems/rake-0.8.3/test/test_test_task.rb new file mode 100644 index 0000000..23921f7 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_test_task.rb @@ -0,0 +1,75 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'rake/testtask' + +class TestTestTask < Test::Unit::TestCase + include Rake + def setup + Task.clear + ENV.delete('TEST') + end + + def teardown + FileUtils.rm_rf("testdata") + end + + def test_no_task + assert ! Task.task_defined?(:test) + end + + def test_defaults + tt = Rake::TestTask.new do |t| end + assert_not_nil tt + assert_equal :test, tt.name + assert_equal ['lib'], tt.libs + assert_equal 'test/test*.rb', tt.pattern + assert_equal false, tt.verbose + assert Task.task_defined?(:test) + end + + def test_non_defaults + tt = Rake::TestTask.new(:example) do |t| + t.libs = ['src', 'ext'] + t.pattern = 'test/tc_*.rb' + t.verbose = true + end + assert_not_nil tt + assert_equal :example, tt.name + assert_equal ['src', 'ext'], tt.libs + assert_equal 'test/tc_*.rb', tt.pattern + assert_equal true, tt.verbose + assert Task.task_defined?(:example) + end + + def test_pattern + tt = Rake::TestTask.new do |t| + t.pattern = '*.rb' + end + assert_equal ['install.rb'], tt.file_list.to_a + end + + def test_env_test + ENV['TEST'] = 'testfile.rb' + tt = Rake::TestTask.new do |t| + t.pattern = '*' + end + assert_equal ["testfile.rb"], tt.file_list.to_a + end + + def test_test_files + tt = Rake::TestTask.new do |t| + t.test_files = FileList['a.rb', 'b.rb'] + end + assert_equal ["a.rb", 'b.rb'], tt.file_list.to_a + end + + def test_both_pattern_and_test_files + tt = Rake::TestTask.new do |t| + t.test_files = FileList['a.rb', 'b.rb'] + t.pattern = '*.rb' + end + assert_equal ['a.rb', 'b.rb', 'install.rb'], tt.file_list.to_a + end + +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_top_level_functions.rb b/vendor/gems/gems/rake-0.8.3/test/test_top_level_functions.rb new file mode 100644 index 0000000..7ca298c --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_top_level_functions.rb @@ -0,0 +1,84 @@ +#!/usr/bin/env ruby + +begin + require 'rubygems' +rescue LoadError + # got no gems +end + +require 'test/unit' +require 'test/capture_stdout' +require 'rake' +require 'flexmock/test_unit' + +class TestTopLevelFunctions < Test::Unit::TestCase + include CaptureStdout + + def setup + super + @app = Rake.application + Rake.application = flexmock("app") + end + + def teardown + Rake.application = @app + super + end + + def test_namespace + Rake.application.should_receive(:in_namespace).with("xyz", any).once + namespace "xyz" do end + end + + def test_import + Rake.application.should_receive(:add_import).with("x").once.ordered + Rake.application.should_receive(:add_import).with("y").once.ordered + Rake.application.should_receive(:add_import).with("z").once.ordered + import('x', 'y', 'z') + end + + def test_when_writing + out = capture_stdout do + when_writing("NOTWRITING") do + puts "WRITING" + end + end + assert_equal "WRITING\n", out + end + + def test_when_not_writing + RakeFileUtils.nowrite_flag = true + out = capture_stdout do + when_writing("NOTWRITING") do + puts "WRITING" + end + end + assert_equal "DRYRUN: NOTWRITING\n", out + ensure + RakeFileUtils.nowrite_flag = false + end + + def test_missing_constants_task + Rake.application.should_receive(:const_warning).with(:Task).once + Object.const_missing(:Task) + end + + def test_missing_constants_file_task + Rake.application.should_receive(:const_warning).with(:FileTask).once + Object.const_missing(:FileTask) + end + + def test_missing_constants_file_creation_task + Rake.application.should_receive(:const_warning).with(:FileCreationTask).once + Object.const_missing(:FileCreationTask) + end + + def test_missing_constants_rake_app + Rake.application.should_receive(:const_warning).with(:RakeApp).once + Object.const_missing(:RakeApp) + end + + def test_missing_other_constant + assert_raise(NameError) do Object.const_missing(:Xyz) end + end +end diff --git a/vendor/gems/gems/rake-0.8.3/test/test_win32.rb b/vendor/gems/gems/rake-0.8.3/test/test_win32.rb new file mode 100644 index 0000000..80dec77 --- /dev/null +++ b/vendor/gems/gems/rake-0.8.3/test/test_win32.rb @@ -0,0 +1,57 @@ +#!/usr/bin/env ruby + +require 'test/unit' +require 'test/rake_test_setup' +require 'test/in_environment' + +require 'rake' + +class TestWin32 < Test::Unit::TestCase + include InEnvironment + + Win32 = Rake::Win32 + + def test_win32_system_dir_uses_appdata_if_defined + in_environment('RAKE_SYSTEM' => nil, 'APPDATA' => '\\AD') do + assert_equal "/AD/Rake", Win32.win32_system_dir + end + end + + def test_win32_system_dir_uses_homedrive_otherwise + in_environment( + 'RAKE_SYSTEM' => nil, + 'APPDATA' => nil, + 'HOMEDRIVE' => "C:", + "HOMEPATH" => "\\HP" + ) do + assert_equal "C:/HP/Rake", Win32.win32_system_dir + end + end + + def test_win32_system_dir_uses_userprofile_otherwise + in_environment( + 'RAKE_SYSTEM' => nil, + 'APPDATA' => nil, + 'HOMEDRIVE' => nil, + "HOMEPATH" => nil, + "USERPROFILE" => '\\UP' + ) do + assert_equal "/UP/Rake", Win32.win32_system_dir + end + end + + def test_win32_system_dir_nil_of_no_env_vars + in_environment( + 'RAKE_SYSTEM' => nil, + 'APPDATA' => nil, + 'HOMEDRIVE' => nil, + "HOMEPATH" => nil, + "USERPROFILE" => nil + ) do + assert_raise(Rake::Win32::Win32HomeError) do + Win32.win32_system_dir + end + end + end + +end diff --git a/vendor/gems/gems/rubyforge-1.0.1/History.txt b/vendor/gems/gems/rubyforge-1.0.1/History.txt new file mode 100644 index 0000000..25491b3 --- /dev/null +++ b/vendor/gems/gems/rubyforge-1.0.1/History.txt @@ -0,0 +1,82 @@ +== Version History: + +=== 1.0.1 / 2008-10-22: + +* Fixed multipart form upload so it isn't url escaping the data. DOH. + * Affects release_notes and release_changes, but never reported for 5 months. + +=== 1.0.0 / 2008-05-20: + +* Removed HTTPAccess2, thanks to Aaron Patterson. Even tho he's whiny. +* Changed initialize/configure to make testing scream. 100x faster. + +=== 0.4.5 / 2008-03-11: + +* Update for Ruby 1.9.0. +* Updated History, Rakefile, and Readme for new hoe abilities. +* Added config backup/restore rake tasks (for testing). + +=== 0.4.4 / 2007-08-13: + +* New type_id values will merge with extant data. (self-repairing data is Good) +* Scrape processor_ids, merging in with extant data. +* Default to "Other" if a file's type is unrecognized. + +=== 0.4.3 / 2007-07-23: + +* Set mode on .rubyforge directory to 700. +* Fix fetching of user id when user has no releases. + +=== 0.4.2 / 2007-05-21: + +* Fix for windoze users (spaces in path). +* Added check for extant release. +* Added default hash for first-time releases. + +=== 0.4.1 / 2007-03-08: + +* Verify that login succeeded and warn against if not (prolly should raise). +* Print a friendly error if you have the wrong package id. +* Handle upload error in add_release a bit better. + +=== 0.4.0 / 2007-01-09: + +* config.yml split and moved to user-config.yml (up to the user to do). +* auto-config.yml now generated via config command. +* @config renamed to @userconfig. +* @config["rubyforge"] moved to @autoconfig. +* Added save_autoconfig. +* Pulled scrape_project from scrape_config. +* scrape_config no longer takes a user param. Use opts to specify. +* scrape_project, add_project, add/remove_release now save automatically. + +=== 0.3.2 / 2006-11-29: + +* Fixed file uploads for windows. +* Correctly scrape releases with funky characters. + +=== 0.3.1 / 2006-10-24: + +* Added SSL login. +* Added yet more debugging output if $DEBUG. + +=== 0.3.0 / 2006-09-30: + +* Added more debugging output if $DEBUG +* Added news posting. +* Added multiple file release to add_release (uses add_file for extras). +* add_release now returns release_id +* Fixed config scraper to include '-' in names. + +=== 0.2.1 / 2006-09-14: + +* Gemspec was too loose about packaging. Now using manifest. + +=== 0.2.0 / 2006-09-13: + +* Split original script into script and library. +* Added tests for library. +* Refactored heavily. +* Added "config" command to scrape group/project/release ids from rubyforge. +* Added "names" command to help pick groups and projects. +* Added "add_file" command to add a file to an existing release. diff --git a/vendor/gems/gems/rubyforge-1.0.1/Manifest.txt b/vendor/gems/gems/rubyforge-1.0.1/Manifest.txt new file mode 100644 index 0000000..abc33fd --- /dev/null +++ b/vendor/gems/gems/rubyforge-1.0.1/Manifest.txt @@ -0,0 +1,11 @@ +History.txt +Manifest.txt +README.txt +Rakefile +bin/rubyforge +lib/rubyforge.rb +lib/rubyforge/client.rb +lib/rubyforge/cookie_manager.rb +test/test_rubyforge.rb +test/test_rubyforge_client.rb +test/test_rubyforge_cookie_manager.rb diff --git a/vendor/gems/gems/rubyforge-1.0.1/README.txt b/vendor/gems/gems/rubyforge-1.0.1/README.txt new file mode 100644 index 0000000..2217844 --- /dev/null +++ b/vendor/gems/gems/rubyforge-1.0.1/README.txt @@ -0,0 +1,24 @@ += Rubyforge + +* http://codeforpeople.rubyforge.org/rubyforge/ +* http://rubyforge.org/projects/codeforpeople/ + +== Description + +A script which automates a limited set of rubyforge operations. + +* Run 'rubyforge help' for complete usage. +* Setup: For first time users AND upgrades to 0.4.0: + * rubyforge setup (deletes your username and password, so run sparingly!) + * edit ~/.rubyforge/user-config.yml + * rubyforge config +* For all rubyforge upgrades, run 'rubyforge config' to ensure you have latest. +* Don't forget to login! logging in will store a cookie in your + .rubyforge directory which expires after a time. always run the + login command before any operation that requires authentication, + such as uploading a package. + +== Synopsis + + rubyforge [options]* mode [mode_args]* + diff --git a/vendor/gems/gems/rubyforge-1.0.1/Rakefile b/vendor/gems/gems/rubyforge-1.0.1/Rakefile new file mode 100644 index 0000000..da07354 --- /dev/null +++ b/vendor/gems/gems/rubyforge-1.0.1/Rakefile @@ -0,0 +1,39 @@ +# -*- ruby -*- + +begin + require 'hoe' +rescue LoadError + abort "ERROR: This Rakefile is only useful with hoe installed. + If you're trying to install the rubyforge library, + please install it via rubygems." +end + +abort "you _must_ install this gem to release it" if + ENV['VERSION'] && ENV['VERSION'] != RubyForge::VERSION + +Hoe.new("rubyforge", RubyForge::VERSION) do |rubyforge| + rubyforge.rubyforge_name = "codeforpeople" + rubyforge.need_tar = false + + rubyforge.developer('Ryan Davis', 'ryand-ruby@zenspider.com') + rubyforge.developer('Eric Hodel', 'drbrain@segment7.net') + rubyforge.developer('Ara T Howard', 'ara.t.howard@gmail.com') + + rubyforge.multiruby_skip << "rubinius" +end + +task :backup do + Dir.chdir File.expand_path("~/.rubyforge") do + cp "user-config.yml", "user-config.yml.bak" + cp "auto-config.yml", "auto-config.yml.bak" + end +end + +task :restore do + Dir.chdir File.expand_path("~/.rubyforge") do + cp "user-config.yml.bak", "user-config.yml" + cp "auto-config.yml.bak", "auto-config.yml" + end +end + +# vim:syntax=ruby diff --git a/vendor/gems/gems/rubyforge-1.0.1/bin/rubyforge b/vendor/gems/gems/rubyforge-1.0.1/bin/rubyforge new file mode 100755 index 0000000..b083e84 --- /dev/null +++ b/vendor/gems/gems/rubyforge-1.0.1/bin/rubyforge @@ -0,0 +1,223 @@ +#! /usr/bin/env ruby + +$VERBOSE = true + +$:.unshift(File::join(File::dirname(File::dirname(__FILE__)), "lib")) + +require 'getoptlong' +require 'rubyforge' + +PROGRAM = File::basename $0 + +USAGE = <<-EOL +SYNOPSIS + + #{ PROGRAM } [options]* mode [mode_args]* + +DESCRIPTION + + simplistic script which automates a limited set of rubyforge operations + +MODES + + setup() + initializes your .rubyforge directory. you need to run this first before + doing anything else. + + example : + #{ PROGRAM } setup + + config([project]) + Helps you populate your auto-config.yml file by scraping rubyforge and + getting your groups, projects, and releases. + + example : + #{ PROGRAM } config + #{ PROGRAM } config myproject + + names() + Prints out the names of your configured groups and projects. + + example : + #{ PROGRAM } names + + login() + sends username and password from config.yml (or --username/--password + options) and stores login cookie in cookie.dat. this is required for + subsquent operations work. + + example : + #{ PROGRAM } login + #{ PROGRAM } login --username zaphod --password 42 + + create_package(group_id, package_name) + creates the named package under the specified group. + + example : + #{ PROGRAM } create_package 1024 traits + #{ PROGRAM } login && #{ PROGRAM } create_package codeforpeople.com traits + + add_release(group_id, package_id, release_name, userfile) + release a file as release_name under the specified group_id and + package_id. + + example : + #{ PROGRAM } add_release codeforpeople.com traits 0.8.0 traits-0.8.0.gem + #{ PROGRAM } add_release codeforpeople.com traits 0.8.0 traits-0.8.0.tgz + #{ PROGRAM } add_release 1024 1242 0.8.0 traits-0.8.0.gem + #{ PROGRAM } login && #{ PROGRAM } add_release 1024 1242 0.8.0 traits-0.8.0.gem + + add_file(group_id, package_id, release_id, userfile) + add a file to an existing release under the specified group_id, + package_id, and release_id + + example : + #{ PROGRAM } add_file codeforpeople.com traits 0.8.0 traits-0.8.0.gem + #{ PROGRAM } add_file codeforpeople.com traits 0.8.0 traits-0.8.0.tgz + #{ PROGRAM } add_file 1024 1242 0.8.0 traits-0.8.0.gem + + delete_package(group_id, package_name) + deletes a package and all its files. + + example : + #{ PROGRAM } delete_package codeforpeople.com traits + #{ PROGRAM } delete_package 1024 traits + +NOTES + + - In order to use group_id, package_id, or release_id by name, + rather than number, you must edit the rubyforge[group_ids] and + rubyforge[package_ids] translation tables in your config.yml. See + the config command for more information and help. + + - don\'t forget to login! logging in will store a cookie in your + .rubyforge directory which expires after a time. always run the login + command before any operation that requires authentication, such as + uploading a package. + +TODO + + - add error checking. this requires screen scraping to see of an operation + succeeded since 200 is returned from rubyforge even for failed operations + and only the html text reveals the status. + +OPTIONS + + global : + --help , -h + this message + --config , -c + specify a config file (default #{ RubyForge::CONFIG_F }) + --username , -u + specify username, taken from config otherwise + --password , -p + specify password, taken from config otherwise + --cookie_jar , -C + specify cookie storage file (default #{ RubyForge::COOKIE_F }) + + add_release : + --is_private , -P + if true, release is not public + --release_date , -r + specify time of release (default 'now') + --type_id , -t + specify filetype code (default determined by ext) + --processor_id , -o + specify processor (default 'Any') + --release_notes , -n + specify release notes as string or file + --release_changes , -a + specify release changes as string or file + --preformatted , -f + specify whether release_notes/changes are preformatted + +EOL + +mode = ARGV.shift + +opts = GetoptLong::new( + [ "--help" , "-h" , GetoptLong::REQUIRED_ARGUMENT ], + [ "--username" , "-u" , GetoptLong::REQUIRED_ARGUMENT ], + [ "--password" , "-p" , GetoptLong::REQUIRED_ARGUMENT ], + [ "--cookie_jar" , "-C" , GetoptLong::REQUIRED_ARGUMENT ], + [ "--is_private" , "-P" , GetoptLong::REQUIRED_ARGUMENT ], + [ "--release_date" , "-r" , GetoptLong::REQUIRED_ARGUMENT ], + [ "--type_id" , "-t" , GetoptLong::REQUIRED_ARGUMENT ], + [ "--processor_id" , "-o" , GetoptLong::REQUIRED_ARGUMENT ], + [ "--release_notes" , "-n" , GetoptLong::REQUIRED_ARGUMENT ], + [ "--release_changes" , "-a" , GetoptLong::REQUIRED_ARGUMENT ], + [ "--preformatted" , "-f" , GetoptLong::NO_ARGUMENT ] + ).enum_for.inject({}) { |h, (k, v)| h.update k.delete('-') => v } + +rubyforge = RubyForge.new +rubyforge.configure opts + +mode = "help" if opts["help"] + +case mode +when %r/help/ + USAGE.display +when %r/setup/ + rubyforge.setup +when %r/config/ + project = ARGV.shift + if project then + rubyforge.scrape_project(project) + else + rubyforge.scrape_config + end +when %r/names/ + rf = rubyforge.autoconfig + puts "groups : #{rf["group_ids"].keys.sort.join(", ")}" + puts "packages: #{rf["package_ids"].keys.sort.join(", ")}" +when %r/login/ + rubyforge.login +when %r/create_package/ + page, msg = "/frs/admin/index.php", "post_content" + + group_id, package_name = ARGV + + abort "no " unless group_id + abort "no " unless package_name + + group_id = Integer(group_id) rescue group_id + + rubyforge.create_package group_id, package_name +when %r/delete_package/ + group_id, package_id = ARGV + + abort "no " unless group_id + abort "no " unless package_id + + group_id = Integer(group_id) rescue group_id + package_id = Integer(package_id) rescue package_id + + rubyforge.delete_package group_id, package_id +when %r/add_release/ + group_id, package_id, release_name, userfile = ARGV + + abort "no " unless group_id + abort "no " unless package_id + abort "no " unless release_name + abort "no " unless userfile + + group_id = Integer(group_id) rescue group_id + package_id = Integer(package_id) rescue package_id + + rubyforge.add_release group_id, package_id, release_name, userfile +when %r/add_file/ + group_id, package_id, release_id, userfile = ARGV + + abort "no " unless group_id + abort "no " unless package_id + abort "no " unless release_id + abort "no " unless userfile + + group_id = Integer(group_id) rescue group_id + package_id = Integer(package_id) rescue package_id + release_id = Integer(release_id) rescue release_id + + rubyforge.add_file group_id, package_id, release_id, userfile +else + abort USAGE +end diff --git a/vendor/gems/gems/rubyforge-1.0.1/lib/rubyforge.rb b/vendor/gems/gems/rubyforge-1.0.1/lib/rubyforge.rb new file mode 100755 index 0000000..fb3981d --- /dev/null +++ b/vendor/gems/gems/rubyforge-1.0.1/lib/rubyforge.rb @@ -0,0 +1,475 @@ +#! /usr/bin/env ruby -w + +require 'enumerator' +require 'fileutils' +require 'yaml' +require 'open-uri' +require 'rubyforge/client' + +$TESTING = false unless defined? $TESTING + +class RubyForge + + # :stopdoc: + VERSION = '1.0.1' + HOME = ENV["HOME"] || ENV["HOMEPATH"] || File::expand_path("~") + RUBYFORGE_D = File::join HOME, ".rubyforge" + CONFIG_F = File::join RUBYFORGE_D, "user-config.yml" + COOKIE_F = File::join RUBYFORGE_D, "cookie.dat" + + # We must use __FILE__ instead of DATA because this is now a library + # and DATA is relative to $0, not __FILE__. + config = File.read(__FILE__).split(/__END__/).last.gsub(/#\{(.*)\}/) {eval $1} + CONFIG = YAML.load(config) + # :startdoc: + + attr_reader :userconfig, :autoconfig + + def initialize(userconfig=nil, autoconfig=nil, opts=nil) + # def initialize(userconfig=CONFIG_F, opts={}) + @userconfig, @autoconfig = userconfig, autoconfig + + @autoconfig ||= CONFIG["rubyforge"].dup + @userconfig.merge! opts if opts + + @client = nil + @uri = nil + end + + def configure opts = {} + user_path = CONFIG_F + dir, file = File.split(user_path) + + @userconfig = if test(?e, user_path) then + YAML.load_file(user_path) + else + CONFIG + end.merge(opts) + @autoconfig_path = File.join(dir, file.sub(/^user/, 'auto')) + @autoconfig = if test(?e, @autoconfig_path) then + YAML.load_file(@autoconfig_path) + else + CONFIG["rubyforge"].dup + end + @autoconfig["type_ids"] = CONFIG['rubyforge']['type_ids'].dup + + raise "no " unless @userconfig["username"] + raise "no " unless @userconfig["password"] + raise "no " unless @userconfig["cookie_jar"] + + self + end + + def uri + @uri ||= URI.parse @userconfig['uri'] + end + + def setup + FileUtils::mkdir_p RUBYFORGE_D, :mode => 0700 unless test ?d, RUBYFORGE_D + test ?e, CONFIG_F and FileUtils::mv CONFIG_F, "#{CONFIG_F}.bak" + config = CONFIG.dup + config.delete "rubyforge" + + open(CONFIG_F, "w") { |f| + f.write YAML.dump(config) + } + FileUtils::touch COOKIE_F + edit = (ENV["EDITOR"] || ENV["EDIT"] || "vi") + " '#{CONFIG_F}'" + system edit or puts "edit '#{CONFIG_F}'" + end + + def save_autoconfig + File.open(@autoconfig_path, "w") do |file| + YAML.dump @autoconfig, file + end + end + + def scrape_config + username = @userconfig['username'] + + %w(group package processor release).each do |type| + @autoconfig["#{type}_ids"].clear + end + + puts "Getting #{username}" + html = URI.parse("http://rubyforge.org/users/#{username}/index.html").read + + projects = html.scan(%r%/projects/([^/]+)/%).flatten + + puts "Fetching #{projects.size} projects" + projects.each do |project| + next if project == "support" + scrape_project(project) + end + end + + def scrape_project(project) + data = { + "group_ids" => {}, + "package_ids" => {}, + "processor_ids" => Hash.new { |h,k| h[k] = {} }, + "release_ids" => Hash.new { |h,k| h[k] = {} }, + } + + puts "Updating #{project}" + + unless data["group_ids"].has_key? project then + html = URI.parse("http://rubyforge.org/projects/#{project}/index.html").read + group_id = html[/(frs|tracker|mail)\/\?group_id=\d+/][/\d+/].to_i + data["group_ids"][project] = group_id + end + + group_id = data["group_ids"][project] + + html = URI.parse("http://rubyforge.org/frs/?group_id=#{group_id}").read + + package = nil + html.scan(/

[^<]+|release_id=\d+">[^>]+|filemodule_id=\d+/).each do |s| + case s + when /

([^<]+)/ then + package = $1.strip + when /release_id=(\d+)">([^<]+)/ then + data["release_ids"][package][$2] = $1.to_i + when /filemodule_id=(\d+)/ then + data["package_ids"][package] = $1.to_i + end + end + + if not data['release_ids'][package].empty? and + @autoconfig['processor_ids'].empty? then + puts "Fetching processor ids" + + login + + html = client.get_content "http://rubyforge.org/frs/admin/qrs.php?package=&group_id=#{group_id}" + + html =~ / + + + + + EOF + + @rubyforge.scrape_project('my_project') + + expected = { + "group_ids" => { "my_project" => 1513 }, + "package_ids" => { "ar_mailer" => 4566 }, + "processor_ids" => { "i386" => 1000, "i387" => 1001 }, + "release_ids" => { + "ar_mailer" => { "1.2.0" => 12185, "1.3.1" => 13368 } + }, + "type_ids" => {}, + } + + assert_equal expected, @rubyforge.autoconfig + ensure + $stdout = orig_stdout + $stderr = orig_stderr + end + + def util_new(klass) + @cookie_path = File.join(Dir.tmpdir, "cookie.#{$$}.dat") + File.open(@cookie_path, 'w') {} # touch + + user_data = { + "uri" => "http://rubyforge.org", + "is_private" => false, + "cookie_jar" => @cookie_path, + "username" => "username", + "password" => "password" + } + + auto_data = { + "group_ids" => {}, + "package_ids" => {}, + "release_ids" => Hash.new { |h,k| h[k] = {} }, + "type_ids" => {}, + "processor_ids" => {"Any"=>8000}, + } + + @rubyforge = klass.new user_data, auto_data + + @rubyforge.client = RubyForge::FakeClient.new + + @rubyforge.userconfig["release_date"] = "today" + @rubyforge.autoconfig["type_ids"][".rb"] = 9999 + @rubyforge.autoconfig["group_ids"]["seattlerb"] = 42 + @rubyforge.autoconfig["package_ids"]["woot_pkg"] = 666 + end + + def util_run(page, form={}, extheader={}) + form_result = @rubyforge.form + assert form_result.delete("userfile") unless extheader.empty? + + assert_equal page, @rubyforge.page.to_s + assert_equal form, form_result + assert_equal extheader, @rubyforge.extheader + end + + def util_add_release + util_run('/frs/admin/qrs.php', + {"processor_id" => 8000, + "submit" => "Release File", + "preformatted" => 0, + "release_changes" => nil, + "type_id" => 9999, + "group_id" => 42, + "release_name" => "1.2.3", + "release_notes" => nil, + "package_id" => 666, + "release_date" => "today"}, + {"content-type"=> "multipart/form-data; boundary=___00__03__03__39__09__19__21__36___"}) + end + + def util_delete_package + util_run('/frs/admin/index.php', + "submit" => "Delete", + "really_sure" => "1", + "group_id" => 42, + "func" => "delete_package", + "package_id" => 666, + "sure" => "1") + end +end diff --git a/vendor/gems/gems/rubyforge-1.0.1/test/test_rubyforge_client.rb b/vendor/gems/gems/rubyforge-1.0.1/test/test_rubyforge_client.rb new file mode 100644 index 0000000..2907cb7 --- /dev/null +++ b/vendor/gems/gems/rubyforge-1.0.1/test/test_rubyforge_client.rb @@ -0,0 +1,122 @@ +require 'test/unit' unless defined? $ZENTEST and $ZENTEST +require 'rubyforge' + +class RubyForge::FakeAgent + class << self + attr_accessor :t_data, :t_request + end + + def initialize(*args) + end + + def request(request, data) + self.class.t_request = request + self.class.t_data = data + response = Net::HTTPOK.new('1.1', 200, '') + def response.read_body; ''; end + return response + end + + class Post + def initialize(*args) + @args = args + @stuff = {} + end + + def [] key + @stuff[key.downcase] + end + + def []= key, val + @stuff[key.downcase] = val + end + + def method_missing(*stuff) + # warn stuff.inspect + end + end +end + +class TestRubyForgeClient < Test::Unit::TestCase + def setup + @client = RubyForge::Client.new + @client.agent_class = RubyForge::FakeAgent + RubyForge::FakeAgent.t_data = :unassigned + RubyForge::FakeAgent.t_request = :unassigned + end + + def test_post_with_params + @client.post_content('http://example.com', { :f => 'adsf aoeu'}) + assert_equal('f=adsf+aoeu', RubyForge::FakeAgent.t_data) + + @client.post_content('http://example.com', { :a => 'b', :c => 'd' }) + assert_equal('a=b&c=d', RubyForge::FakeAgent.t_data) + end + + def test_multipart_post_one_param + random = Array::new(8){ "%2.2d" % rand(42) }.join('__') + boundary = "multipart/form-data; boundary=___#{ random }___" + + expected = <<-END +--___#{random}___\r +Content-Disposition: form-data; name="a"\r\n\r +a b c\r +--___#{random}___--\r +END + + @client.post_content( 'http://example.com', + { :a => 'a b c' }, + { 'content-type' => boundary } + ) + assert_equal(expected, RubyForge::FakeAgent.t_data) + end + + def test_multipart_post_two_params + random = Array::new(8){ "%2.2d" % rand(42) }.join('__') + boundary = "multipart/form-data; boundary=___#{ random }___" + + request = <<-END +--___#{random}___\r +Content-Disposition: form-data; name="a"\r\n\r +b\r +--___#{random}___\r +Content-Disposition: form-data; name="c"\r\n\r +d\r +--___#{random}___--\r +END + + @client.post_content( 'http://example.com', + { :a => 'b', :c => 'd' }, + { 'content-type' => boundary } + ) + assert_equal(request, RubyForge::FakeAgent.t_data) + end + + def test_multipart_io + random = Array::new(8){ "%2.2d" % rand(42) }.join('__') + boundary = "multipart/form-data; boundary=___#{ random }___" + + file_contents = 'blah blah blah' + file = StringIO.new(file_contents) + class << file + def path + '/one/two/three.rb' + end + end + + request = <<-END +--___#{random}___\r +Content-Disposition: form-data; name="userfile"; filename="three.rb"\r +Content-Transfer-Encoding: binary\r +Content-Type: text/plain\r\n\r +#{file_contents}\r +--___#{random}___--\r +END + + @client.post_content( 'http://example.com', + { :userfile => file }, + { 'content-type' => boundary } + ) + assert_equal(request, RubyForge::FakeAgent.t_data) + end +end diff --git a/vendor/gems/gems/rubyforge-1.0.1/test/test_rubyforge_cookie_manager.rb b/vendor/gems/gems/rubyforge-1.0.1/test/test_rubyforge_cookie_manager.rb new file mode 100644 index 0000000..0d931e2 --- /dev/null +++ b/vendor/gems/gems/rubyforge-1.0.1/test/test_rubyforge_cookie_manager.rb @@ -0,0 +1,97 @@ +require 'test/unit' unless defined? $ZENTEST and $ZENTEST +require 'rubyforge' +require 'time' +require 'yaml' +require 'tempfile' + +class TestRubyForgeCookieManager < Test::Unit::TestCase + def setup + cookie = cookie_string('session_ser', 'zzzzzzzzzzzzzzzzzz') + @url = URI.parse('http://rubyforge.org/account/login.php') + @cookie = WEBrick::Cookie.parse_set_cookie(cookie) + @manager = RubyForge::CookieManager.new + end + + def test_empty? + manager = RubyForge::CookieManager.new + assert(manager.empty?) + + assert_equal(0, manager[URI.parse('http://rubyforge.org/')].length) + assert(manager.empty?) + end + + def test_add + manager = RubyForge::CookieManager.new + assert(manager.empty?) + manager.add(@url, @cookie) + assert(!manager.empty?) + + cookie = manager[@url][@cookie.name] + assert cookie + assert_equal(@cookie.object_id, cookie.object_id) + end + + def test_add_expired_cookie + cookie = cookie_string('session_ser', 'zzzz', + :expires => (Time.now - 10).strftime('%A, %d-%b-%Y %H:%M:%S %Z')) + cookie = WEBrick::Cookie.parse_set_cookie(cookie) + + manager = RubyForge::CookieManager.new + assert(manager.empty?) + manager.add(@url, cookie) + assert(manager.empty?) + end + + def test_marshal + @manager.add(@url, @cookie) + assert(!@manager.empty?) + m = YAML.load(YAML.dump(@manager)) + assert(!m.empty?) + end + + def test_save! + tmp = Tempfile.new('cookie_jar') + @manager.cookies_file = tmp.path + @manager.add(@url, @cookie) + @manager.save! + + @manager = RubyForge::CookieManager.load(tmp.path) + assert(! @manager.empty?) + end + + def test_load_empty_file + tmp = Tempfile.new('cookie_jar') + manager = RubyForge::CookieManager.load(tmp.path) + assert(manager.empty?) + end + + def test_load_legacy_file + tmp = Tempfile.new('cookie_jar') + tmp.write([ + 'https://rubyforge.org/account/login.php', + 'session_ser', + 'zzzzzz', + '123456', + '.rubyforge.org', + '/', + '13' + ].join("\t")) + manager = RubyForge::CookieManager.load(tmp.path) + assert(manager.empty?) + end + + def test_cookies_file= + tmp = Tempfile.new('cookie_jar') + @manager.cookies_file = tmp.path + assert(@manager.empty?) + end + + def cookie_string(name, value, options = {}) + options = { + :expires => (Time.now + 86400).strftime('%A, %d-%b-%Y %H:%M:%S %Z'), + :path => '/', + :domain => '.rubyforge.org', + }.merge(options) + "#{name}=#{value}; #{options.map { |o| o.join('=') }.join('; ')}" + end +end diff --git a/vendor/gems/specifications/hoe-1.8.2.gemspec b/vendor/gems/specifications/hoe-1.8.2.gemspec new file mode 100644 index 0000000..ab03ce8 --- /dev/null +++ b/vendor/gems/specifications/hoe-1.8.2.gemspec @@ -0,0 +1,38 @@ +Gem::Specification.new do |s| + s.name = %q{hoe} + s.version = "1.8.2" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["Ryan Davis"] + s.date = %q{2008-10-24} + s.default_executable = %q{sow} + s.description = %q{Hoe is a simple rake/rubygems helper for project Rakefiles. It generates all the usual tasks for projects including rdoc generation, testing, packaging, and deployment. Tasks Provided: * announce - Create news email file and post to rubyforge. * audit - Run ZenTest against the package. * check_manifest - Verify the manifest. * clean - Clean up all the extras. * config_hoe - Create a fresh ~/.hoerc file. * debug_gem - Show information about the gem. * default - Run the default tasks. * deps:email - Print a contact list for gems dependent on this gem * deps:fetch - Fetch all the dependent gems of this gem into tarballs * deps:list - List all the dependent gems of this gem * docs - Build the docs HTML Files * email - Generate email announcement file. * gem - Build the gem file hoe-1.8.0.gem * generate_key - Generate a key for signing your gems. * install_gem - Install the package as a gem. * multi - Run the test suite using multiruby. * package - Build all the packages * post_blog - Post announcement to blog. * post_news - Post announcement to rubyforge. * publish_docs - Publish RDoc to RubyForge. * release - Package and upload the release to rubyforge. * ridocs - Generate ri locally for testing. * tasks - Generate a list of tasks for doco. * test - Run the test suite. * test_deps - Show which test files fail when run alone. See class rdoc for help. Hint: ri Hoe} + s.email = ["ryand-ruby@zenspider.com"] + s.executables = ["sow"] + s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"] + s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile", "bin/sow", "lib/hoe.rb", "test/test_hoe.rb"] + s.has_rdoc = true + s.homepage = %q{http://rubyforge.org/projects/seattlerb/} + s.rdoc_options = ["--main", "README.txt"] + s.require_paths = ["lib"] + s.rubyforge_project = %q{seattlerb} + s.rubygems_version = %q{1.2.0} + s.summary = %q{Hoe is a simple rake/rubygems helper for project Rakefiles} + s.test_files = ["test/test_hoe.rb"] + + if s.respond_to? :specification_version then + current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION + s.specification_version = 2 + + if current_version >= 3 then + s.add_runtime_dependency(%q, [">= 1.0.1"]) + s.add_runtime_dependency(%q, [">= 0.8.3"]) + else + s.add_dependency(%q, [">= 1.0.1"]) + s.add_dependency(%q, [">= 0.8.3"]) + end + else + s.add_dependency(%q, [">= 1.0.1"]) + s.add_dependency(%q, [">= 0.8.3"]) + end +end diff --git a/vendor/gems/specifications/rake-0.8.3.gemspec b/vendor/gems/specifications/rake-0.8.3.gemspec new file mode 100644 index 0000000..3b8e366 --- /dev/null +++ b/vendor/gems/specifications/rake-0.8.3.gemspec @@ -0,0 +1,31 @@ +Gem::Specification.new do |s| + s.name = %q{rake} + s.version = "0.8.3" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["Jim Weirich"] + s.date = %q{2008-09-24} + s.default_executable = %q{rake} + s.description = %q{Rake is a Make-like program implemented in Ruby. Tasks and dependencies are specified in standard Ruby syntax.} + s.email = %q{jim@weirichhouse.org} + s.executables = ["rake"] + s.extra_rdoc_files = ["README", "MIT-LICENSE", "TODO", "CHANGES", "doc/glossary.rdoc", "doc/proto_rake.rdoc", "doc/rakefile.rdoc", "doc/rational.rdoc", "doc/release_notes/rake-0.4.14.rdoc", "doc/release_notes/rake-0.4.15.rdoc", "doc/release_notes/rake-0.5.0.rdoc", "doc/release_notes/rake-0.5.3.rdoc", "doc/release_notes/rake-0.5.4.rdoc", "doc/release_notes/rake-0.6.0.rdoc", "doc/release_notes/rake-0.7.0.rdoc", "doc/release_notes/rake-0.7.1.rdoc", "doc/release_notes/rake-0.7.2.rdoc", "doc/release_notes/rake-0.7.3.rdoc", "doc/release_notes/rake-0.8.0.rdoc", "doc/release_notes/rake-0.8.2.rdoc", "doc/release_notes/rake-0.8.3.rdoc"] + s.files = ["install.rb", "CHANGES", "MIT-LICENSE", "Rakefile", "README", "TODO", "bin/rake", "lib/rake/classic_namespace.rb", "lib/rake/clean.rb", "lib/rake/contrib/compositepublisher.rb", "lib/rake/contrib/ftptools.rb", "lib/rake/contrib/publisher.rb", "lib/rake/contrib/rubyforgepublisher.rb", "lib/rake/contrib/sshpublisher.rb", "lib/rake/contrib/sys.rb", "lib/rake/gempackagetask.rb", "lib/rake/loaders/makefile.rb", "lib/rake/packagetask.rb", "lib/rake/rake_test_loader.rb", "lib/rake/rdoctask.rb", "lib/rake/ruby182_test_unit_fix.rb", "lib/rake/runtest.rb", "lib/rake/tasklib.rb", "lib/rake/testtask.rb", "lib/rake/win32.rb", "lib/rake.rb", "test/capture_stdout.rb", "test/check_expansion.rb", "test/contrib/test_sys.rb", "test/data/rakelib/test1.rb", "test/data/rbext/rakefile.rb", "test/filecreation.rb", "test/functional.rb", "test/in_environment.rb", "test/rake_test_setup.rb", "test/reqfile.rb", "test/reqfile2.rb", "test/session_functional.rb", "test/shellcommand.rb", "test/test_application.rb", "test/test_clean.rb", "test/test_definitions.rb", "test/test_earlytime.rb", "test/test_extension.rb", "test/test_file_creation_task.rb", "test/test_file_task.rb", "test/test_filelist.rb", "test/test_fileutils.rb", "test/test_ftp.rb", "test/test_invocation_chain.rb", "test/test_makefile_loader.rb", "test/test_multitask.rb", "test/test_namespace.rb", "test/test_package_task.rb", "test/test_pathmap.rb", "test/test_rake.rb", "test/test_require.rb", "test/test_rules.rb", "test/test_task_arguments.rb", "test/test_task_manager.rb", "test/test_tasklib.rb", "test/test_tasks.rb", "test/test_test_task.rb", "test/test_top_level_functions.rb", "test/test_win32.rb", "test/data/imports/deps.mf", "test/data/sample.mf", "test/data/chains/Rakefile", "test/data/default/Rakefile", "test/data/dryrun/Rakefile", "test/data/file_creation_task/Rakefile", "test/data/imports/Rakefile", "test/data/multidesc/Rakefile", "test/data/namespace/Rakefile", "test/data/statusreturn/Rakefile", "test/data/unittest/Rakefile", "test/data/unittest/subdir", "doc/example", "doc/example/a.c", "doc/example/b.c", "doc/example/main.c", "doc/example/Rakefile1", "doc/example/Rakefile2", "doc/glossary.rdoc", "doc/jamis.rb", "doc/proto_rake.rdoc", "doc/rake.1.gz", "doc/rakefile.rdoc", "doc/rational.rdoc", "doc/release_notes", "doc/release_notes/rake-0.4.14.rdoc", "doc/release_notes/rake-0.4.15.rdoc", "doc/release_notes/rake-0.5.0.rdoc", "doc/release_notes/rake-0.5.3.rdoc", "doc/release_notes/rake-0.5.4.rdoc", "doc/release_notes/rake-0.6.0.rdoc", "doc/release_notes/rake-0.7.0.rdoc", "doc/release_notes/rake-0.7.1.rdoc", "doc/release_notes/rake-0.7.2.rdoc", "doc/release_notes/rake-0.7.3.rdoc", "doc/release_notes/rake-0.8.0.rdoc", "doc/release_notes/rake-0.8.2.rdoc", "doc/release_notes/rake-0.8.3.rdoc"] + s.has_rdoc = true + s.homepage = %q{http://rake.rubyforge.org} + s.rdoc_options = ["--line-numbers", "--inline-source", "--main", "README", "--title", "Rake -- Ruby Make"] + s.require_paths = ["lib"] + s.rubyforge_project = %q{rake} + s.rubygems_version = %q{1.2.0} + s.summary = %q{Ruby based make-like utility.} + + if s.respond_to? :specification_version then + current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION + s.specification_version = 2 + + if current_version >= 3 then + else + end + else + end +end diff --git a/vendor/gems/specifications/rubyforge-1.0.1.gemspec b/vendor/gems/specifications/rubyforge-1.0.1.gemspec new file mode 100644 index 0000000..966bc89 --- /dev/null +++ b/vendor/gems/specifications/rubyforge-1.0.1.gemspec @@ -0,0 +1,32 @@ +Gem::Specification.new do |s| + s.name = %q{rubyforge} + s.version = "1.0.1" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["Ryan Davis", "Eric Hodel", "Ara T Howard"] + s.date = %q{2008-10-21} + s.default_executable = %q{rubyforge} + s.description = %q{A script which automates a limited set of rubyforge operations. * Run 'rubyforge help' for complete usage. * Setup: For first time users AND upgrades to 0.4.0: * rubyforge setup (deletes your username and password, so run sparingly!) * edit ~/.rubyforge/user-config.yml * rubyforge config * For all rubyforge upgrades, run 'rubyforge config' to ensure you have latest. * Don't forget to login! logging in will store a cookie in your .rubyforge directory which expires after a time. always run the login command before any operation that requires authentication, such as uploading a package.} + s.email = ["ryand-ruby@zenspider.com", "drbrain@segment7.net", "ara.t.howard@gmail.com"] + s.executables = ["rubyforge"] + s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"] + s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile", "bin/rubyforge", "lib/rubyforge.rb", "lib/rubyforge/client.rb", "lib/rubyforge/cookie_manager.rb", "test/test_rubyforge.rb", "test/test_rubyforge_client.rb", "test/test_rubyforge_cookie_manager.rb"] + s.has_rdoc = true + s.homepage = %q{http://codeforpeople.rubyforge.org/rubyforge/} + s.rdoc_options = ["--main", "README.txt"] + s.require_paths = ["lib"] + s.rubyforge_project = %q{codeforpeople} + s.rubygems_version = %q{1.2.0} + s.summary = %q{A script which automates a limited set of rubyforge operations} + s.test_files = ["test/test_rubyforge.rb", "test/test_rubyforge_client.rb", "test/test_rubyforge_cookie_manager.rb"] + + if s.respond_to? :specification_version then + current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION + s.specification_version = 2 + + if current_version >= 3 then + else + end + else + end +end