mercurial-ruby 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|