build-tool 0.5.7 → 0.6.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. data/.gitignore +1 -0
  2. data/.rvmrc +1 -0
  3. data/.yardopts +1 -0
  4. data/Gemfile +5 -0
  5. data/Gemfile.lock +56 -0
  6. data/History.txt +64 -0
  7. data/README.txt +0 -7
  8. data/Rakefile +8 -56
  9. data/bin/build-tool +4 -1
  10. data/build-tool.gemspec +62 -0
  11. data/db/migrations/20110703074000_add_command_logs.rb +17 -0
  12. data/db/migrations/20110703075000_add_module_logs.rb +20 -0
  13. data/db/migrations/20110815170000_add_features.rb +17 -0
  14. data/db/migrations/20120103204700_add_modules.rb +17 -0
  15. data/db/migrations/20120106181200_add_settings.rb +18 -0
  16. data/lib/build-tool.rb +3 -4
  17. data/lib/build-tool/application.rb +127 -37
  18. data/lib/build-tool/build-system/autoconf.rb +2 -8
  19. data/lib/build-tool/build-system/base.rb +12 -4
  20. data/lib/build-tool/build-system/cmake.rb +2 -0
  21. data/lib/build-tool/build-system/custom.rb +2 -0
  22. data/lib/build-tool/build-system/kdel10n.rb +2 -0
  23. data/lib/build-tool/build-system/make.rb +2 -0
  24. data/lib/build-tool/build-system/none.rb +2 -0
  25. data/lib/build-tool/build-system/qmake.rb +2 -0
  26. data/lib/build-tool/build-system/qt.rb +4 -0
  27. data/lib/build-tool/cfg/lexer.rex +40 -8
  28. data/lib/build-tool/cfg/lexer_base.rb +3 -1
  29. data/lib/build-tool/cfg/node.rb +17 -1
  30. data/lib/build-tool/cfg/parser.y +92 -10
  31. data/lib/build-tool/cfg/visitor.rb +202 -78
  32. data/lib/build-tool/command_actions.rb +26 -10
  33. data/lib/build-tool/commands.rb +289 -197
  34. data/lib/build-tool/commands/build.rb +13 -9
  35. data/lib/build-tool/commands/configuration.rb +25 -0
  36. data/lib/build-tool/commands/configuration/edit.rb +42 -0
  37. data/lib/build-tool/commands/configuration/list.rb +48 -0
  38. data/lib/build-tool/commands/configure.rb +9 -5
  39. data/lib/build-tool/commands/ctags.rb +8 -3
  40. data/lib/build-tool/commands/environments.rb +2 -4
  41. data/lib/build-tool/commands/environments/list.rb +13 -10
  42. data/lib/build-tool/commands/environments/set.rb +5 -1
  43. data/lib/build-tool/commands/features.rb +24 -0
  44. data/lib/build-tool/commands/features/disable.rb +70 -0
  45. data/lib/build-tool/commands/features/enable.rb +66 -0
  46. data/lib/build-tool/commands/features/list.rb +92 -0
  47. data/lib/build-tool/commands/fetch.rb +9 -3
  48. data/lib/build-tool/commands/files.rb +9 -5
  49. data/lib/build-tool/commands/gc.rb +48 -15
  50. data/lib/build-tool/commands/history.rb +21 -16
  51. data/lib/build-tool/commands/info.rb +16 -13
  52. data/lib/build-tool/commands/install.rb +8 -4
  53. data/lib/build-tool/commands/modules.rb +2 -4
  54. data/lib/build-tool/commands/modules/cleanup.rb +52 -0
  55. data/lib/build-tool/commands/modules/disable.rb +95 -0
  56. data/lib/build-tool/commands/modules/enable.rb +52 -0
  57. data/lib/build-tool/commands/modules/info.rb +44 -35
  58. data/lib/build-tool/commands/modules/list.rb +67 -15
  59. data/lib/build-tool/commands/modules/shell.rb +8 -2
  60. data/lib/build-tool/commands/rebase.rb +15 -7
  61. data/lib/build-tool/commands/recipes.rb +2 -4
  62. data/lib/build-tool/commands/recipes/add.rb +16 -2
  63. data/lib/build-tool/commands/recipes/edit.rb +72 -0
  64. data/lib/build-tool/commands/recipes/incoming.rb +11 -7
  65. data/lib/build-tool/commands/recipes/info.rb +12 -8
  66. data/lib/build-tool/commands/recipes/install.rb +37 -42
  67. data/lib/build-tool/commands/recipes/list.rb +6 -2
  68. data/lib/build-tool/configuration.rb +88 -3
  69. data/lib/build-tool/environment.rb +2 -0
  70. data/lib/build-tool/errors.rb +5 -0
  71. data/lib/build-tool/history.rb +3 -181
  72. data/lib/build-tool/model/command_log.rb +93 -0
  73. data/lib/build-tool/model/feature.rb +80 -0
  74. data/lib/build-tool/{module.rb → model/module.rb} +110 -29
  75. data/lib/build-tool/model/module_log.rb +64 -0
  76. data/lib/build-tool/model/setting.rb +84 -0
  77. data/lib/build-tool/recipe.rb +40 -18
  78. data/lib/build-tool/repository.rb +39 -33
  79. data/lib/build-tool/server.rb +27 -3
  80. data/lib/build-tool/singleton.rb +2 -0
  81. data/lib/build-tool/sshkey.rb +2 -0
  82. data/lib/build-tool/state_helper.rb +64 -0
  83. data/lib/build-tool/vcs/archive.rb +3 -1
  84. data/lib/build-tool/vcs/base.rb +13 -0
  85. data/lib/build-tool/vcs/git-svn.rb +36 -14
  86. data/lib/build-tool/vcs/git.rb +180 -44
  87. data/lib/build-tool/vcs/mercurial.rb +25 -13
  88. data/lib/build-tool/vcs/svn.rb +20 -15
  89. data/lib/build-tool/version.rb +30 -0
  90. data/lib/mj/error.rb +2 -0
  91. data/lib/mj/logging.rb +2 -0
  92. data/lib/mj/mixins/inherited_attributes.rb +73 -0
  93. data/lib/mj/tools/editor.rb +34 -0
  94. data/lib/mj/tools/ssh.rb +2 -0
  95. data/lib/mj/tools/subprocess.rb +2 -1
  96. data/lib/mj/vcs/git.rb +14 -2
  97. data/lib/mj/visitor.rb +22 -0
  98. data/tasks/db.rake +36 -0
  99. data/tasks/racc.rake +14 -0
  100. data/tasks/rdoc.rake +8 -0
  101. data/tasks/rexical.rake +14 -0
  102. data/tasks/test.rake +21 -0
  103. data/test/integration/history_test.rb +88 -0
  104. data/test/integration/parser_configuration.rb +36 -0
  105. data/test/integration/parser_environment_parser.rb +156 -0
  106. data/test/integration/parser_feature_test.rb +75 -0
  107. data/test/integration/parser_git-svn_test.rb +92 -0
  108. data/test/integration/parser_git_test.rb +97 -0
  109. data/test/integration/parser_mercurial_test.rb +77 -0
  110. data/test/integration/parser_module_test.rb +103 -0
  111. data/test/integration/parser_svn_test.rb +92 -0
  112. data/test/integration/parser_test.rb +73 -0
  113. data/test/test_helper.rb +61 -0
  114. data/test/unit/configuration_test.rb +36 -0
  115. data/test/unit/git_configuration_test.rb +163 -0
  116. data/test/unit/git_svn_configuration_test.rb +240 -0
  117. data/test/unit/mercurial_configuration_test.rb +64 -0
  118. data/test/unit/model/command_log_test.rb +103 -0
  119. data/test/unit/model/feature_test.rb +29 -0
  120. data/test/unit/model/module_log_test.rb +70 -0
  121. data/test/unit/model/module_test.rb +32 -0
  122. data/test/unit/repository_test.rb +110 -0
  123. data/test/unit/server_test.rb +66 -0
  124. data/test/unit/svn_configuration_test.rb +90 -0
  125. metadata +134 -93
  126. data/Manifest.txt +0 -80
  127. data/db/migrations/001_command_histories.rb +0 -20
  128. data/db/migrations/002_module_events.rb +0 -24
  129. data/db/migrations/003_command_histories_add_logfile.rb +0 -19
  130. data/lib/build-tool/GUI.rb +0 -360
  131. data/lib/build-tool/commands/help.rb +0 -22
  132. data/lib/build-tool/commands/lsfeatures.rb +0 -76
  133. data/lib/build-tool/feature.rb +0 -47
