braid 0.6.2 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,29 +6,30 @@ module Braid
6
6
  end
7
7
 
8
8
  protected
9
- def setup_all
10
- msg "Setting up all mirrors."
11
- config.mirrors.each do |path|
12
- setup_one(path)
13
- end
9
+
10
+ def setup_all
11
+ msg "Setting up all mirrors."
12
+ config.mirrors.each do |path|
13
+ setup_one(path)
14
14
  end
15
+ end
15
16
 
16
- def setup_one(path)
17
- mirror = config.get!(path)
17
+ def setup_one(path)
18
+ mirror = config.get!(path)
18
19
 
19
- if git.remote_url(mirror.remote)
20
- msg "Setup: Mirror '#{mirror.path}' already has a remote. Reusing it." if verbose?
21
- return
22
- end
20
+ if git.remote_url(mirror.remote)
21
+ msg "Setup: Mirror '#{mirror.path}' already has a remote. Reusing it." if verbose?
22
+ return
23
+ end
23
24
 
24
- msg "Setup: Creating remote for '#{mirror.path}'."
25
- unless mirror.type == "svn"
26
- url = use_local_cache? ? git_cache.path(mirror.url) : mirror.url
27
- git.remote_add(mirror.remote, url, mirror.branch)
28
- else
29
- git_svn.init(mirror.remote, mirror.url)
30
- end
25
+ msg "Setup: Creating remote for '#{mirror.path}'."
26
+ unless mirror.type == "svn"
27
+ url = use_local_cache? ? git_cache.path(mirror.url) : mirror.url
28
+ git.remote_add(mirror.remote, url, mirror.branch)
29
+ else
30
+ git_svn.init(mirror.remote, mirror.url)
31
31
  end
32
+ end
32
33
  end
33
34
  end
34
35
  end
@@ -10,92 +10,93 @@ module Braid
10
10
  end
11
11
 
12
12
  protected
13
- def update_all(options = {})
14
- options.reject! { |k,v| %w(revision head).include?(k) }
15
- msg "Updating all mirrors."
16
- config.mirrors.each do |path|
17
- update_one(path, options)
18
- end
13
+
14
+ def update_all(options = {})
15
+ options.reject! { |k, v| %w(revision head).include?(k) }
16
+ msg "Updating all mirrors."
17
+ config.mirrors.each do |path|
18
+ update_one(path, options)
19
19
  end
20
+ end
20
21
 
21
- def update_one(path, options = {})
22
- mirror = config.get!(path)
22
+ def update_one(path, options = {})
23
+ mirror = config.get!(path)
23
24
 
24
- revision_message = options["revision"] ? " to #{display_revision(mirror, options["revision"])}" : ""
25
- msg "Updating mirror '#{mirror.path}'#{revision_message}."
25
+ revision_message = options["revision"] ? " to #{display_revision(mirror, options["revision"])}" : ""
26
+ msg "Updating mirror '#{mirror.path}'#{revision_message}."
26
27
 
27
- # check options for lock modification
28
- if mirror.locked?
29
- if options["head"]
30
- msg "Unlocking mirror '#{mirror.path}'." if verbose?
31
- mirror.lock = nil
32
- elsif !options["revision"]
33
- msg "Mirror '#{mirror.path}' is locked to #{display_revision(mirror, mirror.lock)}. Use --head to force."
34
- return
35
- end
28
+ # check options for lock modification
29
+ if mirror.locked?
30
+ if options["head"]
31
+ msg "Unlocking mirror '#{mirror.path}'." if verbose?
32
+ mirror.lock = nil
33
+ elsif !options["revision"]
34
+ msg "Mirror '#{mirror.path}' is locked to #{display_revision(mirror, mirror.lock)}. Use --head to force."
35
+ return
36
36
  end
37
+ end
37
38
 
38
- setup_remote(mirror)
39
- msg "Fetching new commits for '#{mirror.path}'." if verbose?
40
- mirror.fetch
39
+ setup_remote(mirror)
40
+ msg "Fetching new commits for '#{mirror.path}'." if verbose?
41
+ mirror.fetch
41
42
 
