build-tool 0.1.4 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data.tar.gz.sig +2 -3
  2. data/History.txt +29 -0
  3. data/Manifest.txt +39 -10
  4. data/README.txt +5 -8
  5. data/Rakefile +14 -6
  6. data/bin/build-tool +3 -35
  7. data/db/migrations/001_command_histories.rb +20 -0
  8. data/db/migrations/002_module_events.rb +24 -0
  9. data/db/migrations/003_command_histories_add_logfile.rb +19 -0
  10. data/lib/build-tool.rb +1 -1
  11. data/lib/build-tool/application.rb +103 -30
  12. data/lib/build-tool/build-system/autoconf.rb +69 -6
  13. data/lib/build-tool/build-system/base.rb +2 -25
  14. data/lib/build-tool/build-system/custom.rb +6 -19
  15. data/lib/build-tool/build-system/kdel10n.rb +39 -0
  16. data/lib/build-tool/build-system/none.rb +82 -0
  17. data/lib/build-tool/cfg/lexer.rb +133 -7
  18. data/lib/build-tool/cfg/lexer.rex +58 -6
  19. data/lib/build-tool/cfg/node.rb +13 -1
  20. data/lib/build-tool/cfg/parser.rb +519 -333
  21. data/lib/build-tool/cfg/parser.y +74 -11
  22. data/lib/build-tool/cfg/visitor.rb +182 -20
  23. data/lib/build-tool/command_actions.rb +202 -0
  24. data/lib/build-tool/commands.rb +193 -49
  25. data/lib/build-tool/commands/build.rb +13 -8
  26. data/lib/build-tool/commands/configure.rb +8 -3
  27. data/lib/build-tool/commands/environments.rb +4 -8
  28. data/lib/build-tool/commands/environments/list.rb +8 -0
  29. data/lib/build-tool/commands/fetch.rb +7 -2
  30. data/lib/build-tool/commands/gc.rb +53 -0
  31. data/lib/build-tool/commands/history.rb +111 -0
  32. data/lib/build-tool/commands/install.rb +6 -1
  33. data/lib/build-tool/commands/lsfeatures.rb +73 -0
  34. data/lib/build-tool/commands/modules.rb +3 -7
  35. data/lib/build-tool/commands/modules/info.rb +15 -6
  36. data/lib/build-tool/commands/modules/list.rb +10 -5
  37. data/lib/build-tool/commands/rebase.rb +6 -1
  38. data/lib/build-tool/commands/recipes.rb +3 -7
  39. data/lib/build-tool/configuration.rb +24 -1
  40. data/lib/build-tool/environment.rb +17 -3
  41. data/lib/build-tool/feature.rb +47 -0
  42. data/lib/build-tool/history.rb +173 -0
  43. data/lib/build-tool/module.rb +49 -90
  44. data/lib/build-tool/recipe.rb +5 -0
  45. data/lib/build-tool/vcs/archive.rb +140 -0
  46. data/lib/build-tool/vcs/base.rb +5 -5
  47. data/lib/build-tool/vcs/git-svn.rb +4 -0
  48. data/lib/build-tool/vcs/git.rb +4 -0
  49. data/lib/mj/logging.rb +11 -0
  50. data/recipes/{kdeqt4.6 → kde}/custom/qt/qtscriptgenerator/compile.sh +0 -0
  51. data/recipes/{kdeqt4.6 → kde}/custom/qt/qtscriptgenerator/configure.sh +0 -0
  52. data/recipes/{kdeqt4.6 → kde}/custom/qt/qtscriptgenerator/install.sh +0 -0
  53. data/recipes/kde/custom/scripting/pyqt4/compile.sh +10 -0
  54. data/recipes/kde/custom/scripting/pyqt4/configure.sh +14 -0
  55. data/recipes/kde/custom/scripting/pyqt4/install.sh +10 -0
  56. data/recipes/kde/custom/scripting/sip/compile.sh +10 -0
  57. data/recipes/kde/custom/scripting/sip/configure.sh +13 -0
  58. data/recipes/kde/custom/scripting/sip/install.sh +10 -0
  59. data/recipes/kde/files/xsession +8 -4
  60. data/recipes/kde/kde-bindings.recipe +22 -0
  61. data/recipes/kde/kde-core.recipe +104 -0
  62. data/recipes/kde/kde-devel.recipe +38 -0
  63. data/recipes/kde/kde-finance.recipe +17 -0
  64. data/recipes/kde/kde-graphics.recipe +27 -0
  65. data/recipes/kde/kde-kdevelop.recipe +116 -0
  66. data/recipes/kde/kde-l10n.recipe +14 -0
  67. data/recipes/kde/kde-multimedia.recipe +31 -0
  68. data/recipes/kde/kde-network.recipe +55 -0
  69. data/recipes/kde/kde-office.recipe +28 -0
  70. data/recipes/kde/kde-plasma.recipe +117 -0
  71. data/recipes/{kdeqt4.6/recipe → kde/kde-qt.recipe} +25 -57
  72. data/recipes/kde/kde-scripting.recipe +63 -0
  73. data/recipes/kde/kde-support.recipe +73 -0
  74. data/recipes/kde/kde-utils.recipe +22 -0
  75. data/recipes/kde/kde-webdev.recipe +41 -0
  76. data/recipes/kde/recipe +92 -532
  77. data/recipes/kde/recipe-local +58 -2
  78. data/recipes/kde/settings.yaml +17 -0
  79. data/recipes/kde43/recipe-local +58 -2
  80. data/test/test_configuration_parser.rb +76 -21
  81. data/test/test_feature.rb +34 -0
  82. data/test/test_history.rb +149 -0
  83. metadata +185 -30
  84. metadata.gz.sig +0 -0
  85. data/lib/build-tool/pluginbase.rb +0 -43
  86. data/recipes/kdeqt4.6/info.yaml +0 -7
  87. data/recipes/kdeqt4.6/recipe-local +0 -30
  88. data/recipes/kdeqt4.6/settings.yaml +0 -27
  89. data/tasks/rdoc.rake +0 -34
  90. data/test.rb +0 -28