@@ -1,3 +1,7 @@
1
+ # -*- coding: UTF-8 -*-
2
+
3
+ require 'mj/tools/ssh'
4
+
1
5
  require "build-tool/singleton"
2
6
  require 'build-tool/errors'
3
7
  require 'build-tool/command_actions'
@@ -76,6 +80,7 @@ class Base
76
80
  class UsageError < BuildTool::Error; end
77
81
 
78
82
  include HelpText
83
+ include ANSI::Code
79
84
 
80
85
  def <=> (other)
81
86
  return self.name <=> other.name
@@ -94,6 +99,7 @@ def initialize(parent = nil)
94
99
  @skip_command = false
95
100
  @parent = parent
96
101
  @cmd = nil
102
+ setup_options
97
103
  end
98
104
 
99
105
  def applicable?
@@ -107,37 +113,7 @@ def configuration
107
113
  def initialize_options
108
114
  end
109
115
 
110
- def complete_readline_1_8( string )
111
- # Readline in 1.8 does not provide all needed information. We have to hand made
112
- # it ourselves. We get the complete commandline here.
113
-
114
- # We want the complete commandline in line_buffer
115
- line_buffer = string
116
- # An array of completed arguments/options in args
117
- args = Shellwords.shellwords( line_buffer )
118
-
119
- # And the string to complete in string. If the last character is a space we
120
- # complete from that. if not we take the last arg
121
- if line_buffer.empty? or line_buffer[-1] == 32
122
- args << ""
123
- end
124
-
125
- do_complete_1_8( args )
126
- end
127
-
128
- def do_complete_1_8( args )
129
- # puts "do_complete_1_8( #{args.inspect} )"
130
- compl = complete_arguments( args )
131
- if compl.length >= 1
132
- return compl.collect do |res|
133
- args.dup[0..-2].push(res).join(" ")
134
- end
135
- else
136
- return []
137
- end
138
- end
139
-
140
- def complete_readline_1_9( string )
116
+ def complete_readline( string )
141
117
  # We have three sources of information (ruby 1.9 only)
