mercurial-ruby 0.3.0

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 (173) hide show
  1. data/.document +5 -0
  2. data/Gemfile +10 -0
  3. data/Gemfile.lock +32 -0
  4. data/LICENSE.txt +20 -0
  5. data/README.rdoc +86 -0
  6. data/Rakefile +53 -0
  7. data/VERSION +1 -0
  8. data/lib/mercurial-ruby.rb +66 -0
  9. data/lib/mercurial-ruby/branch.rb +45 -0
  10. data/lib/mercurial-ruby/changed_file.rb +51 -0
  11. data/lib/mercurial-ruby/command.rb +77 -0
  12. data/lib/mercurial-ruby/commit.rb +152 -0
  13. data/lib/mercurial-ruby/config_file.rb +119 -0
  14. data/lib/mercurial-ruby/configuration.rb +14 -0
  15. data/lib/mercurial-ruby/diff.rb +50 -0
  16. data/lib/mercurial-ruby/factories/branch_factory.rb +91 -0
  17. data/lib/mercurial-ruby/factories/changed_file_factory.rb +50 -0
  18. data/lib/mercurial-ruby/factories/commit_factory.rb +154 -0
  19. data/lib/mercurial-ruby/factories/diff_factory.rb +63 -0
  20. data/lib/mercurial-ruby/factories/hook_factory.rb +45 -0
  21. data/lib/mercurial-ruby/factories/node_factory.rb +111 -0
  22. data/lib/mercurial-ruby/factories/tag_factory.rb +48 -0
  23. data/lib/mercurial-ruby/file_index.rb +209 -0
  24. data/lib/mercurial-ruby/helper.rb +23 -0
  25. data/lib/mercurial-ruby/hook.rb +23 -0
  26. data/lib/mercurial-ruby/manifest.rb +58 -0
  27. data/lib/mercurial-ruby/node.rb +100 -0
  28. data/lib/mercurial-ruby/repository.rb +94 -0
  29. data/lib/mercurial-ruby/root_node.rb +27 -0
  30. data/lib/mercurial-ruby/shell.rb +64 -0
  31. data/lib/mercurial-ruby/style.rb +23 -0
  32. data/lib/mercurial-ruby/tag.rb +33 -0
  33. data/lib/stdlib_exts/string.rb +12 -0
  34. data/lib/styles/changeset.style +5 -0
  35. data/lib/styles/file_index.style +3 -0
  36. data/mercurial-ruby.gemspec +227 -0
  37. data/test/fixtures.rb +28 -0
  38. data/test/fixtures/test-repo/.DotFile +1 -0
  39. data/test/fixtures/test-repo/.hg/00changelog.i +0 -0
  40. data/test/fixtures/test-repo/.hg/branch +1 -0
  41. data/test/fixtures/test-repo/.hg/cache/branchheads +6 -0
  42. data/test/fixtures/test-repo/.hg/cache/tags +7 -0
  43. data/test/fixtures/test-repo/.hg/dirstate +0 -0
  44. data/test/fixtures/test-repo/.hg/hgrc +3 -0
  45. data/test/fixtures/test-repo/.hg/last-message.txt +1 -0
  46. data/test/fixtures/test-repo/.hg/requires +4 -0
  47. data/test/fixtures/test-repo/.hg/store/00changelog.i +0 -0
  48. data/test/fixtures/test-repo/.hg/store/00manifest.i +0 -0
  49. data/test/fixtures/test-repo/.hg/store/data/_file _with _whitespace.pdf.i +0 -0
  50. data/test/fixtures/test-repo/.hg/store/data/_l_i_c_e_n_s_e.txt.i +0 -0
  51. data/test/fixtures/test-repo/.hg/store/data/_l_i_c_e_n_s_e2.txt.i +0 -0
  52. data/test/fixtures/test-repo/.hg/store/data/_l_i_c_e_n_s_e3.txt.i +0 -0
  53. data/test/fixtures/test-repo/.hg/store/data/_l_i_c_e_n_s_e4.txt.i +0 -0
  54. data/test/fixtures/test-repo/.hg/store/data/_r_e_a_d_m_e.markdown.i +0 -0
  55. data/test/fixtures/test-repo/.hg/store/data/_r_e_a_d_m_e.markup.i +0 -0
  56. data/test/fixtures/test-repo/.hg/store/data/_rakefile.i +0 -0
  57. data/test/fixtures/test-repo/.hg/store/data/_rakefile2.i +0 -0
  58. data/test/fixtures/test-repo/.hg/store/data/_rakefile3.i +0 -0
  59. data/test/fixtures/test-repo/.hg/store/data/check ~5c this ~5c out ~22 now.i +0 -0
  60. data/test/fixtures/test-repo/.hg/store/data/directory two/minitest__mixin.rb.i +0 -0
  61. data/test/fixtures/test-repo/.hg/store/data/directory two/options.rb.i +0 -0
  62. data/test/fixtures/test-repo/.hg/store/data/directory two/rdoc__mixin.rb.i +0 -0
  63. data/test/fixtures/test-repo/.hg/store/data/directory two/rspec__mixin.rb.i +0 -0
  64. data/test/fixtures/test-repo/.hg/store/data/directory two/shindo__mixin.rb.i +0 -0
  65. data/test/fixtures/test-repo/.hg/store/data/directory two/shoulda__mixin.rb.i +0 -0
  66. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/_gemfile.i +0 -0
  67. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/_l_i_c_e_n_s_e.txt.i +0 -0
  68. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/_r_e_a_d_m_e.rdoc.i +0 -0
  69. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/_rakefile.i +0 -0
  70. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/bacon/flunking.rb.i +0 -0
  71. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/bacon/helper.rb.i +0 -0
  72. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/bundler__setup.erb.i +0 -0
  73. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/features/default.feature.i +0 -0
  74. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/features/support/env.rb.i +0 -0
  75. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/jeweler__tasks.erb.i +0 -0
  76. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/micronaut/flunking.rb.i +0 -0
  77. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/micronaut/helper.rb.i +0 -0
  78. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/minitest/flunking.rb.i +0 -0
  79. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/minitest/helper.rb.i +0 -0
  80. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/other__tasks.erb.i +0 -0
  81. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/riot/flunking.rb.i +0 -0
  82. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/riot/helper.rb.i +0 -0
  83. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/rspec/flunking.rb.i +0 -0
  84. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/rspec/helper.rb.i +0 -0
  85. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/rspec/~2erspec.i +0 -0
  86. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/shindo/flunking.rb.i +0 -0
  87. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/shindo/helper.rb.i +0 -0
  88. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/shoulda/flunking.rb.i +0 -0
  89. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/shoulda/helper.rb.i +0 -0
  90. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/testspec/flunking.rb.i +0 -0
  91. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/testspec/helper.rb.i +0 -0
  92. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/testunit/flunking.rb.i +0 -0
  93. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/testunit/helper.rb.i +0 -0
  94. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/~2edocument.i +0 -0
  95. data/test/fixtures/test-repo/.hg/store/data/directory two/templates/~2egitignore.i +0 -0
  96. data/test/fixtures/test-repo/.hg/store/data/directory two/~2e_d_s___store.i +0 -0
  97. data/test/fixtures/test-repo/.hg/store/data/directory__1/rubygems__dot__org__tasks.rb.i +0 -0
  98. data/test/fixtures/test-repo/.hg/store/data/directory__1/rubygems__tasks.rb.i +0 -0
  99. data/test/fixtures/test-repo/.hg/store/data/directory__1/specification.rb.i +0 -0
  100. data/test/fixtures/test-repo/.hg/store/data/directory__1/tasks.rb.i +0 -0
  101. data/test/fixtures/test-repo/.hg/store/data/directory__1/~2e_d_s___store.i +0 -0
  102. data/test/fixtures/test-repo/.hg/store/data/empty-file.i +0 -0
  103. data/test/fixtures/test-repo/.hg/store/data/goose.png.i +0 -0
  104. data/test/fixtures/test-repo/.hg/store/data/goose/pretty-thing.txt.i +0 -0
  105. data/test/fixtures/test-repo/.hg/store/data/new-directory/another-boring-file.i +0 -0
  106. data/test/fixtures/test-repo/.hg/store/data/new-directory/something.csv.i +0 -0
  107. data/test/fixtures/test-repo/.hg/store/data/new-directory/subdirectory/_e_u_l_a5seat___chin___sim02.03.04.pdf.d +0 -0
  108. data/test/fixtures/test-repo/.hg/store/data/new-directory/subdirectory/_e_u_l_a5seat___chin___sim02.03.04.pdf.i +0 -0
  109. data/test/fixtures/test-repo/.hg/store/data/new-directory/subdirectory/_file _with _whitespace.pdf.i +0 -0
  110. data/test/fixtures/test-repo/.hg/store/data/new-directory/subdirectory/beansprout.png.i +0 -0
  111. data/test/fixtures/test-repo/.hg/store/data/new-file.i +0 -0
  112. data/test/fixtures/test-repo/.hg/store/data/old-directory/minitest__mixin.rb.i +0 -0
  113. data/test/fixtures/test-repo/.hg/store/data/old-directory/options.rb.i +0 -0
  114. data/test/fixtures/test-repo/.hg/store/data/old-directory/rspec__mixin.rb.i +0 -0
  115. data/test/fixtures/test-repo/.hg/store/data/old-directory/shindo__mixin.rb.i +0 -0
  116. data/test/fixtures/test-repo/.hg/store/data/old-directory/testunit__mixin.rb.i +0 -0
  117. data/test/fixtures/test-repo/.hg/store/data/old-directory/yard__mixin.rb.i +0 -0
  118. data/test/fixtures/test-repo/.hg/store/data/riot__mixin.rb.i +0 -0
  119. data/test/fixtures/test-repo/.hg/store/data/riot__mixin__copy.rb.i +0 -0
  120. data/test/fixtures/test-repo/.hg/store/data/style.i +0 -0
  121. data/test/fixtures/test-repo/.hg/store/data/super-cow.i +0 -0
  122. data/test/fixtures/test-repo/.hg/store/data/superman.txt.i +0 -0
  123. data/test/fixtures/test-repo/.hg/store/data/testspec__mixin.rb.i +0 -0
  124. data/test/fixtures/test-repo/.hg/store/data/testspec__mixin__new.rb.i +0 -0
  125. data/test/fixtures/test-repo/.hg/store/data/~2e_dot_file.i +0 -0
  126. data/test/fixtures/test-repo/.hg/store/data/~2ehgignore.i +0 -0
  127. data/test/fixtures/test-repo/.hg/store/data/~2ehgtags.i +0 -0
  128. data/test/fixtures/test-repo/.hg/store/fncache +79 -0
  129. data/test/fixtures/test-repo/.hg/store/undo +0 -0
  130. data/test/fixtures/test-repo/.hg/undo.bookmarks +0 -0
  131. data/test/fixtures/test-repo/.hg/undo.branch +1 -0
  132. data/test/fixtures/test-repo/.hg/undo.desc +2 -0
  133. data/test/fixtures/test-repo/.hg/undo.dirstate +0 -0
  134. data/test/fixtures/test-repo/.hgignore +1 -0
  135. data/test/fixtures/test-repo/.hgtags +1 -0
  136. data/test/fixtures/test-repo/LICENSE3.txt +15 -0
  137. data/test/fixtures/test-repo/LICENSE4.txt +17 -0
  138. data/test/fixtures/test-repo/README.markup +218 -0
  139. data/test/fixtures/test-repo/Rakefile3 +83 -0
  140. data/test/fixtures/test-repo/check // this // out /" now" "b/data/test/fixtures/test-repo/check // this // out / → now +0 -0
  141. data/test/fixtures/test-repo/empty-file +0 -0
  142. data/test/fixtures/test-repo/goose.png +0 -0
  143. data/test/fixtures/test-repo/goose/pretty-thing.txt +0 -0
  144. data/test/fixtures/test-repo/new-directory/another-boring-file +78 -0
  145. data/test/fixtures/test-repo/new-directory/something.csv +1 -0
  146. data/test/fixtures/test-repo/new-directory/subdirectory/EULA5seat_Chin_Sim02.03.04.pdf +0 -0
  147. data/test/fixtures/test-repo/new-directory/subdirectory/File With Whitespace.pdf b/data/test/fixtures/test-repo/new-directory/subdirectory/File With → Whitespace.pdf +0 -0
  148. data/test/fixtures/test-repo/new-directory/subdirectory/beansprout.png +0 -0
  149. data/test/fixtures/test-repo/riot_mixin.rb +45 -0
  150. data/test/fixtures/test-repo/style +4 -0
  151. data/test/fixtures/test-repo/superman.txt +1 -0
  152. data/test/fixtures/test-repo/testspec_mixin_new.rb +44 -0
  153. data/test/helper.rb +41 -0
  154. data/test/test_branch_factory.rb +46 -0
  155. data/test/test_changed_file.rb +46 -0
  156. data/test/test_changed_file_factory.rb +16 -0
  157. data/test/test_command.rb +62 -0
  158. data/test/test_commit.rb +66 -0
  159. data/test/test_commit_factory.rb +101 -0
  160. data/test/test_config_file.rb +105 -0
  161. data/test/test_configuration.rb +26 -0
  162. data/test/test_diff.rb +39 -0
  163. data/test/test_diff_factory.rb +38 -0
  164. data/test/test_file_index.rb +113 -0
  165. data/test/test_hook.rb +39 -0
  166. data/test/test_hook_factory.rb +40 -0
  167. data/test/test_manifest.rb +39 -0
  168. data/test/test_node.rb +34 -0
  169. data/test/test_node_factory.rb +125 -0
  170. data/test/test_repository.rb +58 -0
  171. data/test/test_shell.rb +33 -0
  172. data/test/test_tag_factory.rb +27 -0
  173. metadata +328 -0