42
- new_revision = validate_new_revision(mirror, options["revision"])
43
- target_revision = determine_target_revision(mirror, new_revision)
43
+ new_revision = validate_new_revision(mirror, options["revision"])
44
+ target_revision = determine_target_revision(mirror, new_revision)
44
45
 
45
- if mirror.merged?(target_revision)
46
- msg "Mirror '#{mirror.path}' is already up to date."
47
- return
48
- end
46
+ if mirror.merged?(target_revision)
47
+ msg "Mirror '#{mirror.path}' is already up to date."
48
+ return
49
+ end
49
50
 
50
- if mirror.squashed?
51
- diff = mirror.diff
52
- base_revision = mirror.base_revision
53
- end
51
+ if mirror.squashed?
52
+ diff = mirror.diff
53
+ base_revision = mirror.base_revision
54
+ end
55
+
56
+ mirror.revision = new_revision
57
+ mirror.lock = new_revision if options["revision"]
54
58
 
55
- mirror.revision = new_revision
56
- mirror.lock = new_revision if options["revision"]
57
-
58
- msg "Merging in mirror '#{mirror.path}'." if verbose?
59
- begin
60
- if mirror.squashed?
61
- local_hash = git.rev_parse("HEAD")
62
- if !diff.empty?
63
- base_hash = generate_tree_hash(mirror, base_revision)
64
- else
65
- base_hash = local_hash
66
- end
67
- remote_hash = generate_tree_hash(mirror, target_revision)
68
- ENV["GITHEAD_#{local_hash}"] = "HEAD"
69
- ENV["GITHEAD_#{remote_hash}"] = target_revision
70
- git.merge_recursive(base_hash, local_hash, remote_hash)
59
+ msg "Merging in mirror '#{mirror.path}'." if verbose?
60
+ begin
61
+ if mirror.squashed?
62
+ local_hash = git.rev_parse("HEAD")
63
+ if !diff.empty?
64
+ base_hash = generate_tree_hash(mirror, base_revision)
71
65
  else
72
- git.merge_subtree(target_revision)
66
+ base_hash = local_hash
73
67
  end
74
- rescue Operations::MergeError => error
75
- msg "Caught merge error. Breaking."
68
+ remote_hash = generate_tree_hash(mirror, target_revision)
69
+ ENV["GITHEAD_#{local_hash}"] = "HEAD"
70
+ ENV["GITHEAD_#{remote_hash}"] = target_revision
71
+ git.merge_recursive(base_hash, local_hash, remote_hash)
72
+ else
73
+ git.merge_subtree(target_revision)
76
74
  end
75
+ rescue Operations::MergeError => error
76
+ msg "Caught merge error. Breaking."
77
+ end
77
78
 
78
- config.update(mirror)
79
- add_config_file
79
+ config.update(mirror)
80
+ add_config_file
80
81
 
81
- commit_message = "Update mirror '#{mirror.path}' to #{display_revision(mirror)}"
82
- if error
83
- File.open(".git/MERGE_MSG", 'w') { |f| f.puts(commit_message) }
84
- return
85
- end
86
-
87
- git.commit(commit_message)
88
- msg "Updated mirror to #{display_revision(mirror)}."
82
+ commit_message = "Update mirror '#{mirror.path}' to #{display_revision(mirror)}"
83
+ if error
84
+ File.open(".git/MERGE_MSG", 'w') { |f| f.puts(commit_message) }
85
+ return
89
86
  end
90
87
 