@@ -0,0 +1,202 @@
1
+ require 'ftools'
2
+
3
+ module BuildTool
4
+
5
+ module ModuleActions
6
+
7
+ class Base
8
+
9
+ def initialize( command, prio, type, mod )
10
+ @command = command
11
+ @logdir = command.log_directory.join( mod.name )
12
+ @type = type
13
+ @prio = prio
14
+ @filename = "#{prio.to_s}_#{type.to_s}"
15
+ @logfile = @logdir.join( @filename )
16
+ @module = mod
17
+ end
18
+
19
+ def do
20
+ # Make sure the directory for this module exists
21
+ FileUtils.mkdir_p( @logdir ) if ! $noop
22
+
23
+ # Open the logfile and then execute the command
24
+ while_logging do
25
+ execute
26
+ end
27
+ end
28
+
29
+ #########
30
+ protected
31
+ #########
32
+
33
+ def while_logging( level = :trace, &block )
34
+ # Only create a logfile if we do real work
35
+ if !$noop
36
+ Logging.logger['root'].add_appenders(
37
+ Logging.appenders.file(
38
+ @filename,
39
+ :filename => @logfile,
40
+ :layout => Logging::Layouts::Pattern.new( :pattern => '%m\n' ),
41
+ :level => level ))
42
+ end
43
+
44
+ begin
45
+ # If there is an associated command_history entry, add a module_event entry
46
+ logentry = nil
47
+ state = History::ModuleLog::FINISHED_SUCCESSFUL
48
+ if @command.cmd
49
+ logentry = History::ModuleLog.new(
50
+ :module => @module.name,
51
+ :event => @type,
52
+ :logfile => @logfile)
53
+ @command.cmd.add_module_log(logentry)
54
+ logentry.started
55
+ end
56
+ logger.debug "Opening logfile #{@logfile}"
57
+ yield
58
+ rescue Interrupt => e
59
+ state = History::ModuleLog::CANCELED_BY_USER
60
+ logger.error "User Interrupt!"
61
+ raise e
62
+ rescue Exception => e
63
+ state = History::ModuleLog::FINISHED_WITH_ERRORS
64
+ logger.error "#{e.class}:#{e.message}"
65
+ got_exception = true
66
+ raise e
67
+ ensure
68
+ if logentry
69
+ logentry.finished( state )
70
+ end
71
+ Logging.logger['root'].remove_appenders( @filename )
72
+ logger.debug "Closing logfile #{@logfile}"
73
+ logger.info("More information in #{@logfile}") if got_exception
74
+ end
75
+ end
76
+
77
+ end
78
+
79
+ class Clean < Base
80
+
81
+ def initialize( command, mod, remove_build_directory )
82
+ super( command, 10, :clean, mod )
83
+ @remove_build_directory = remove_build_directory
84
+ end
85
+
86
+ def execute()
87
+ logger.info "Cleaning"
88
+ @module.clean( @remove_build_directory )
89
+ end
90
+
91
+ end
92
+
93
+ class Clone < Base
94
+
95
+ def initialize( command, mod )
96
+ super( command, 20, :fetch, mod )
97
+ end
98
+
99
+ def execute()
100
+ logger.info "Fetching"
101
+ @module.clone
102
+ end
103
+
104
+ end
105
+
106
+ class Fetch < Base
107
+
108
+ def initialize( command, mod )
109
+ super( command, 20, :fetch, mod )
110
+ if !mod.vcs_required.fetching_supported?
111
+ logger.info "Fetching/Rebase not supported by vcs #{mod.vcs.name}. Doing it in one step."
112
+ end
113
+ end
114
+
115
+ def execute()
116
+ logger.info "Fetching remote changes."
117
+ @module.fetch
118
+ end
119
+
120
+ end
121
+
122
+ class Rebase < Base
123
+
124
+ def initialize( command, mod )
125
+ super( command, 20, :rebase, mod )
126
+ if !mod.vcs_required.fetching_supported?
127
+ logger.info "Fetching not supported by vcs #{mod.vcs.name}. Doing nothing."
128
+ return
129
+ end
130
+ end
131
+
132
+ def execute()
133
+ logger.info "Rebasing"
134
+ @module.rebase
135
+ end
136
+
137
+ end
138
+
139
+ class Configure < Base
140
+
141
+ def initialize( command, mod )
142
+ super( command, 40, :configure, mod )
143
+ end
144
+
145
+ def execute()
146
+ logger.info "Configuring"
147
+ if !$noop and !@module.vcs_required.checkedout?
148
+ raise ConfigurationError, "Module is not checked out. Enable updating."
149
+ end
150
+ @module.configure
151
+ end
152
+
153
+ end
154
+
155
+ class Reconfigure < Base
156
+
157
+ def initialize( command, mod )
158
+ super( command, 40, :reconfigure, mod )
159
+ end
160
+
161
+ def execute()
162
+ logger.info "Reconfiguring"
163
+ if !$noop and !@module.vcs_required.checkedout?
164
+ raise ConfigurationError, "Module is not checked out. Enable updating."
165
+ end
166
+ @module.build_system_required.reconfigure
167
+ end
168
+
169
+ end
170
+
171
+ class Make < Base
172
+
173
+ def initialize( command, mod, target = nil )
174
+ super( command, 50, :compile, mod )
175
+ @target = target
176
+ end
177
+
178
+ def execute()
179
+ logger.info "Building"
180
+ @module.build_system_required.make( @target )
181
+ end
182
+
183
+ end
184
+
185
+ class Install < Base
186
+
187
+ def initialize( command, mod, fast = false )
188
+ super( command, 60, :install, mod )
189
+ @fast = fast
190
+ end
191
+
192
+ def execute()
193
+ logger.info "Installing"
194
+ @module.build_system_required.install( @fast )
195
+ end
196
+
197
+ end
198
+
199
+ end # module ModuleAction
200
+
201
+ end # module BuildTool
202
+
@@ -1,5 +1,7 @@
1
1
  require "build-tool/singleton"