142
118
  # argument:
143
119
  # See Readline::completer_word_break_characters . The part
@@ -148,7 +124,7 @@ def complete_readline_1_9( string )
148
124
  # The position of the cursor in commandline
149
125
  # Ruby 1.9 <start>
150
126
  # First check if we have to complete the first shellword (command)
151
- args = Shellwords.shellwords( string )
127
+ args = Shellwords.shellwords( Readline.line_buffer )
152
128
 
153
129
  # And the string to complete in string. If the last character is a space we
154
130
  # complete from that. if not we take the last arg
@@ -156,19 +132,7 @@ def complete_readline_1_9( string )
156
132
  args << ""
157
133
  end
158
134
 
159
- do_complete_1_9( args )
160
- end
161
-
162
- def do_complete_1_9( args )
163
- return complete_arguments( args )
164
- end
165
-
166
- def complete( string )
167
- if Readline.respond_to? "line_buffer"
168
- complete_readline_1_9( string )
169
- else
170
- complete_readline_1_8( string )
171
- end
135
+ do_complete( args )
172
136
  end
173
137
 
174
138
  def complete_arguments( args )
@@ -187,6 +151,11 @@ def complete_arguments( args )
187
151
  res.flatten.compact.sort
188
152
  end
189
153
 
154
+ def do_complete( args )
155
+ return complete_arguments( args )
156
+ do_complete( args )
157
+ end
158
+
190
159
  def each_option
191
160
  list = options.instance_variable_get( "@stack" )
192
161
  if block_given?
@@ -197,7 +166,11 @@ def each_option
197
166
  end
198
167
  end
199
168
  else
200
- list.collect { |l| l.list.collect { |sw| sw unless sw.is_a? String } }.flatten.compact
169
+ list.collect { |l|
170
+ l.list.collect { |sw|
171
+ sw unless not sw.is_a? OptionParser::Switch
172
+ }
173
+ }.flatten.compact
201
174
  end
202
175
  end
203
176
 
@@ -217,40 +190,49 @@ def summarize
217
190
  # Cleanup after vcs_access
218
191
  def cleanup_after_vcs_access
219
192
  if MJ::Tools::SSH::has_keys?
220
- logger.info ""
221
- logger.info "#### Cleaning up the ssh keys"
193
+ info( "" )
194
+ info( "#### Cleaning up the ssh keys" )
222
195
  MJ::Tools::SSH::keys.each do |file|
223
- logger.info " - Removing key #{file}"
196
+ info( " - Removing key #{file}" )
224
197
  end
225
198
  MJ::Tools::SSH::cleanup()
226
199
  end
227
200
  end
228
201
 
229
- def execute( args )
202
+ def setup_options
230
203
  @options = OptionParser.new
231
204
  @options.set_program_name( name )
232
- @options.separator long_description if long_description
233
-
234
- @parsing = true
205
+ if long_description
206
+ @options.separator ''
207
+ @options.separator long_description
208
+ end
235
209
  initialize_options
210
+ end
211
+
212
+ def execute( args )
213
+ # Reinitialize the option parser.
214
+ setup_options
236
215
  begin
237
216
  realargs = @options.parse( args )
238
217
  rescue OptionParser::ParseError => e
239
- logger.error( "#{e}" )
218
+ error( "#{name}: #{e}" )
240
219
  @skip_command = true
241
220
  end
242
- @parsing = false
243
221
 
244
222
  setup_command
245
223
 
246
224
  # Log the command into history
247
225
  state = BuildTool::History::CommandLog::FINISHED_SUCCESSFUL
248
226
  rc = -1 # -1 for @skip_command
249
- if log?
250
- @cmd = BuildTool::History::CommandLog.new( :command => "#{self.fullname} #{args.join( ' ')}", :logdir => log_directory )
251
- @cmd.started
252
- end
253
227
  if !@skip_command
