Module: Tasks
Overview
Tasks is the namespace in which to define task generators.
Class Method Summary collapse
-
.avail(name, &cond) ⇒ Object
Used to set task generator availablity condition.
-
.available ⇒ Object
Used to determine task generator availablity.
Instance Method Summary collapse
-
#announce(name, &data) ⇒ Object
Announce.
-
#backup(name, &data) ⇒ Object
Backup.
-
#count(name, &data) ⇒ Object
Count.
-
#doap(name, &data) ⇒ Object
Doap.
-
#extest(name, &data) ⇒ Object
ExTest (Extract Tests).
-
#file(name, &exe) ⇒ Object
File.
-
#info(name) ⇒ Object
Info.
-
#manifest(name, &data) ⇒ Object
Manifest.
-
#package(name, &data) ⇒ Object
Package.
-
#publish(name, &data) ⇒ Object
Publish.
-
#rdoc(name, &data) ⇒ Object
RDoc.
-
#release(name, &data) ⇒ Object
Release.
-
#scaffold(name) ⇒ Object
Scaffold.
-
#setup(name, &data) ⇒ Object
Setup.
-
#template(name) ⇒ Object
Template.
-
#test(name, &data) ⇒ Object
Test.
Methods included from Reap::TaskUtils
#ask, #initialize, #master, #preq_from_name, #provide_setup_rb, #sh, #tell
Class Method Details
.avail(name, &cond) ⇒ Object
Used to set task generator availablity condition.
31 32 33 |
# File 'lib/reap/tasks.rb', line 31 def self.avail( name, &cond ) available[name] = cond end |
.available ⇒ Object
Used to determine task generator availablity. – TODO This is kind of a weak point in the design, I think. And tasks themselves also need to have Rake’s #needed? feature. ++
25 26 27 |
# File 'lib/reap/tasks.rb', line 25 def self.available @available ||= {} end |
Instance Method Details
#announce(name, &data) ⇒ Object
Announce
The announce task is intended for sending out a nice formated email message to a mailing address, especially mailing-lists.
Announcement specific settings:
server Email server to route message.
port Email server's port.
domain Email server's domain name.
account Email account name.
type Login type, either plain, cram_md5 or login.
secure Uses TLS security, true or false?
to Email address to send announcemnt.
from Email address sent from.
subject Subject of email message.
links Array of http links to related sites.
file File that contains announcement message.
memo Embedded announcement message.
slogan Motto for you project.
Inherited settings:
title Project title.
summary Brief one-line description.
description Long description of project.
homepage Project homepage web address.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/reap/tasks.rb', line 65 def announce( name, &data ) require 'reap/class/announce.rb' desc "Email project announcement" unless desc task name do data = data.to_openobject data.title ||= master.title data.description ||= master.description data.version ||= master.version data.from ||= master.email Reap::Announce.new( data ).write_and_email end end |
#backup(name, &data) ⇒ Object
Backup
Backup your project to a backup directory. The location of the backup will be under the backup dir
given in the backup section of the ProjectInfo file, then under the name of the project’s dir and a subdirectory of today’s date. For example, today reap itself was backed up to:
../BACKUPS/reap/2006-06-21/reap
Backup specific settings:
dir The backup directory (eg. '../BACKUPS').
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/reap/tasks.rb', line 97 def backup( name, &data ) desc "Backup project folder" unless desc task name do data = data.to_openobject if data.dir bdir = ::File.join( ::File.basename(Dir.pwd), Time.now.strftime("%Y_%m_%d") ) bdir = ::File.join( data.dir, bdir ) if File.exist?( bdir ) and not $FORCE tell bdir tell "Backup folder already exists. Use -f to overwrite." else if $PRETEND puts "rm -r #{bdir}" puts "mkdir -p #{bdir}" puts "cp -r #{Dir.pwd} #{bdir}" else FileUtils.rm_r( bdir ) if File.exist?( bdir ) FileUtils.mkdir_p( bdir ) FileUtils.cp_r( Dir.pwd, bdir) end tell "Completed backup to '#{bdir}'." end else tell "No backup 'dir' setting given for backup task." end end end |
#count(name, &data) ⇒ Object
Count
Count the file and lines of code in your project.
dir The directory of scripts to count.
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 |
# File 'lib/reap/tasks.rb', line 281 def count( name, &data ) desc "Line count project scripts" unless desc task name do data = data.to_openobject incl = data.include || 'lib/**/*' fc, l, c, t, bt, r, rb = 0, 0, 0, 0, false, 0, false Dir.glob( incl ).each do |fname| next unless fname =~ /.*rb/ # TODO should this be done? fc += 1 File.open( fname ) do |f| while line = f.gets l += 1 next if line =~ /^\s*$/ case line when /^=begin\s+test/ tb = true; t+=1 when /^=begin/ rb = true; r+=1 when /^=end/ r+=1 if !(rb or tb) (rb = false; r+=1) if rb (tb = false; t+=1) if tb when /^\s*#/ r += 1 else c+=1 if !(rb or tb) r+=1 if rb t+=1 if tb end end end end s = l - c - r puts "FILES: #{fc}, LINES: #{l}, CODE: #{c}, DOC: #{r}, TEST: #{t}, SPACE: #{s}" end end |
#doap(name, &data) ⇒ Object
Doap
This task generates an XML DOAP project file.
DOAP is an XML/RTF format for describing a project. It contains much of the same information as Reap’s ProjectInfo file, but is more suitable to RESTful interapplication communications, like RSS/Atom feeds –useful to project tracking sites.
The task gets almost all of the required parametes from the root node (i.e. master) of ProjectInfo file.
140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/reap/tasks.rb', line 140 def doap( name, &data ) require 'reap/class/doap.rb' desc "Generate DOAP project file" unless desc task name do data = data.to_openobject Reap::Doap.new( data.__merge__( master ) ).call end end |
#extest(name, &data) ⇒ Object
ExTest (Extract Tests)
This task scans every package script looking for sections of the form:
=begin test
...
=end
With appropriate headers, it copies these sections to files in your project’s test/ dir, which then can be run using the Reap test task. The exact directory layout of the files to be tested is reflected in the test directory. You can then use Reap’s test task to run the tests.
Specific Settings:
dir Specify the test directory. Default is 'test'.
files Specify files to extract. Default is 'lib/**/*.rb'.
176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/reap/tasks.rb', line 176 def extest( name, &data ) require 'reap/class/extest.rb' desc "Extract embedded unit tests from scripts" unless desc task name do data = data.to_openobject Reap::ExTest.new( data ).extract end end |
#file(name, &exe) ⇒ Object
File
191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/reap/tasks.rb', line 191 def file( name, &exe ) require 'reap/class/filer' name, source = preq_from_name( name ) task name do Reap::Filer.new( name, source, &exe ).build end end |
#info(name) ⇒ Object
Info
Displays the ProjectInfo file. This task is of little use –it’s easy enough to look at a ProjectInfo file with less or your favorite editor. Mainly this task serves as a development example.
210 211 212 213 214 215 216 217 218 |
# File 'lib/reap/tasks.rb', line 210 def info( name ) desc "Display ProjectInfo file" unless desc task name do puts ProjectInfo.instance.info_stream end end |
#manifest(name, &data) ⇒ Object
Manifest
Create a manifest file for the package. Presently it is a very simple md5 + filename manifest. In the future this will be exanded to build a varity of manifest formats.
Task specific settings:
include Files to include
exclude Files to exclude from the included.
334 335 336 337 338 339 340 341 342 343 344 345 |
# File 'lib/reap/tasks.rb', line 334 def manifest( name, &data ) require 'reap/class/manifest' desc "Create a MANIFEST file for this package" unless desc task name do data = data.to_openobject Reap::Manifest.new( data ).generate end end |
#package(name, &data) ⇒ Object
Package
This task creates standard .zip, .tgz, or .tbz packages, plus .gem or .deb distributions.
Builds distribution packages. The package task supports tar.gz, tar.bz2, zip source packages and gem, pacman and debian ditribution packages.
Task specific settings:
dir Directory in which to store distributions.
include Files to include in distribution.
exclude Files to exclude from those.
distribute List of distribution types desired. Eg.
tgz, tar.gz, tbz, tar.bz2, zip
gem, deb, pac
project Project name.
category Software category.
architecture Can be any, i368, i686, ppc, etc.
dependencies List of packages this program depends.
recommends List of packages that can be used with this package.
replaces List of packages this one replaces.
executables Executable files in this distribution.
rules (see below)
RubyGems specific settings:
autorequire
platform
require_paths
The package task also has subsection for each type of distribution. These can be used to override settings in the package information if they in some way differ. Possible subsections are:
gems
pacman
debian
Finally there is one last parameter that you can use for creating packages called ‘rules’. The rules setting allows you to define how files are copied into the distribution package, so instead of a one to one copy of the included files, you can actually have a file placed in a different location within the distribution. This can be very handy if you wish to develop you project with one layout, but need to distribute it with another.
The rules parameter is a literal string that consists of one rule per line. A line consists three space separated entries.
from_path, file_glob, to_path
If no ‘to_path’ is given then it is considered the same as the ‘from_path’. It also supports two variables $name and $version which will be substitued any of these entries. Here is a possible example:
rules: |
lib **/* lib/$name/$version
This will move any file under lib/ to the equivalent location under lib/$name/$version/. The default set of rules is a mirror image transfer, spelled out it would be:
rules: |
bin *
ext **/*
lib **/*
data **/*
conf **/*
If your using Rolls against a normal project folder the alterntive is to create versioned paths, probably as follows:
rules: |
ext/$name **/* ext/$name/$version
lib/$name **/* lib/$name/$version
data/$name **/* ext/$name/$version
conf/$name **/* ext/$name/$version ?
Please note that the rules parameter is a new feature and is still considered beta.
427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 |
# File 'lib/reap/tasks.rb', line 427 def package( name, &data ) require 'reap/class/package' desc "Create distribution packages" unless desc task name do data = data.to_openobject data.name ||= master.name data.title ||= master.title data.version ||= master.version data.status ||= master.status data.series ||= master.series data. ||= master. data.maintainer ||= master.maintainer data.email ||= master.email data.summary ||= master.summary data.architecture ||= master.architecture data.license ||= master.license data.project ||= master.project data.homepage ||= master.homepage Reap::Package.new( data ).generate_packages end end |
#publish(name, &data) ⇒ Object
Publish
Publish documents to hosting service. Three means of publishing are current supported, ftp uploading, scp, and web convenience option that recognizes particular hosts (only RubyForge is currently supported).
type Type of publishing, 'web', 'scp' or 'ftp'.
host Host server, default is 'rubyforge.org'
username Username for host.
dir Directory of files to publish. Or,
copy Files to publish using from and to.
project Project name (used for Rubyforge)
If the type is ‘scp’ or ‘ftp’ you will also need to provide the root directory parameter.
root Document root directory at host.
The dir parameter allows you to simply specify a local directory, the contents of which will be published to host’s document root location (directory tree intact).
If you need more control over which files to publish where, you can use the copy parameter instead. Provide an array of pattern strings in the form of “from to”. If the desitination is the host’s document root you do not need to specify the to part. For example:
copy: [ 'web/*', 'doc/api/* doc/api' ]
The first copies the files under your project’s web directory to the host’s document root. The second copies your projects doc/api files to the doc/api location on the host.
When using the ‘scp’ type the internal template used for the outbound destination is ‘username@host:root/’.
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 |
# File 'lib/reap/tasks.rb', line 493 def publish( name, &data ) require 'reap/class/publish.rb' desc "Publish documents to the web or host" unless desc task name do data = data.to_openobject data.project ||= master.rubyforge.project || master.name data.username ||= master.rubyforge.username Reap::Publish.new( data ).publish end end |
#rdoc(name, &data) ⇒ Object
RDoc
This task generates RDoc API documentation from source comments.
Task specific settings:
dir Directory to store documentation [doc].
main File to use as main page of RDocs.
template Which RDoc template to use.
include Files to include in RDocs.
exclude Files to exclude from those.
options Pass-thru extra options to RDoc command.
Inherited settings:
title Project title to use in RDocs.
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 |
# File 'lib/reap/tasks.rb', line 529 def rdoc( name, &data ) require 'reap/class/rdoc' desc "Generate RDoc API documentation" unless desc task name do data = data.to_openobject data.title ||= master.title Reap::RDoc.new( data ).call end end |
#release(name, &data) ⇒ Object
Release
This task releases files to RubyForge –it should work with other GForge instaces or SourceForge clones too.
While defaults are nice, you may want a little more control. You can specify additional attributes:
dir Distribution directory
exclude Distribution types to exclude
host URL of host service
username Username of host service
project Project name at host
package Package name
date Date of release (defaults to Time.now)
groupid Group id number
processor Processor/Architecture (Any, i386, PPC, etc.)
release Release name (default is "%s")
is_public Public release?
changelog Change log file
notelog Release notes file
The release option can be a template by using %s in the string. The version number of your project will be sub’d in for the %s. This saves you from having to update the release name before every release.
572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 |
# File 'lib/reap/tasks.rb', line 572 def release( name, &data ) require 'reap/class/release' desc "Release distribution files" unless desc task name do data = data.to_openobject data.version = master.version data.project ||= master.rubyforge.project || master.name data.username ||= master.rubyforge.username data.package ||= master.rubyforge.package data.groupid ||= master.rubyforge.groupid Reap::Release.new( data ).release end end |
#scaffold(name) ⇒ Object
Scaffold
Generates a project directory layout within the current directory. The scaffolding includes all the standard features such as directories lib/ bin/ doc/ and files such as README.
To use this task you should first create an empty directory and than change into it. This command will not create a new project directory. As a safegaurd, this command will not generate scaffolding in a directory with files already present, unless you use the -f (force) option.
There are currently two types of supported scaffoldings: ‘standard’, which is the default if no type is given, and ‘subversion’ which creates a “trunk” hierarchy.
609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 |
# File 'lib/reap/tasks.rb', line 609 def scaffold( name ) desc "Generate a project directory layout" unless desc task name do |type| content = Dir.entries('.') - [ '.', '..' ] if not content.empty? and not $FORCE tell "Directory already has content. Use -f option to force scaffolding." return nil end type ||= 'standard' type = 'standard' if type == 'std' type = 'subversion' if type == 'svn' # gems workaround if dir = Gem.gempath('reap') dir = File.join( dir, 'data', 'reap', 'scaffold', type ) else dir = File.join( ::Config::CONFIG['datadir'], 'reap', 'scaffold', type ) end # unless File.directory?( dir ) tell "Unrecognized project type." else #FileUtils.mkdir_p( name ) FileUtils.cp_r( File.join( dir, '.'), '.' ) tell "Project ready." end end end |
#setup(name, &data) ⇒ Object
Setup
This task manually installs a project using setup.rb. If setup.rb doesn’t exist it will be created.
649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 |
# File 'lib/reap/tasks.rb', line 649 def setup( name, &data ) desc "Locally install package using setup.rb" unless desc task name do data = data.to_openobject data. ||= [] unless provide_setup_rb puts "Setup.rb is missing. Forced to cancel task." return nil end puts "Reap is shelling out work to setup.rb..." #-- # SHELL OUT! This will be fixed with swtich to Reap's installer instead of setup.rb. #++ exe = %{ruby setup.rb} exe << ' -q ' unless $VERBOSE exe << data..join(' ') exe << ' all' #success = false success = sh( exe ) puts "Setup complete!" if success end end |
#template(name) ⇒ Object
Template
Creates an empty ProjectInfo file in the current directory. It will not overwrite a ProjectInfo file if one is already present. Unlike ‘scaffold’, this is especially useful for pre-existing projects.
688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 |
# File 'lib/reap/tasks.rb', line 688 def template( name ) require 'facet/gem/self/gempath' desc "Create a ProjectInfo template" unless desc task name do f = nil if ::ProjectInfo::INFO_FILES.any?{ |f| File.exists?(f) } puts "Project file '#{f}' already exists." return end filename = 'ProjectInfo' # if using gems if dir = Gem.gempath('reap') dir = File.join( dir, 'data', 'reap', 'scaffold', 'standard' ) else dir = File.join( ::Config::CONFIG['datadir'], 'reap', 'scaffold', 'standard' ) end f = File.join( dir, filename ) raise "ProjectInfo template file #{f} is missing." unless File.file?( f ) # copy FileUtils.install( f, '.' ) tell "#{filename} created. You'll need to fill it out." end end |
#test(name, &data) ⇒ Object
Test
The Reap test class runs each test in it’s own proccess, making for a more pure test facility. Reap runs each test in a separate proccess to aviod potential conflicts between scripts.
files Test files (eg. test/tc_**/*.rb)
Defaults to typcial selection.
libs List of lookup directories to include in
load path. './lib' is always included.
live Flag to quickly deactive use of local libs.
Test against installed files instead.
requires List of any files to pre-require.
NOTE This works well enough but it is a tad delicate. It actually marshals test results across stdout->stdin shell pipe. One consequence of this is that you can’t send debug info to stdout in your tests (including #p and #puts).
743 744 745 746 747 748 749 750 751 752 753 754 |
# File 'lib/reap/tasks.rb', line 743 def test( name, &data ) require 'reap/class/test' desc "Run unit-tests (each in a separate process)" unless desc task name do data = data.to_openobject Reap::Test.new( data ).call end end |