2
2
  require 'build-tool/errors'
3
+ require 'build-tool/command_actions'
4
+ require 'build-tool/history'
3
5
  require 'shellwords'
4
6
  require 'optparse'
5
7
  require 'delegate'
@@ -70,15 +72,26 @@ module BuildTool; module Commands;
70
72
 
71
73
  include HelpText
72
74
 
75
+ def <=> (other)
76
+ return self.name <=> other.name
77
+ end
78
+
79
+ # The OptionParser instance associated with this command
73
80
  attr_reader :options
81
+
82
+ # The parent command if this is a sub command
74
83
  attr_reader :parent
75
84
 
85
+ # The commands entry in the history db or nil
86
+ attr_accessor :cmd
87
+
76
88
  def initialize(parent = nil)
77
89
  @options = OptionParser.new
78
90
  @options.set_program_name( name )
79
91
  initialize_options
80
92
  @skip_command = false
81
93
  @parent = parent
94
+ @cmd = nil
82
95
  end
83
96
 
84
97
  def applicable?
@@ -204,17 +217,57 @@ module BuildTool; module Commands;
204
217
  end
205
218
  @parsing = false
206
219
 
220
+ # Log the command into history
221
+ state = BuildTool::History::CommandLog::FINISHED_SUCCESSFUL
222
+ rc = -1 # -1 for @skip_command
223
+ if log?
224
+ @cmd = BuildTool::History::CommandLog.new( :command => "#{self.fullname} #{args.join( ' ')}", :logdir => log_directory )
225
+ @cmd.started
226
+ end
207
227
  if !@skip_command
