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 +23 -0
- data/lib/build-tool/application.rb +7 -1
- data/lib/build-tool/build-system/custom.rb +1 -0
- data/lib/build-tool/commands.rb +15 -6
- data/lib/build-tool/commands/history.rb +2 -2
- data/lib/build-tool/commands/modules/info.rb +12 -0
- data/lib/build-tool/commands/modules/status.rb +84 -0
- data/lib/build-tool/model/command_log.rb +1 -1
- data/lib/build-tool/model/module.rb +18 -6
- data/lib/build-tool/vcs/archive.rb +13 -1
- data/lib/build-tool/vcs/base.rb +34 -1
- data/lib/build-tool/vcs/bazar.rb +41 -12
- data/lib/build-tool/vcs/git-svn.rb +36 -7
- data/lib/build-tool/vcs/git.rb +32 -10
- data/lib/build-tool/vcs/mercurial.rb +56 -1
- data/lib/build-tool/vcs/svn.rb +83 -14
- data/lib/build-tool/version.rb +1 -1
- data/lib/mj/logging.rb +24 -17
- metadata +163 -184
@@ -103,11 +103,7 @@ def fetching_supported?
|
|
103
103
|
#
|
104
104
|
|
105
105
|
def checkedout?
|
106
|
-
|
107
|
-
if !Pathname.new( local_path ).join( ".git" ).exist?
|
108
|
-
raise Base::VcsError, "Checkout path #{local_path} is not a git repo!"
|
109
|
-
end
|
110
|
-
return true
|
106
|
+
git.checkedout?
|
111
107
|
end
|
112
108
|
|
113
109
|
def clone( verbose = false )
|
@@ -121,6 +117,8 @@ def clone( verbose = false )
|
|
121
117
|
raise GitSvnError, "Error while initializing the repo `git svn init '#{config.repository}/#{remote_path}'`: #{$?}"
|
122
118
|
end
|
123
119
|
|
120
|
+
check_config
|
121
|
+
|
124
122
|
fetch(false, "HEAD")
|
125
123
|
end
|
126
124
|
|
@@ -128,6 +126,25 @@ def configure
|
|
128
126
|
git.configure
|
129
127
|
end
|
130
128
|
|
129
|
+
def check_config
|
130
|
+
return if @already_checked_config
|
131
|
+
git.check_config
|
132
|
+
if checkedout?
|
133
|
+
# Check that the remotes are the same as configured.
|
134
|
+
gitconfig = Grit::RepoConfig.new(git.repo)
|
135
|
+
svnurlrec = Pathname.new( config.repository.url ).join( remote_path ).cleanpath
|
136
|
+
svnurlcur = Pathname.new( gitconfig["svn-remote.svn.url"] ).cleanpath
|
137
|
+
if svnurlcur.nil?
|
138
|
+
if git.git( "svn init #{svnurl}" ) != 0
|
139
|
+
raise GitError, "Error while initializing the repo `git svn init #{svnurlrec}`"
|
140
|
+
end
|
141
|
+
elsif svnurlcur != svnurlrec
|
142
|
+
logger.info "repo: Setting remote.origin.url to #{svnurlrec}"
|
143
|
+
gitconfig["svn-remote.svn.url"] = svnurlrec
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
131
148
|
# Fetch from +repository+
|
132
149
|
#
|
133
150
|
# Initializes the local clone if it does not exist.
|
@@ -136,7 +153,7 @@ def fetch( verbose = false, revision = nil )
|
|
136
153
|
clone( verbose )
|
137
154
|
else
|
138
155
|
# clone() calls those methods.
|
139
|
-
|
156
|
+
check_config
|
140
157
|
end
|
141
158
|
|
142
159
|
if revision
|
@@ -174,7 +191,7 @@ def prepare_for_fetch
|
|
174
191
|
end
|
175
192
|
|
176
193
|
def rebase( verbose = false )
|
177
|
-
|
194
|
+
check_config
|
178
195
|
remote_branch = "#{config.track_branch}"
|
179
196
|
|
180
197
|
if verbose
|
@@ -188,6 +205,18 @@ def rebase( verbose = false )
|
|
188
205
|
end
|
189
206
|
end
|
190
207
|
|
208
|
+
def dirty?
|
209
|
+
return git.dirty?
|
210
|
+
end
|
211
|
+
|
212
|
+
def do_remote_changes( &block )
|
213
|
+
return git.do_remote_changes( &block )
|
214
|
+
end
|
215
|
+
|
216
|
+
def do_local_changes( &block )
|
217
|
+
return git.do_local_changes( &block )
|
218
|
+
end
|
219
|
+
|
191
220
|
def ready_for_fetch
|
192
221
|
if not GitSvn.git_svn_available
|
193
222
|
logger.info( "#{config.module.name}: Calling `git svn` failed!" )
|
data/lib/build-tool/vcs/git.rb
CHANGED
@@ -410,20 +410,26 @@ def ready_for_fetch
|
|
410
410
|
return true
|
411
411
|
end
|
412
412
|
|
413
|
+
# Check if the checkout is dirty.
|
414
|
+
def dirty?
|
415
|
+
# Check if the index is dirty.
|
416
|
+
if git( "diff --exit-code" ) != 0
|
417
|
+
return true
|
418
|
+
end
|
419
|
+
|
420
|
+
if git( "diff --cached --exit-code" ) != 0
|
421
|
+
return true
|
422
|
+
end
|
423
|
+
|
424
|
+
return false
|
425
|
+
end
|
426
|
+
|
413
427
|
# Check if the module is ready for a rebase.
|
414
428
|
def ready_for_rebase
|
415
429
|
check_user_config
|
416
430
|
if checkedout?
|
417
431
|
# Check if the index is dirty.
|
418
|
-
if
|
419
|
-
logger.info( "#{config.module.name}: A dirty index will prevent the rebase." )
|
420
|
-
git( "status -s -uno" ) do |line|
|
421
|
-
logger.info line.chomp
|
422
|
-
end
|
423
|
-
return false
|
424
|
-
end
|
425
|
-
|
426
|
-
if git( "diff --cached --exit-code" ) != 0
|
432
|
+
if dirty?
|
427
433
|
logger.info( "#{config.module.name}: A dirty index will prevent the rebase." )
|
428
434
|
git( "status -s -uno" ) do |line|
|
429
435
|
logger.info line.chomp
|
@@ -434,12 +440,28 @@ def ready_for_rebase
|
|
434
440
|
true
|
435
441
|
end
|
436
442
|
|
443
|
+
# Print the pending changes.
|
444
|
+
#
|
445
|
+
#
|
446
|
+
def do_remote_changes( &block )
|
447
|
+
remote_branch = "#{config.track_remote}/#{config.track_branch}"
|
448
|
+
git('log --first-parent --pretty=oneline HEAD..%s' % remote_branch, &block )
|
449
|
+
end
|
450
|
+
|
451
|
+
# Print the unpushed changes.
|
452
|
+
#
|
453
|
+
#
|
454
|
+
def do_local_changes( &block )
|
455
|
+
remote_branch = "#{config.track_remote}/#{config.track_branch}"
|
456
|
+
git('log --first-parent --pretty=oneline %s..HEAD' % remote_branch, &block )
|
457
|
+
end
|
458
|
+
|
437
459
|
def rebase( verbose = false )
|
438
460
|
check_config
|
439
461
|
remote_branch = "#{config.track_remote}/#{config.track_branch}"
|
440
462
|
|
441
463
|
if verbose
|
442
|
-
|
464
|
+
remote_changes.each do |line|
|
443
465
|
logger.info( line )
|
444
466
|
end
|
445
467
|
end
|
@@ -92,6 +92,29 @@ def clone
|
|
92
92
|
rebase()
|
93
93
|
end
|
94
94
|
|
95
|
+
def ready_for_fetch
|
96
|
+
if not self.class.hg_available?
|
97
|
+
logger.error( "#{config.module.name}: Calling `hg` failed!" )
|
98
|
+
return false
|
99
|
+
end
|
100
|
+
return true
|
101
|
+
end
|
102
|
+
|
103
|
+
def ready_for_rebase
|
104
|
+
if checkedout?
|
105
|
+
# Check if the index is dirty.
|
106
|
+
if dirty?
|
107
|
+
logger.info( "#{config.module.name}: Local changes will prevent the update." )
|
108
|
+
hg( "status -q" ) do |line|
|
109
|
+
logger.info line.chomp
|
110
|
+
end
|
111
|
+
return false
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
return true
|
116
|
+
end
|
117
|
+
|
95
118
|
# Fetch from +repository+
|
96
119
|
#
|
97
120
|
# Initializes the local clone if it does not exist.
|
@@ -114,7 +137,6 @@ def hg( command, wd = local_path, &block )
|
|
114
137
|
end
|
115
138
|
|
116
139
|
def rebase( verbose = false )
|
117
|
-
|
118
140
|
if verbose
|
119
141
|
logger.info( 'Verbose rebase not yet implemented for mercurial.' )
|
120
142
|
end
|
@@ -124,6 +146,39 @@ def rebase( verbose = false )
|
|
124
146
|
end
|
125
147
|
end
|
126
148
|
|
149
|
+
def dirty?
|
150
|
+
dirty = false
|
151
|
+
hg( "status -q" ) do
|
152
|
+
dirty = true
|
153
|
+
end
|
154
|
+
return dirty
|
155
|
+
end
|
156
|
+
|
157
|
+
def do_remote_changes
|
158
|
+
yield nil
|
159
|
+
end
|
160
|
+
|
161
|
+
def do_local_changes
|
162
|
+
yield nil
|
163
|
+
end
|
164
|
+
|
165
|
+
#
|
166
|
+
# CLASS METHODS
|
167
|
+
#
|
168
|
+
# Is the git executable available?
|
169
|
+
class << self
|
170
|
+
|
171
|
+
@hg_available = nil
|
172
|
+
|
173
|
+
def hg_available?()
|
174
|
+
return @hg_available unless @hg_available.nil?
|
175
|
+
%x( hg --version 2>&1 )
|
176
|
+
@hg_available = $?.success?
|
177
|
+
return @hg_available
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
181
|
+
|
127
182
|
end # class Mercurial
|
128
183
|
|
129
184
|
end; end # module BuildTool::VCS
|
data/lib/build-tool/vcs/svn.rb
CHANGED
@@ -57,13 +57,15 @@ class Svn < Base
|
|
57
57
|
|
58
58
|
class SvnError < BuildTool::Error; end
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
def initialize( *args )
|
61
|
+
super( *args )
|
62
|
+
@remote_info = nil
|
63
|
+
@local_info
|
64
|
+
end
|
63
65
|
|
64
66
|
class << self
|
65
67
|
|
66
|
-
svn_available = nil
|
68
|
+
@svn_available = nil
|
67
69
|
|
68
70
|
# Is the git executable available?
|
69
71
|
def svn_available?
|
@@ -101,6 +103,14 @@ def checkedout?
|
|
101
103
|
return true
|
102
104
|
end
|
103
105
|
|
106
|
+
# Make sure the configuration is correct.
|
107
|
+
def check_config
|
108
|
+
if self.url != "#{remote_url}"
|
109
|
+
logger.info( "Relocating checkout to #{remote_url}" )
|
110
|
+
svn( "switch --relocate #{self.url} #{remote_url}" )
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
104
114
|
# Initialize the local repository
|
105
115
|
def clone
|
106
116
|
# Check if local_path exists
|
@@ -113,13 +123,16 @@ def clone
|
|
113
123
|
|
114
124
|
# Init the repository
|
115
125
|
if config.only
|
116
|
-
svn "checkout --depth=files #{
|
126
|
+
svn "checkout --depth=files #{remote_url} #{local_path}", local_path.dirname
|
117
127
|
config.only.each do |elem|
|
118
128
|
svn "update --depth=infinity #{elem}", local_path
|
119
129
|
end
|
120
130
|
else
|
121
|
-
svn "checkout --depth=infinity #{
|
131
|
+
svn "checkout --depth=infinity #{remote_url} #{local_path}", local_path.dirname
|
122
132
|
end
|
133
|
+
|
134
|
+
check_config
|
135
|
+
|
123
136
|
return true
|
124
137
|
end
|
125
138
|
|
@@ -135,6 +148,9 @@ def fetch( verbose = false )
|
|
135
148
|
|
136
149
|
if !checkedout?
|
137
150
|
return clone
|
151
|
+
else
|
152
|
+
# Micro optimization. clone calls check_config
|
153
|
+
check_config
|
138
154
|
end
|
139
155
|
|
140
156
|
if verbose
|
@@ -148,21 +164,46 @@ def fetch( verbose = false )
|
|
148
164
|
return true
|
149
165
|
end
|
150
166
|
|
167
|
+
# Run svn info and return the result in a hash
|
168
|
+
def info( local = true )
|
169
|
+
if local
|
170
|
+
return @local_info if @local_info
|
171
|
+
@local_info = Hash.new
|
172
|
+
svn( "info" ) {
|
173
|
+
|line|
|
174
|
+
key, value = line.chomp.split( ':', 2 )
|
175
|
+
@local_info[key] = value
|
176
|
+
}
|
177
|
+
return @local_info
|
178
|
+
else
|
179
|
+
return @remote_info if @remote_info
|
180
|
+
@remote_info = Hash.new
|
181
|
+
svn( "info #{remote_url}", nil ) {
|
182
|
+
|line|
|
183
|
+
key, value = line.chomp.split( ':', 2 )
|
184
|
+
@remote_info[key] = value
|
185
|
+
}
|
186
|
+
return @remote_info
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
151
190
|
# Returns the last changed revision on the remote repository.
|
152
191
|
# Return 0 if the last changed revision could not be determined.
|
153
192
|
def last_changed_rev
|
154
|
-
info = Hash.new
|
155
|
-
svn( "info #{repository.url}/#{remote_path}", nil ) {
|
156
|
-
|line|
|
157
|
-
key, value = line.chomp.split( ':', 2 )
|
158
|
-
info[key] = value
|
159
|
-
}
|
160
193
|
return 777777 if $noop
|
161
|
-
version = info["Last Changed Rev"];
|
162
|
-
raise SvnError, "Failed to determine revision for #{
|
194
|
+
version = info( false )["Last Changed Rev"];
|
195
|
+
raise SvnError, "Failed to determine revision for #{remote_url}" if version.nil?
|
163
196
|
return version
|
164
197
|
end
|
165
198
|
|
199
|
+
# Return the currently active url
|
200
|
+
def url
|
201
|
+
return "http://example.com/my/example_repo" if $noop
|
202
|
+
url = info( true )["URL"]
|
203
|
+
raise SvnError, "Failed to determine url for #{remote_url}" if url.nil?
|
204
|
+
return url
|
205
|
+
end
|
206
|
+
|
166
207
|
def prepare_for_fetch
|
167
208
|
# If our server has an associated ssh-key, add it to the ssh-agent.
|
168
209
|
return check_for_sshkey( config.repository.sshkey )
|
@@ -172,10 +213,38 @@ def remote_path
|
|
172
213
|
@config.remote_path
|
173
214
|
end
|
174
215
|
|
216
|
+
# convenience method
|
217
|
+
def remote_url
|
218
|
+
"#{repository.url}/#{remote_path}"
|
219
|
+
end
|
220
|
+
|
221
|
+
|
175
222
|
def repository
|
176
223
|
config.repository
|
177
224
|
end
|
178
225
|
|
226
|
+
def dirty?
|
227
|
+
dirty = false
|
228
|
+
svn( "status -q" ) do
|
229
|
+
dirty = true
|
230
|
+
end
|
231
|
+
return dirty
|
232
|
+
end
|
233
|
+
|
234
|
+
def do_local_changes
|
235
|
+
yield nil
|
236
|
+
end
|
237
|
+
|
238
|
+
def do_remote_changes( &block )
|
239
|
+
svn( "log -rHEAD:BASE --quiet" ) do |x|
|
240
|
+
if not x.starts_with?( '----------' )
|
241
|
+
yield x
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
|
247
|
+
|
179
248
|
|
180
249
|
# Call svn with command
|
181
250
|
def svn( command, wd = local_path, &block )
|
data/lib/build-tool/version.rb
CHANGED
data/lib/mj/logging.rb
CHANGED
@@ -58,6 +58,10 @@ def debug?
|
|
58
58
|
return logger.level > ::Logging.level_num(:debug)
|
59
59
|
end
|
60
60
|
|
61
|
+
def quiet( string )
|
62
|
+
logger.quiet( "<#{@prefix}> info #{string}" )
|
63
|
+
end
|
64
|
+
|
61
65
|
def info( string )
|
62
66
|
logger.info( "<#{@prefix}> info #{string}" )
|
63
67
|
end
|
@@ -103,27 +107,30 @@ def initialize( title, total = 100, &block )
|
|
103
107
|
super( 'Progressbar', :level => :DEBUG )
|
104
108
|
@pbar = nil
|
105
109
|
@oldlogger = nil
|
106
|
-
if
|
110
|
+
if not STDOUT.tty? or
|
111
|
+
::Logging.appenders['stdout'].level != ::Logging::level_num(:INFO)
|
107
112
|
# We only do the progressbar thing if there is no verbose output active.
|
108
|
-
|
109
|
-
# Remove the old stdout logger.
|
110
|
-
@oldlogger = ::Logging.appenders[ 'stdout' ]
|
111
|
-
::Logging.logger[ 'root' ].remove_appenders( 'stdout' )
|
112
|
-
::Logging.logger[ 'root' ].add_appenders( self )
|
113
|
-
# Add the progressbar logger
|
114
|
-
@pbar = ANSI::Progressbar.new( title, total )
|
115
|
-
yield
|
116
|
-
ensure
|
117
|
-
@pbar.finish unless @pbar.nil?
|
118
|
-
# Reset the logger
|
119
|
-
::Logging.logger[ 'root' ].remove_appenders( 'Progressbar' )
|
120
|
-
::Logging.logger[ 'root' ].add_appenders( @oldlogger )
|
121
|
-
end
|
122
|
-
else
|
123
|
-
# If there is verbose output just print the text
|
113
|
+
# And only if there is a terminal listening.
|
124
114
|
logger.info( title )
|
125
115
|
yield
|
116
|
+
return
|
117
|
+
end
|
118
|
+
|
119
|
+
begin
|
120
|
+
# Remove the old stdout logger.
|
121
|
+
@oldlogger = ::Logging.appenders[ 'stdout' ]
|
122
|
+
::Logging.logger[ 'root' ].remove_appenders( 'stdout' )
|
123
|
+
::Logging.logger[ 'root' ].add_appenders( self )
|
124
|
+
# Add the progressbar logger
|
125
|
+
@pbar = ANSI::Progressbar.new( title, total, out = STDOUT )
|
126
|
+
yield
|
127
|
+
ensure
|
128
|
+
@pbar.finish unless @pbar.nil?
|
129
|
+
# Reset the logger
|
130
|
+
::Logging.logger[ 'root' ].remove_appenders( 'Progressbar' )
|
131
|
+
::Logging.logger[ 'root' ].add_appenders( @oldlogger )
|
126
132
|
end
|
127
133
|
end
|
128
134
|
end # class Progressbar
|
135
|
+
|
129
136
|
end; end
|