91
- def generate_tree_hash(mirror, revision)
92
- git.rm_r(mirror.path)
93
- git.read_tree_prefix(revision, mirror.path)
94
- success = git.commit("Temporary commit for mirror '#{mirror.path}'")
95
- hash = git.rev_parse("HEAD")
96
- git.reset_hard("HEAD^") if success
97
- hash
98
- end
88
+ git.commit(commit_message)
89
+ msg "Updated mirror to #{display_revision(mirror)}."
90
+ end
91
+
92
+ def generate_tree_hash(mirror, revision)
93
+ git.rm_r(mirror.path)
94
+ git.read_tree_prefix(revision, mirror.path)
95
+ success = git.commit("Temporary commit for mirror '#{mirror.path}'")
96
+ hash = git.rev_parse("HEAD")
97
+ git.reset_hard("HEAD^") if success
98
+ hash
99
+ end
99
100
  end
100
101
  end
101
102
  end
data/lib/braid/config.rb CHANGED
@@ -79,10 +79,10 @@ module Braid
79
79
  @db.roots.each do |path|
80
80
  attributes = @db[path]
81
81
  if attributes["local_branch"]
82
- attributes["url"] = attributes.delete("remote")
83
- attributes["remote"] = attributes.delete("local_branch")
82
+ attributes["url"] = attributes.delete("remote")
83
+ attributes["remote"] = attributes.delete("local_branch")
84
84
  attributes["squashed"] = attributes.delete("squash")
85
- attributes["lock"] = attributes["revision"] # so far this has always been true
85
+ attributes["lock"] = attributes["revision"] # so far this has always been true
86
86
  end
87
87
  @db[path] = clean_attributes(attributes)
88
88
  end
@@ -90,12 +90,12 @@ module Braid
90
90
  end
91
91
 
92
92
  private
93
- def write_mirror(mirror)
94
- @db[mirror.path] = clean_attributes(mirror.attributes)
95
- end
93
+ def write_mirror(mirror)
94
+ @db[mirror.path] = clean_attributes(mirror.attributes)
95
+ end
96
96
 
97
- def clean_attributes(hash)
98
- hash.reject { |k,v| v.nil? }
99
- end
97
+ def clean_attributes(hash)
98
+ hash.reject { |k, v| v.nil? }
99
+ end
100
100
  end
101
101
  end
data/lib/braid/mirror.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Braid
2
2
  class Mirror
3
- TYPES = %w(git svn)
3
+ TYPES = %w(git svn)
4
4
  ATTRIBUTES = %w(url remote type branch squashed revision lock)
5
5
 
6
6
  class UnknownType < BraidError
@@ -24,12 +24,12 @@ module Braid
24
24
  attr_reader :path, :attributes
25
25
 
26
26
  def initialize(path, attributes = {})
27
- @path = path.sub(/\/$/, '')
27
+ @path = path.sub(/\/$/, '')
28
28
  @attributes = attributes
29
29
  end
30
30
 
31
31
  def self.new_from_options(url, options = {})
32
- url = url.sub(/\/$/, '')
32
+ url = url.sub(/\/$/, '')
33
33
 
34
34
  branch = options["branch"] || "master"
35
35
 
@@ -47,11 +47,11 @@ module Braid
47
47
  path = "vendor/plugins/#{path}"
48
48
  end
49
49
 
50
- remote = "braid/#{path}".gsub("_", '-') # stupid git svn changes all _ to ., weird
50
+ remote = "braid/#{path}".gsub("_", '-') # stupid git svn changes all _ to ., weird
51
51
  squashed = !options["full"]
52
52
  branch = nil if type == "svn"
53
53
 
54
- attributes = { "url" => url, "remote" => remote, "type" => type, "branch" => branch, "squashed" => squashed }
54
+ attributes = {"url" => url, "remote" => remote, "type" => type, "branch" => branch, "squashed" => squashed}
55
55
  self.new(path, attributes)
56
56
  end
57
57
 
@@ -85,7 +85,7 @@ module Braid
85
85
 
86
86
  def diff
87
87
  remote_hash = git.rev_parse("#{base_revision}:")
88
- local_hash = git.tree_hash(path)
88
+ local_hash = git.tree_hash(path)
89
89
  remote_hash != local_hash ? git.diff_tree(remote_hash, local_hash) : ""