208
228
  begin
209
- return do_execute( realargs )
229
+ rc = do_execute( realargs )
230
+ if rc != 0
231
+ state = BuildTool::History::CommandLog::FINISHED_WITH_ERRORS
232
+ end
210
233
  rescue BuildTool::Error => e
234
+ state = BuildTool::History::CommandLog::FINISHED_WITH_ERRORS
211
235
  logger.error e.message
212
236
  logger.verbose e.backtrace.join("\n")
237
+ rc = -1
238
+ rescue Interrupt => e
239
+ state = BuildTool::History::CommandLog::CANCELED_BY_USER
240
+ raise e
241
+ ensure
242
+ if @cmd
243
+ @cmd.finished( state )
244
+ @cmd = nil
245
+ end
213
246
  end
214
247
  end
215
248
 
216
249
  # Either we skipped the command or we catched an exception
217
- return -1;
250
+ return rc;
251
+ end
252
+
253
+ # Return the commands full name.
254
+ #
255
+ # The full name includes the parents name (if any).
256
+ #
257
+ # @return [String] The commands full name
258
+ #
259
+ def fullname
260
+ if parent.fullname
261
+ return parent.fullname + " " + name
262
+ else
263
+ return name
264
+ end
265
+ end
266
+
267
+ # Should this command be logged?
268
+ #
269
+ def log?
270
+ false
218
271
  end
219
272
 
220
273
  def show_help( args = [] )
@@ -297,15 +350,18 @@ module BuildTool; module Commands;
297
350
 
298
351
  def while_logging_to( dir, fname, level, &block )
299
352
  got_exception = false
300
- dirname = @log_directory
301
- dirname = "#{@log_directory}/#{dir}" if dir
302
- FileUtils.mkdir_p( dirname )
303
- Logging.logger['root'].add_appenders(
304
- Logging.appenders.file(
305
- fname,
306
- :filename => dirname + '/' + fname,
307
- :layout => Logging::Layouts::Pattern.new( :pattern => '%m\n' ),
308
- :level => level ))
353
+ # Only create a logfile if we do real work
354
+ if log?
355
+ dirname = log_directory.to_s
356
+ dirname = "#{log_directory.to_s}/#{dir}" if dir
357
+ FileUtils.mkdir_p( dirname )
358
+ Logging.logger['root'].add_appenders(
359
+ Logging.appenders.file(
360
+ fname,
361
+ :filename => dirname + '/' + fname,
362
+ :layout => Logging::Layouts::Pattern.new( :pattern => '%m\n' ),
363
+ :level => level ))
364
+ end
309
365
 
310
366
  begin
311
367
  yield
@@ -321,29 +377,45 @@ module BuildTool; module Commands;
321
377
  end
