evilchelu-braid 0.4.0 → 0.4.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/{License.txt → LICENSE} +1 -1
  2. data/README.rdoc +27 -0
  3. data/Rakefile +17 -4
  4. data/bin/braid +29 -24
  5. data/braid.gemspec +7 -7
  6. data/lib/braid.rb +15 -18
  7. data/lib/braid/command.rb +94 -44
  8. data/lib/braid/commands/add.rb +20 -31
  9. data/lib/braid/commands/diff.rb +4 -3
  10. data/lib/braid/commands/remove.rb +8 -12
  11. data/lib/braid/commands/setup.rb +13 -18
  12. data/lib/braid/commands/update.rb +47 -48
  13. data/lib/braid/config.rb +54 -101
  14. data/lib/braid/mirror.rb +181 -0
  15. data/lib/braid/operations.rb +229 -204
  16. data/{spec/braid_spec.rb → test/braid_test.rb} +1 -1
  17. data/test/config_test.rb +62 -0
  18. data/test/fixtures/shiny/README +3 -0
  19. data/test/fixtures/skit1.1/layouts/layout.liquid +219 -0
  20. data/test/fixtures/skit1.2/layouts/layout.liquid +221 -0
  21. data/test/fixtures/skit1/layouts/layout.liquid +219 -0
  22. data/test/fixtures/skit1/preview.png +0 -0
  23. data/test/integration/adding_test.rb +80 -0
  24. data/test/integration/updating_test.rb +87 -0
  25. data/test/integration_helper.rb +69 -0
  26. data/test/mirror_test.rb +118 -0
  27. data/test/operations_test.rb +74 -0
  28. data/test/test_helper.rb +15 -0
  29. metadata +30 -33
  30. data/History.txt +0 -4
  31. data/Manifest.txt +0 -32
  32. data/README.txt +0 -53
  33. data/config/hoe.rb +0 -68
  34. data/config/requirements.rb +0 -17
  35. data/lib/braid/exceptions.rb +0 -33
  36. data/lib/braid/version.rb +0 -9
  37. data/script/destroy +0 -14
  38. data/script/generate +0 -14
  39. data/setup.rb +0 -1585
  40. data/spec/config_spec.rb +0 -117
  41. data/spec/operations_spec.rb +0 -48
  42. data/spec/spec.opts +0 -3
  43. data/spec/spec_helper.rb +0 -11
  44. data/tasks/deployment.rake +0 -27
  45. data/tasks/environment.rake +0 -7
  46. data/tasks/rspec.rake +0 -32
  47. data/tasks/website.rake +0 -9
@@ -1,4 +1,4 @@
1
- Copyright (c) 2007 Cristi Balan
1
+ Copyright (c) 2007-2008 Cristi Balan, Norbert Crombach
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -0,0 +1,27 @@
1
+ = braid
2
+ A simple tool for tracking vendor branches in git.
3
+
4
+ http://evil.che.lu/projects/braid/
5
+
6
+ == Requirements
7
+
8
+ You will need git 1.5.4.5 or higher to run this version.
9
+
10
+ == Installation
11
+
12
+ git clone git://github.com/evilchelu/braid.git
13
+ cd braid
14
+ gem build braid.gemspec
15
+ sudo gem install braid-x.y.z.gem
16
+
17
+ == Usage
18
+
19
+ braid help
20
+ braid help COMMANDNAME
21
+
22
+ For more usage examples and documentation check the project wiki at http://github.com/evilchelu/braid/wikis.
23
+ Also see the bug tracker at http://evilchelu.lighthouseapp.com/projects/10600-braid for current issues and future plans.
24
+
25
+ == Contributing
26
+
27
+ If you want to send a patch please fork the project on GitHub and send a pull request.
data/Rakefile CHANGED
@@ -1,4 +1,17 @@
1
- require 'config/requirements'
2
- require 'config/hoe' # setup Hoe + all gem configuration
3
-
4
- Dir['tasks/**/*.rake'].each { |rake| load rake }
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+
4
+ task :default => :test
5
+
6
+ def test_task(name, pattern)
7
+ Rake::TestTask.new(name) do |t|
8
+ ENV['TESTOPTS'] = '--runner=s'
9
+
10
+ t.libs << 'lib'
11
+ t.pattern = pattern
12
+ t.verbose = true
13
+ end
14
+ end
15
+
16
+ test_task(:test, "test/*_test.rb")
17
+ namespace(:test) { test_task(:integration, "test/integration/*_test.rb") }
data/bin/braid CHANGED
@@ -1,14 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
+
2
3
  $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
