evilchelu-braid 0.4.0 → 0.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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