322
378
  end
323
379
 
324
- def initialize_log_directory
380
+ # On demand initialization
381
+ def log_directory
382
+ return @log_directory if @log_directory
383
+
384
+ # Get the root logfile directory
325
385
  logdir = configuration.log_directory
326
386
 
327
- # Ensure the base log directory exists
387
+ # Try to find the next log directory for today.
388
+ i = -1
389
+ begin
390
+ @log_directory = logdir.join( "#{Date.today.to_s}-%02d" % i+=1 )
391
+ end until !@log_directory.exist?
392
+
393
+ # If noop is active we are finished
394
+ return @log_directory if $noop
395
+
396
+ # Ensure the base log directory exists.
328
397
  if !File.exist? "#{logdir}"
329
398
  FileUtils.mkdir_p "#{logdir}"
330
399
  end
331
400
 
332
- i = -1
333
-
334
- begin
335
- @log_directory = "#{logdir}/#{Date.today.to_s}-%02d" % i+=1
336
- end until !File.exist?( @log_directory )
337
-
338
- FileUtils.mkdir_p( @log_directory )
401
+ # Create the latest symbolic link
402
+ FileUtils.mkdir_p( @log_directory.to_s )
339
403
  FileUtils.rm_f( "#{logdir}/latest" )
340
- FileUtils.ln_sf( @log_directory, "#{logdir}/latest" )
404
+ FileUtils.ln_sf( @log_directory.to_s, "#{logdir}/latest" )
405
+
406
+ @log_directory
341
407
  end
342
408
 
409
+
343
410
  end # class Standard
344
411
 
345
412
  class ModuleBasedCommand < Standard
346
413
 
414
+ def initialize( *args )
415
+ @all = false
416
+ super( *args )
417
+ end
418
+
347
419
  def is_module_ready?( mod )
348
420
  true
349
421
  end
@@ -374,15 +446,14 @@ module BuildTool; module Commands;
374
446
  return -1
375
447
  end
376
448
 
377
- # 3. Let's go
378
- initialize_log_directory
379
-
380
449
  rc = 0 # Our return code.
381
450
 
382
451
  while_logging_to nil, 'build-status', :info do
383
452
 
384
453
  modules.each do |mod|
385
454
 
455
+ next if !( mod.active? || @all )
456
+
386
457
  begin
387
458
  logger.info ""
388
459
  logger.info "#### Module #{mod.name}"
@@ -407,6 +478,62 @@ module BuildTool; module Commands;
407
478
  return rc;
408
479
  end
409
480
 
481
+ # Call the #clean method of the module.
482
+ #
483
+ # @param [Object] mod The module to use
484
+ def clean( mod, *args )
485
+ ModuleActions::Clean.new( self, mod, *args ).do
486
+ end
487
+
488
+ # Call the #clone method of the module.
489
+ #
490
+ # @param [Object] mod The module to use
491
+ def clone( mod )
492
+ ModuleActions::Clone.new( self, mod ).do
493
+ end
494
+
495
+ # Call the #configure method of the module.
496
+ #
497
+ # @param [Object] mod The module to use
498
+ def configure( mod )
499
+ ModuleActions::Configure.new( self, mod ).do
500
+ end
501
+
502
+ # Call the #fetch method of the module.
503
+ #
504
+ # @param [Object] mod The module to use
505
+ def fetch( mod )
506
+ ModuleActions::Fetch.new( self, mod ).do
507
+ end
508
+
509
+ # Call the #install method of the module.
510
+ #
511
+ # @param [Object] mod The module to use
512
+ def install( mod, *args )
513
+ ModuleActions::Install.new( self, mod, *args ).do
514
+ end
515
+
516
+ # Call the #make method of the module.
517
+ #
518
+ # @param [Object] mod The module to use
519
+ def make( mod, *args )
520
+ ModuleActions::Make.new( self, mod, *args ).do
521
+ end
522
+
523
+ # Call the #rebase method of the module.
524
+ #
525
+ # @param [Object] mod The module to use
526
+ def rebase( mod )
527
+ ModuleActions::Rebase.new( self, mod ).do
528
+ end
529
+
530
+ # Call the #reconfigure method of the module.
531
+ #
532
+ # @param [Object] mod The module to use
533
+ def reconfigure( mod )
534
+ ModuleActions::Reconfigure.new( self, mod ).do
535
+ end
536
+
410
537
  end