228
+ # Initialize the command log if necessary
229
+ if log?
230
+ @cmd = BuildTool::History::CommandLog.new(
231
+ :command => "#{self.fullname} #{args.join( ' ')}",
232
+ :logdir => log_directory.to_s.encode( 'UTF-8' ) )
233
+ @cmd.started
234
+ end
235
+ # Now execute the command
254
236
  begin
255
237
  rc = do_execute( realargs )
256
238
  if rc != 0
@@ -258,8 +240,8 @@ def execute( args )
258
240
  end
259
241
  rescue BuildTool::Error => e
260
242
  state = BuildTool::History::CommandLog::FINISHED_WITH_ERRORS
261
- logger.error e.message
262
- logger.verbose e.backtrace.join("\n")
243
+ error( e.message )
244
+ verbose( e.backtrace.join("\n") )
263
245
  rc = -1
264
246
  rescue Interrupt => e
265
247
  state = BuildTool::History::CommandLog::CANCELED_BY_USER
@@ -303,7 +285,7 @@ def log?
303
285
 
304
286
  def show_help( args = [] )
305
287
  # Just ignore potential arguments
306
- say @options.help
288
+ info( options.help )
307
289
  skip_command
308
290
  return 0
309
291
  end
@@ -314,12 +296,42 @@ def skip_command
314
296
  @skip_command = true
315
297
  end
316
298
 
317
- def say( *args )
299
+ # Print out a normal message (if enabled)
300
+ def info( *args )
318
301
  logger.info( *args )
319
302
  end
320
303
 
304
+ # Print out a verbose message (if enabled)
305
+ def verbose( *args )
306
+ logger.verbose( *args )
307
+ end
308
+
309
+ # Print out a verbose message (if enabled)
310
+ def trace( *args )
311
+ logger.trace( *args )
312
+ end
313
+
314
+ # Print out a verbose message (if enabled)
315
+ def debug( *args )
316
+ logger.debug( *args )
317
+ end
318
+
319
+ def debug2( *args )
320
+ logger.debug2( *args )
321
+ end
322
+
323
+ # Print out a warning message (if enabled)
324
+ def warn( *args )
325
+ logger.warn( *args )
326
+ end
327
+
328
+ # Print out a error message (if enabled)
329
+ def error( *args )
330
+ logger.error( *args )
331
+ end
332
+
321
333
  def usage( error )
322
- logger.error error
334
+ error( error )
323
335
  show_help
324
336
  return -2
325
337
  end
@@ -348,12 +360,11 @@ def initialize( *args )
348
360
  end
349
361
 
350
362
  def initialize_options
363
+ options.separator ''
351
364
  options.separator "Common options"
352
365
 
353
366
  options.on( "-v", "--verbose", "Enable verbose output" ) do
354
- Logging.appenders['stdout'].level = [ Logging.appenders['stdout'].level-1, 0 ].max
355
- Logging.logger['MJ::Logging::LoggerAdapter'].level =
356
- [ Logging.logger['MJ::Logging::LoggerAdapter'].level - 1, 0 ].max
367
+ Logging.appenders['stdout'].level = [ Logging.appenders['stdout'].level - 1, 0 ].max()
357
368
  end
358
369
 
359
370
  options.on( nil, "--dry-run", "Enable dry run." ) do
@@ -365,10 +376,20 @@ def initialize_options
365
376
  end
366
377
  end
367
378
 
379
+ # Complete buildsets
380
+ def complete_buildsets( name )
381
+ if name == ':all'
382
+ return complete_modules( '*' )
383
+ end
384
+ end
385
+
368
386
  # Gathers all modules currently known.
369
387
  #
370
388
  # @param all Return template modules too.
371
389
  def complete_modules( name, include_templates = false )
390
+ if name.start_with? ':'
391
+ return complete_buildsets( name )
392
+ end
372
393
  res = []
373
394
  found = false
374
395
  should_be_unique = false
@@ -388,14 +409,15 @@ def complete_modules( name, include_templates = false )
388
409
  elsif mod.name == name
389
410
  found = true
390
411
  should_be_unique = true
412
+ take_module = true
413
+ elsif name == '*'
414
+ found = true
391
415
  # Now check if it is active.
392
416
  next if !( mod.active? || @all )
393
417
  take_module = true
394
418
  elsif mod.name.end_with?( "/#{name}" )
395
419
  found = true
396
420
  should_be_unique = true
397
- # Now check if it is active.
398
- next if !( mod.active? || @all )
399
421
  take_module = true
400
422
  end
401
423
 
@@ -422,7 +444,7 @@ def complete_modules( name, include_templates = false )
422
444
  end
423
445
 
424
446
  # Give a warning if all modules where