4
+ require 'braid'
3
5
 
4
- begin
5
- require 'rubygems'
6
- rescue LoadError
7
- end
6
+ require 'rubygems'
8
7
  require 'main'
9
8
 
10
- require 'braid'
11
-
12
9
  Home = File.expand_path(ENV['HOME'] || '~')
13
10
 
14
11
  # mostly blantantly stolen from ara's punch script
@@ -54,10 +51,10 @@ Main {
54
51
  . braid add svn://remote/path --branch notmaster
55
52
  TXT
56
53
 
57
- mixin :argument_remote, :option_type, :optional_mirror, :option_branch, :option_rails_plugin, :option_revision, :option_full
54
+ mixin :argument_url, :option_type, :optional_path, :option_branch, :option_rails_plugin, :option_revision, :option_full
58
55
 
59
56
  run {
60
- Braid::Command.run(:add, remote, { "type" => type, "mirror" => mirror, "branch" => branch, "rails_plugin" => rails_plugin, "revision" => revision, "full" => full })
57
+ Braid::Command.run(:add, url, { "type" => type, "path" => path, "branch" => branch, "rails_plugin" => rails_plugin, "revision" => revision, "full" => full })
61
58
  }
62
59
  }
63
60
 
@@ -77,10 +74,10 @@ Main {
77
74
  . braid update local/dir
78
75
  TXT
79
76
 
80
- mixin :optional_mirror, :option_revision, :option_head
77
+ mixin :optional_path, :option_revision, :option_head, :option_safe
81
78
 
82
79
  run {
83
- Braid::Command.run(:update, mirror, { "revision" => revision, "head" => head })
80
+ Braid::Command.run(:update, path, { "revision" => revision, "head" => head , "safe" => safe })
84
81
  }
85
82
  }
86
83
 
@@ -97,10 +94,10 @@ Main {
97
94
  . braid remove local/dir
98
95
  TXT
99
96
 
100
- mixin :argument_mirror
97
+ mixin :argument_path
101
98
 
102
99
  run {
103
- Braid::Command.run(:remove, mirror)
100
+ Braid::Command.run(:remove, path)
104
101
  }
105
102
  }
106
103
 
@@ -113,26 +110,26 @@ Main {
113
110
  . braid setup local/dir
114
111
  TXT
115
112
 
116
- mixin :optional_mirror
113
+ mixin :optional_path
117
114
 
118
115
  run {
119
- Braid::Command.run(:setup, mirror)
116
+ Braid::Command.run(:setup, path)
120
117
  }
121
118
  }
122
119
 
123
120
  mode(:diff) {
124
121
  description <<-TXT
125
- Show diff between '#{Braid::WORK_BRANCH}' and HEAD.
122
+ Show diff of local changes to mirror.
126
123
  TXT
127
124
 
128
125
  examples <<-TXT
129
126
  . braid diff local/dir
130
127
  TXT
131
128
 
132
- mixin :argument_mirror
129
+ mixin :argument_path
133
130
 
134
131
  run {
135
- Braid::Command.run(:diff, mirror)
132
+ Braid::Command.run(:diff, path)
136
133
  }
137
134
  }
138
135
 
@@ -140,25 +137,25 @@ Main {
140
137
  description 'Show braid version.'
141
138
 
142
139
  run {
143
- puts "braid #{Braid::VERSION::STRING}"
140
+ puts "braid #{Braid::VERSION}"
144
141
  }
145
142
  }
146
143
 
