mercurial-ruby 0.7.0 → 0.7.1
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/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: []
|