build-tool 0.6.7 → 0.6.8

Sign up to get free protection for your applications and to get access to all the features.
data/History.rdoc CHANGED
@@ -1,3 +1,26 @@
1
+ == Version 0.6.8
2
+
3
+ == Features
4
+ - Implement option --quiet
5
+ - module status: New command that shows
6
+ - Local unpushed changes (if vcs supports that)
7
+ - Local uncommitted changes
8
+ - Remote changes
9
+
10
+ == Enhancements
11
+ - module history: Print name instead of id
12
+ - module info:
13
+ - Show ssh key for svn too
14
+ - Show timestamp for module state too
15
+ - Minor Performance improvements
16
+ - Disable ansi color output for files (logfiles too)
17
+ - VCS SVN: Do a "switch --relocate" if required
18
+ - VCS GIT-SVN: Change gitconfig svn-remote.svn.url if required.
19
+
20
+ == Bugfixes
21
+ - VCS Archive: Is Checked out if the source-dir exists, not when the archive is there.
22
+ - Custom BuildSystem: Is configured is the build dir exists
23
+
1
24
  == Version 0.6.7
2
25
  === Bugfix
3
26
  - Fix [#29650] 'could not parse line' when installing recipe
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: UTF-8 -*-
2
2
 
3
3
  require 'logging'
4
- Logging.init :debug2, :debug, :trace, :verbose, :info, :warn, :error
4
+ Logging.init :debug2, :debug, :trace, :verbose, :info, :quiet, :warn, :error
5
5
  include Logging.globally
6
6
 
7
7
  require 'mj/logging'
@@ -10,6 +10,7 @@
10
10
  require 'build-tool/singleton'
11
11
 
12
12
  require 'active_record'
13
+ require 'ansi/code'
13
14
 
14
15
  $noop = false
15
16
 
@@ -39,6 +40,11 @@ def initialize( name, application_root )
39
40
  @database = nil
40
41
  @name = File.basename( name ).sub( "-build", "" )
41
42
  @local_settings_file_path = local_configuration_dir.join("#{@name}.yaml")
43
+
44
+ # If stdout is not a terminal don't use ansi codes
45
+ if ! STDOUT.tty?
46
+ $ansi = false
47
+ end
42
48
  end
43
49
 
44
50
  # Load the configuration
@@ -27,6 +27,7 @@ def initialize( *args )
27
27
 
28
28
  # Check if the module is configured
29
29
  def configured?
30
+ Pathname.new( build_directory ).exist?
30
31
  end
31
32
 
32
33
  def name
@@ -153,7 +153,6 @@ def complete_arguments( args )
153
153
 
154
154
  def do_complete( args )
155
155
  return complete_arguments( args )
156
- do_complete( args )
157
156
  end
158
157
 
159
158
  def each_option
@@ -296,6 +295,11 @@ def skip_command
296
295
  @skip_command = true
297
296
  end
298
297
 
298
+ # Print out a normal message (if enabled)
299
+ def quiet( *args )
300
+ logger.quiet( *args )
301
+ end
302
+
299
303
  # Print out a normal message (if enabled)
300
304
  def info( *args )
301
305
  logger.info( *args )
@@ -367,6 +371,10 @@ def initialize_options
367
371
  Logging.appenders['stdout'].level = [ Logging.appenders['stdout'].level - 1, 0 ].max()
368
372
  end
369
373
 
374
+ options.on( "-q", "--quiet", "More quiet output" ) do
375
+ Logging.appenders['stdout'].level = [ Logging.appenders['stdout'].level + 1, 0 ].max()
376
+ end
377
+
370
378
  options.on( nil, "--dry-run", "Enable dry run." ) do
371
379
  $noop = true
372
380
  end
@@ -454,9 +462,9 @@ def log_directory
454
462
 
455
463
  class ModuleProgressbar < MJ::Logging::Progressbar
456
464
 
457
- def initialize( title, mod, &block )
458
- super( title, mod.size ) do
459
- mod.each_with_index do |mod, i|
465
+ def initialize( title, mods, &block )
466
+ super( title, mods.size ) do
467
+ mods.each_with_index do |mod, i|
460
468
  if @pbar
461
469
  @pbar.set( i )
462
470
  @pbar.title= mod.name.split( '/' )[-1]
@@ -539,6 +547,7 @@ def do_execute( args )
539
547
  # 1. Resolve the modules
540
548
  modules = []
541
549
  args.each do |arg|
550
+ # :FIXME: what if arg is invalid?
542
551
  complete_modules( arg ).each do |mod|
543
552
  modules << mod
544
553
  end
@@ -605,7 +614,7 @@ def do_execute( args )
605
614
  begin
606
615
 
607
616
  info( "" )
608
- info( "#### Module #{mod.name} (#{index+1}/#{modules.size})" )
617
+ quiet( "#### Module #{mod.name} (#{index+1}/#{modules.size})" )
609
618
  do_execute_module( mod )
610
619
  rescue Interrupt => e
611
620
  raise e
@@ -816,7 +825,7 @@ def do_complete( args )
816
825
  end
817
826
 
818
827
  def complete_command( cmdname )
819
- cmds = @commands.collect { |com|
828
+ @commands.collect { |com|
820
829
  com.name if com.name.start_with? cmdname
821
830
  }.compact
822
831
  end
@@ -94,7 +94,7 @@ def show_module_history( modname )
94
94
  last_module=""
95
95
  cmd.module_logs.where( :module => mod.name ).each do |e|
96
96
  if e.module != last_module
97
- info( blue { "\t#{e.module}" } )
97
+ info( blue { "\t#{e.module.name}" } )
98
98
  last_module = e.module
99
99
  end
100
100
  info( "\t\t %s %s (%s) [%s]" % [ e.duration, e.event, e.logfile, e.state_str ] )
@@ -119,7 +119,7 @@ def show_detailed_command_history( id )
119
119
  last_module=""
120
120
  cmd.module_logs.each do |e|
121
121
  if e.module != last_module
122
- info( blue { "\t#{e.module}" } )
122
+ info( blue { "\t#{e.module.name}" } )
123
123
  last_module = e.module
124
124
  end
125
125
  info( "\t\t %s %s (%s) [%s]" % [ e.duration, e.event, e.logfile, e.state_str ] )
@@ -58,15 +58,23 @@ def do_execute_module( mod )
58
58
  info( "VCS: #{mod.vcs_configuration ? mod.vcs_configuration.name : 'not configured' }" )
59
59
  if mod.vcs_configuration
60
60
  case mod.vcs_configuration.name
61
+
61
62
  when 'svn'
62
63
  info( " Repository: %s/%s" % [ mod.vcs_configuration.repository.url, mod.vcs_configuration.remote_path ] )
64
+ if mod.vcs_configuration.repository and mod.vcs_configuration.repository.sshkey
65
+ info( " SSH Key: '#{mod.vcs_configuration.repository.sshkey.name}' (#{mod.vcs_configuration.repository.sshkey.file})" )
66
+ end
67
+
63
68
  when 'bazar'
64
69
  info( " Branch: %s" % [ mod.vcs_configuration.url ] )
70
+
65
71
  when 'mercurial'
66
72
  info( " URL: %s" % [ mod.vcs_configuration.url ] )
67
73
  info( " Track: %s" % [ mod.vcs_configuration.track ] )
74
+
68
75
  when 'archive'
69
76
  info( " URL: %s" % [ mod.vcs.archive_url ] )
77
+
70
78
  when 'git'
71
79
  mod.vcs_configuration.merged_remote.each do |key, val|
72
80
  if val.push_url
@@ -76,6 +84,7 @@ def do_execute_module( mod )
76
84
  end
77
85
  end
78
86
  info( " Track branch: #{mod.vcs_configuration.track_remote}/#{mod.vcs_configuration.track_branch}" )
87
+
79
88
  when 'git-svn'
80
89
  info( " Repository: %s/%s" % [ mod.vcs_configuration.repository.url, mod.vcs_configuration.remote_path ] )
81
90
  mod.vcs_configuration.merged_remote.each do |key, val|
@@ -84,9 +93,12 @@ def do_execute_module( mod )
84
93
  mod.vcs_configuration.merged_externals.each do |key, val|
85
94
  info( " External: #{key} -> #{val}" )
86
95
  end
96
+
87
97
  else
88
98
  warn( "Unknown vcs #{mod.vcs_configuration.name}" )
89
99
  end
100
+
101
+
90
102
  end # if mod.vcs_configuration
91
103
 
92
104
  bs = mod.build_system
@@ -0,0 +1,84 @@
1
+ # -*- coding: UTF-8 -*-
2
+
3
+ require 'build-tool/commands'
4
+
5
+ module BuildTool; module Commands; module Modules
6
+
7
+ #
8
+ # BuildCommand
9
+ #
10
+ class Status < ModuleBasedCommand
11
+
12
+ name "status"
13
+ description "show module status"
14
+ long_description [ "Show information about the modules status" ]
15
+
16
+ def do_execute_module( mod )
17
+
18
+ info( "Active: #{mod.active?}" )
19
+ info( "Status: #{mod.state}" )
20
+
21
+ dirty = mod.dirty?
22
+ if dirty
23
+ quiet( "Modified: #{dirty}" )
24
+ else
25
+ info( "Modified: #{dirty}" )
26
+ end
27
+
28
+ info( "VCS: #{mod.vcs_configuration ? mod.vcs_configuration.name : 'not configured' }" )
29
+
30
+ if mod.vcs_configuration
31
+
32
+ c = mod.vcs.remote_changes()
33
+ if c.nil?
34
+ verbose( "Remote Changes: Not supported." )
35
+ elsif c.empty?
36
+ verbose( "Remote Changes: None" )
37
+ else
38
+ quiet( "Remote Changes" )
39
+ c.each do |line|
40
+ quiet( " " + line )
41
+ end
42
+ end
43
+
44
+ if not @local_only
45
+ c = mod.vcs.local_changes()
46
+ if c.nil?
47
+ verbose( "Local Changes: Not supported." )
48
+ elsif c.empty?
49
+ verbose( "Local Changes: None" )
50
+ else
51
+ quiet( "Local Changes:" )
52
+ c.each do |line|
53
+ quiet( " " + line )
54
+ end
55
+ end
56
+ end
57
+
58
+ end # if mod.vcs_configuration
59
+
60
+ return 0
61
+ end
62
+
63
+ def initialize_options
64
+ options.banner = "Usage: #{self.fullname} [OPTIONS]... MODULES..."
65
+ options.separator( "" )
66
+ options.separator( "Options" )
67
+
68
+ @all = false
69
+ options.on( "--all", "Include inactive modules." ) {
70
+ @all = true
71
+ }
72
+
73
+ @local_only = false
74
+ options.on( "--local-only", "Only show local unpushed changes." ) {
75
+ @local_only = true
76
+ }
77
+ super
78
+ end
79
+
80
+ end # class Info
81
+
82
+ end; end; end # module BuildTool::Commands::Modules
83
+
84
+
@@ -13,7 +13,7 @@ class CommandLog < ActiveRecord::Base
13
13
  include StateHelper
14
14
 
15
15
  # A command can have many module events
16
- has_many :module_logs, :order => :id, :dependent => :destroy
16
+ has_many :module_logs, :order => :id, :dependent => :destroy, :include => :module
17
17
 
18
18
  def duration
19
19
  if self.finished_at
@@ -86,6 +86,13 @@ def active?
86
86
  end
87
87
  end
88
88
 
89
+ def dirty?
90
+ if vcs
91
+ return vcs.dirty?
92
+ end
93
+ return false
94
+ end
95
+
89
96
  # not inherited
90
97
  def build_directory
91
98
  build_prefix_required.join("bld", local_path)
@@ -265,13 +272,18 @@ def lastlog
265
272
 
266
273
  # Returns a current state in string format
267
274
  def state
268
- return 'UNKNOWN' if lastlog.empty?
269
- lastlog[0].module_logs.where( :module => name ).each do |e|
270
- if e.state != History::ModuleLog::FINISHED_SUCCESSFUL
271
- return "#{e.state_str} (#{e.event})"
272
- end
275
+ log = lastlog
276
+ return 'UNKNOWN' if log.empty?
277
+
278
+ e = log[0].module_logs.reverse_order.where( :module => name ).first
279
+ if e.nil?
280
+ return "UNKNOWN"
281
+ end
282
+ if e.state != History::ModuleLog::FINISHED_SUCCESSFUL
283
+ return "#{e.started_at.strftime("%x %X")}: #{e.state_str} (#{e.event})"
284
+ else
285
+ return "#{e.started_at.strftime("%x %X")}: #{e.state_str}"
273
286
  end
274
- return History::ModuleLog::state_str( History::ModuleLog::FINISHED_SUCCESSFUL )
275
287
  end
276
288
 
277
289
  # Return the current state as one char.
@@ -89,7 +89,7 @@ def archive_url
89
89
  #
90
90
 
91
91
  def checkedout?
92
- File.exist? archive_local_path
92
+ local_path_exist?
93
93
  end
94
94
 
95
95
  def apply_patches( patches )
@@ -247,6 +247,18 @@ def prepare_for_fetch
247
247
  return check_for_sshkey( config.repository.sshkey )
248
248
  end
249
249
 
250
+ def dirty?
251
+ return nil
252
+ end
253
+
254
+ def do_remote_changes
255
+ yield nil
256
+ end
257
+
258
+ def do_local_changes
259
+ yield nil
260
+ end
261
+
250
262
  end # class Archive
251
263
 
252
264
  end; end
@@ -127,7 +127,10 @@ def recipe
127
127
  :rebase,
128
128
  :fetching_supported?,
129
129
  :[]=,
130
- :[]
130
+ :[],
131
+ :dirty?,
132
+ :do_remote_changes,
133
+ :do_local_changes
131
134
  ] do
132
135
  class_eval <<-EOS
133
136
  def #{method}
@@ -136,6 +139,36 @@ def #{method}
136
139
  EOS
137
140
  end
138
141
 
142
+ def remote_changes( &block )
143
+ if block_given?
144
+ do_remote_changes( &block )
145
+ else
146
+ r = []
147
+ do_remote_changes() do |c|
148
+ r << c
149
+ end
150
+ if r == [ nil ]
151
+ return nil
152
+ end
153
+ return r
154
+ end
155
+ end
156
+
157
+ def local_changes
158
+ if block_given?
159
+ do_local_changes( &block )
160
+ else
161
+ r = []
162
+ do_local_changes() do |c|
163
+ r << c
164
+ end
165
+ if r == [ nil ]
166
+ return nil
167
+ end
168
+ return r
169
+ end
170
+ end
171
+
139
172
  end # class Base
140
173
 
141
174
  end; end # module BuildTool::VCS
@@ -81,23 +81,18 @@ def clone
81
81
  end
82
82
  end
83
83
 
84
- # Is the git executable available?
85
- def self.bzr_available?()
86
- return @bzr_available unless @bzr_available.nil?
87
- %x( bzr --version 2>&1 )
88
- @bzr_available = $?.success?
89
- return @bzr_available
90
- end
91
-
92
84
  def ready_for_fetch
93
85
  if not self.class.bzr_available?
94
86
  logger.error( "#{config.module.name}: Calling `bzr` failed!" )
95
87
  return false
96
88
  end
89
+ return true
90
+ end
97
91
 
92
+ def ready_for_rebase
98
93
  if checkedout?
99
94
  # Check if the index is dirty.
100
- if bzr( "diff" ) != 0
95
+ if dirty?
101
96
  logger.info( "#{config.module.name}: Local changes will prevent the update." )
102
97
  bzr( "status --short --versioned" ) do |line|
103
98
  logger.info line.chomp
@@ -105,7 +100,6 @@ def ready_for_fetch
105
100
  return false
106
101
  end
107
102
  end
108
-
109
103
  return true
110
104
  end
111
105
 
@@ -125,7 +119,9 @@ def fetch( verbose = false )
125
119
  end
126
120
 
127
121
  rc = bzr( cmd ) do |line|
128
- logger.info( line )
122
+ if verbose
123
+ logger.info( line )
124
+ end
129
125
  end
130
126
 
131
127
  if rc != 0
@@ -135,7 +131,7 @@ def fetch( verbose = false )
135
131
 
136
132
  # Execute +command+ in directory +wd+ and yield every line of output.
137
133
  def bzr( command, wd = local_path, &block )
138
- rc = self.class.execute "bzr #{command}", wd, &block
134
+ self.class.execute "bzr #{command}", wd, &block
139
135
  end
140
136
 
141
137
  def rebase( verbose = false )
@@ -143,6 +139,39 @@ def rebase( verbose = false )
143
139
  0
144
140
  end
145
141
 
142
+ def dirty?
143
+ # Check if the index is dirty.
144
+ if bzr( "diff" ) != 0
145
+ return true
146
+ end
147
+ return false
148
+ end
149
+
150
+ def do_remote_changes
151
+ yield nil
152
+ end
153
+
154
+ def do_local_changes
155
+ yield nil
156
+ end
157
+
158
+ #
159
+ ### CLASS METHODS
160
+ #
161
+ class << self
162
+
163
+ @bzr_available = nil
164
+
165
+ # Is the git executable available?
166
+ def bzr_available?()
167
+ return @bzr_available unless @bzr_available.nil?
168
+ %x( bzr --version 2>&1 )
169
+ @bzr_available = $?.success?
170
+ return @bzr_available
171
+ end
172
+
173
+ end
174
+
146
175
  end # class Bazar
147
176
 
148
177
  end; end # module BuildTool::VCS