147
- mixin(:argument_mirror) {
148
- argument(:mirror) {
144
+ mixin(:argument_path) {
145
+ argument(:path) {
149
146
  attr
150
147
  }
151
148
  }
152
149
 
153
- mixin(:optional_mirror) {
154
- argument(:mirror) {
150
+ mixin(:optional_path) {
151
+ argument(:path) {
155
152
  optional
156
153
  attr
157
154
  }
158
155
  }
159
156
 
160
- mixin(:argument_remote) {
161
- argument(:remote) {
157
+ mixin(:argument_url) {
158
+ argument(:url) {
162
159
  attr
163
160
  }
164
161
  }
@@ -214,5 +211,13 @@ Main {
214
211
  }
215
212
  }
216
213
 
214
+ mixin(:option_safe) {
215
+ option(:safe) {
216
+ optional
217
+ desc 'safe on merge errors'
218
+ attr
219
+ }
220
+ }
221
+
217
222
  run { help! }
218
223
  }
@@ -1,25 +1,25 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = %q{braid}
3
- s.version = "0.4.0"
3
+ s.version = "0.4.10"
4
4
 
5
5
  s.specification_version = 2 if s.respond_to? :specification_version=
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Cristi Balan", "Norbert Crombach"]
9
- s.date = %q{2008-05-01}
9
+ s.date = %q{2008-09-23}
10
10
  s.default_executable = %q{braid}
11
- s.description = %q{Braid is a simple tool to help track git and svn vendor branches in a git repository}
11
+ s.description = %q{A simple tool for tracking vendor branches in git.}
12
12
  s.email = %q{evil@che.lu}
13
13
  s.executables = ["braid"]
14
- s.extra_rdoc_files = ["History.txt", "License.txt", "Manifest.txt", "README.txt"]
15
- s.files = ["History.txt", "License.txt", "Manifest.txt", "README.txt", "Rakefile", "bin/braid", "config/hoe.rb", "config/requirements.rb", "lib/braid.rb", "lib/braid/command.rb", "lib/braid/commands/add.rb", "lib/braid/commands/diff.rb", "lib/braid/commands/remove.rb", "lib/braid/commands/setup.rb", "lib/braid/commands/update.rb", "lib/braid/config.rb", "lib/braid/exceptions.rb", "lib/braid/operations.rb", "lib/braid/version.rb", "braid.gemspec", "script/destroy", "script/generate", "setup.rb", "spec/braid_spec.rb", "spec/config_spec.rb", "spec/operations_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/deployment.rake", "tasks/environment.rake", "tasks/rspec.rake", "tasks/website.rake"]
14
+ s.extra_rdoc_files = ["README.rdoc"]
15
+ s.files = ["bin/braid", "braid.gemspec", "lib/braid/command.rb", "lib/braid/commands/add.rb", "lib/braid/commands/diff.rb", "lib/braid/commands/remove.rb", "lib/braid/commands/setup.rb", "lib/braid/commands/update.rb", "lib/braid/config.rb", "lib/braid/mirror.rb", "lib/braid/operations.rb", "lib/braid.rb", "LICENSE", "Rakefile", "README.rdoc", "test/braid_test.rb", "test/config_test.rb", "test/fixtures/shiny/README", "test/fixtures/skit1/layouts/layout.liquid", "test/fixtures/skit1/preview.png", "test/fixtures/skit1.1/layouts/layout.liquid", "test/fixtures/skit1.2/layouts/layout.liquid", "test/integration/adding_test.rb", "test/integration/updating_test.rb", "test/integration_helper.rb", "test/mirror_test.rb", "test/operations_test.rb", "test/test_helper.rb"]
16
16
  s.has_rdoc = true
17
17
  s.homepage = %q{http://evil.che.lu/projects/braid}
18
- s.rdoc_options = ["--main", "README.txt"]
18
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "braid", "--main", "README.rdoc"]
19
19
  s.require_paths = ["lib"]
20
20
  s.rubyforge_project = %q{braid}
21
21
  s.rubygems_version = %q{1.1.0}
22
- s.summary = %q{Braid is a simple tool to help track git and svn vendor branches in a git repository}
22
+ s.summary = %q{A simple tool for tracking vendor branches in git.}
23
23
 
24
24
  s.add_dependency(%q<main>, [">= 2.8.0"])
25
25
  s.add_dependency(%q<open4>, [">= 0.9.6"])
@@ -1,28 +1,25 @@
1
- $:.unshift dir = File.dirname(__FILE__)
2
-
3
- begin
4
- require 'rubygems'
5
- rescue LoadError
6
- end
7
-
8
- require 'open4'
9
- require 'yaml'
10
- require 'yaml/store'
1
+ $:.unshift File.dirname(__FILE__)
11
2
 
12
3
  module Braid
13
- MIRROR_TYPES = %w[git svn]
14
- WORK_BRANCH = "braid/track"
4
+ VERSION = "0.4.10"
5
+
15
6
  CONFIG_FILE = ".braids"
7
+ USE_LOCAL_CACHE = ENV["BRAID_USE_LOCAL_CACHE"] || true
8
+ LOCAL_CACHE_DIR = ENV["BRAID_LOCAL_CACHE_DIR"] || "#{ENV["HOME"]}/.braid/cache/"
16
9
  REQUIRED_GIT_VERSION = "1.5.4.5"
17
- end
18
10
 
19
- require 'braid/version'
20
- require 'braid/exceptions'
11
+ class BraidError < StandardError
12
+ def message
13
+ value = super
14
+ value if value != self.class.name
15
+ end
16
+ end
17
+ end
21
18
 
22
- require 'braid/config'
23
19
  require 'braid/operations'
24
-
20
+ require 'braid/mirror'
21
+ require 'braid/config'
25
22
  require 'braid/command'
26
- Dir["#{dir}/braid/commands/*"].each do |file|
23
+ Dir[File.dirname(__FILE__) + '/braid/commands/*'].each do |file|
27
24
  require file
28
25
  end
@@ -1,68 +1,118 @@
1
1
  module Braid
2
2
  class Command
3
- include Operations::Mirror
4
- include Operations::Helpers
5
-
6
- class << self
7
- include Operations::Helpers
8
- include Operations::Git
9
-
10
- def run(command, *args)
11
- raise Braid::Git::VersionTooLow unless verify_git_version(REQUIRED_GIT_VERSION)
3
+ class InvalidRevision < BraidError
4
+ end
12
5
 
13
- klass = Braid::Commands.const_get(command.to_s.capitalize)
14
- klass.new.run(*args)
6
+ extend Operations::VersionControl
7
+ include Operations::VersionControl
15
8
 
16
- rescue Braid::Git::LocalChangesPresent => e
17
- msg "Local changes are present. You have to commit or stash them before running braid commands."
18
- msg "Exiting."
9
+ def self.run(command, *args)
10
+ verify_git_version!
19
11
 
20
- rescue Braid::Git::VersionTooLow => e
21
- msg "This version of braid requires at least git #{REQUIRED_GIT_VERSION}. You have #{extract_git_version}."
22
- msg "Exiting."
12
+ klass = Commands.const_get(command.to_s.capitalize)
13
+ klass.new.run(*args)
23
14
 
24
- rescue => e
25
- # FIXME
15
+ rescue BraidError => error
16
+ case error
17
+ when Operations::ShellExecutionError
18
+ msg "Shell error: #{error.message}"
19
+ else
20
+ msg "Error: #{error.message}"
26
21
  end
22
+ exit(1)
23
+ end
27
24
 
28
- def msg(str)
29
- puts str
30
- end
25
+ def self.msg(str)
26
+ puts str
27
+ end
28
+
29
+ def msg(str)
30
+ self.class.msg(str)
31
31
  end
32
32
 
33
33
  def config
34
- @config ||= Braid::Config.new
34
+ @config ||= load_and_migrate_config
35
35
  end
36
36
 
37
37
  private
38
- def msg(str)
39
- self.class.msg(str)
38
+ def self.verify_git_version!
39
+ git.require_version!(REQUIRED_GIT_VERSION)
40
40
  end
41
41
 
42
- def in_work_branch
43
- # make sure there is a git repository
44
- begin
45
- old_branch = get_current_branch
46
- rescue => e
47
- msg "Error occured: #{e.message}"
48
- raise e
49
- end
42
+ def bail_on_local_changes!
43
+ git.ensure_clean!
44
+ end
50
45
 
51
- create_work_branch
52
- work_head = get_work_head
46
+ def with_reset_on_error
47
+ work_head = git.head
53
48
 
54
49
  begin
55
- invoke(:git_checkout, WORK_BRANCH)
56
50
  yield
57
- rescue => e
58
- msg "Error occured: #{e.message}"
59
- if get_current_branch == WORK_BRANCH
60
- msg "Resetting '#{WORK_BRANCH}' to '#{work_head}'."
61
- invoke(:git_reset_hard, work_head)
51
+ rescue => error
52
+ msg "Resetting to '#{work_head[0, 7]}'."
53
+ git.reset_hard(work_head)
54
+ raise error
55
+ end
56
+ end
57
+
58
+ def load_and_migrate_config
59
+ config = Config.new
60
+ unless config.valid?
61
+ msg "Configuration is outdated. Migrating."
62
+ bail_on_local_changes!
63
+ config.migrate!
64
+ git.commit("Upgrade .braids", "-- .braids")
65
+ end
66
+ config
67
+ end
68
+
69
+ def add_config_file
70
+ git.add(CONFIG_FILE)
71
+ end
72
+
73
+ def display_revision(mirror, revision = nil)
74
+ revision ||= mirror.revision
75
+ mirror.type == "svn" ? "r#{revision}" : "'#{revision[0, 7]}'"
76
+ end
77
+
78
+ def validate_new_revision(mirror, new_revision)
79
+ unless new_revision
80
+ unless mirror.type == "svn"
81
+ return git.rev_parse(mirror.remote)
82
+ else
83
+ return svn.head_revision(mirror.url)
84
+ end
85
+ end
86
+
87
+ unless mirror.type == "svn"
88
+ new_revision = git.rev_parse(new_revision)
89
+ else
90
+ new_revision = svn.clean_revision(new_revision)
91
+ end
92
+ old_revision = mirror.revision
93
+
94
+ if new_revision == old_revision
95
+ raise InvalidRevision, "mirror is already at requested revision"
96
+ end
97
+
98
+ if mirror.type == "svn"
99
+ if old_revision && new_revision < old_revision
100
+ raise InvalidRevision, "local revision is higher than request revision"
101
+ end
102
+
103
+ if svn.head_revision(mirror.url) < new_revision
104
+ raise InvalidRevision, "requested revision is higher than remote revision"
62
105
  end
63
- raise e
64
- ensure
65
- invoke(:git_checkout, old_branch)
106
+ end
107
+
108
+ new_revision
109
+ end
110
+
111
+ def determine_target_commit(mirror, new_revision)
112
+ unless mirror.type == "svn"
113
+ git.rev_parse(new_revision)
114
+ else
115
+ git_svn.commit_hash(mirror.remote, new_revision)
66
116
  end
67
117
  end
68
118
  end
@@ -1,54 +1,43 @@
1
1
  module Braid
2
2
  module Commands
3
3
  class Add < Command
4
- def run(remote, options = {})
5
- raise Braid::Git::LocalChangesPresent if invoke(:local_changes?)
4
+ def run(url, options = {})
5
+ bail_on_local_changes!
6
6
 
7
- in_work_branch do
8
- mirror, params = config.add_from_options(remote, options)
9
- local_branch = get_local_branch_name(mirror, params)
7
+ with_reset_on_error do
8
+ mirror = config.add_from_options(url, options)
10
9
 
11
- config.update(mirror, { "local_branch" => local_branch })
12
- params["local_branch"] = local_branch # TODO check
13
-
14
- msg "Adding #{params["type"]} mirror of '#{params["remote"]}'" + (params["type"] == "git" ? ", branch '#{params["branch"]}'" : "") + "."
10
+ branch_message = (mirror.type == "svn" || mirror.branch == "master") ? "" : " branch '#{mirror.branch}'"
11
+ revision_message = options["revision"] ? " at #{display_revision(mirror)}" : ""
12
+ msg "Adding #{mirror.type} mirror of '#{mirror.url}'#{branch_message}#{revision_message}."
15
13
 
16
14
  # these commands are explained in the subtree merge guide
17
15
  # http://www.kernel.org/pub/software/scm/git/docs/howto/using-merge-subtree.html
18
16
 
19
17
  setup_remote(mirror)
20
- fetch_remote(params["type"], local_branch)
21
-
22
- validate_revision_option(params, options)
23
- target = determine_target_commit(params, options)
18
+ mirror.fetch
24
19
 
25
- msg "Merging code into '#{mirror}/'."
20
+ new_revision = validate_new_revision(mirror, options["revision"])
21
+ target_hash = determine_target_commit(mirror, new_revision)
26
22
 
27
- unless params["squash"]
28
- invoke(:git_merge_ours, target)
23
+ unless mirror.squashed?
24
+ git.merge_ours(target_hash)
29
25
  end
30
- invoke(:git_read_tree, target, mirror)
26
+ git.read_tree(target_hash, mirror.path)
31
27
 
32
- config.update(mirror, { "revision" => options["revision"] })
28
+ mirror.revision = new_revision
29
+ mirror.lock = new_revision if options["revision"]
30
+ config.update(mirror)
33
31
  add_config_file
34
32
 
35
- revision_message = options["revision"] ? " at #{display_revision(params["type"], options["revision"])}" : ""
36
- commit_message = "Add mirror '#{mirror}/'#{revision_message}."
37
- invoke(:git_commit, commit_message)
33
+ commit_message = "Add mirror '#{mirror.path}/'#{revision_message}"
34
+ git.commit(commit_message)
38
35
  end
39
36
  end
40
37
 
41
- protected
42
- def setup_remote(mirror)
43
- Braid::Command.run(:setup, mirror)
44
- end
45
-
46
38
  private
47
- def get_local_branch_name(mirror, params)
48
- res = "braid/#{params["type"]}/#{mirror}"
49
- res << "/#{params["branch"]}" if params["type"] == "git"
50
- res.gsub!("_", '-') # stupid git svn changes all _ to ., weird
51
- res
39
+ def setup_remote(mirror)
40
+ Command.run(:setup, mirror.path)
52
41
  end
53
42
  end
54
43
  end