mercurial-ruby 0.5.0 → 0.6.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.
- data/README.rdoc +8 -0
- data/VERSION +1 -1
- data/lib/mercurial-ruby.rb +1 -1
- data/lib/mercurial-ruby/command.rb +15 -7
- data/lib/mercurial-ruby/commit.rb +5 -1
- data/lib/mercurial-ruby/config_file.rb +16 -2
- data/lib/mercurial-ruby/configuration.rb +20 -2
- data/lib/mercurial-ruby/factories/blame_factory.rb +2 -2
- data/lib/mercurial-ruby/factories/branch_factory.rb +4 -4
- data/lib/mercurial-ruby/factories/commit_factory.rb +80 -15
- data/lib/mercurial-ruby/factories/diff_factory.rb +4 -4
- data/lib/mercurial-ruby/factories/hook_factory.rb +2 -2
- data/lib/mercurial-ruby/factories/node_factory.rb +0 -1
- data/lib/mercurial-ruby/factories/tag_factory.rb +2 -2
- data/lib/mercurial-ruby/file_index.rb +14 -6
- data/lib/mercurial-ruby/helper.rb +7 -6
- data/lib/mercurial-ruby/manifest.rb +2 -2
- data/lib/mercurial-ruby/node.rb +8 -0
- data/lib/mercurial-ruby/repository.rb +51 -2
- data/lib/mercurial-ruby/shell.rb +11 -8
- data/mercurial-ruby.gemspec +2 -2
- data/test/test_command.rb +26 -2
- data/test/test_commit.rb +5 -1
- data/test/test_commit_factory.rb +30 -3
- data/test/test_config_file.rb +20 -1
- data/test/test_file_index.rb +10 -0
- data/test/test_hook.rb +1 -1
- data/test/test_repository.rb +35 -2
- data/test/test_shell.rb +4 -4
- metadata +4 -4
data/README.rdoc
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
|
3
3
|
Ruby API for Mercurial DVCS. Uses command line interface to communicate with Mercurial repositories.
|
4
4
|
|
5
|
+
== Documentation
|
6
|
+
|
7
|
+
Please refer to YARD documentation here:
|
8
|
+
|
9
|
+
http://rubydoc.info/gems/mercurial-ruby/file/README.rdoc
|
10
|
+
|
11
|
+
Github doesn't support some YARd-specific syntax so this README can look broken.
|
12
|
+
|
5
13
|
== Installation
|
6
14
|
|
7
15
|
gem install mercurial-ruby
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
data/lib/mercurial-ruby.rb
CHANGED
@@ -5,12 +5,13 @@ module Mercurial
|
|
5
5
|
class CommandError < Error; end
|
6
6
|
|
7
7
|
class Command
|
8
|
-
attr_accessor :command, :repository, :use_cache
|
8
|
+
attr_accessor :command, :repository, :use_cache, :timeout
|
9
9
|
|
10
10
|
def initialize(cmd, options={})
|
11
11
|
@command = cmd
|
12
12
|
@repository = options[:repository]
|
13
|
-
@use_cache = options[:cache]
|
13
|
+
@use_cache = options[:cache].nil? || options[:cache] == false ? false : true
|
14
|
+
@timeout = options[:timeout] ? options[:timeout].to_i : global_execution_timeout.to_i
|
14
15
|
end
|
15
16
|
|
16
17
|
def execute
|
@@ -24,14 +25,14 @@ module Mercurial
|
|
24
25
|
private
|
25
26
|
|
26
27
|
def cache_commands?
|
27
|
-
repository &&
|
28
|
+
repository && !repository.cache_disabled_by_override? && cache_store && use_cache
|
28
29
|
end
|
29
30
|
|
30
31
|
def cache_store
|
31
32
|
Mercurial.configuration.cache_store
|
32
33
|
end
|
33
34
|
|
34
|
-
def
|
35
|
+
def global_execution_timeout
|
35
36
|
Mercurial.configuration.shell_timeout
|
36
37
|
end
|
37
38
|
|
@@ -45,9 +46,10 @@ module Mercurial
|
|
45
46
|
|
46
47
|
def execution_proc
|
47
48
|
Proc.new do
|
48
|
-
|
49
|
+
debug(command)
|
50
|
+
result, error = '', ''
|
49
51
|
Open3.popen3(command) do |_, stdout, stderr|
|
50
|
-
Timeout.timeout(
|
52
|
+
Timeout.timeout(timeout) do
|
51
53
|
while tmp = stdout.read(102400)
|
52
54
|
result += tmp
|
53
55
|
end
|
@@ -71,7 +73,13 @@ module Mercurial
|
|
71
73
|
def cache_key
|
72
74
|
"hg.#{ repository.mtime }." + Digest::MD5.hexdigest(command)
|
73
75
|
end
|
76
|
+
|
77
|
+
def debug(msg)
|
78
|
+
if Mercurial.configuration.debug_mode
|
79
|
+
puts msg
|
80
|
+
end
|
81
|
+
end
|
74
82
|
|
75
83
|
end
|
76
84
|
|
77
|
-
end
|
85
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Mercurial
|
2
|
-
|
2
|
+
|
3
3
|
#
|
4
4
|
# Represents +.hg/hgrc+ configuration file stored in the repository.
|
5
5
|
# Useful for adding/removing various settings.
|
@@ -9,6 +9,8 @@ module Mercurial
|
|
9
9
|
# http://www.selenic.com/mercurial/hgrc.5.html
|
10
10
|
#
|
11
11
|
class ConfigFile
|
12
|
+
|
13
|
+
class DuplicateSetting < Error; end
|
12
14
|
|
13
15
|
attr_reader :repository
|
14
16
|
|
@@ -51,6 +53,8 @@ module Mercurial
|
|
51
53
|
# kdiff3.executable = ~/bin/kdiff3
|
52
54
|
#
|
53
55
|
def add_setting(header, name, value)
|
56
|
+
raise DuplicateSetting if setting_exists?(header, name)
|
57
|
+
|
54
58
|
new_setting = %Q{[#{ header }]\n#{ name } = #{ value }\n}
|
55
59
|
write do
|
56
60
|
if contents.nil?
|
@@ -73,6 +77,15 @@ module Mercurial
|
|
73
77
|
contents.gsub(find_setting(header, name), '')
|
74
78
|
end
|
75
79
|
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Returns true if specified setting exists in specified group.
|
83
|
+
#
|
84
|
+
# config.setting_exists?('hooks', 'changegroup')
|
85
|
+
#
|
86
|
+
def setting_exists?(header, name)
|
87
|
+
!!find_setting(header, name)
|
88
|
+
end
|
76
89
|
|
77
90
|
#
|
78
91
|
# Returns content of the specified section of hgrc.
|
@@ -90,6 +103,7 @@ module Mercurial
|
|
90
103
|
# Returns content of the specified setting from a section.
|
91
104
|
#
|
92
105
|
def find_setting(header, setting) #:nodoc:
|
106
|
+
return nil if contents.nil?
|
93
107
|
contents.scan(setting_regexp(header, setting)).flatten.first
|
94
108
|
end
|
95
109
|
|
@@ -116,4 +130,4 @@ module Mercurial
|
|
116
130
|
|
117
131
|
end
|
118
132
|
|
119
|
-
end
|
133
|
+
end
|
@@ -1,14 +1,32 @@
|
|
1
1
|
module Mercurial
|
2
2
|
|
3
|
+
#
|
4
|
+
# Use this class to setup various internal settings of the gem.
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
#
|
8
|
+
# Mercurial.configure do |conf|
|
9
|
+
# conf.cache_store = Rails.cache
|
10
|
+
# conf.debug_mode = true
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# Currently only the following settings are supported:
|
14
|
+
#
|
15
|
+
# * hg_binary_path — path to hg binary in your system. Default is /usr/local/bin/hg.
|
16
|
+
# * shell_timeout — default execution timeout for all hg shell commands. Default is 3000.
|
17
|
+
# * cache_store — Rails's CacheStore compatible class for caching results of successful hg commands. Default is nil.
|
18
|
+
# * debug_mode — send all hg commands to stdout before execution. Default is false.
|
19
|
+
#
|
3
20
|
class Configuration
|
4
21
|
|
5
|
-
attr_accessor :hg_binary_path, :shell_timeout, :cache_store
|
22
|
+
attr_accessor :hg_binary_path, :shell_timeout, :cache_store, :debug_mode
|
6
23
|
|
7
24
|
def initialize
|
8
25
|
@hg_binary_path = '/usr/local/bin/hg'
|
9
26
|
@shell_timeout = 3000
|
27
|
+
@debug_mode = false
|
10
28
|
end
|
11
29
|
|
12
30
|
end
|
13
31
|
|
14
|
-
end
|
32
|
+
end
|
@@ -9,10 +9,10 @@ module Mercurial
|
|
9
9
|
@repository = repository
|
10
10
|
end
|
11
11
|
|
12
|
-
def for_path(path, revision=nil)
|
12
|
+
def for_path(path, revision=nil, cmd_options={})
|
13
13
|
revision ||= 'tip'
|
14
14
|
build do
|
15
|
-
hg(["blame ? -ucl -r ?", path, revision])
|
15
|
+
hg(["blame ? -ucl -r ?", path, revision], cmd_options)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -18,8 +18,8 @@ module Mercurial
|
|
18
18
|
# == Example:
|
19
19
|
# repository.branches.all
|
20
20
|
#
|
21
|
-
def all
|
22
|
-
hg_to_array
|
21
|
+
def all(cmd_options={})
|
22
|
+
hg_to_array("branches -c", {}, cmd_options) do |line|
|
23
23
|
build(line)
|
24
24
|
end
|
25
25
|
end
|
@@ -63,8 +63,8 @@ module Mercurial
|
|
63
63
|
# == Example:
|
64
64
|
# repository.branches.for_commit('291a498f04e9')
|
65
65
|
#
|
66
|
-
def for_commit(hash_id)
|
67
|
-
hg_to_array
|
66
|
+
def for_commit(hash_id, cmd_options={})
|
67
|
+
hg_to_array(["log -r 'descendants(?) and head()' --template '\n{branches}'", hash_id], {}, cmd_options) do |line|
|
68
68
|
build_with_name_only(line)
|
69
69
|
end.compact.uniq
|
70
70
|
end
|
@@ -12,14 +12,29 @@ module Mercurial
|
|
12
12
|
def initialize(repository) #:nodoc:
|
13
13
|
@repository = repository
|
14
14
|
end
|
15
|
+
|
16
|
+
# Return a parent commit for this working copy.
|
17
|
+
#
|
18
|
+
# == Example:
|
19
|
+
# repository.commits.parent
|
20
|
+
#
|
21
|
+
def parent(cmd_options={})
|
22
|
+
build do
|
23
|
+
hg(["parent --style ?", style], cmd_options)
|
24
|
+
end
|
25
|
+
end
|
15
26
|
|
16
27
|
# Return an array of {Mercurial::Commit Commit} instances for all changesets in the repository.
|
28
|
+
# Accept a :limit setting.
|
17
29
|
#
|
18
30
|
# == Example:
|
19
|
-
# repository.commits.all
|
31
|
+
# repository.commits.all
|
32
|
+
# repository.commits.all(:limit => 15)
|
20
33
|
#
|
21
|
-
def all
|
22
|
-
|
34
|
+
def all(options={}, cmd_options={})
|
35
|
+
cmd = command_with_limit(["log --style ?", style], options[:limit])
|
36
|
+
|
37
|
+
hg_to_array(cmd, {:separator => changeset_separator}, cmd_options) do |line|
|
23
38
|
build(line)
|
24
39
|
end
|
25
40
|
end
|
@@ -40,8 +55,19 @@ module Mercurial
|
|
40
55
|
# == Example:
|
41
56
|
# repository.commits.count
|
42
57
|
#
|
43
|
-
def count
|
44
|
-
hg_to_array
|
58
|
+
def count(cmd_options={})
|
59
|
+
hg_to_array(%Q[log --template "{node}\n"], {}, cmd_options) do |line|
|
60
|
+
line
|
61
|
+
end.size
|
62
|
+
end
|
63
|
+
|
64
|
+
# Count changesets in the range from hash_a to hash_b in the repository.
|
65
|
+
#
|
66
|
+
# == Example:
|
67
|
+
# repository.commits.count_range(hash_a, hash_b)
|
68
|
+
#
|
69
|
+
def count_range(hash_a, hash_b, cmd_options={})
|
70
|
+
hg_to_array([%Q[log -r ?:? --template "{node}\n"], hash_a, hash_b], {}, cmd_options) do |line|
|
45
71
|
line
|
46
72
|
end.size
|
47
73
|
end
|
@@ -51,8 +77,8 @@ module Mercurial
|
|
51
77
|
# == Example:
|
52
78
|
# repository.commits.by_branch('brancname')
|
53
79
|
#
|
54
|
-
def by_branch(branch)
|
55
|
-
hg_to_array
|
80
|
+
def by_branch(branch, cmd_options={})
|
81
|
+
hg_to_array(["log -b ? --style ?", branch, style], {:separator => changeset_separator}, cmd_options) do |line|
|
56
82
|
build(line)
|
57
83
|
end
|
58
84
|
end
|
@@ -62,9 +88,9 @@ module Mercurial
|
|
62
88
|
# == Example:
|
63
89
|
# repository.commits.by_hash_id('291a498f04e9')
|
64
90
|
#
|
65
|
-
def by_hash_id(hash)
|
91
|
+
def by_hash_id(hash, cmd_options={})
|
66
92
|
build do
|
67
|
-
hg(["log -r ? --style ?", hash, style])
|
93
|
+
hg(["log -r ? --style ?", hash, style], cmd_options)
|
68
94
|
end
|
69
95
|
end
|
70
96
|
|
@@ -74,6 +100,8 @@ module Mercurial
|
|
74
100
|
# repository.commits.by_hash_ids('291a498f04e9', '63f70b2314ed')
|
75
101
|
#
|
76
102
|
def by_hash_ids(*args)
|
103
|
+
cmd_options = args.last.kind_of?(Hash) ? args.last : {}
|
104
|
+
|
77
105
|
if args.size == 1 && args.first.kind_of?(Array)
|
78
106
|
array = args.first
|
79
107
|
else
|
@@ -82,7 +110,7 @@ module Mercurial
|
|
82
110
|
return [] if array.empty?
|
83
111
|
|
84
112
|
args = array.map{|hash| " -r#{ hash }"}
|
85
|
-
hg_to_array ["log#{ args } --style ?", style], changeset_separator do |line|
|
113
|
+
hg_to_array ["log#{ args } --style ?", style], {:separator => changeset_separator}, cmd_options do |line|
|
86
114
|
build(line)
|
87
115
|
end
|
88
116
|
end
|
@@ -92,25 +120,54 @@ module Mercurial
|
|
92
120
|
# == Example:
|
93
121
|
# repository.commits.for_range('bf6386c0a0cc', '63f70b2314ed')
|
94
122
|
#
|
95
|
-
def for_range(hash_a, hash_b)
|
96
|
-
|
123
|
+
def for_range(hash_a, hash_b, options={}, cmd_options={})
|
124
|
+
cmd = command_with_limit(["log -r ?:? --style ?", hash_a, hash_b, style], options[:limit])
|
125
|
+
hg_to_array(cmd, {:separator => changeset_separator}, cmd_options) do |line|
|
97
126
|
build(line)
|
98
127
|
end
|
99
128
|
end
|
129
|
+
|
130
|
+
# Return an array of {Mercurial::Commit Commit} instances that appear in hg log before the specified revision id.
|
131
|
+
#
|
132
|
+
# == Example:
|
133
|
+
# repository.commits.before('bf6386c0a0cc')
|
134
|
+
#
|
135
|
+
def before(hash_id, options={}, cmd_options={})
|
136
|
+
in_direction(:before, hash_id, options, cmd_options)
|
137
|
+
end
|
138
|
+
|
139
|
+
# Return an array of {Mercurial::Commit Commit} instances that appear in hg log after the specified revision id.
|
140
|
+
#
|
141
|
+
# == Example:
|
142
|
+
# repository.commits.after('bf6386c0a0cc')
|
143
|
+
#
|
144
|
+
def after(hash_id, options={}, cmd_options={})
|
145
|
+
in_direction(:after, hash_id, options, cmd_options)
|
146
|
+
end
|
100
147
|
|
101
148
|
# Return an instance of {Mercurial::Commit Commit} for a repository's tip changeset (latest).
|
102
149
|
#
|
103
150
|
# == Example:
|
104
151
|
# repository.commits.tip
|
105
152
|
#
|
106
|
-
def tip
|
153
|
+
def tip(cmd_options={})
|
107
154
|
build do
|
108
|
-
hg(["tip --style ?", style])
|
155
|
+
hg(["tip --style ?", style], cmd_options)
|
109
156
|
end
|
110
157
|
end
|
111
158
|
alias :latest :tip
|
112
159
|
|
113
160
|
protected
|
161
|
+
|
162
|
+
def in_direction(direction, hash_id, options={}, cmd_options={})
|
163
|
+
query = direction.to_sym == :before ? '"reverse(:?)"' : '?:'
|
164
|
+
cmd = command_with_limit(["log -r #{ query } --style ?", hash_id, style], options[:limit])
|
165
|
+
|
166
|
+
hg_to_array(cmd, {:separator => changeset_separator}, cmd_options) do |line|
|
167
|
+
c = build(line)
|
168
|
+
c.short_hash_id == hash_id[0,12] ? next : c
|
169
|
+
end
|
170
|
+
end
|
114
171
|
|
115
172
|
def changeset_separator
|
116
173
|
Mercurial::Style::CHANGESET_SEPARATOR
|
@@ -148,7 +205,15 @@ module Mercurial
|
|
148
205
|
def style
|
149
206
|
Mercurial::Style.changeset
|
150
207
|
end
|
208
|
+
|
209
|
+
def command_with_limit(cmd, limit)
|
210
|
+
if limit
|
211
|
+
cmd[0] << ' --limit ?'
|
212
|
+
cmd << limit
|
213
|
+
end
|
214
|
+
cmd
|
215
|
+
end
|
151
216
|
|
152
217
|
end
|
153
218
|
|
154
|
-
end
|
219
|
+
end
|
@@ -20,9 +20,9 @@ module Mercurial
|
|
20
20
|
# commit = repository.commits.by_hash_id('291a498f04e9')
|
21
21
|
# repository.diffs.for_commit(commit)
|
22
22
|
#
|
23
|
-
def for_commit(commit)
|
23
|
+
def for_commit(commit, cmd_options={})
|
24
24
|
[].tap do |returning|
|
25
|
-
data = hg(["diff -c ?", commit.hash_id])
|
25
|
+
data = hg(["diff -c ?", commit.hash_id], cmd_options)
|
26
26
|
chunks = data.split(/^diff/)[1..-1]
|
27
27
|
unless chunks.nil?
|
28
28
|
chunks.map do |piece|
|
@@ -33,8 +33,8 @@ module Mercurial
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
def for_path(path, revision_a, revision_b)
|
37
|
-
build(hg(["diff ? -r ? -r ?", path, revision_a, revision_b]))
|
36
|
+
def for_path(path, revision_a, revision_b, cmd_options={})
|
37
|
+
build(hg(["diff ? -r ? -r ?", path, revision_a, revision_b], cmd_options))
|
38
38
|
end
|
39
39
|
|
40
40
|
private
|
@@ -11,11 +11,9 @@ module Mercurial
|
|
11
11
|
class FileIndex
|
12
12
|
include Mercurial::Helper
|
13
13
|
|
14
|
-
class IndexFileNotFound < StandardError
|
15
|
-
end
|
16
|
-
|
17
|
-
class UnsupportedRef < StandardError
|
18
|
-
end
|
14
|
+
class IndexFileNotFound < StandardError;end
|
15
|
+
class IndexFileTooBig < StandardError;end
|
16
|
+
class UnsupportedRef < StandardError;end
|
19
17
|
|
20
18
|
class << self
|
21
19
|
attr_accessor :max_file_size
|
@@ -169,9 +167,19 @@ module Mercurial
|
|
169
167
|
end
|
170
168
|
end
|
171
169
|
end
|
170
|
+
|
171
|
+
def validate_index_file
|
172
|
+
if File.file?(path)
|
173
|
+
if File.size(path) > Mercurial::FileIndex.max_file_size
|
174
|
+
raise IndexFileTooBig, "#{ path } is bigger than #{ Mercurial::FileIndex.max_file_size }"
|
175
|
+
end
|
176
|
+
else
|
177
|
+
raise IndexFileNotFound, path unless index_file_valid?
|
178
|
+
end
|
179
|
+
end
|
172
180
|
|
173
181
|
def read_index
|
174
|
-
|
182
|
+
validate_index_file
|
175
183
|
f = File.new(path)
|
176
184
|
@sha_count = 0
|
177
185
|
@commit_index = {}
|
@@ -2,17 +2,18 @@ module Mercurial
|
|
2
2
|
|
3
3
|
module Helper
|
4
4
|
|
5
|
-
def hg(cmd)
|
6
|
-
repository.shell.hg(cmd)
|
5
|
+
def hg(cmd, options={})
|
6
|
+
repository.shell.hg(cmd, options)
|
7
7
|
end
|
8
8
|
|
9
|
-
def shell(cmd)
|
10
|
-
repository.shell.run(cmd)
|
9
|
+
def shell(cmd, options={})
|
10
|
+
repository.shell.run(cmd, options)
|
11
11
|
end
|
12
12
|
|
13
|
-
def hg_to_array(cmd,
|
13
|
+
def hg_to_array(cmd, options={}, cmd_options={}, &block)
|
14
|
+
separator = options[:separator] || "\n"
|
14
15
|
[].tap do |returning|
|
15
|
-
hg(cmd).split(separator).each do |line|
|
16
|
+
hg(cmd, cmd_options).split(separator).each do |line|
|
16
17
|
returning << block.call(line)
|
17
18
|
end
|
18
19
|
end.compact
|
@@ -24,9 +24,9 @@ module Mercurial
|
|
24
24
|
# == Example:
|
25
25
|
# repository.manifest.contents
|
26
26
|
#
|
27
|
-
def contents(revision=nil)
|
27
|
+
def contents(revision=nil, cmd_options={})
|
28
28
|
revision ||= 'tip'
|
29
|
-
hg(manifest_cmd(revision))
|
29
|
+
hg(manifest_cmd(revision), cmd_options)
|
30
30
|
end
|
31
31
|
|
32
32
|
# Returns an array of file paths from manifest that start with the specified +path+ at a specified +revision+.
|
data/lib/mercurial-ruby/node.rb
CHANGED
@@ -65,6 +65,14 @@ module Mercurial
|
|
65
65
|
@_entries ||= repository.nodes.entries_for(path, revision, self)
|
66
66
|
end
|
67
67
|
|
68
|
+
def diff_to(revision_b)
|
69
|
+
repository.diffs.for_path(path, revision, revision_b)
|
70
|
+
end
|
71
|
+
|
72
|
+
def blame
|
73
|
+
repository.blames.for_path(path, revision)
|
74
|
+
end
|
75
|
+
|
68
76
|
def has_entry?(name)
|
69
77
|
entries.find do |e|
|
70
78
|
e.name == name
|
@@ -14,6 +14,13 @@ module Mercurial
|
|
14
14
|
raise Mercurial::RepositoryNotFound.new(destination)
|
15
15
|
end
|
16
16
|
end
|
17
|
+
|
18
|
+
def self.clone(url, destination, cmd_options)
|
19
|
+
create_destination(destination)
|
20
|
+
opts = cmd_options.merge(:append_hg => true)
|
21
|
+
Mercurial::Shell.run(["clone ? ?", url, destination], opts)
|
22
|
+
open(destination)
|
23
|
+
end
|
17
24
|
|
18
25
|
def initialize(source)
|
19
26
|
@path = source
|
@@ -67,10 +74,38 @@ module Mercurial
|
|
67
74
|
nodes.find(name, hash_id)
|
68
75
|
end
|
69
76
|
|
77
|
+
def clone(destination_path, cmd_options={})
|
78
|
+
self.class.clone(file_system_url, destination_path, cmd_options)
|
79
|
+
end
|
80
|
+
|
81
|
+
def pull(origin='default', cmd_options={})
|
82
|
+
shell.hg(['pull ?', origin], cmd_options)
|
83
|
+
end
|
84
|
+
|
85
|
+
def verify
|
86
|
+
shell.hg('verify')
|
87
|
+
true
|
88
|
+
rescue Mercurial::CommandError
|
89
|
+
false
|
90
|
+
end
|
91
|
+
|
92
|
+
def paths
|
93
|
+
{}.tap do |result|
|
94
|
+
shell.hg('paths').each do |line|
|
95
|
+
path, url = *line.strip.split(" = ")
|
96
|
+
result[path] = url
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
70
101
|
def destroy!
|
71
102
|
FileUtils.rm_rf(path)
|
72
103
|
end
|
73
104
|
|
105
|
+
def file_system_url
|
106
|
+
%Q[file://#{ path }]
|
107
|
+
end
|
108
|
+
|
74
109
|
def path
|
75
110
|
File.expand_path(@path)
|
76
111
|
end
|
@@ -83,10 +118,24 @@ module Mercurial
|
|
83
118
|
File.mtime(dothg_path).to_i
|
84
119
|
end
|
85
120
|
|
121
|
+
def no_cache
|
122
|
+
@cache_disabled_by_override = true
|
123
|
+
yield
|
124
|
+
@cache_disabled_by_override = false
|
125
|
+
end
|
126
|
+
|
127
|
+
def cache_disabled_by_override?
|
128
|
+
@cache_disabled_by_override || false
|
129
|
+
end
|
130
|
+
|
86
131
|
protected
|
132
|
+
|
133
|
+
def self.create_destination(path)
|
134
|
+
Mercurial::Shell.run("mkdir -p #{ path }")
|
135
|
+
end
|
87
136
|
|
88
137
|
def self.init_repository(destination)
|
89
|
-
|
138
|
+
create_destination(destination)
|
90
139
|
open(destination).tap do |repo|
|
91
140
|
repo.shell.hg('init', :cache => false)
|
92
141
|
repo.shell.hg('update null', :cache => false)
|
@@ -95,4 +144,4 @@ module Mercurial
|
|
95
144
|
|
96
145
|
end
|
97
146
|
|
98
|
-
end
|
147
|
+
end
|
data/lib/mercurial-ruby/shell.rb
CHANGED
@@ -5,11 +5,14 @@ module Mercurial
|
|
5
5
|
attr_reader :repository
|
6
6
|
|
7
7
|
def self.run(cmd, options={})
|
8
|
-
options[:cache] = true if options[:cache].nil?
|
9
8
|
build = []
|
10
9
|
|
11
|
-
if options[:
|
12
|
-
|
10
|
+
if options[:append_hg]
|
11
|
+
cmd = append_command_with(hg_binary_path, cmd)
|
12
|
+
end
|
13
|
+
|
14
|
+
if dir = options.delete(:in)
|
15
|
+
build << "cd #{ dir }"
|
13
16
|
end
|
14
17
|
|
15
18
|
if cmd.kind_of?(Array)
|
@@ -18,7 +21,7 @@ module Mercurial
|
|
18
21
|
|
19
22
|
build << cmd
|
20
23
|
to_run = build.join(' && ')
|
21
|
-
Mercurial::Command.new(to_run,
|
24
|
+
Mercurial::Command.new(to_run, options).execute
|
22
25
|
end
|
23
26
|
|
24
27
|
def initialize(repository)
|
@@ -28,7 +31,7 @@ module Mercurial
|
|
28
31
|
def hg(cmd, options={})
|
29
32
|
options[:in] ||= repository.path
|
30
33
|
options[:repository] = repository
|
31
|
-
|
34
|
+
options[:append_hg] = true
|
32
35
|
run(cmd, options)
|
33
36
|
end
|
34
37
|
|
@@ -38,7 +41,7 @@ module Mercurial
|
|
38
41
|
|
39
42
|
private
|
40
43
|
|
41
|
-
def hg_binary_path
|
44
|
+
def self.hg_binary_path
|
42
45
|
Mercurial.configuration.hg_binary_path
|
43
46
|
end
|
44
47
|
|
@@ -50,7 +53,7 @@ module Mercurial
|
|
50
53
|
end
|
51
54
|
end
|
52
55
|
|
53
|
-
def append_command_with(append, cmd)
|
56
|
+
def self.append_command_with(append, cmd)
|
54
57
|
if cmd.kind_of?(Array)
|
55
58
|
cmd[0].insert(0, "#{ append } ")
|
56
59
|
cmd
|
@@ -61,4 +64,4 @@ module Mercurial
|
|
61
64
|
|
62
65
|
end
|
63
66
|
|
64
|
-
end
|
67
|
+
end
|
data/mercurial-ruby.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{mercurial-ruby}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.6.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ilya Sabanin"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-11-25}
|
13
13
|
s.description = %q{Ruby API for Mercurial DVCS.}
|
14
14
|
s.email = %q{ilya.sabanin@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/test/test_command.rb
CHANGED
@@ -20,7 +20,13 @@ describe Mercurial::Command do
|
|
20
20
|
it "should execute commands with timeout" do
|
21
21
|
Mercurial.configuration.stubs(:shell_timeout).returns(1)
|
22
22
|
lambda{
|
23
|
-
Mercurial::Command.new("sleep
|
23
|
+
Mercurial::Command.new("sleep 6").execute
|
24
|
+
}.must_raise Timeout::Error
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should support custom timeout settings" do
|
28
|
+
lambda{
|
29
|
+
Mercurial::Command.new("sleep 3", :timeout => 1).execute
|
24
30
|
}.must_raise Timeout::Error
|
25
31
|
end
|
26
32
|
|
@@ -58,5 +64,23 @@ describe Mercurial::Command do
|
|
58
64
|
cache_store.expects(:fetch).never
|
59
65
|
command.execute
|
60
66
|
end
|
67
|
+
|
68
|
+
it "should not cache command when caching was specifically disabled" do
|
69
|
+
command = Mercurial::Command.new("hg version", :cache => false, :repository => @repository)
|
70
|
+
cache_store = mock('cache_store')
|
71
|
+
Mercurial.configuration.stubs(:cache_store).returns(cache_store)
|
72
|
+
cache_store.expects(:fetch).never
|
73
|
+
command.execute
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should not use caching it it was overridden by repository" do
|
77
|
+
command = Mercurial::Command.new("cd #{ @repository.path } && hg log -v", :repository => @repository)
|
78
|
+
cache_store = mock('cache_store')
|
79
|
+
cache_store.expects(:fetch).never
|
80
|
+
Mercurial.configuration.stubs(:cache_store).returns(cache_store)
|
81
|
+
@repository.no_cache do
|
82
|
+
command.execute
|
83
|
+
end
|
84
|
+
end
|
61
85
|
|
62
|
-
end
|
86
|
+
end
|
data/test/test_commit.rb
CHANGED
@@ -6,6 +6,10 @@ describe Mercurial::Commit do
|
|
6
6
|
@repository = Mercurial::Repository.open(Fixtures.test_repo)
|
7
7
|
@commit = @repository.commits.by_hash_id('34f85a44acf1')
|
8
8
|
end
|
9
|
+
|
10
|
+
it "should have short version of it's id" do
|
11
|
+
@commit.short_hash_id.must_equal '34f85a44acf1'
|
12
|
+
end
|
9
13
|
|
10
14
|
it "should parse date to Ruby format" do
|
11
15
|
@commit.date.must_be_kind_of Time
|
@@ -63,4 +67,4 @@ describe Mercurial::Commit do
|
|
63
67
|
commit.exist_in_branches.map(&:name).sort.must_equal %w(default another-branch).sort
|
64
68
|
end
|
65
69
|
|
66
|
-
end
|
70
|
+
end
|
data/test/test_commit_factory.rb
CHANGED
@@ -6,6 +6,28 @@ describe Mercurial::CommitFactory do
|
|
6
6
|
@repository = Mercurial::Repository.open(Fixtures.test_repo)
|
7
7
|
end
|
8
8
|
|
9
|
+
it "should find commits after specific revision" do
|
10
|
+
commits = @repository.commits.after('2d32410d9629')
|
11
|
+
commits.size.must_equal 4
|
12
|
+
commits.map(&:hash_id).must_equal %w(88b5cc7860153671b0d3aa3c16d01ecad987490e 57a6efe309bfa6c8054084de8c26490fca8a6104 f67625ea8586cd5c4d43c883a273db3ef7f38716 9f76ea916c5100bf61f533c33a6aa9f22532d526)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should find commits before specific revision" do
|
16
|
+
commits = @repository.commits.before('63f70b2314ed')
|
17
|
+
commits.size.must_equal 2
|
18
|
+
commits.map(&:hash_id).must_equal %w(bc729b15e2b556065dd4f32c161f54be5dd92776 bf6386c0a0ccd1282dbbe51888f52fe82b1806e3)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should find commits with limit" do
|
22
|
+
commits = @repository.commits.all(:limit => 1)
|
23
|
+
commits.size.must_equal 1
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should find parent commit" do
|
27
|
+
commit = @repository.commits.parent
|
28
|
+
commit.must_be_kind_of Mercurial::Commit
|
29
|
+
end
|
30
|
+
|
9
31
|
it "should find commit by hash" do
|
10
32
|
commit = @repository.commits.by_hash_id('bc729b15e2b5')
|
11
33
|
commit.author.must_equal 'Ilya Sabanin'
|
@@ -62,13 +84,18 @@ describe Mercurial::CommitFactory do
|
|
62
84
|
count = @repository.commits.count
|
63
85
|
count.must_equal 40
|
64
86
|
end
|
65
|
-
|
87
|
+
|
88
|
+
it "should count range of commits" do
|
89
|
+
count = @repository.commits.count_range('63f70b2314ed', '3cdad3d3ca00')
|
90
|
+
count.must_equal 4
|
91
|
+
end
|
92
|
+
|
66
93
|
it "should iterate through commits" do
|
67
94
|
@repository.commits.each do |c|
|
68
95
|
c.must_be_kind_of Mercurial::Commit
|
69
96
|
end
|
70
97
|
end
|
71
|
-
|
98
|
+
|
72
99
|
it "should find commits for range" do
|
73
100
|
commits = @repository.commits.for_range('bc729b15e2b5', 'a07263ded072')
|
74
101
|
commits.map(&:hash_id).sort.must_equal ['bc729b15e2b556065dd4f32c161f54be5dd92776', '63f70b2314ede1e12813cae87f6f303ee8d5c09a', '6157254a442343181939c7af1a744cf2a16afcce', 'a07263ded0729d146062e6ec076cf1e6af214218'].sort
|
@@ -98,4 +125,4 @@ getting a reasonable exception.
|
|
98
125
|
[1] http://docs.python.org/dev/whatsnew/3.2.html]
|
99
126
|
end
|
100
127
|
|
101
|
-
end
|
128
|
+
end
|
data/test/test_config_file.rb
CHANGED
@@ -48,6 +48,25 @@ describe Mercurial::ConfigFile do
|
|
48
48
|
repository.config.add_setting("something", "super", "True")
|
49
49
|
repository.config.contents.must_equal "[something]\nsuper = True\n"
|
50
50
|
end
|
51
|
+
|
52
|
+
it "should detect if setting was already added" do
|
53
|
+
@config.add_setting('hooks', 'incoming', 'hg update')
|
54
|
+
@config.add_setting('somethingelse', 'shikaka', 'True')
|
55
|
+
@config.add_setting('somethingelse', 'monster', 'False')
|
56
|
+
@config.delete_setting!('somethingelse', 'shikaka')
|
57
|
+
|
58
|
+
assert @config.setting_exists?('hooks', 'incoming')
|
59
|
+
assert @config.setting_exists?('somethingelse', 'monster')
|
60
|
+
assert !@config.setting_exists?('somethingelse', 'shikaka')
|
61
|
+
assert !@config.setting_exists?('merge-tools', 'kdiff')
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should raise an error when trying to add a duplicating setting" do
|
65
|
+
@config.add_setting('hooks', 'incoming', 'hg update')
|
66
|
+
assert_raises Mercurial::ConfigFile::DuplicateSetting do
|
67
|
+
@config.add_setting('hooks', 'incoming', 'hg update')
|
68
|
+
end
|
69
|
+
end
|
51
70
|
|
52
71
|
private
|
53
72
|
|
@@ -102,4 +121,4 @@ shikaka = True
|
|
102
121
|
]
|
103
122
|
end
|
104
123
|
|
105
|
-
end
|
124
|
+
end
|
data/test/test_file_index.rb
CHANGED
@@ -94,6 +94,16 @@ describe Mercurial::FileIndex do
|
|
94
94
|
@file_index.instance_variable_get('@commit_index').keys.sort.must_equal(['bf6386c0a0ccd1282dbbe51888f52fe82b1806e3', 'bc729b15e2b556065dd4f32c161f54be5dd92776', '63f70b2314ede1e12813cae87f6f303ee8d5c09a', '6157254a442343181939c7af1a744cf2a16afcce', 'a07263ded0729d146062e6ec076cf1e6af214218', '3cdad3d3ca0054ebfcd2652cc83442bd0d272bbb', '25bb5c51fd613b8b58d88ef1caf99da559af51f3', '63e18640e83af60196334f16cc31f4f99c419918', '8fc3d59965d71a9b83308c53a76f3af0235b6eb6', '0f41dd2ec1667518741da599db7264943c9ed472', '16fac694db0a52edfd266576acafb475f7f8420f', '34f85a44acf11c3386f771a65445d6c39e5261d6', '4474d1ddaf653cb7fbf18bb62ff1e39a4e571969', 'cd9fa0c59c7f189fa1d70edea564e534ac9478d0', '611407bf9b369e061eaf0bee1a261c9e62ad713d', 'd14b0c16b21d9d3e08101ef264959a7d91a8b5db', '3e1ea66bdd04dbfb8d91e4f2de3baca218cd4cca', 'bbfe40f4a56961bdfc6b497a19cc35e18f2d40a3', '4e9f11e95eade74c55fc785e3159015f8a472f4b', '11998206a49ca9a55b4065508ce6ca10945e3e73', '1b99d0243f8e5542c1b33a013b63130f9009ac52', '612af4851a6c483f499cadf1dd28040d7996aa78', '54d96f4b1a260dc5614e89c1ed8c2d2edaa4942f', '207476112e024921b1538a096e5f6812d0698cab', 'ea1e37a728e989176e9e7b33f0d0e035fd347623', 'a8b39838302fc5aad12bb6b043331b9ef50149ed'].sort)
|
95
95
|
end
|
96
96
|
|
97
|
+
it "should raise error if file_index not found" do
|
98
|
+
@file_index.stubs(:path).returns('/tmp/blablabla')
|
99
|
+
lambda{ @file_index.send(:read_index) }.must_raise Mercurial::FileIndex::IndexFileNotFound
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should raise error if file_index is too big" do
|
103
|
+
Mercurial::FileIndex.stubs(:max_file_size).returns(1)
|
104
|
+
lambda{ @file_index.send(:read_index) }.must_raise Mercurial::FileIndex::IndexFileTooBig
|
105
|
+
end
|
106
|
+
|
97
107
|
private
|
98
108
|
|
99
109
|
# contains two oldest commits only
|
data/test/test_hook.rb
CHANGED
data/test/test_repository.rb
CHANGED
@@ -6,9 +6,13 @@ describe Mercurial::Repository do
|
|
6
6
|
lambda{ Mercurial::Repository.open('/shikaka/bambucha') }.must_raise Mercurial::RepositoryNotFound
|
7
7
|
end
|
8
8
|
|
9
|
-
describe "
|
9
|
+
describe "when created" do
|
10
10
|
before do
|
11
11
|
@repository = Mercurial::Repository.create('/tmp/test-hg-repo')
|
12
|
+
File.open(File.join(@repository.dothg_path, 'hgrc'), 'w') do |f|
|
13
|
+
f << "[paths]
|
14
|
+
default = #{@repository.file_system_url}"
|
15
|
+
end
|
12
16
|
end
|
13
17
|
|
14
18
|
after do
|
@@ -42,6 +46,35 @@ describe Mercurial::Repository do
|
|
42
46
|
it "should respond to diffs" do
|
43
47
|
@repository.must_respond_to :diffs
|
44
48
|
end
|
49
|
+
|
50
|
+
it "should have file system url" do
|
51
|
+
@repository.file_system_url.must_equal "file:///tmp/test-hg-repo"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should clone" do
|
55
|
+
result = @repository.clone('/tmp/test-hg-repo-clone')
|
56
|
+
assert_kind_of Mercurial::Repository, result
|
57
|
+
assert_equal '/tmp/test-hg-repo-clone', result.path
|
58
|
+
assert FileTest.directory?('/tmp/test-hg-repo-clone/.hg')
|
59
|
+
FileUtils.rm_rf('/tmp/test-hg-repo-clone')
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should pull" do
|
63
|
+
assert @repository.pull
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should return paths" do
|
67
|
+
assert_equal({'default' => 'file:///tmp/test-hg-repo'}, @repository.paths)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should treat working repository as verified" do
|
71
|
+
assert @repository.verify
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should treat broken repository as not verified" do
|
75
|
+
FileUtils.rm_rf("#{@repository.dothg_path}/store")
|
76
|
+
assert !@repository.verify
|
77
|
+
end
|
45
78
|
end
|
46
79
|
|
47
80
|
describe "destroying" do
|
@@ -55,4 +88,4 @@ describe Mercurial::Repository do
|
|
55
88
|
end
|
56
89
|
end
|
57
90
|
|
58
|
-
end
|
91
|
+
end
|
data/test/test_shell.rb
CHANGED
@@ -9,13 +9,13 @@ describe Mercurial::Shell do
|
|
9
9
|
|
10
10
|
it "should compile commands" do
|
11
11
|
command_mock = mock('command', :execute => true)
|
12
|
-
Mercurial::Command.expects(:new).with("cd #{ @repository.path } && /usr/local/bin/hg log", :repository => @repository, :
|
12
|
+
Mercurial::Command.expects(:new).with("cd #{ @repository.path } && /usr/local/bin/hg log", :repository => @repository, :append_hg => true).returns(command_mock).once
|
13
13
|
@shell.hg('log')
|
14
14
|
end
|
15
15
|
|
16
16
|
it "should sanitize command arguments" do
|
17
17
|
command_mock = mock('command', :execute => true)
|
18
|
-
Mercurial::Command.expects(:new).with(%Q[ls 'file with nasty '\\''quote'],
|
18
|
+
Mercurial::Command.expects(:new).with(%Q[ls 'file with nasty '\\''quote'], {}).returns(command_mock).once
|
19
19
|
@shell.run(["ls ?", "file with nasty 'quote"])
|
20
20
|
end
|
21
21
|
|
@@ -26,8 +26,8 @@ describe Mercurial::Shell do
|
|
26
26
|
|
27
27
|
it "should execute commands without cache" do
|
28
28
|
command_mock = mock('command', :execute => true)
|
29
|
-
Mercurial::Command.expects(:new).with('ls -l /', :
|
29
|
+
Mercurial::Command.expects(:new).with('ls -l /', :cache => false).returns(command_mock).once
|
30
30
|
Mercurial::Shell.run('ls -l /', :cache => false)
|
31
31
|
end
|
32
32
|
|
33
|
-
end
|
33
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mercurial-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 6
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.6.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ilya Sabanin
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-11-25 00:00:00 +08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|