2
2
3
3
#--
4
4
5
- # Copyright (c) 2003, 2004, 2005, 2006 Jim Weirich
5
+ # Copyright (c) 2003, 2004, 2005, 2006, 2007 Jim Weirich
6
6
#
7
7
# Permission is hereby granted, free of charge, to any person obtaining a copy
8
8
# of this software and associated documentation files (the "Software"), to
@@ -303,15 +303,19 @@ class Task
303
303
# Application owning this task.
304
304
attr_accessor :application
305
305
306
- # Comment for this task.
307
- attr_accessor :comment
306
+ # Comment for this task. Restricted to a single line of no more than 50
307
+ # characters.
308
+ attr_reader :comment
309
+
310
+ # Full text of the (possibly multi-line) comment.
311
+ attr_reader :full_comment
308
312
309
313
# Array of nested namespaces names used for task lookup by this task.
310
314
attr_reader :scope
311
315
312
316
# List of arguments to the task
313
317
attr_accessor :args
314
-
318
+
315
319
# Return task name
316
320
def to_s
317
321
name
@@ -335,11 +339,13 @@ def initialize(task_name, app)
335
339
@prerequisites = FileList [ ]
336
340
@actions = [ ]
337
341
@already_invoked = false
342
+ @full_comment = nil
338
343
@comment = nil
339
344
@lock = Mutex . new
340
345
@application = app
341
346
@scope = app . current_scope
342
347
@args = [ ]
348
+ @arg_names = nil
343
349
end
344
350
345
351
# Enhance a task with prerequisites or actions. Returns self.
@@ -353,6 +359,35 @@ def enhance(deps=nil, &block)
353
359
def name
354
360
@name . to_s
355
361
end
362
+
363
+ # Name of task with argument list description.
364
+ def name_with_args # :nodoc:
365
+ if arg_description
366
+ "#{ name } #{ arg_description } "
367
+ else
368
+ name
369
+ end
370
+ end
371
+
372
+ # Argument description (nil if none).
373
+ def arg_description # :nodoc:
374
+ @arg_names ? "[#{ ( arg_names || [ ] ) . join ( ',' ) } ]" : nil
375
+ end
376
+
377
+ # Hash of argument names to argument positions (0 based). (empty if no
378
+ # named arguments).
379
+ def arg_map
380
+ result = { }
381
+ arg_names . each_with_index do |n , i |
382
+ result [ n ] = i
383
+ end
384
+ result
385
+ end
386
+
387
+ # Name of arguments for this task.
388
+ def arg_names
389
+ @arg_names || [ ]
390
+ end
356
391
357
392
# Invoke the task if it is needed. Prerequites are invoked first.
358
393
def invoke
@@ -370,10 +405,22 @@ def invoke
370
405
# Invoke all the prerequisites of a task.
371
406
def invoke_prerequisites
372
407
@prerequisites . each { |n |
373
- application [ n , @scope ] . invoke
408
+ prereq = application [ n , @scope ]
409
+ setup_arguments ( prereq )
410
+ prereq . invoke
374
411
}
375
412
end
376
413
414
+ # Setup the arguments to be passed to prerequesites.
415
+ def setup_arguments ( prereq ) # :nodoc:
416
+ if ! arg_names . empty? && ! prereq . arg_names . empty?
417
+ prereq . args = prereq . arg_names . collect do |name |
418
+ arg_map [ name ] ? args [ arg_map [ name ] ] : nil
419
+ end
420
+ end
421
+ end
422
+ private :setup_arguments
423
+
377
424
# Format the trace flags for display.
378
425
def format_trace_flags
379
426
flags = [ ]
@@ -416,17 +463,45 @@ def timestamp
416
463
@prerequisites . collect { |p | application [ p ] . timestamp } . max || Time . now
417
464
end
418
465
466
+ # Add a description to the task. The description can consist of an option
467
+ # argument list (enclosed brackets) and an optional comment.
468
+ def add_description ( description )
469
+ return if ! description
470
+ if description =~ %r{\A \s *(\[ ([^\] ]*)\] )\s *(.*)\Z }m
471
+ arg_string = $2
472
+ comment = $3. strip
473
+ else
474
+ comment = description . strip
475
+ end
476
+ set_arg_names ( arg_string ) if arg_string
477
+ add_comment ( comment ) if comment && ! comment . empty?
478
+ end
479
+
419
480
# Add a comment to the task. If a comment alread exists, separate
420
481
# the new comment with " / ".
421
482
def add_comment ( comment )
422
- return if ! comment
423
- if @comment
424
- @comment << " / "
483
+ if @full_comment
484
+ @full_comment << " / "
485
+ else
486
+ @full_comment = ''
487
+ end
488
+ @full_comment << comment
489
+ if @full_comment =~ /\A ([^.]+?\. )/
490
+ @comment = $1
425
491
else
426
- @comment = ''
492
+ @comment = @full_comment
493
+ end
494
+ if @comment . length > 50
495
+ @comment = @comment [ 0 , 47 ] + "..."
427
496
end
428
- @comment << comment
429
497
end
498
+ private :add_comment
499
+
500
+ # Set the names of the arguments for this task.
501
+ def set_arg_names ( arg_string )
502
+ @arg_names = arg_string . split ( ',' ) . collect { |n | n . strip }
503
+ end
504
+ private :set_arg_names
430
505
431
506
# Return a string describing the internal state of a task. Useful for
432
507
# debugging.
@@ -673,8 +748,8 @@ def rule(args, &block)
673
748
# runtests
674
749
# end
675
750
#
676
- def desc ( comment )
677
- Rake . application . last_comment = comment
751
+ def desc ( description )
752
+ Rake . application . last_description = description
678
753
end
679
754
680
755
# Import the partial Rakefiles +fn+. Imported files are loaded _after_ the
@@ -1442,14 +1517,15 @@ def tasks
1442
1517
# The TaskManager module is a mixin for managing tasks.
1443
1518
module TaskManager
1444
1519
# Track the last comment made in the Rakefile.
1445
- attr_accessor :last_comment
1520
+ attr_accessor :last_description
1521
+ alias :last_comment :last_description # Backwards compatibility
1446
1522
1447
1523
def initialize
1448
1524
super
1449
1525
@tasks = Hash . new
1450
1526
@rules = Array . new
1451
1527
@scope = Array . new
1452
- @last_comment = nil
1528
+ @last_description = nil
1453
1529
end
1454
1530
1455
1531
def create_rule ( args , &block )
@@ -1464,8 +1540,8 @@ def define_task(task_class, args, &block)
1464
1540
deps = [ deps ] unless deps . respond_to? ( :to_ary )
1465
1541
deps = deps . collect { |d | d . to_s }
1466
1542
task = intern ( task_class , task_name )
1467
- task . add_comment ( @last_comment )
1468
- @last_comment = nil
1543
+ task . add_description ( @last_description )
1544
+ @last_description = nil
1469
1545
task . enhance ( deps , &block )
1470
1546
task
1471
1547
end
@@ -1658,38 +1734,40 @@ class Application
1658
1734
DEFAULT_RAKEFILES = [ 'rakefile' , 'Rakefile' , 'rakefile.rb' , 'Rakefile.rb' ] . freeze
1659
1735
1660
1736
OPTIONS = [ # :nodoc:
1661
- [ '--dry-run' , '-n' , GetoptLong ::NO_ARGUMENT ,
1662
- "Do a dry run without executing actions." ] ,
1737
+ [ '--classic-namespace' , '-C' , GetoptLong ::NO_ARGUMENT ,
1738
+ "Put Task and FileTask in the top level namespace" ] ,
1739
+ [ '--describe' , '-D' , GetoptLong ::OPTIONAL_ARGUMENT ,
1740
+ "Describe the tasks (matching optional PATTERN), then exit." ] ,
1741
+ [ '--rakefile' , '-f' , GetoptLong ::OPTIONAL_ARGUMENT ,
1742
+ "Use FILE as the rakefile." ] ,
1743
+ [ '--usage' , '-h' , GetoptLong ::NO_ARGUMENT ,
1744
+ "Display usage." ] ,
1663
1745
[ '--help' , '-H' , GetoptLong ::NO_ARGUMENT ,
1664
1746
"Display this help message." ] ,
1665
1747
[ '--libdir' , '-I' , GetoptLong ::REQUIRED_ARGUMENT ,
1666
1748
"Include LIBDIR in the search path for required modules." ] ,
1667
- [ '--rakelibdir ' , '-R ', GetoptLong ::REQUIRED_ARGUMENT ,
1668
- "Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib') " ] ,
1749
+ [ '--dry-run ' , '-n ', GetoptLong ::NO_ARGUMENT ,
1750
+ "Do a dry run without executing actions. " ] ,
1669
1751
[ '--nosearch' , '-N' , GetoptLong ::NO_ARGUMENT ,
1670
1752
"Do not search parent directories for the Rakefile." ] ,
1671
1753
[ '--prereqs' , '-P' , GetoptLong ::NO_ARGUMENT ,
1672
1754
"Display the tasks and dependencies, then exit." ] ,
1673
1755
[ '--quiet' , '-q' , GetoptLong ::NO_ARGUMENT ,
1674
1756
"Do not log messages to standard output." ] ,
1675
- [ '--rakefile' , '-f' , GetoptLong ::OPTIONAL_ARGUMENT ,
1676
- "Use FILE as the rakefile." ] ,
1677
1757
[ '--require' , '-r' , GetoptLong ::REQUIRED_ARGUMENT ,
1678
1758
"Require MODULE before executing rakefile." ] ,
1759
+ [ '--rakelibdir' , '-R' , GetoptLong ::REQUIRED_ARGUMENT ,
1760
+ "Auto-import any .rake files in RAKELIBDIR. (default is 'rakelib')" ] ,
1679
1761
[ '--silent' , '-s' , GetoptLong ::NO_ARGUMENT ,
1680
1762
"Like --quiet, but also suppresses the 'in directory' announcement." ] ,
1681
1763
[ '--tasks' , '-T' , GetoptLong ::OPTIONAL_ARGUMENT ,
1682
1764
"Display the tasks (matching optional PATTERN) with descriptions, then exit." ] ,
1683
1765
[ '--trace' , '-t' , GetoptLong ::NO_ARGUMENT ,
1684
1766
"Turn on invoke/execute tracing, enable full backtrace." ] ,
1685
- [ '--usage' , '-h' , GetoptLong ::NO_ARGUMENT ,
1686
- "Display usage." ] ,
1687
1767
[ '--verbose' , '-v' , GetoptLong ::NO_ARGUMENT ,
1688
1768
"Log message to standard output (default)." ] ,
1689
1769
[ '--version' , '-V' , GetoptLong ::NO_ARGUMENT ,
1690
1770
"Display the program version." ] ,
1691
- [ '--classic-namespace' , '-C' , GetoptLong ::NO_ARGUMENT ,
1692
- "Put Task and FileTask in the top level namespace" ] ,
1693
1771
]
1694
1772
1695
1773
# Initialize a Rake::Application object.
@@ -1851,9 +1929,29 @@ def display_tasks_and_comments
1851
1929
displayable_tasks = tasks . select { |t |
1852
1930
t . comment && t . name =~ options . show_task_pattern
1853
1931
}
1854
- width = displayable_tasks . collect { |t | t . name . length } . max
1855
- displayable_tasks . each do |t |
1856
- printf "#{ name } %-#{ width } s # %s\n " , t . name , t . comment
1932
+ if options . full_description
1933
+ displayable_tasks . each do |t |
1934
+ puts "task #{ t . name_with_args } "
1935
+ t . full_comment . each do |line |
1936
+ puts " #{ line } "
1937
+ end
1938
+ puts
1939
+ end
1940
+ else
1941
+ width = displayable_tasks . collect { |t | t . name_with_args . length } . max
1942
+ max_column = 80 - name . size - width - 7
1943
+ displayable_tasks . each do |t |
1944
+ printf "#{ name } %-#{ width } s # %s\n " ,
1945
+ t . name_with_args , truncate ( t . comment , max_column )
1946
+ end
1947
+ end
1948
+ end
1949
+
1950
+ def truncate ( string , width )
1951
+ if string . length <= width
1952
+ string
1953
+ else
1954
+ string [ 0 , width -3 ] + "..."
1857
1955
end
1858
1956
end
1859
1957
@@ -1874,6 +1972,10 @@ def command_line_options
1874
1972
# Do the option defined by +opt+ and +value+.
1875
1973
def do_option ( opt , value )
1876
1974
case opt
1975
+ when '--describe'
1976
+ options . show_tasks = true
1977
+ options . show_task_pattern = Regexp . new ( value || '.' )
1978
+ options . full_description = true
1877
1979
when '--dry-run'
1878
1980
verbose ( true )
1879
1981
nowrite ( true )
@@ -1911,6 +2013,7 @@ def do_option(opt, value)
1911
2013
when '--tasks'
1912
2014
options . show_tasks = true
1913
2015
options . show_task_pattern = Regexp . new ( value || '.' )
2016
+ options . full_description = false
1914
2017
when '--trace'
1915
2018
options . trace = true
1916
2019
verbose ( true )
0 commit comments