425
- logger.warn "All modules for #{name} are inactive! Will ignore it." if res.empty?
447
+ warn( "All modules for #{name} are inactive! Will ignore it." ) if res.empty?
426
448
  return res
427
449
  end
428
450
 
@@ -439,13 +461,13 @@ def while_logging_to( dir, fname, level, &block )
439
461
  got_exception = false
440
462
  # Only create a logfile if we do real work
441
463
  if log?
442
- dirname = log_directory.to_s
443
- dirname = "#{log_directory.to_s}/#{dir}" if dir
464
+ dirname = log_directory
465
+ dirname += dir if dir
444
466
  FileUtils.mkdir_p( dirname )
445
467
  Logging.logger['root'].add_appenders(
446
468
  Logging.appenders.file(
447
469
  fname,
448
- :filename => dirname + '/' + fname,
470
+ :filename => dirname + fname,
449
471
  :layout => Logging::Layouts::Pattern.new( :pattern => '%m\n' ),
450
472
  :level => level ))
451
473
  end
@@ -453,18 +475,18 @@ def while_logging_to( dir, fname, level, &block )
453
475
  begin
454
476
  yield
455
477
  rescue Interrupt => e
456
- logger.error "User Interrupt!"
478
+ error( "User Interrupt!" )
457
479
  rescue BuildTool::Error => e
458
- logger.error "#{e.message}"
480
+ error( "#{e.message}" )
459
481
  got_exception = true
460
482
  raise e
461
483
  rescue Exception => e
462
- logger.error "#{e.class}:#{e.message}"
484
+ error( "#{e.class}:#{e.message}" )
463
485
  got_exception = true
464
486
  raise e
465
487
  ensure
466
488
  Logging.logger['root'].remove_appenders( fname )
467
- logger.info("More information in #{dirname}/#{fname}") if got_exception
489
+ info( "More information in #{dirname}/#{fname}" ) if got_exception
468
490
  end
469
491
  end
470
492
 
@@ -527,7 +549,8 @@ def write( event )
527
549
  @pbar.clear() if @pbar
528
550
  @oldlogger.append(event)
529
551
  rescue Exception => e
530
- puts e
552
+ error( e )
553
+ verbose( e.backtrace.join("\n") )
531
554
  end
532
555
  end
533
556
  end
@@ -545,7 +568,7 @@ def initialize( *args )
545
568
  end
546
569
 
547
570
  def initialize_options