@@ -0,0 +1,23 @@
1
+ module Mercurial
2
+
3
+ module Helper
4
+
5
+ def hg(cmd)
6
+ repository.shell.hg(cmd)
7
+ end
8
+
9
+ def shell(cmd)
10
+ repository.shell.run(cmd)
11
+ end
12
+
13
+ def hg_to_array(cmd, separator="\n", &block)
14
+ [].tap do |returning|
15
+ hg(cmd).split(separator).each do |line|
16
+ returning << block.call(line)
17
+ end
18
+ end.compact
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,23 @@
1
+ module Mercurial
2
+
3
+ class Hook
4
+
5
+ attr_reader :repository, :name, :value
6
+
7
+ def initialize(repository, name, value)
8
+ @repository = repository
9
+ @name = name
10
+ @value = value
11
+ end
12
+
13
+ def save
14
+ repository.config.add_setting('hooks', name, value)
15
+ end
16
+
17
+ def destroy!
18
+ repository.config.delete_setting!('hooks', name)
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,58 @@
1
+ module Mercurial
2
+
3
+ #
4
+ # Represents Mercurial manifest file. Use this class to get manifest's contents
5
+ # and scan it for file paths at specific revisions.
6
+ #
7
+ # Read more about Mercurial manifest:
8
+ #
9
+ # http://mercurial.selenic.com/wiki/Manifest
10
+ #
11
+ class Manifest
12
+ include Mercurial::Helper
13
+
14
+ # Instance of {Mercurial::Repository Repository}.
15
+ attr_reader :repository
16
+
17
+ def initialize(repository)
18
+ @repository = repository
19
+ end
20
+
21
+ # Returns contents of the manifest as a String at a specified revision.
22
+ # Latest version of the manifest is used if +revision+ is ommitted.
23
+ #
24
+ # == Example:
25
+ # repository.manifest.contents
26
+ #
27
+ def contents(revision=nil)
28
+ revision ||= 'tip'
29
+ hg(manifest_cmd(revision))
30
+ end
31
+
32
+ # Returns an array of file paths from manifest that start with the specified +path+ at a specified +revision+.
33
+ # Latest version of the manifest is used if +revision+ is ommitted.
34
+ #
35
+ # == Example:
36
+ # repository.manifest.scan_for_path('/')
37
+ # repository.manifest.scan_for_path('some-interesting-directory/', '2d32410d9629')
38
+ #
39
+ def scan_for_path(path, revision=nil)
40
+ revision ||= 'tip'
41
+ path = path.without_trailing_slash
42
+ if path == '/' || path == ''
43
+ search_for = ".*"
44
+ else
45
+ path_re = Regexp.escape(path)
46
+ search_for = "#{ path_re }$|#{ path_re }\/.*"
47
+ end
48
+ contents(revision).scan(/^(\w{40}) (\d{3}) (\*?) +(#{ search_for })/)
49
+ end
50
+
51
+ private
52
+
53
+ def manifest_cmd(revision)
54
+ ["manifest -r ? --debug", revision]
55
+ end
56
+ end
57
+
58
+ end
@@ -0,0 +1,100 @@
1
+ module Mercurial
2
+
3
+ #
4
+ # The class represents Mercurial file or directory. Data obtained by scanning +hg manifest+ output.
5
+ #
6
+ # The class represents Node object itself, {Mercurial::NodeFactory NodeFactory} is responsible
7
+ # for assembling instances of Node. For the list of all possible branch-related operations please
8
+ # look documentation for {Mercurial::NodeFactory NodeFactory}.
9
+ #
10
+ # Additionally {Mercurial::Manifest Manifest} is responsible for reading and scanning the manifest.
11
+ #
12
+ class Node
13
+ include Mercurial::Helper
14
+
15
+ # Instance of {Mercurial::Repository Repository}.
16
+ attr_reader :repository
17
+
18
+ # Absolute path to the node.
19
+ attr_reader :path
20
+
21
+ # File mode of the node in Octal notation (if file).
22
+ attr_reader :fmode
23
+
24
+ # Executable flag of the node (if file).
25
+ attr_reader :executable
26
+
27
+ # nodeid value for the node (if file).
28
+ attr_reader :nodeid
29
+
30
+ # Node's parent, instance of {Mercurial::Node Node}.
31
+ attr_reader :parent
32
+
33
+ def initialize(opts={})
34
+ @repository = opts[:repository]
35
+ @path = opts[:path]
36
+ @parent = opts[:parent]
37
+ @name = opts[:name]
38
+ @fmode = opts[:fmode]
39
+ @executable = opts[:executable] == '*' ? true : false
40
+ @revision = opts[:revision]
41
+ @nodeid = opts[:nodeid]
42
+ end
43
+
44
+ def name
45
+ @name ||= begin
46
+ n = path.split('/').last
47
+ n << '/' if path =~ /\/$/
48
+ n
49
+ end
50
+ end
51
+
52
+ def revision
53
+ @revision || (parent ? parent.revision : nil) || 'tip'
54
+ end
55
+
56
+ def path_without_parent
57
+ if parent
58
+ path.gsub(/^#{ Regexp.escape(parent.path) }/, '')
59
+ else
60
+ path
61
+ end
62
+ end
63
+
64
+ def entries
65
+ @_entries ||= repository.nodes.entries_for(path, revision, self)
66
+ end
67
+
68
+ def has_entry?(name)
69
+ entries.find do |e|
70
+ e.name == name
71
+ end
72
+ end
73
+
74
+ def directory?
75
+ not file?
76
+ end
77
+
78
+ def file?
79
+ (name =~ /\/$/).nil?
80
+ end
81
+
82
+ def root?
83
+ false
84
+ end
85
+
86
+ def binary?
87
+ false
88
+ end
89
+
90
+ def contents
91
+ hg(["cat ? -r ?", path, revision])
92
+ end
93
+
94
+ def size
95
+ contents.size
96
+ end
97
+
98
+ end
99
+
100
+ end
@@ -0,0 +1,94 @@
1
+ module Mercurial
2
+ class RepositoryNotFound < Error; end
3
+
4
+ class Repository
5
+
6
+ def self.create(destination)
7
+ init_repository(destination)
8
+ end
9
+
10
+ def self.open(destination)
11
+ if File.exists?(destination)
12
+ new(destination)
13
+ else
14
+ raise Mercurial::RepositoryNotFound.new(destination)
15
+ end
16
+ end
17
+
18
+ def initialize(source)
19
+ @path = source
20
+ end
21
+
22
+ def shell
23
+ @_shell ||= Mercurial::Shell.new(self)
24
+ end
25
+
26
+ def config
27
+ @_config ||= Mercurial::ConfigFile.new(self)
28
+ end
29
+
30
+ def hooks
31
+ @_hook_factory ||= Mercurial::HookFactory.new(self)
32
+ end
33
+
34
+ def commits
35
+ @_commits ||= Mercurial::CommitFactory.new(self)
36
+ end
37
+
38
+ def branches
39
+ @_branches ||= Mercurial::BranchFactory.new(self)
40
+ end
41
+
42
+ def tags
43
+ @_tags ||= Mercurial::TagFactory.new(self)
44
+ end
45
+
46
+ def diffs
47
+ @_diffs ||= Mercurial::DiffFactory.new(self)
48
+ end
49
+
50
+ def nodes
51
+ @_nodes ||= Mercurial::NodeFactory.new(self)
52
+ end
53
+
54
+ def manifest
55
+ @_manifest ||= Mercurial::Manifest.new(self)
56
+ end
57
+
58
+ def file_index
59
+ @_file_index ||= Mercurial::FileIndex.new(self)
60
+ end
61
+
62
+ def node(name, hash_id)
63
+ nodes.find(name, hash_id)
64
+ end
65
+
66
+ def destroy!
67
+ FileUtils.rm_rf(path)
68
+ end
69
+
70
+ def path
71
+ File.expand_path(@path)
72
+ end
73
+
74
+ def dothg_path
75
+ File.join(path, '.hg')
76
+ end
77
+
78
+ def mtime
79
+ File.mtime(dothg_path).to_i
80
+ end
81
+
82
+ protected
83
+
84
+ def self.init_repository(destination)
85
+ Mercurial::Shell.run("mkdir -p #{ destination }")
86
+ open(destination).tap do |repo|
87
+ repo.shell.hg('init', :cache => false)
88
+ repo.shell.hg('update null', :cache => false)
89
+ end
90
+ end
91
+
92
+ end
93
+
94
+ end
@@ -0,0 +1,27 @@
1
+ module Mercurial
2
+
3
+ class RootNode < Node
4
+
5
+ def directory?
6
+ true
7
+ end
8
+
9
+ def file?
10
+ false
11
+ end
12
+
13
+ def root?
14
+ true
15
+ end
16
+
17
+ def binary?
18
+ false
19
+ end
20
+
21
+ def path
22
+ ''
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,64 @@
1
+ module Mercurial
2
+
3
+ class Shell
4
+
5
+ attr_reader :repository
6
+
7
+ def self.run(cmd, options={})
8
+ options[:cache] = true if options[:cache].nil?
9
+ build = []
10
+
11
+ if options[:in]
12
+ build << "cd #{ options[:in] }"
13
+ end
14
+
15
+ if cmd.kind_of?(Array)
16
+ cmd = interpolate_arguments(cmd)
17
+ end
18
+
19
+ build << cmd
20
+ to_run = build.join(' && ')
21
+ Mercurial::Command.new(to_run, :repository => options[:repository], :cache => options[:cache]).execute
22
+ end
23
+
24
+ def initialize(repository)
25
+ @repository = repository
26
+ end
27
+
28
+ def hg(cmd, options={})
29
+ options[:in] ||= repository.path
30
+ options[:repository] = repository
31
+ cmd = append_command_with(hg_binary_path, cmd)
32
+ run(cmd, options)
33
+ end
34
+
35
+ def run(cmd, options={})
36
+ self.class.run(cmd, options)
37
+ end
38
+
39
+ private
40
+
41
+ def hg_binary_path
42
+ Mercurial.configuration.hg_binary_path
43
+ end
44
+
45
+ def self.interpolate_arguments(cmd_with_args)
46
+ cmd_with_args.shift.tap do |cmd|
47
+ cmd.gsub!(/\?/) do
48
+ cmd_with_args.shift.to_s.enclose_in_single_quotes
49
+ end
50
+ end
51
+ end
52
+
53
+ def append_command_with(append, cmd)
54
+ if cmd.kind_of?(Array)
55
+ cmd[0].insert(0, "#{ append } ")
56
+ cmd
57
+ else
58
+ "#{ append } #{ cmd }"
59
+ end
60
+ end
61
+
62
+ end
63
+
64
+ end
@@ -0,0 +1,23 @@
1
+ module Mercurial
2
+
3
+ module Style
4
+ extend self
5
+
6
+ FIELD_SEPARATOR = '|><|'
7
+ CHANGESET_SEPARATOR = "||$||\n"
8
+
9
+ def root_path
10
+ File.expand_path(File.join(File.dirname(__FILE__), '..', 'styles'))
11
+ end
12
+
13
+ def changeset
14
+ File.join(root_path, 'changeset.style')
15
+ end
16
+
17
+ def file_index
18
+ File.join(root_path, 'file_index.style')
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,33 @@
1
+ module Mercurial
2
+
3
+ #
4
+ # The class represents Mercurial tag. Obtained by running an +hg tags+ command.
5
+ #
6
+ # The class represents Tag object itself, {Mercurial::TagFactory TagFactory} is responsible
7
+ # for assembling instances of Tag. For the list of all possible tag-related operations please
8
+ # look documentation for {Mercurial::TagFactory TagFactory}.
9
+ #
10
+ # Read more about Mercurial tags:
11
+ #
12
+ # http://mercurial.selenic.com/wiki/Tag
13
+ #
14
+ class Tag
15
+
16
+ # Instance of {Mercurial::Repository Repository}.
17
+ attr_reader :repository
18
+
19
+ # Name of the tag.
20
+ attr_reader :name
21
+
22
+ # Mercurial changeset ID of the tag. 40-chars long SHA1 hash.
23
+ attr_reader :hash_id
24
+
25
+ def initialize(repository, name, hash_id)
26
+ @repository = repository
27
+ @name = name
28
+ @hash_id = hash_id
29
+ end
30
+
31
+ end
32
+
33
+ end