mercurial-ruby 0.7.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -0
- data/Gemfile.lock +2 -0
- data/README.rdoc +14 -1
- data/VERSION +1 -1
- data/lib/mercurial-ruby.rb +1 -1
- data/lib/mercurial-ruby/blame.rb +11 -1
- data/lib/mercurial-ruby/blame_line.rb +11 -1
- data/lib/mercurial-ruby/command.rb +11 -5
- data/lib/mercurial-ruby/factories/blame_factory.rb +13 -1
- data/lib/mercurial-ruby/factories/branch_factory.rb +14 -14
- data/lib/mercurial-ruby/factories/commit_factory.rb +15 -15
- data/lib/mercurial-ruby/factories/diff_factory.rb +1 -1
- data/lib/mercurial-ruby/factories/hook_factory.rb +28 -0
- data/lib/mercurial-ruby/factories/node_factory.rb +3 -3
- data/lib/mercurial-ruby/factories/tag_factory.rb +4 -4
- data/lib/mercurial-ruby/file_index.rb +1 -1
- data/lib/mercurial-ruby/manifest.rb +2 -2
- data/lib/mercurial-ruby/node.rb +2 -6
- data/lib/mercurial-ruby/repository.rb +89 -1
- data/lib/mercurial-ruby/shell.rb +51 -1
- data/mercurial-ruby.gemspec +5 -2
- data/test/test_command.rb +10 -0
- metadata +32 -16
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -11,6 +11,7 @@ GEM
|
|
11
11
|
rbx-require-relative (> 0.0.4)
|
12
12
|
minitest (2.3.1)
|
13
13
|
mocha (0.9.12)
|
14
|
+
open4 (1.3.0)
|
14
15
|
rake (0.9.2)
|
15
16
|
rbx-require-relative (0.0.5)
|
16
17
|
rcov (0.9.9)
|
@@ -28,5 +29,6 @@ DEPENDENCIES
|
|
28
29
|
jeweler (~> 1.6.4)
|
29
30
|
minitest
|
30
31
|
mocha (~> 0.9)
|
32
|
+
open4 (~> 1.3.0)
|
31
33
|
rcov
|
32
34
|
ruby-debug (~> 0.10)
|
data/README.rdoc
CHANGED
@@ -52,14 +52,21 @@ See Features section below for a full list of entities and their methods.
|
|
52
52
|
|
53
53
|
=== Mercurial Entities
|
54
54
|
|
55
|
+
* {Mercurial::Repository Repository}
|
56
|
+
* {Mercurial::ConfigFile .hgrc} — hooks and various settings
|
55
57
|
* {Mercurial::Commit Commits}
|
56
58
|
* {Mercurial::Node Nodes} — files and directories
|
57
59
|
* {Mercurial::Branch Branches}
|
58
60
|
* {Mercurial::Tag Tags}
|
59
61
|
* {Mercurial::Diff Diffs}
|
62
|
+
* {Mercurial::Blame Blame}
|
60
63
|
* {Mercurial::Manifest Manifest}
|
61
64
|
* {Mercurial::FileIndex File Index}
|
62
|
-
|
65
|
+
|
66
|
+
=== Custom Commands
|
67
|
+
|
68
|
+
You can use {Mercurial::Shell Shell} class to execute custom shell commands that
|
69
|
+
weren't added to the gem as first-class citizens yet.
|
63
70
|
|
64
71
|
=== Built-in Caching
|
65
72
|
|
@@ -77,6 +84,12 @@ Here's how you configure it:
|
|
77
84
|
The gem is using a single method of the CacheStore called +fetch+.
|
78
85
|
Cache expires automatically when repository's mtime changes, and it's your job to update it.
|
79
86
|
|
87
|
+
=== Built-in Timeouts
|
88
|
+
|
89
|
+
You can provide a timeout for pretty much any command you are running. Do it like this:
|
90
|
+
|
91
|
+
repository.commits.all(:timeout => 5)
|
92
|
+
|
80
93
|
== Contributing to mercurial-ruby
|
81
94
|
|
82
95
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.1
|
data/lib/mercurial-ruby.rb
CHANGED
data/lib/mercurial-ruby/blame.rb
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
module Mercurial
|
2
2
|
|
3
|
+
#
|
4
|
+
# The class represents Mercurial blame output. Obtained by running an +hg blame+ command.
|
5
|
+
#
|
6
|
+
# This is for the Blame object itself, {Mercurial::BlameFactory BlameFactory} is responsible
|
7
|
+
# for assembling instances of the Blame. For the list of all possible blame-related operations please
|
8
|
+
# look documentation for {Mercurial::BlameFactory BlameFactory}.
|
9
|
+
#
|
3
10
|
class Blame
|
4
11
|
|
5
12
|
attr_reader :repository
|
@@ -9,7 +16,10 @@ module Mercurial
|
|
9
16
|
@repository = repository
|
10
17
|
@contents = data
|
11
18
|
end
|
12
|
-
|
19
|
+
|
20
|
+
#
|
21
|
+
# Returns an array of {Mercurial::BlameLine BlameLine} instances.
|
22
|
+
#
|
13
23
|
def lines
|
14
24
|
[].tap do |result|
|
15
25
|
contents.each do |line|
|
@@ -1,10 +1,20 @@
|
|
1
1
|
module Mercurial
|
2
|
-
|
2
|
+
|
3
|
+
#
|
4
|
+
# The class represents a single line of the Mercurial blame output.
|
5
|
+
#
|
3
6
|
class BlameLine
|
4
7
|
|
8
|
+
# Commit author.
|
5
9
|
attr_reader :author
|
10
|
+
|
11
|
+
# Line number.
|
6
12
|
attr_reader :num
|
13
|
+
|
14
|
+
# ID of the commit associated with the line.
|
7
15
|
attr_reader :revision
|
16
|
+
|
17
|
+
# Contents of the line.
|
8
18
|
attr_reader :contents
|
9
19
|
|
10
20
|
def initialize(attrs={})
|
@@ -1,9 +1,14 @@
|
|
1
1
|
require 'timeout'
|
2
2
|
require 'digest/md5'
|
3
|
+
require 'open4'
|
3
4
|
|
4
5
|
module Mercurial
|
5
6
|
class CommandError < Error; end
|
6
7
|
|
8
|
+
#
|
9
|
+
# This class represents a command that will be executed in a shell. You probably don't want to deal with this yourself,
|
10
|
+
# use the {Mercurial::Shell Shell} class instead.
|
11
|
+
#
|
7
12
|
class Command
|
8
13
|
attr_accessor :command, :repository, :use_cache, :timeout
|
9
14
|
|
@@ -47,8 +52,8 @@ module Mercurial
|
|
47
52
|
def execution_proc
|
48
53
|
Proc.new do
|
49
54
|
debug(command)
|
50
|
-
result, error = '', ''
|
51
|
-
|
55
|
+
result, error, = '', ''
|
56
|
+
status = Open4.popen4(command) do |pid, stdin, stdout, stderr|
|
52
57
|
Timeout.timeout(timeout) do
|
53
58
|
while tmp = stdout.read(102400)
|
54
59
|
result += tmp
|
@@ -59,12 +64,13 @@ module Mercurial
|
|
59
64
|
error += tmp
|
60
65
|
end
|
61
66
|
end
|
62
|
-
raise_error_if_needed(error)
|
67
|
+
raise_error_if_needed(status, error)
|
63
68
|
result
|
64
69
|
end
|
65
70
|
end
|
66
71
|
|
67
|
-
def raise_error_if_needed(error)
|
72
|
+
def raise_error_if_needed(status, error)
|
73
|
+
return if status.exitstatus == 0
|
68
74
|
if error && error != ''
|
69
75
|
raise CommandError, error
|
70
76
|
end
|
@@ -77,7 +83,7 @@ module Mercurial
|
|
77
83
|
def debug(msg)
|
78
84
|
if Mercurial.configuration.debug_mode
|
79
85
|
puts msg
|
80
|
-
end
|
86
|
+
end
|
81
87
|
end
|
82
88
|
|
83
89
|
end
|
@@ -1,14 +1,26 @@
|
|
1
1
|
module Mercurial
|
2
2
|
|
3
|
+
#
|
4
|
+
# This class represents a factory for {Mercurial::Blame Blame} instances.
|
5
|
+
#
|
3
6
|
class BlameFactory
|
4
7
|
include Mercurial::Helper
|
5
8
|
|
9
|
+
# Instance of a {Mercurial::Repository Repository}.
|
6
10
|
attr_reader :repository
|
7
11
|
|
8
12
|
def initialize(repository)
|
9
13
|
@repository = repository
|
10
14
|
end
|
11
|
-
|
15
|
+
|
16
|
+
# Finds a blame for a specified file path at a specified revision.
|
17
|
+
# Returns an instance of {Mercurial::Blame Blame}.
|
18
|
+
#
|
19
|
+
# Omit +revision+ if you want the latest blame.
|
20
|
+
#
|
21
|
+
# === Example:
|
22
|
+
# repository.blames.for_path('some-fancy-directory/all-blame-is-on-me.rb')
|
23
|
+
#
|
12
24
|
def for_path(path, revision=nil, cmd_options={})
|
13
25
|
revision ||= 'tip'
|
14
26
|
build do
|
@@ -15,7 +15,7 @@ module Mercurial
|
|
15
15
|
|
16
16
|
# Return an array of {Mercurial::Branch Branch} instances for all branches in the repository.
|
17
17
|
#
|
18
|
-
#
|
18
|
+
# === Example:
|
19
19
|
# repository.branches.all
|
20
20
|
#
|
21
21
|
def all(cmd_options={})
|
@@ -26,44 +26,44 @@ module Mercurial
|
|
26
26
|
|
27
27
|
# Run a block for every {Mercurial::Branch Branch} instance of all branches in the repository.
|
28
28
|
#
|
29
|
-
#
|
29
|
+
# === Example:
|
30
30
|
# repository.branches.each {|commit| ... }
|
31
31
|
#
|
32
|
-
def each(&block)
|
33
|
-
all.each do |branch|
|
32
|
+
def each(cmd_options={}, &block)
|
33
|
+
all(cmd_options).each do |branch|
|
34
34
|
block.call(branch)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
38
|
# Return an array of {Mercurial::Branch Branch} instances for all active branches in the repository.
|
39
39
|
#
|
40
|
-
#
|
40
|
+
# === Example:
|
41
41
|
# repository.branches.active
|
42
42
|
#
|
43
|
-
def active
|
44
|
-
all.find_all do |b|
|
43
|
+
def active(cmd_options={})
|
44
|
+
all(cmd_options).find_all do |b|
|
45
45
|
b.active?
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
49
|
# Return an array of {Mercurial::Branch Branch} instances for all closed branches in the repository.
|
50
50
|
#
|
51
|
-
#
|
51
|
+
# === Example:
|
52
52
|
# repository.branches.closed
|
53
53
|
#
|
54
|
-
def closed
|
55
|
-
all.find_all do |b|
|
54
|
+
def closed(cmd_options={})
|
55
|
+
all(cmd_options).find_all do |b|
|
56
56
|
b.closed?
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
60
|
# Return a {Mercurial::Branch Branch} instance for a branch with a specified name.
|
61
61
|
#
|
62
|
-
#
|
62
|
+
# === Example:
|
63
63
|
# repository.branches.by_name('branchname')
|
64
64
|
#
|
65
|
-
def by_name(name)
|
66
|
-
all.find do |b|
|
65
|
+
def by_name(name, cmd_options={})
|
66
|
+
all(cmd_options).find do |b|
|
67
67
|
b.name == name
|
68
68
|
end
|
69
69
|
end
|
@@ -71,7 +71,7 @@ module Mercurial
|
|
71
71
|
# Return an array of {Mercurial::Branch Branch} instances where a specified commit exists.
|
72
72
|
# Experimental, doesn't always return a correct list of branches.
|
73
73
|
#
|
74
|
-
#
|
74
|
+
# === Example:
|
75
75
|
# repository.branches.for_commit('291a498f04e9')
|
76
76
|
#
|
77
77
|
def for_commit(hash_id, cmd_options={})
|
@@ -15,7 +15,7 @@ module Mercurial
|
|
15
15
|
|
16
16
|
# Return a parent commit for this working copy.
|
17
17
|
#
|
18
|
-
#
|
18
|
+
# === Example:
|
19
19
|
# repository.commits.parent
|
20
20
|
#
|
21
21
|
def parent(cmd_options={})
|
@@ -27,7 +27,7 @@ module Mercurial
|
|
27
27
|
# Return an array of {Mercurial::Commit Commit} instances for all changesets in the repository.
|
28
28
|
# Accept a :limit setting.
|
29
29
|
#
|
30
|
-
#
|
30
|
+
# === Example:
|
31
31
|
# repository.commits.all
|
32
32
|
# repository.commits.all(:limit => 15)
|
33
33
|
#
|
@@ -41,18 +41,18 @@ module Mercurial
|
|
41
41
|
|
42
42
|
# Run a block for every {Mercurial::Commit Commit} instance of all changesets in the repository.
|
43
43
|
#
|
44
|
-
#
|
44
|
+
# === Example:
|
45
45
|
# repository.commits.each {|commit| ... }
|
46
46
|
#
|
47
|
-
def each(&block)
|
48
|
-
all.each do |commit|
|
47
|
+
def each(cmd_options={}, &block)
|
48
|
+
all(cmd_options).each do |commit|
|
49
49
|
block.call(commit)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
53
|
# Count all changesets in the repository.
|
54
54
|
#
|
55
|
-
#
|
55
|
+
# === Example:
|
56
56
|
# repository.commits.count
|
57
57
|
#
|
58
58
|
def count(cmd_options={})
|
@@ -63,7 +63,7 @@ module Mercurial
|
|
63
63
|
|
64
64
|
# Count changesets in the range from hash_a to hash_b in the repository.
|
65
65
|
#
|
66
|
-
#
|
66
|
+
# === Example:
|
67
67
|
# repository.commits.count_range(hash_a, hash_b)
|
68
68
|
#
|
69
69
|
def count_range(hash_a, hash_b, cmd_options={})
|
@@ -74,7 +74,7 @@ module Mercurial
|
|
74
74
|
|
75
75
|
# Return an array of {Mercurial::Commit Commit} instances for changesets in a specific branch.
|
76
76
|
#
|
77
|
-
#
|
77
|
+
# === Example:
|
78
78
|
# repository.commits.by_branch('brancname')
|
79
79
|
#
|
80
80
|
def by_branch(branch, cmd_options={})
|
@@ -85,7 +85,7 @@ module Mercurial
|
|
85
85
|
|
86
86
|
# Return an instance of {Mercurial::Commit Commit} for a changeset with a specified id.
|
87
87
|
#
|
88
|
-
#
|
88
|
+
# === Example:
|
89
89
|
# repository.commits.by_hash_id('291a498f04e9')
|
90
90
|
#
|
91
91
|
def by_hash_id(hash, cmd_options={})
|
@@ -96,7 +96,7 @@ module Mercurial
|
|
96
96
|
|
97
97
|
# Return an array of {Mercurial::Commit Commit} instances for changesets with specified ids.
|
98
98
|
#
|
99
|
-
#
|
99
|
+
# === Example:
|
100
100
|
# repository.commits.by_hash_ids('291a498f04e9', '63f70b2314ed')
|
101
101
|
#
|
102
102
|
def by_hash_ids(*args)
|
@@ -117,7 +117,7 @@ module Mercurial
|
|
117
117
|
|
118
118
|
# Return an array of {Mercurial::Commit Commit} instances for a specified range of changeset ids.
|
119
119
|
#
|
120
|
-
#
|
120
|
+
# === Example:
|
121
121
|
# repository.commits.for_range('bf6386c0a0cc', '63f70b2314ed')
|
122
122
|
#
|
123
123
|
def for_range(hash_a, hash_b, options={}, cmd_options={})
|
@@ -129,7 +129,7 @@ module Mercurial
|
|
129
129
|
|
130
130
|
# Return an array of {Mercurial::Commit Commit} instances that appear in hg log before the specified revision id.
|
131
131
|
#
|
132
|
-
#
|
132
|
+
# === Example:
|
133
133
|
# repository.commits.before('bf6386c0a0cc')
|
134
134
|
#
|
135
135
|
def before(hash_id, options={}, cmd_options={})
|
@@ -138,7 +138,7 @@ module Mercurial
|
|
138
138
|
|
139
139
|
# Return an array of {Mercurial::Commit Commit} instances that appear in hg log after the specified revision id.
|
140
140
|
#
|
141
|
-
#
|
141
|
+
# === Example:
|
142
142
|
# repository.commits.after('bf6386c0a0cc')
|
143
143
|
#
|
144
144
|
def after(hash_id, options={}, cmd_options={})
|
@@ -147,7 +147,7 @@ module Mercurial
|
|
147
147
|
|
148
148
|
# Return an instance of {Mercurial::Commit Commit} for a repository's tip changeset (latest).
|
149
149
|
#
|
150
|
-
#
|
150
|
+
# === Example:
|
151
151
|
# repository.commits.tip
|
152
152
|
#
|
153
153
|
def tip(cmd_options={})
|
@@ -159,7 +159,7 @@ module Mercurial
|
|
159
159
|
|
160
160
|
# Return an array of {Mercurial::Commit Commit} instances that appear in hg log as ancestors of the specified commit ID.
|
161
161
|
#
|
162
|
-
#
|
162
|
+
# === Example:
|
163
163
|
# repository.commits.ancestors_of('bf6386c0a0cc')
|
164
164
|
#
|
165
165
|
def ancestors_of(hash_id, options={}, cmd_options={})
|
@@ -16,7 +16,7 @@ module Mercurial
|
|
16
16
|
# Returns an array of {Mercurial::Diff Diff} instances for a specified
|
17
17
|
# instance of {Mercurial::Commit Commit}. Represents changeset's diffs.
|
18
18
|
#
|
19
|
-
#
|
19
|
+
# === Example:
|
20
20
|
# commit = repository.commits.by_hash_id('291a498f04e9')
|
21
21
|
# repository.diffs.for_commit(commit)
|
22
22
|
#
|
@@ -1,13 +1,23 @@
|
|
1
1
|
module Mercurial
|
2
2
|
|
3
|
+
#
|
4
|
+
# This class is a handy way to manage hooks in your repository.
|
5
|
+
#
|
3
6
|
class HookFactory
|
4
7
|
|
8
|
+
# Instance of {Mercurial::Repository Repository}.
|
5
9
|
attr_reader :repository
|
6
10
|
|
7
11
|
def initialize(repository)
|
8
12
|
@repository = repository
|
9
13
|
end
|
10
14
|
|
15
|
+
#
|
16
|
+
# Finds all repository hooks. Returns an array of {Mercurial::Hook Hook} instances.
|
17
|
+
#
|
18
|
+
# === Example:
|
19
|
+
# repository.hooks.all
|
20
|
+
#
|
11
21
|
def all
|
12
22
|
[].tap do |returning|
|
13
23
|
repository.config.find_header('hooks').each_pair do |name, value|
|
@@ -16,18 +26,36 @@ module Mercurial
|
|
16
26
|
end
|
17
27
|
end
|
18
28
|
|
29
|
+
#
|
30
|
+
# Finds a specific hook by it's name. Returns an instance of {Mercurial::Hook Hook}.
|
31
|
+
#
|
32
|
+
# === Example:
|
33
|
+
# repository.hooks.by_name('changegroup')
|
34
|
+
#
|
19
35
|
def by_name(name)
|
20
36
|
all.find do |h|
|
21
37
|
h.name == name.to_s
|
22
38
|
end
|
23
39
|
end
|
24
40
|
|
41
|
+
#
|
42
|
+
# Adds a new hook to the repository.
|
43
|
+
#
|
44
|
+
# === Example:
|
45
|
+
# repository.hooks.add('changegroup', 'do_something')
|
46
|
+
#
|
25
47
|
def add(name, value)
|
26
48
|
build(name, value).tap do |hook|
|
27
49
|
hook.save
|
28
50
|
end
|
29
51
|
end
|
30
52
|
|
53
|
+
#
|
54
|
+
# Removes a hook from the repository.
|
55
|
+
#
|
56
|
+
# === Example:
|
57
|
+
# repository.hooks.remove('changegroup')
|
58
|
+
#
|
31
59
|
def remove(name)
|
32
60
|
if hook = by_name(name)
|
33
61
|
hook.destroy!
|
@@ -6,7 +6,7 @@ module Mercurial
|
|
6
6
|
#
|
7
7
|
class NodeFactory
|
8
8
|
|
9
|
-
# Instance of {Mercurial::Repository Repository}.
|
9
|
+
# Instance of a {Mercurial::Repository Repository}.
|
10
10
|
attr_reader :repository
|
11
11
|
|
12
12
|
def initialize(repository)
|
@@ -19,7 +19,7 @@ module Mercurial
|
|
19
19
|
# Will find node in the latest version of repo if revision is ommitted.
|
20
20
|
# Will return nil if node wasn't found.
|
21
21
|
#
|
22
|
-
#
|
22
|
+
# === Example:
|
23
23
|
# repository.nodes.find('/')
|
24
24
|
# repository.nodes.find('some-fancy-directory/Weird File Name.pdf', '291a498f04e9')
|
25
25
|
# repository.nodes.find('some-fancy-directory/subdirectory/', '291a498f04e9')
|
@@ -58,7 +58,7 @@ module Mercurial
|
|
58
58
|
#
|
59
59
|
# Will find node in the latest version of repo if revision is ommitted.
|
60
60
|
#
|
61
|
-
#
|
61
|
+
# === Example:
|
62
62
|
# repository.nodes.entries_for('/')
|
63
63
|
# repository.nodes.entries_for('some-fancy-directory/subdirectory/', '291a498f04e9')
|
64
64
|
#
|
@@ -15,7 +15,7 @@ module Mercurial
|
|
15
15
|
|
16
16
|
# Return an array of {Mercurial::Tag Tag} instances for all tags in the repository.
|
17
17
|
#
|
18
|
-
#
|
18
|
+
# === Example:
|
19
19
|
# repository.tags.all
|
20
20
|
#
|
21
21
|
def all(cmd_options={})
|
@@ -26,11 +26,11 @@ module Mercurial
|
|
26
26
|
|
27
27
|
# Return a {Mercurial::Tag Tag} instance for a tag with a specified name.
|
28
28
|
#
|
29
|
-
#
|
29
|
+
# === Example:
|
30
30
|
# repository.tags.by_name('tagname')
|
31
31
|
#
|
32
|
-
def by_name(name)
|
33
|
-
all.find do |b|
|
32
|
+
def by_name(name, cmd_options={})
|
33
|
+
all(cmd_options).find do |b|
|
34
34
|
b.name == name
|
35
35
|
end
|
36
36
|
end
|
@@ -2,7 +2,7 @@ module Mercurial
|
|
2
2
|
|
3
3
|
# This class was ported from grit.
|
4
4
|
#
|
5
|
-
#
|
5
|
+
# It implements a file-based 'file index', a simple index of
|
6
6
|
# all of the reachable commits in a repo, along with the parents
|
7
7
|
# and which files were modified during each commit.
|
8
8
|
#
|
@@ -21,7 +21,7 @@ module Mercurial
|
|
21
21
|
# Returns contents of the manifest as a String at a specified revision.
|
22
22
|
# Latest version of the manifest is used if +revision+ is ommitted.
|
23
23
|
#
|
24
|
-
#
|
24
|
+
# === Example:
|
25
25
|
# repository.manifest.contents
|
26
26
|
#
|
27
27
|
def contents(revision=nil, cmd_options={})
|
@@ -32,7 +32,7 @@ module Mercurial
|
|
32
32
|
# Returns an array of file paths from manifest that start with the specified +path+ at a specified +revision+.
|
33
33
|
# Latest version of the manifest is used if +revision+ is ommitted.
|
34
34
|
#
|
35
|
-
#
|
35
|
+
# === Example:
|
36
36
|
# repository.manifest.scan_for_path('/')
|
37
37
|
# repository.manifest.scan_for_path('some-interesting-directory/', '2d32410d9629')
|
38
38
|
#
|
data/lib/mercurial-ruby/node.rb
CHANGED
@@ -1,13 +1,9 @@
|
|
1
1
|
module Mercurial
|
2
2
|
|
3
3
|
#
|
4
|
-
#
|
4
|
+
# This class represents a file or a directory stored inside a repository. The data is provided by {Mercurial::Manifest Manifest}.
|
5
5
|
#
|
6
|
-
#
|
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.
|
6
|
+
# To see how Node instances are assembled, check the {Mercurial::NodeFactory NodeFactory}.
|
11
7
|
#
|
12
8
|
class Node
|
13
9
|
include Mercurial::Helper
|
@@ -1,12 +1,28 @@
|
|
1
1
|
module Mercurial
|
2
2
|
class RepositoryNotFound < Error; end
|
3
3
|
|
4
|
+
#
|
5
|
+
# This class represents a Mercurial repository. Most of the time you will use this as a proxy for
|
6
|
+
# all your hg operations.
|
7
|
+
#
|
4
8
|
class Repository
|
5
9
|
|
10
|
+
#
|
11
|
+
# Creates a new repository on disk. Returns a {Mercurial::Repository Repository} instance.
|
12
|
+
#
|
13
|
+
# === Example:
|
14
|
+
# Mercurial::Repository.create("/Users/ilya/Desktop/cool_repository")
|
15
|
+
#
|
6
16
|
def self.create(destination)
|
7
17
|
init_repository(destination)
|
8
18
|
end
|
9
19
|
|
20
|
+
#
|
21
|
+
# Opens an existing repository on disk. Returns a {Mercurial::Repository Repository} instance.
|
22
|
+
#
|
23
|
+
# === Example:
|
24
|
+
# Mercurial::Repository.open("/Users/ilya/Desktop/existing-repo")
|
25
|
+
#
|
10
26
|
def self.open(destination)
|
11
27
|
if File.exists?(destination)
|
12
28
|
new(destination)
|
@@ -15,6 +31,12 @@ module Mercurial
|
|
15
31
|
end
|
16
32
|
end
|
17
33
|
|
34
|
+
#
|
35
|
+
# Creates a clone of an existing repository via URL.
|
36
|
+
#
|
37
|
+
# === Example:
|
38
|
+
# Mercurial::Repository.clone("file:///Users/ilya/Desktop/existing-repo", "/path/to/the/clone")
|
39
|
+
#
|
18
40
|
def self.clone(url, destination, cmd_options)
|
19
41
|
create_destination(destination)
|
20
42
|
opts = cmd_options.merge(:append_hg => true)
|
@@ -26,50 +48,86 @@ module Mercurial
|
|
26
48
|
@path = source
|
27
49
|
end
|
28
50
|
|
51
|
+
#
|
52
|
+
# Returns an instance of {Mercurial::Shell Shell} attached to the repository.
|
53
|
+
#
|
29
54
|
def shell
|
30
55
|
@_shell ||= Mercurial::Shell.new(self)
|
31
56
|
end
|
32
57
|
|
58
|
+
#
|
59
|
+
# Returns an instance of {Mercurial::ConfigFile ConfigFile} attached to the repository.
|
60
|
+
#
|
33
61
|
def config
|
34
62
|
@_config ||= Mercurial::ConfigFile.new(self)
|
35
63
|
end
|
36
64
|
|
65
|
+
#
|
66
|
+
# Returns an instance of {Mercurial::HookFactory HookFactory} attached to the repository.
|
67
|
+
#
|
37
68
|
def hooks
|
38
69
|
@_hook_factory ||= Mercurial::HookFactory.new(self)
|
39
70
|
end
|
40
71
|
|
72
|
+
#
|
73
|
+
# Returns an instance of {Mercurial::CommitFactory CommitFactory} attached to the repository.
|
74
|
+
#
|
41
75
|
def commits
|
42
76
|
@_commits ||= Mercurial::CommitFactory.new(self)
|
43
77
|
end
|
44
78
|
|
79
|
+
#
|
80
|
+
# Returns an instance of {Mercurial::BranchFactory BranchFactory} attached to the repository.
|
81
|
+
#
|
45
82
|
def branches
|
46
83
|
@_branches ||= Mercurial::BranchFactory.new(self)
|
47
84
|
end
|
48
85
|
|
86
|
+
#
|
87
|
+
# Returns an instance of {Mercurial::TagFactory TagFactory} attached to the repository.
|
88
|
+
#
|
49
89
|
def tags
|
50
90
|
@_tags ||= Mercurial::TagFactory.new(self)
|
51
91
|
end
|
52
92
|
|
93
|
+
#
|
94
|
+
# Returns an instance of {Mercurial::DiffFactory DiffFactory} attached to the repository.
|
95
|
+
#
|
53
96
|
def diffs
|
54
97
|
@_diffs ||= Mercurial::DiffFactory.new(self)
|
55
98
|
end
|
56
99
|
|
100
|
+
#
|
101
|
+
# Returns an instance of {Mercurial::NodeFactory NodeFactory} attached to the repository.
|
102
|
+
#
|
57
103
|
def nodes
|
58
104
|
@_nodes ||= Mercurial::NodeFactory.new(self)
|
59
105
|
end
|
60
106
|
|
107
|
+
#
|
108
|
+
# Returns an instance of {Mercurial::BlameFactory BlameFactory} attached to the repository.
|
109
|
+
#
|
61
110
|
def blames
|
62
111
|
@_blames ||= Mercurial::BlameFactory.new(self)
|
63
112
|
end
|
64
113
|
|
114
|
+
#
|
115
|
+
# Returns an instance of {Mercurial::Manifest Manifest} attached to the repository.
|
116
|
+
#
|
65
117
|
def manifest
|
66
118
|
@_manifest ||= Mercurial::Manifest.new(self)
|
67
119
|
end
|
68
120
|
|
121
|
+
#
|
122
|
+
# Returns an instance of {Mercurial::FileIndex FileIndex} attached to the repository.
|
123
|
+
#
|
69
124
|
def file_index
|
70
125
|
@_file_index ||= Mercurial::FileIndex.new(self)
|
71
126
|
end
|
72
127
|
|
128
|
+
#
|
129
|
+
# Shortcut for +nodes.find+.
|
130
|
+
#
|
73
131
|
def node(name, hash_id)
|
74
132
|
nodes.find(name, hash_id)
|
75
133
|
end
|
@@ -78,17 +136,29 @@ module Mercurial
|
|
78
136
|
self.class.clone(file_system_url, destination_path, cmd_options)
|
79
137
|
end
|
80
138
|
|
139
|
+
#
|
140
|
+
# Pull from an origin.
|
141
|
+
#
|
142
|
+
# === Example:
|
143
|
+
# repository.pull
|
144
|
+
#
|
81
145
|
def pull(origin='default', cmd_options={})
|
82
146
|
shell.hg(['pull ?', origin], cmd_options)
|
83
147
|
end
|
84
148
|
|
149
|
+
#
|
150
|
+
# Run +hg verify+ on the repository. Returns +true+ if verified, +false+ otherwise.
|
151
|
+
#
|
85
152
|
def verify
|
86
153
|
shell.hg('verify')
|
87
154
|
true
|
88
155
|
rescue Mercurial::CommandError
|
89
156
|
false
|
90
157
|
end
|
91
|
-
|
158
|
+
|
159
|
+
#
|
160
|
+
# Returns an array of repository's paths (as remotes).
|
161
|
+
#
|
92
162
|
def paths
|
93
163
|
{}.tap do |result|
|
94
164
|
shell.hg('paths').each do |line|
|
@@ -98,6 +168,9 @@ module Mercurial
|
|
98
168
|
end
|
99
169
|
end
|
100
170
|
|
171
|
+
#
|
172
|
+
# Deletes the repository from disk.
|
173
|
+
#
|
101
174
|
def destroy!
|
102
175
|
FileUtils.rm_rf(path)
|
103
176
|
end
|
@@ -118,6 +191,21 @@ module Mercurial
|
|
118
191
|
File.mtime(dothg_path).to_i
|
119
192
|
end
|
120
193
|
|
194
|
+
#
|
195
|
+
# Accepts a block, executes all commands inside the block with caching disabled.
|
196
|
+
#
|
197
|
+
# === Example:
|
198
|
+
#
|
199
|
+
# repository.no_cache do
|
200
|
+
# repository.commits.all
|
201
|
+
# repository.branches.all
|
202
|
+
# end
|
203
|
+
#
|
204
|
+
# Same as:
|
205
|
+
#
|
206
|
+
# repository.commits.all :cache => false
|
207
|
+
# repository.branches.all :cache => false
|
208
|
+
#
|
121
209
|
def no_cache
|
122
210
|
@cache_disabled_by_override = true
|
123
211
|
yield
|
data/lib/mercurial-ruby/shell.rb
CHANGED
@@ -1,9 +1,56 @@
|
|
1
1
|
module Mercurial
|
2
2
|
|
3
|
+
#
|
4
|
+
# This is a tiny helper class that makes it simple for you to execute shell commands.
|
5
|
+
# Use it to execute hg commands that don't have a proper wrappers yet.
|
6
|
+
#
|
3
7
|
class Shell
|
4
8
|
|
5
9
|
attr_reader :repository
|
6
10
|
|
11
|
+
#
|
12
|
+
# Creates a {Mercurial::Command Command} instance and executes it. Supports a few neat options:
|
13
|
+
#
|
14
|
+
# ==== :append_hg
|
15
|
+
#
|
16
|
+
# You don't have to worry about specifying a correct path to your hg binary every time you want to execute a command:
|
17
|
+
#
|
18
|
+
# Shell.run("help", :append_hg => true)
|
19
|
+
#
|
20
|
+
# ==== Arguments interpolation
|
21
|
+
#
|
22
|
+
# Interpolation make your commands secure by escaping dangerous characters and wrapping everything in quotes:
|
23
|
+
#
|
24
|
+
# Shell.run(["clone ? ?", url, destination], :append_hg => true)
|
25
|
+
#
|
26
|
+
# ==== :in
|
27
|
+
#
|
28
|
+
# Allows you to execute commands in a specific directory:
|
29
|
+
#
|
30
|
+
# Shell.run('log', :in => repository_path)
|
31
|
+
#
|
32
|
+
# ==== :pipe
|
33
|
+
#
|
34
|
+
# Gives you piping flexibility:
|
35
|
+
#
|
36
|
+
# Shell.run('log', :pipe => "grep '9:0f41dd2ec166' -wc", :in => repository_path)
|
37
|
+
#
|
38
|
+
# Same as running +hg log | grep '9:0f41dd2ec166' -wc+
|
39
|
+
#
|
40
|
+
# ==== :timeout
|
41
|
+
#
|
42
|
+
# Specify a timeout in seconds for your command:
|
43
|
+
#
|
44
|
+
# Shell.run("/usr/bin/long-running-task", :timeout => 5)
|
45
|
+
#
|
46
|
+
# +Timeout::Error+ will be raised on timeout.
|
47
|
+
#
|
48
|
+
# ==== :cache
|
49
|
+
#
|
50
|
+
# Caching is enabled by default for all commands. Use this setting to avoid it:
|
51
|
+
#
|
52
|
+
# Shell.run("init", :append_hg => true, :cache => false)
|
53
|
+
#
|
7
54
|
def self.run(cmd, options={})
|
8
55
|
build = []
|
9
56
|
|
@@ -33,13 +80,16 @@ module Mercurial
|
|
33
80
|
@repository = repository
|
34
81
|
end
|
35
82
|
|
83
|
+
#
|
84
|
+
# This method is a shortcut to +Shell.run(cmd, :append_hg => true, :in => repository.path)+.
|
85
|
+
#
|
36
86
|
def hg(cmd, options={})
|
37
87
|
options[:in] ||= repository.path
|
38
88
|
options[:repository] = repository
|
39
89
|
options[:append_hg] = true
|
40
90
|
run(cmd, options)
|
41
91
|
end
|
42
|
-
|
92
|
+
|
43
93
|
def run(cmd, options={})
|
44
94
|
self.class.run(cmd, options)
|
45
95
|
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.7.
|
8
|
+
s.version = "0.7.1"
|
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{2012-03-
|
12
|
+
s.date = %q{2012-03-05}
|
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 = [
|
@@ -92,6 +92,7 @@ Gem::Specification.new do |s|
|
|
92
92
|
s.specification_version = 3
|
93
93
|
|
94
94
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
95
|
+
s.add_runtime_dependency(%q<open4>, ["~> 1.3.0"])
|
95
96
|
s.add_development_dependency(%q<minitest>, [">= 0"])
|
96
97
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
97
98
|
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
@@ -99,6 +100,7 @@ Gem::Specification.new do |s|
|
|
99
100
|
s.add_development_dependency(%q<mocha>, ["~> 0.9"])
|
100
101
|
s.add_development_dependency(%q<ruby-debug>, ["~> 0.10"])
|
101
102
|
else
|
103
|
+
s.add_dependency(%q<open4>, ["~> 1.3.0"])
|
102
104
|
s.add_dependency(%q<minitest>, [">= 0"])
|
103
105
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
104
106
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
@@ -107,6 +109,7 @@ Gem::Specification.new do |s|
|
|
107
109
|
s.add_dependency(%q<ruby-debug>, ["~> 0.10"])
|
108
110
|
end
|
109
111
|
else
|
112
|
+
s.add_dependency(%q<open4>, ["~> 1.3.0"])
|
110
113
|
s.add_dependency(%q<minitest>, [">= 0"])
|
111
114
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
112
115
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
data/test/test_command.rb
CHANGED
@@ -16,6 +16,16 @@ describe Mercurial::Command do
|
|
16
16
|
Mercurial::Command.new("cd #{ @repository.path } && hg shikaka").execute
|
17
17
|
}.must_raise Mercurial::CommandError
|
18
18
|
end
|
19
|
+
|
20
|
+
it "should not translate exit status of zero with shell errors to ruby exceptions" do
|
21
|
+
Mercurial::Command.new("echo stderr >&2 && echo stdout && exit 0").execute.strip.must_equal "stdout"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should translate exit status of non-zero with shell errors to ruby exceptions" do
|
25
|
+
lambda{
|
26
|
+
Mercurial::Command.new("echo stderr >&2 && echo stdout && exit 1").execute
|
27
|
+
}.must_raise Mercurial::CommandError
|
28
|
+
end
|
19
29
|
|
20
30
|
it "should execute commands with timeout" do
|
21
31
|
Mercurial.configuration.stubs(:shell_timeout).returns(1)
|
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: 1
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 7
|
9
|
-
-
|
10
|
-
version: 0.7.
|
9
|
+
- 1
|
10
|
+
version: 0.7.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ilya Sabanin
|
@@ -15,14 +15,30 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-03-
|
18
|
+
date: 2012-03-05 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
name: open4
|
25
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 27
|
31
|
+
segments:
|
32
|
+
- 1
|
33
|
+
- 3
|
34
|
+
- 0
|
35
|
+
version: 1.3.0
|
36
|
+
requirement: *id001
|
21
37
|
- !ruby/object:Gem::Dependency
|
22
38
|
type: :development
|
23
39
|
prerelease: false
|
24
40
|
name: minitest
|
25
|
-
version_requirements: &
|
41
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
26
42
|
none: false
|
27
43
|
requirements:
|
28
44
|
- - ">="
|
@@ -31,12 +47,12 @@ dependencies:
|
|
31
47
|
segments:
|
32
48
|
- 0
|
33
49
|
version: "0"
|
34
|
-
requirement: *
|
50
|
+
requirement: *id002
|
35
51
|
- !ruby/object:Gem::Dependency
|
36
52
|
type: :development
|
37
53
|
prerelease: false
|
38
54
|
name: bundler
|
39
|
-
version_requirements: &
|
55
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
40
56
|
none: false
|
41
57
|
requirements:
|
42
58
|
- - ~>
|
@@ -47,12 +63,12 @@ dependencies:
|
|
47
63
|
- 0
|
48
64
|
- 0
|
49
65
|
version: 1.0.0
|
50
|
-
requirement: *
|
66
|
+
requirement: *id003
|
51
67
|
- !ruby/object:Gem::Dependency
|
52
68
|
type: :development
|
53
69
|
prerelease: false
|
54
70
|
name: jeweler
|
55
|
-
version_requirements: &
|
71
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
56
72
|
none: false
|
57
73
|
requirements:
|
58
74
|
- - ~>
|
@@ -63,12 +79,12 @@ dependencies:
|
|
63
79
|
- 6
|
64
80
|
- 4
|
65
81
|
version: 1.6.4
|
66
|
-
requirement: *
|
82
|
+
requirement: *id004
|
67
83
|
- !ruby/object:Gem::Dependency
|
68
84
|
type: :development
|
69
85
|
prerelease: false
|
70
86
|
name: rcov
|
71
|
-
version_requirements: &
|
87
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
72
88
|
none: false
|
73
89
|
requirements:
|
74
90
|
- - ">="
|
@@ -77,12 +93,12 @@ dependencies:
|
|
77
93
|
segments:
|
78
94
|
- 0
|
79
95
|
version: "0"
|
80
|
-
requirement: *
|
96
|
+
requirement: *id005
|
81
97
|
- !ruby/object:Gem::Dependency
|
82
98
|
type: :development
|
83
99
|
prerelease: false
|
84
100
|
name: mocha
|
85
|
-
version_requirements: &
|
101
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
86
102
|
none: false
|
87
103
|
requirements:
|
88
104
|
- - ~>
|
@@ -92,12 +108,12 @@ dependencies:
|
|
92
108
|
- 0
|
93
109
|
- 9
|
94
110
|
version: "0.9"
|
95
|
-
requirement: *
|
111
|
+
requirement: *id006
|
96
112
|
- !ruby/object:Gem::Dependency
|
97
113
|
type: :development
|
98
114
|
prerelease: false
|
99
115
|
name: ruby-debug
|
100
|
-
version_requirements: &
|
116
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
101
117
|
none: false
|
102
118
|
requirements:
|
103
119
|
- - ~>
|
@@ -107,7 +123,7 @@ dependencies:
|
|
107
123
|
- 0
|
108
124
|
- 10
|
109
125
|
version: "0.10"
|
110
|
-
requirement: *
|
126
|
+
requirement: *id007
|
111
127
|
description: Ruby API for Mercurial DVCS.
|
112
128
|
email: ilya.sabanin@gmail.com
|
113
129
|
executables: []
|