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 CHANGED
@@ -1,5 +1,7 @@
1
1
  source "http://rubygems.org"
2
2
 
3
+ gem "open4", "~>1.3.0"
4
+
3
5
  group :development do
4
6
  gem "minitest", ">= 0"
5
7
  gem "bundler", "~> 1.0.0"
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
- * {Mercurial::ConfigFile Repository config} — hooks and various settings
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.0
1
+ 0.7.1
@@ -4,7 +4,7 @@
4
4
  #
5
5
  module Mercurial
6
6
 
7
- VERSION = '0.7.0'
7
+ VERSION = '0.7.1'
8
8
 
9
9
  class Error < RuntimeError; end
10
10
 
@@ -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
- Open3.popen3(command) do |_, stdout, stderr|
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # == Example:
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
- # This implements a file-based 'file index', an simple index of
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
- # == Example:
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
- # == Example:
35
+ # === Example:
36
36
  # repository.manifest.scan_for_path('/')
37
37
  # repository.manifest.scan_for_path('some-interesting-directory/', '2d32410d9629')
38
38
  #
@@ -1,13 +1,9 @@
1
1
  module Mercurial
2
2
 
3
3
  #
4
- # The class represents Mercurial file or directory. Data obtained by scanning +hg manifest+ output.
4
+ # This class represents a file or a directory stored inside a repository. The data is provided by {Mercurial::Manifest Manifest}.
5
5
  #
6
- # The class represents Node object itself, {Mercurial::NodeFactory NodeFactory} is responsible
7
- # for assembling instances of Node. For the list of all possible branch-related operations please
8
- # look documentation for {Mercurial::NodeFactory NodeFactory}.
9
- #
10
- # Additionally {Mercurial::Manifest Manifest} is responsible for reading and scanning the manifest.
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
@@ -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
@@ -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.0"
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-02}
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: 3
4
+ hash: 1
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 7
9
- - 0
10
- version: 0.7.0
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-02 00:00:00 -05:00
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: &id001 !ruby/object:Gem::Requirement
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: *id001
50
+ requirement: *id002
35
51
  - !ruby/object:Gem::Dependency
36
52
  type: :development
37
53
  prerelease: false
38
54
  name: bundler
39
- version_requirements: &id002 !ruby/object:Gem::Requirement
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: *id002
66
+ requirement: *id003
51
67
  - !ruby/object:Gem::Dependency
52
68
  type: :development
53
69
  prerelease: false
54
70
  name: jeweler
55
- version_requirements: &id003 !ruby/object:Gem::Requirement
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: *id003
82
+ requirement: *id004
67
83
  - !ruby/object:Gem::Dependency
68
84
  type: :development
69
85
  prerelease: false
70
86
  name: rcov
71
- version_requirements: &id004 !ruby/object:Gem::Requirement
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: *id004
96
+ requirement: *id005
81
97
  - !ruby/object:Gem::Dependency
82
98
  type: :development
83
99
  prerelease: false
84
100
  name: mocha
85
- version_requirements: &id005 !ruby/object:Gem::Requirement
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: *id005
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: &id006 !ruby/object:Gem::Requirement
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: *id006
126
+ requirement: *id007
111
127
  description: Ruby API for Mercurial DVCS.
112
128
  email: ilya.sabanin@gmail.com
113
129
  executables: []