90
90
  end
91
91
 
@@ -119,59 +119,60 @@ module Braid
119
119
  end
120
120
 
121
121
  private
122
- def method_missing(name, *args)
123
- if ATTRIBUTES.find { |attribute| name.to_s =~ /^(#{attribute})(=)?$/ }
124
- unless $2
125
- attributes[$1]
126
- else
127
- attributes[$1] = args[0]
128
- end
122
+
123
+ def method_missing(name, *args)
124
+ if ATTRIBUTES.find { |attribute| name.to_s =~ /^(#{attribute})(=)?$/ }
125
+ unless $2
126
+ attributes[$1]
129
127
  else
130
- raise NameError, "unknown attribute `#{name}'"
128
+ attributes[$1] = args[0]
131
129
  end
130
+ else
131
+ raise NameError, "unknown attribute `#{name}'"
132
132
  end
133
+ end
133
134
 
134
- def inferred_revision
135
- local_commits = git.rev_list("HEAD", "-- #{path}").split("\n")
136
- remote_hashes = git.rev_list("--pretty=format:\"%T\"", remote).split("commit ").map do |chunk|
137
- chunk.split("\n", 2).map { |value| value.strip }
138
- end
139
- hash = nil
140
- local_commits.each do |local_commit|
141
- local_tree = git.tree_hash(path, local_commit)
142
- if match = remote_hashes.find { |_, remote_tree| local_tree == remote_tree }
143
- hash = match[0]
144
- break
145
- end
135
+ def inferred_revision
136
+ local_commits = git.rev_list("HEAD", "-- #{path}").split("\n")
137
+ remote_hashes = git.rev_list("--pretty=format:\"%T\"", remote).split("commit ").map do |chunk|
138
+ chunk.split("\n", 2).map { |value| value.strip }
139
+ end
140
+ hash = nil
141
+ local_commits.each do |local_commit|
142
+ local_tree = git.tree_hash(path, local_commit)
143
+ if match = remote_hashes.find { |_, remote_tree| local_tree == remote_tree }
144
+ hash = match[0]
145
+ break
146
146
  end
147
- hash
148
147
  end
148
+ hash
149
+ end
149
150
 
150
- def self.extract_type_from_url(url)
151
- return nil unless url
152
- url.sub!(/\/$/, '')
151
+ def self.extract_type_from_url(url)
152
+ return nil unless url
153
+ url.sub!(/\/$/, '')
153
154
 
154
- # check for git:// and svn:// URLs
155
- url_scheme = url.split(":").first
156
- return url_scheme if TYPES.include?(url_scheme)
155
+ # check for git:// and svn:// URLs
156
+ url_scheme = url.split(":").first
157
+ return url_scheme if TYPES.include?(url_scheme)
157
158
 
158
- return "svn" if url[-6..-1] == "/trunk"
159
- return "git" if url[-4..-1] == ".git"
160
- end
159
+ return "svn" if url[-6..-1] == "/trunk"
160
+ return "git" if url[-4..-1] == ".git"
161
+ end
161
162
 
162
- def self.extract_path_from_url(url)
163
- return nil unless url
164
- name = File.basename(url)
163
+ def self.extract_path_from_url(url)
164
+ return nil unless url
165
+ name = File.basename(url)
165
166
 
166
- if File.extname(name) == ".git"
167
- # strip .git
168
- name[0..-5]
169
- elsif name == "trunk"
170
- # use parent
171
- File.basename(File.dirname(url))
172
- else
173
- name
174
- end
167
+ if File.extname(name) == ".git"
168
+ # strip .git
169
+ name[0..-5]
170
+ elsif name == "trunk"
171
+ # use parent
172
+ File.basename(File.dirname(url))
173
+ else
174
+ name
175
175
  end
176
+ end
176
177
  end
177
178
  end
@@ -1,6 +1,6 @@
1
1
  require 'singleton'
2
2
  require 'rubygems'
3
- require 'open4'
3
+ require defined?(JRUBY_VERSION) ? 'open3' : 'open4'
4
4
  require 'tempfile'
5
5
 
6
6
  module Braid
@@ -16,8 +16,8 @@ module Braid
16
16
  end
17
17
  class VersionTooLow < BraidError
18
18
  def initialize(command, version, required)
19
- @command = command
20
- @version = version.to_s.split("\n").first
19
+ @command = command
20
+ @version = version.to_s.split("\n").first
21
21
  @required = required
22
22
  end
23
23
 
@@ -45,8 +45,11 @@ module Braid
45
45
  class Proxy
46
46
  include Singleton
47
47
 
48
- def self.command; name.split('::').last.downcase; end # hax!
48
+ def self.command;
49
+ name.split('::').last.downcase;
50
+ end
49
51
 
52
+ # hax!
50
53
  def version
51
54
  status, out, err = exec!("#{self.class.command} --version")
52
55
  out.sub(/^.* version/, "").strip
@@ -54,7 +57,7 @@ module Braid
54
57
 
55
58
  def require_version(required)
56
59
  required = required.split(".")
57
- actual = version.split(".")
60
+ actual = version.split(".")
58
61
 
59
62
  actual.each_with_index do |actual_piece, idx|
60
63
  required_piece = required[idx]
@@ -79,62 +82,72 @@ module Braid
79
82
  end
80
83
 
81
84
  private
82
- def command(name)
83
- # stub
84
- name
85
- end
86
85
 
87
- def invoke(arg, *args)
88
- exec!("#{command(arg)} #{args.join(' ')}".strip)[1].strip # return stdout
89
- end
86
+ def command(name)
87
+ # stub
88
+ name
89
+ end
90
90
 
91
- def method_missing(name, *args)
92
- invoke(name, *args)
93
- end
91
+ def invoke(arg, *args)
92
+ exec!("#{command(arg)} #{args.join(' ')}".strip)[1].strip # return stdout
93
+ end
94
+
95
+ def method_missing(name, *args)
96
+ invoke(name, *args)
97
+ end
98
+
99
+ def exec(cmd)
100
+ cmd.strip!
94
101
 
95
- def exec(cmd)
96
- cmd.strip!
102
+ previous_lang = ENV['LANG']
103
+ ENV['LANG'] = 'C'
97
104
 
98
- previous_lang = ENV['LANG']
99
- ENV['LANG'] = 'C'
105
+ out, err = nil
106
+ log(cmd)
100
107
 
101
- out, err = nil
102
- log(cmd)
108
+ if defined?(JRUBY_VERSION)
109
+ Open3.popen3(cmd) do |stdin, stdout, stderr|
110
+ out = stdout.read
111
+ err = stderr.read
112
+ end
113
+ status = $?.exitstatus
114
+ else
103
115
  status = Open4.popen4(cmd) do |pid, stdin, stdout, stderr|
104
116
  out = stdout.read
105
117
  err = stderr.read
106
118
  end.exitstatus
107
- [status, out, err]
108
-
109
- ensure
110
- ENV['LANG'] = previous_lang
111
119
  end
112
120
 
113
- def exec!(cmd)
114
- status, out, err = exec(cmd)
115
- raise ShellExecutionError, err unless status == 0
116
- [status, out, err]
117
- end
121
+ [status, out, err]
122
+ ensure
123
+ ENV['LANG'] = previous_lang
124
+ end
118
125
 
119
- def sh(cmd, message = nil)
120
- message ||= "could not fetch" if cmd =~ /fetch/
121
- log(cmd)
122
- `#{cmd}`
123
- raise ShellExecutionError, message unless $?.exitstatus == 0
124
- true
125
- end
126
+ def exec!(cmd)
127
+ status, out, err = exec(cmd)
128
+ raise ShellExecutionError, err unless status == 0
129
+ [status, out, err]
130
+ end
126
131
 
127
- def msg(str)
128
- puts "Braid: #{str}"
129
- end
132
+ def sh(cmd, message = nil)
133
+ message ||= "could not fetch" if cmd =~ /fetch/
134
+ log(cmd)
135
+ `#{cmd}`
136
+ raise ShellExecutionError, message unless $?.exitstatus == 0
137
+ true
138
+ end
130
139
 
131
- def log(cmd)
132
- msg "Executing `#{cmd}`" if verbose?
133
- end
140
+ def msg(str)
141
+ puts "Braid: #{str}"
142
+ end
134
143
 
135
- def verbose?
136
- Braid.verbose
137
- end
144
+ def log(cmd)
145
+ msg "Executing `#{cmd}`" if verbose?
146
+ end
147
+
148
+ def verbose?
149
+ Braid.verbose
150
+ end
138
151
  end
139
152
 
140
153
  class Git < Proxy
@@ -275,12 +288,22 @@ module Braid
275
288
 
276
289
  def apply(diff, *args)
277
290
  err = nil
278
- status = Open4.popen4("git apply --index --whitespace=nowarn #{args.join(' ')} -") do |pid, stdin, stdout, stderr|
279
- stdin.puts(diff)
280
- stdin.close
281
291
 
282
- err = stderr.read
283
- end.exitstatus
292
+ if defined?(JRUBY_VERSION)
293
+ Open3.popen3("git apply --index --whitespace=nowarn #{args.join(' ')} -") do |stdin, stdout, stderr|
294
+ stdin.puts(diff)
295
+ stdin.close
296
+ err = stderr.read
297
+ end
298
+ status = $?.exitstatus
299
+ else
300
+ status = Open4.popen4("git apply --index --whitespace=nowarn #{args.join(' ')} -") do |pid, stdin, stdout, stderr|
301
+ stdin.puts(diff)
302
+ stdin.close
303
+ err = stderr.read
304
+ end.exitstatus
305
+ end
306
+
284
307
  raise ShellExecutionError, err unless status == 0
285
308
  true
286
309
  end
@@ -291,17 +314,21 @@ module Braid
291
314
  end
292
315
 
293
316
  private
294
- def command(name)
295
- "#{self.class.command} #{name.to_s.gsub('_', '-')}"
296
- end
317
+
318
+ def command(name)
319
+ "#{self.class.command} #{name.to_s.gsub('_', '-')}"
320
+ end
297
321
  end
298
322
 
299
323
  class GitSvn < Proxy
300
- def self.command; "git svn"; end
324
+ def self.command;
325
+ "git svn";
326
+ end
301
327
 
302
328
  def commit_hash(remote, revision)
303
- out = invoke(:log, "--show-commit --oneline", "-r #{revision}", remote)
304
- part = out.to_s.split(" | ")[1]
329
+ out = invoke(:log, "--show-commit --oneline", "-r #{revision}", remote)
330
+ part = out.to_s.split("|")[1]
331
+ part.strip!
305
332
  raise UnknownRevision, "r#{revision}" unless part
306
333
  git.rev_parse(part)
307
334
  end
@@ -316,13 +343,14 @@ module Braid
316
343
  end
317
344
 
318
345
  private
319
- def command(name)
320
- "#{self.class.command} #{name}"
321
- end
322
346
 
323
- def git
324
- Git.instance
325
- end
347
+ def command(name)
348
+ "#{self.class.command} #{name}"
349
+ end
350
+
351
+ def git
352
+ Git.instance
353
+ end
326
354
  end
327
355
 
328
356
  class Svn < Proxy
@@ -364,13 +392,14 @@ module Braid
364
392
  end
365
393
 
366
394
  private
367
- def local_cache_dir
368
- Braid.local_cache_dir
369
- end
370
395
 
371
- def git
372
- Git.instance
373
- end
396
+ def local_cache_dir
397
+ Braid.local_cache_dir
398
+ end
399
+
400
+ def git
401
+ Git.instance
402
+ end
374
403
  end
375
404
 
376
405
  module VersionControl