548
- options.on( "--resume-from [module]", "Skip all module before module." ) { |t|
571
+ options.on( "--resume-from MODULE", "Skip all module before module." ) { |t|
549
572
  begin
550
573
  @resume_from = complete_module( t )
551
574
  rescue UsageError => e
@@ -553,7 +576,7 @@ def initialize_options
553
576
  end
554
577
  raise UsageError, "Both --resume-from and --resume-after specified!" if @resume_after
555
578
  }
556
- options.on( "--resume-after [module]", "Skip all module before and including module." ) { |t|
579
+ options.on( "--resume-after MODULE", "Skip all module before and including module." ) { |t|
557
580
  begin
558
581
  @resume_after = complete_module( t )
559
582
  rescue UsageError => e
@@ -592,14 +615,27 @@ def do_execute( args )
592
615
  end
593
616
 
594
617
  # 2. Check if the modules are ready
595
- logger.info( '#### Checking for obstacles' )
618
+ info( '#### Checking for obstacles' )
596
619
  isready = true
597
620
  ModuleProgressbar.new( 'Modules', modules ) do |mod|
598
- isready &= is_module_ready?( mod )
621
+ begin
622
+ isready &= is_module_ready?( mod )
623
+ rescue Interrupt => e
624
+ info( "User Interrupt" )
625
+ return -1
626
+ rescue BuildTool::Error => e
627
+ error( e.message )
628
+ verbose( e.backtrace.join("\n") )
629
+ raise
630
+ rescue Exception => e
631
+ error( "#{e.class}:#{e.message}" )
632
+ verbose( e.backtrace.join("\n") )
633
+ raise
634
+ end
599
635
  end
600
636
 
601
637
  if !isready
602
- logger.error "There were some problems detected. Exiting."
638
+ error( "There were some problems detected. Exiting." )
603
639
  return -1
604
640
  end
605
641
 
@@ -608,13 +644,21 @@ def do_execute( args )
608
644
  begin
609
645
  isready &= prepare_module( mod )
610
646
  rescue Interrupt => e
611
- logger.info( "User Interrupt" )
647
+ info( "User Interrupt" )
612
648
  return -1
649
+ rescue BuildTool::Error => e
650
+ error( e.message )
651
+ verbose( e.backtrace.join("\n") )
652
+ raise
653
+ rescue Exception => e
654
+ error( "#{e.class}:#{e.message}" )
655
+ verbose( e.backtrace.join("\n") )
656
+ raise
613
657
  end
614
658
  end
615
659
 
616
660
  if !isready
617
- logger.error "Unexpected problems encountered. Exiting."
661
+ error( "Unexpected problems encountered. Exiting." )
618
662
  return -1
619
663
  end
620
664
 
@@ -630,25 +674,25 @@ def do_execute( args )
630
674
 
631
675
  begin
632
676
 
633
- logger.info ""
634
- logger.info "#### Module #{mod.name} (#{index+1}/#{modules.size})"
677
+ info( "" )
678
+ info( "#### Module #{mod.name} (#{index+1}/#{modules.size})" )
635
679
  do_execute_module( mod )
636
680
  rescue Interrupt => e
637
681
  raise e
638
682
  rescue BuildTool::Error => e
639
- logger.error e.message
640
- logger.verbose e.backtrace.join("\n")
683
+ error( e.message )
684
+ verbose( e.backtrace.join("\n") )
641
685
  @failed_modules << mod.name
642
686
  rc = -1
643
687
  break if @stop_on_error
644
688
  rescue Exception => e
645
- logger.error "#{e.class}:#{e.message}"
646
- logger.verbose e.backtrace.join("\n")
689
+ error( "#{e.class}:#{e.message}" )
690
+ verbose( e.backtrace.join("\n") )
647
691
  @failed_modules << mod.name
648
692
  rc = -1
649
693
  break if @stop_on_error
650
694
  ensure
651
- logger.info "#### Module #{mod.name} finished"
695
+ info( "#### Module #{mod.name} finished" )
652
696
  end
653
697
  end
654
698
 
@@ -661,12 +705,12 @@ def do_execute( args )
661
705
  end
662
706
 
663
707
  def summarize
664
- logger.info ""
708
+ info( "" )
665
709
  if !@failed_modules.empty?
666
- logger.info "#### Finished with errors"
667
- logger.info "Failed modules:\n\t#{ @failed_modules.join( "\n\t" ) }"
710
+ info( "#### Finished with errors" )
711
+ info( "Failed modules:\n\t#{ @failed_modules.join( "\n\t" ) }" )
668
712
  else
669
- logger.info "#### Finished without errors"
713
+ info( "#### Finished without errors" )
670
714
  end
671
715
  end
672
716
 
@@ -716,8 +760,8 @@ def make( mod, *args )
716
760
  # Call the #rebase method of the module.
717
761
  #
718
762
  # @param [Object] mod The module to use
719
- def rebase( mod )
720
- ModuleActions::Rebase.new( self, mod ).do
763
+ def rebase( mod, verbose = false )
764
+ ModuleActions::Rebase.new( self, mod, verbose ).do
721
765
  end
722
766
 
723
767
  # Call the #reconfigure method of the module.
@@ -727,11 +771,18 @@ def reconfigure( mod )
727
771
  ModuleActions::Reconfigure.new( self, mod ).do
728
772
  end
729
773
 
730
- # Call the #clear_build_directory method of the module.
774
+ # Call the #remove_build_directory method of the module.
775
+ #
776
+ # @param [Object] mod The module to use
777
+ def remove_build_directory( mod, force = false )
778
+ ModuleActions::RemoveBuildDirectory.new( self, mod, force ).do
779
+ end
780
+
781
+ # Call the #remove_source_directory method of the module.
731
782
  #
732
783
  # @param [Object] mod The module to use
733
- def remove_build_directory( mod )
734
- ModuleActions::RemoveBuildDirectory.new( self, mod ).do
784
+ def remove_source_directory( mod, force = false )
785
+ ModuleActions::RemoveSourceDirectory.new( self, mod, force ).do
735
786
  end
736
787
 
737
788
  end
@@ -747,8 +798,21 @@ def initialize( *args )
747
798
  @commands = []
748
799
  end
749
800
 
801
+ def initialize_options()
802
+ options.banner = "Usage: #{name} [OPTIONS]... COMMAND [COMMAND OPTIONS]..."
803
+
804
+ options.on( "-h", "--help", "Show this help text." ) do
805
+ show_help
806
+ end
807
+
808
+ options.separator( '' )
809
+ options.separator( "Use '#{name} help' to see a list of commands" )
810
+
811
+ super()
812
+ end
813
+
750
814
  def add_command( cmd )
751
- logger.trace "#{name}: Adding command #{cmd.name}"
815
+ trace( "#{name}: Adding command #{cmd.name}" )
752
816
  @commands << cmd
753
817
  end
754
818
 
@@ -765,77 +829,63 @@ def get_command( name )
765
829
  end
766
830
 
767
831
  def execute( args )
768
- # There has to be a subcommand
769
- if args.length == 0
770
- return show_help
832
+ debug2( '%s: %s' % [ name, args ] )
833
+
834
+ # Reinitialize the option parser.
835
+ setup_options
836
+
837
+ # Parse our options. Store the rest for later.
838
+ begin
839
+ args = @options.order( args )
840
+ rescue OptionParser::ParseError => e
841
+ error( "#{name}: #{e}" )
842
+ return -1
771
843
  end
772
844
 
773
- cmd = get_command( args[0] )
774
- if cmd.nil?
775
- if self.name
776
- raise UsageError, "Unknown command #{args[0]} for #{self.name}"
777
- else
778
- raise UsageError, "Unknown command #{args[0]}"
845
+ setup_command
846
+
847
+ begin
848
+
849
+ # There has to be a subcommand
850
+ if args.length == 0
851
+ return default_command()
779
852
  end
780
- end
781
- cmd.execute( args[1..-1] )
782
- end
783
853
 
784
- def do_complete_1_8( args )
785
- # puts "#{self.name}.do_complete_1_8( #{args.inspect}"
786
- if args.length <= 1
787
- # There is only one or no argument. We try to complete to a
788
- # command.
789
- if subcmd = get_command( args[0] )
790
- # We have a exact match. If we had to complete to get to
791
- # the commands return here. If not forward to the command
792
- if args[0] != subcmd.name
793
- return [ subcmd.name ]
854
+ # Always accept help as a command
855
+ return help_commands() if args[0] == 'help'
856
+
857
+ # Now follow up with real ones.
858
+ cmd = get_command( args[0] )
859
+ if cmd.nil?
860
+ if self.name
861
+ raise UsageError, "Unknown command #{args[0]} for #{self.name}"
794
862
  else
795
- return subcmd.do_complete_1_8( [""] ).collect do |res|
796
- [ subcmd.name ].push(res).join(" ")
797
- end
798
- end
799
- else
800
- # We have a no exact match. Complete the available
801
- # commands
802
- return complete_command( args[0] )
803
- end
804
- else
805
- # At least two arguments are present
806
- if subcmd = get_command( args[0] )
807
- # We have a exact match. Forward to that command.
808
- return subcmd.do_complete_1_8( args[1..-1] ).collect do |res|
809
- [ subcmd.name ].push(res).join(" ")
863
+ raise UsageError, "Unknown command #{args[0]}"
810
864
  end
811
- else
812
- # No exact match. Since there is at least on argument
813
- # behind the current position just keep the user input
814
- # intact.
815
- return []
816
865
  end
866
+
867
+ cmd.execute( args[1..-1] )
868
+ ensure
869
+
870
+ teardown_command
817
871
  end
818
872
  end
819
873
 
820
- def do_complete_1_9( args )
821
- # puts "#{self.name}.do_complete_1_9( #{args.inspect} )"
822
- if args.length <= 1
823
- if subcmd = get_command( args[0] )
824
- return subcmd.do_complete_1_9( [""] )
825
- else
826
- return complete_command( args[0] )
827
- end
874
+ def do_complete( args )
875
+ cur = args[0]
876
+ # Check if we have a match for one command
877
+ if subcmd = get_command( cur )
878
+ # Check if the commands is complete. If not complete it.
879
+ return [ subcmd.name() ] if cur != subcmd.name()
880
+ # It is complete. forward.
881
+ return subcmd.do_complete( args[1..-1] )
828
882
  else
829
- if subcmd = get_command( args[0] )
830
- return subcmd.do_complete_1_9( args[1..-1] )
831
- else
832
- return args
833
- end
883
+ # No match. Give back possible matches.
884
+ return complete_command( cur )
834
885
  end
835
886
  end
836
887
 
837
888
  def complete_command( cmdname )
838
- # puts "#{self.name}.complete_command( #{cmdname.inspect} )"
839
889
  cmds = @commands.collect { |com|
840
890
  com.name if com.name.start_with? cmdname
841
891
  }.compact
@@ -850,27 +900,8 @@ def complete_arguments( args, string )
850
900
  end
851
901
  end
852
902
 
853
- def show_help( args = [] )
854
- if args.length == 0
855
- @commands.sort.each do |cmd|
856
- say "%-20s: %s" % [ cmd.name, cmd.description ]
857
- end
858
- else
859
- if cmd = get_command( args[0] )
860
- cmd.show_help( args[1..-1] )
861
- else
862
- if self.name
863
- raise UsageError, "Unknown command #{args[0]} for #{self.name}"
864
- else
865
- raise UsageError, "Unknown command #{args[0]}"
866
- end
867
- end
868
- end
869
- return 0
870
- end
871
-
872
903
  def load_commands( path, parentmod, submod = nil )
873
- logger.debug "load_commands( #{path} #{parentmod.inspect} #{submod.inspect}"
904
+ debug( "load_commands( #{path} #{parentmod.inspect} #{submod.inspect}" )
874
905
  # Load all available ruby files in path
875
906
  Dir[ "#{path}/*.rb" ].each do |mod|
876
907
  load "#{mod}"
@@ -913,6 +944,19 @@ def load_commands( path, parentmod, submod = nil )
913
944
 
914
945
  end
915
946
 
947
+ def show_help()
948
+ super()
949
+ end
950
+
951
+ def help_commands( args = [] )
952
+ @commands.sort.each do |cmd|
953
+ info( "%-20s: %s" % [ cmd.name, cmd.description ] )
954
+ end
955
+ return 0
956
+ end
957
+
958
+ alias :default_command :help_commands
959
+
916
960
  end # class SubCommands
917
961
 
918
962
  #
@@ -920,23 +964,73 @@ def load_commands( path, parentmod, submod = nil )
920
964
  #
921
965
  class Shell < SubCommands
922
966
 
923
- name "shell"
967
+ def name
968
+ return Pathname.new($0).basename.to_s
969
+ end
924
970
 
925
- def execute( args )
926
- if args.length == 0
927
- return cli
971
+ def initialize_options
972
+ options.banner = "Usage: #{name} [OPTIONS]... COMMAND [COMMAND OPTIONS]..."
973
+
974
+ options.separator ''
975
+ options.separator "Options"
976
+
977
+ options.on( "-v", "--verbose", "Enable verbose output" ) do
978
+ Logging.appenders['stdout'].level = [ Logging.appenders['stdout'].level - 1, 0 ].max()
928
979
  end
929
- super
980
+
981
+ options.on( nil, "--dry-run", "Enable dry run." ) do
982
+ $noop = true
983
+ end
984
+
985
+ options.on( "-V", "--version", "Print version information." ) do
986
+ show_version
987
+ end
988
+
989
+ options.on( "--ionice", "Set io io niceness to idle (3)." ) { |n|
990
+
991
+ pid = Process.pid()
992
+ system( "ionice -p #{pid} -c 3" )
993
+ cur = `ionice -p #{pid}`
994
+ info( 'Process priority (io niceness): %s' % cur )
995
+ }
996
+
997
+ options.on( "--nice N", "Set niceness to N." ) { |n|
998
+ if not /^[0-9]+$/.match( n )
999
+ raise OptionParser::ParseError.new( 'value "%s" is not a number' % n )
1000
+ end
1001
+
1002
+ # Set the priority
1003
+ Process.setpriority( Process::PRIO_PROCESS, 0, n.to_i() )
1004
+
1005
+ # Check if it worked.
1006
+ cur = Process.getpriority( Process::PRIO_PROCESS, 0 )
1007
+ if n.to_i() != cur
1008
+ warn( 'Process priority (niceness): %d (%d was given)' % [ cur, n ] )
1009
+ else
1010
+ info( 'Process priority (niceness): %d' % [ cur ] )
1011
+ end
1012
+ }
1013
+
1014
+ options.on( "--debug-db", "Debug the database." ) do
1015
+ Logging.logger['ActiveRecord'].level = :debug
1016
+ end
1017
+
1018
+ super()
1019
+ end
1020
+
1021
+ def setup_command
1022
+ # And the commands require all that database related stuff.
1023
+ load_commands( Application::instance.application_root.join( "lib/build-tool/commands" ), BuildTool::Commands )
1024
+ end
1025
+
1026
+ def show_version
1027
+ @skip_command = true
1028
+ info( "#{name()}: Version #{BuildTool::VERSION}" )
930
1029
  end
931
1030
 
932
1031
  def cli
933
1032
  require 'readline'
934
-
935
- Readline.completion_proc = method(:complete)
936
- if !Readline.respond_to? "line_buffer"
937
- # 1.8 :(
938
- Readline.completer_word_break_characters = "\x00"
939
- end
1033
+ Readline.completion_proc = method(:complete_readline)
940
1034
 
941
1035
  while true
942
1036
 
@@ -958,13 +1052,13 @@ def cli
958
1052
  execute Shellwords.shellwords( line )
959
1053
 
960
1054
  rescue BuildTool::Error => e
961
- logger.error e.message
962
- logger.verbose e.backtrace.join("\n")
1055
+ error( e.message )
1056
+ verbose( e.backtrace.join("\n") )
963
1057
  rescue StandardError => e
964
- logger.error e.message
965
- logger.error e.backtrace.join("\n")
1058
+ error( e.message )
1059
+ error( e.backtrace.join("\n") )
966
1060
  rescue Interrupt => e
967
- say "Use CTRL-D for exit!"
1061
+ info( "Use CTRL-D for exit!" )
968
1062
  end
969
1063
 
970
1064
  end
@@ -972,9 +1066,7 @@ def cli
972
1066
  return 0
973
1067
  end
974
1068
 
975
- def fullname
976
- nil
977
- end
1069
+ alias :default_command :cli
978
1070
 
979
1071
  end # class Shell
980
1072