411
538
 
412
539
 
@@ -525,7 +652,7 @@ module BuildTool; module Commands;
525
652
 
526
653
  def show_help( args = [] )
527
654
  if args.length == 0
528
- @commands.each do |cmd|
655
+ @commands.sort.each do |cmd|
529
656
  say "%-20s: %s" % [ cmd.name, cmd.description ]
530
657
  end
531
658
  else
@@ -542,39 +669,52 @@ module BuildTool; module Commands;
542
669
  return 0
543
670
  end
544
671
 
545
- def load_commands( path, parentmod )
546
- # puts "load_commands( #{path}, #{parentmod} )"
547
- # Load the commands
672
+ def load_commands( path, parentmod, submod = nil )
673
+ logger.debug "load_commands( #{path} #{parentmod.inspect} #{submod.inspect}"
674
+ # Load all available ruby files in path
548
675
  Dir[ "#{path}/*.rb" ].each do |mod|
549
- cmdname = Pathname.new( mod ).basename( '.rb' ).to_s
550
- load_command( path, parentmod, cmdname )
676
+ load "#{mod}"
551
677
  end
552
- end
553
678
 
554
- def load_command( path, parentmod, mod )
555
- # puts "load_command( #{path}, #{parentmod}, #{mod} )"
556
- load "#{path}/#{mod}.rb"
557
- self.instance_eval %{
558
- if #{parentmod}::#{mod.capitalize}.instance_of? ::Module
559
- cmd = #{parentmod}::#{mod.capitalize}.create( self )
560
- else
561
- cmd = #{parentmod}::#{mod.capitalize}.new( self )
679
+ if !submod.nil?
680
+ parentmod = parentmod.const_get( submod )
681
+ end
682
+ # Now look at all constants for candidates
683
+ parentmod.constants.each do |objname|
684
+ # Get the obj
685
+ obj = parentmod.const_get( objname )
686
+ # :TODO: Better solution
687
+ next if [ "Standard", "ModuleBasedCommand", "Base", "SubCommands", "Shell" ].include? objname
688
+ next if ! obj.kind_of? Class
689
+
690
+ tmp = obj
691
+ while tmp.superclass
692
+ if tmp == BuildTool::Commands::SubCommands
693
+ cmd = obj.new( self )
694
+ break if !cmd.applicable?
695
+ if cmd.cmdalias
696
+ parent.add_command( Alias.new( cmd.cmdalias, cmd ) )
697
+ end
698
+ add_command( cmd )
699
+ cmd.load_commands( "#{path}/#{cmd.name}", parentmod, cmd.name.capitalize )
700
+ break
701
+ elsif tmp == BuildTool::Commands::Base
702
+ cmd = obj.new( self )
703
+ break if !cmd.applicable?
704
+ if cmd.cmdalias
705
+ parent.add_command( Alias.new( cmd.cmdalias, cmd ) )
706
+ end
707
+ add_command( cmd )
708
+ break
709
+ end
710
+ tmp = tmp.superclass
562
711
  end
563
- return if !cmd.applicable?
712
+ end
564
713
 
565
- if cmd.cmdalias
566
- parent.add_command( Alias.new( cmd.cmdalias, cmd ) )
567
- end
568
- if cmd.is_a?( SubCommands )
569
- cmd.load_commands( "#{path}/#{mod}", "#{parentmod}::#{mod.capitalize}" )
570
- end
571
- add_command( cmd )
572
- }
573
714
  end
574
715
 
575
716
  end # class SubCommands
576
717
 
577
-
578
718
  #
579
719
  #
580
720
  #
@@ -632,6 +772,10 @@ module BuildTool; module Commands;
632
772
  return 0
633
773
  end
634
774
 
775
+ def fullname
776
+ nil
777
+ end
778
+
635
779
  end # class Shell
636
780
 
637
781