ed 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,6 @@
1
-
2
1
  rvm:
3
- - 1.8.7 # (current default)
4
2
  - 1.9.2
5
3
  - 1.9.3
6
- - jruby-18mode
7
- - jruby-19mode
8
- - rbx-18mode
9
- - rbx-19mode
10
- - ruby-head
11
- - ree
12
4
 
13
5
  notifications:
14
6
  irc: "irc.freenode.org#flowof.info"
@@ -0,0 +1 @@
1
+ -m markdown
data/README.md CHANGED
@@ -11,40 +11,28 @@ __OVERVIEW__
11
11
 
12
12
  __DESCRIPTION__
13
13
 
14
- A Domain Specific Language(DSL) that you can use to talk to Git from Ruby.
15
- It isn't intended to be a full interface to Git, but a very small subset of
16
- one that you can use to check out commits and then run Ruby code in the
17
- context of those commits.
18
-
19
- __USE CASES__
20
-
21
- * Run test suites against different tags, commits, and branches inside Ruby.
22
- * Profile different tags, commits, and branches against one another inside Ruby.
23
- * Explore code in different tags, commits, and branches using a REPL
24
- like [Pry](https://github.com/pry/pry).
25
-
14
+ Ed is a library that you can use to talk to Git from Ruby.
15
+ It is useful when you'd like to run Ruby code in the context of multiple
16
+ commits, tags, or branchs.
17
+
26
18
  __EXAMPLE__
27
19
 
28
- The example below shows how you can run a test suite against two different
20
+ The example below shows how you can run the test suite of two different
29
21
  tags from a remote repository.
30
22
  The [examples](https://github.com/robgleeson/ed/tree/master/examples) directory
31
23
  has a few other examples you might want to check out.
32
24
 
33
25
  __1.__
34
26
 
35
- Travel time and run the tests for tag '0.1.0' and tag '0.2.0'.
27
+ Run the tests for tag 'v0.1.0' and tag 'v0.2.0'.
36
28
 
37
29
  Ed.new "git://github.com/robgleeson/observe.git" do
38
30
  tag "v0.1.0" do |path|
39
- Dir.chdir(path) do
40
- system "rake test"
41
- end
31
+ system "cd '#{path}' && rake test"
42
32
  end
43
33
 
44
34
  tag "v0.2.0" do |path|
45
- Dir.chdir(path) do
46
- system "rake test"
47
- end
35
+ system "cd '#{path}' && rake test"
48
36
  end
49
37
  end
50
38
 
@@ -52,10 +40,8 @@ __PLATFORM SUPPORT__
52
40
 
53
41
  _supported_
54
42
 
55
- * Rubinius
56
- * CRuby (1.8 / 1.9)
57
- * JRuby
58
- * MacRuby
43
+ * CRuby 1.9
44
+
59
45
 
60
46
  __INSTALL__
61
47
 
data/ed.gemspec CHANGED
@@ -20,7 +20,10 @@ Gem::Specification.new do |s|
20
20
 
21
21
 
22
22
  #s.add_runtime_dependency "scm" , "~> 0.1.0.pre1"
23
-
23
+
24
+ s.required_ruby_version = "~> 1.9.1"
25
+
26
+ s.add_runtime_dependency "shell_command", "~> 0.1.0"
24
27
  s.add_runtime_dependency "observe" , "~> 0.2.0"
25
28
  s.add_development_dependency "rake" , "~> 0.9.2"
26
29
  s.add_development_dependency "minitest", "~> 2.6"
data/lib/ed.rb CHANGED
@@ -1,8 +1,11 @@
1
1
  require 'observe'
2
+ require 'shell_command'
3
+ require 'fileutils'
2
4
  require 'ed/version'
3
5
  require 'ed/env'
4
6
  require 'ed/config'
5
7
  require 'ed/repository'
8
+ require 'ed/repository_copy'
6
9
  require 'ed/delegator'
7
10
  require 'ed/core_ext/object'
8
11
 
@@ -37,7 +40,11 @@ class Ed
37
40
  # @return [Ed]
38
41
  #
39
42
  def initialize path, &block
40
- @repo = Ed::Repository.new(path)
43
+ if Ed::Repository.remote?(path) || Ed::Config.copy_repository?
44
+ @repo = Ed::RepositoryCopy.new(path)
45
+ else
46
+ @repo = Ed::Repository.new(path)
47
+ end
41
48
 
42
49
  if block_given?
43
50
  if block.arity == 1
@@ -37,6 +37,23 @@ module Ed::Config
37
37
  @repo_dir
38
38
  end
39
39
 
40
+ #
41
+ # @param [Boolean]
42
+ # If true, a copy of a repository is created to work off.
43
+ #
44
+ def copy_repository= value
45
+ @copy_repository = value
46
+ end
47
+
48
+ #
49
+ # @return [Boolean]
50
+ # When true, a copy of a repository is created to work off.
51
+ #
52
+ def copy_repository
53
+ @copy_repository
54
+ end
55
+ alias_method :copy_repository?, :copy_repository
56
+
40
57
  #
41
58
  # @param [Boolean] value
42
59
  # If true is given, a subprocess is created to check out a commit.
@@ -64,6 +81,7 @@ module Ed::Config
64
81
 
65
82
  change do |config|
66
83
  config.should_fork = false
84
+ config.copy_repository = true
67
85
 
68
86
  if Ed::Env.windows?
69
87
  config.repo_dir = ::ENV["TEMP"]
@@ -1,46 +1,68 @@
1
- require 'fileutils'
1
+ #
2
+ # The {Ed::Repository} class provides a interface to talk to a Git repository.
3
+ # It does _not_ make a copy of the repository but works off the path it is
4
+ # given.
5
+ #
6
+ # The {Ed::RepositoryCopy} class provides the same interface as this class but
7
+ # it creates a working copy of the repository to allow for parallel access.
8
+ #
9
+ # The default behavior is to use {Ed::RepositoryCopy} when talking to a
10
+ # repository but if you would like to disable copying you can use the
11
+ # {Ed::Config#copy_repository=} config option. You should be aware of its
12
+ # implications, though.
13
+ #
2
14
 
3
15
  class Ed::Repository
4
16
 
5
- class << self
6
-
7
- #
8
- # @param [String] *args
9
- # The same commands given to 'git ls-remote'.
10
- #
11
- # @yieldparam [String] sha
12
- # The commit SHA.
13
- #
14
- # @yieldparam [String] ref
15
- # The reference (e.g: HEAD, tag, or branch)
16
- #
17
- # @return [Enumerator]
18
- # Returns a Enumerator if no block is given.
19
- #
20
- def ls_remote *args
21
- unless block_given?
22
- return enum_for(:ls_remote, *args)
23
- end
17
+ #
18
+ # @param [String] path
19
+ # The URI to a git a repository.
20
+ #
21
+ # @return [Boolean]
22
+ # Returns true if the path is considered to be remote.
23
+ #
24
+ def self.remote? path
25
+ !local?(path)
26
+ end
24
27
 
25
- output = `git ls-remote #{args.join(' ')}`
28
+ #
29
+ # @param [String] path
30
+ # The URI to a git a repository.
31
+ #
32
+ # @return [Boolean]
33
+ # Returns true if the path is considered to be local.
34
+ #
35
+ def self.local? path
36
+ URI.parse(path).scheme == "file" || !to_s.include?(':')
37
+ end
26
38
 
27
- output.each_line do |line|
28
- sha, ref = line.split(/\s+/, 2)
29
- yield sha, ref.chomp
30
- end
39
+ #
40
+ # @param [String] *args
41
+ # The same commands given to 'git ls-remote'.
42
+ #
43
+ # @yieldparam [String] sha
44
+ # The commit SHA.
45
+ #
46
+ # @yieldparam [String] ref
47
+ # The reference (e.g: HEAD, tag, or branch)
48
+ #
49
+ # @raise
50
+ # (see Ed::Repository#git)
51
+ #
52
+ # @return [Enumerator]
53
+ # Returns a Enumerator if no block is given.
54
+ #
55
+ def self.ls_remote *args
56
+ unless block_given?
57
+ return enum_for(:ls_remote, *args)
31
58
  end
32
59
 
33
- #
34
- # @param [String] path
35
- # The URI to a git a repository.
36
- #
37
- # @return [Boolean]
38
- # Returns true if the repository is considered to exist on filesystem.
39
- #
40
- def is_local? path
41
- path[0..6] == "file://" || !path.include?(":")
42
- end
60
+ output = ShellCommand.run!("git ls-remote #{args.join(' ')}").stdout
43
61
 
62
+ output.each_line do |line|
63
+ sha, ref = line.split(/\s+/, 2)
64
+ yield sha, ref.chomp
65
+ end
44
66
  end
45
67
 
46
68
  #
@@ -57,15 +79,7 @@ class Ed::Repository
57
79
  # Returns a instance of {Ed::Repository}.
58
80
  #
59
81
  def initialize path
60
- @path = copy!(path.to_s)
61
-
62
- parent = Process.pid
63
-
64
- at_exit do
65
- if parent == Process.pid
66
- FileUtils.rm_rf(@path)
67
- end
68
- end
82
+ @path = path
69
83
  end
70
84
 
71
85
  #
@@ -79,49 +93,18 @@ class Ed::Repository
79
93
  end
80
94
 
81
95
  #
82
- # @param [String] from
83
- # The URI to copy from.
84
- #
85
- # @return [String]
86
- # The path to the copied repository.
96
+ # Provides low-level access to the git binary in the context of {#path}.
87
97
  #
88
- def copy! path
89
- if Ed::Repository.is_local?(path)
90
- sha = system("git", "--git-dir=#{path}/.git", "rev-parse", "HEAD")
91
- else
92
- remotes = Ed::Repository.ls_remote(path)
93
-
94
- sha, _ =
95
- remotes.find do |_, ref|
96
- ref == 'HEAD'
97
- end
98
- end
99
-
100
- #
101
- # Directory layout:
102
- # <REPO_DIR>/ed/<REPO_NAME>/<PROCESS ID>/<THREAD ID>/<COMMIT SHA>
103
- #
104
- repo_name = File.basename(path)
105
- process_id = Process.pid
106
- thread_id = Thread.current.object_id
107
- namespace = "ed/#{repo_name}/#{process_id}/#{thread_id}/#{sha}"
108
- destination = File.join(Ed::Config.repo_dir, namespace)
109
-
110
- unless File.exists? destination
111
- FileUtils.mkdir_p(destination)
112
- system 'git', 'clone', '-q', path, destination
113
- end
114
-
115
- destination
116
- end
117
- private :copy!
118
-
98
+ # @raise [ShellCommand::Exception]
99
+ # If git exits with a status code that is non-zero.
119
100
  #
120
- # Provides low-level access to the git binary in the context of {#path}.
121
- # @return [void]
101
+ # @return [ShellCommand::Command]
122
102
  #
123
103
  def git *args
124
- system "git", "--git-dir=#{@path}/.git", "--work-tree=#{@path}", *args
104
+ ShellCommand.run! "git",
105
+ "--git-dir=#{@path}/.git",
106
+ "--work-tree=#{@path}",
107
+ *args
125
108
  end
126
109
  private :git
127
110
 
@@ -0,0 +1,96 @@
1
+ #
2
+ # A {Ed::RepositoryCopy} is a subclass of {Ed::Repository} but with a distinct
3
+ # difference: it creates a copy of the repository it provides a interface to.
4
+ #
5
+ # By creating copies, it can allow parallel access to the same repository
6
+ # because every instance of {Ed::RepositoryCopy} has its own copy of the
7
+ # repository to work off.
8
+ #
9
+ # All remote repositories are _always_ instances of {Ed::RepositoryCopy}, and
10
+ # local repositories can be copied, too. It is recommended to create copies if
11
+ # you plan to access the same repository in parallel (either from Ed, or
12
+ # outside Ed).
13
+ #
14
+ # The default behavior is to create a copy all the time, but it can be
15
+ # configured from {Ed::Config.copy_repository=}. A {RepositoryCopy} is cached
16
+ # per-thread, and lives for the life of a process but for no longer, it is
17
+ # destroyed when the process exits.
18
+ #
19
+
20
+ class Ed::RepositoryCopy < Ed::Repository
21
+
22
+ #
23
+ # @param
24
+ # (see Ed::Repository#initialize)
25
+ #
26
+ # @return [Ed::RepositoryCopy]
27
+ # Returns a instance of {Ed::RepositoryCopy}.
28
+ #
29
+ def initialize path
30
+ @source = path
31
+ @path = copy!
32
+ @copy_dir = nil
33
+
34
+ parent = Process.pid
35
+
36
+ at_exit do
37
+ if parent == Process.pid
38
+ FileUtils.rm_rf(@path.to_s)
39
+ end
40
+ end
41
+ end
42
+
43
+ #
44
+ # @param [String] from
45
+ # The URI to copy from.
46
+ #
47
+ # @raise
48
+ # (see Ed::Repository#git)
49
+ #
50
+ # @return [String]
51
+ # The path to the copied repository.
52
+ #
53
+ def copy!
54
+ unless File.exists? copy_dir
55
+ FileUtils.mkdir_p copy_dir
56
+ ShellCommand.run! 'git', 'clone', '-q', @source, copy_dir
57
+ end
58
+
59
+ copy_dir
60
+ end
61
+ private :copy!
62
+
63
+ #
64
+ # @raise
65
+ # (see Ed::Repository#git)
66
+ #
67
+ # @return [String]
68
+ # Returns the directory path a repository can be copied into.
69
+ #
70
+ def copy_dir
71
+ if @copy_dir
72
+ return @copy_dir
73
+ end
74
+
75
+ commit = nil
76
+ repo = File.basename(@source)
77
+ pid = Process.pid
78
+ thread_id = Thread.current.object_id
79
+
80
+ if Ed::Repository.local?(@source)
81
+ commit = ShellCommand.run!("git --git-dir=#{@source}/.git HEAD").stdout
82
+ else
83
+ remotes = Ed::Repository.ls_remote(@source)
84
+
85
+ commit, _ =
86
+ remotes.find do |_, ref|
87
+ ref == 'HEAD'
88
+ end
89
+ end
90
+
91
+ @copy_dir =
92
+ File.join Ed::Config.repo_dir, "ed/#{repo}/#{pid}/#{thread_id}/#{commit}"
93
+ end
94
+ private :copy_dir
95
+
96
+ end
@@ -1,3 +1,3 @@
1
1
  class Ed
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.0"
3
3
  end
@@ -43,13 +43,13 @@ context Ed do
43
43
  end
44
44
 
45
45
  it 'must clone and store the repository locally.' do
46
- File.exists?(@repo.path).must_equal(true)
46
+ File.exists?(@repo.path.to_s).must_equal(true)
47
47
  end
48
48
 
49
49
  it 'must checkout the "0.1.0" tag.' do
50
50
  Tempfile.open "assertion" do |tmpfile|
51
51
  @ed.setup do |path|
52
- $: << File.join(path, "lib")
52
+ $: << File.join(path.to_s, "lib")
53
53
  require 'thread'
54
54
  require 'barney'
55
55
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-29 00:00:00.000000000 Z
12
+ date: 2012-02-05 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: shell_command
16
+ requirement: &70357890439740 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.1.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70357890439740
14
25
  - !ruby/object:Gem::Dependency
15
26
  name: observe
16
- requirement: &70119687020140 !ruby/object:Gem::Requirement
27
+ requirement: &70357890439280 !ruby/object:Gem::Requirement
17
28
  none: false
18
29
  requirements:
19
30
  - - ~>
@@ -21,10 +32,10 @@ dependencies:
21
32
  version: 0.2.0
22
33
  type: :runtime
23
34
  prerelease: false
24
- version_requirements: *70119687020140
35
+ version_requirements: *70357890439280
25
36
  - !ruby/object:Gem::Dependency
26
37
  name: rake
27
- requirement: &70119687019520 !ruby/object:Gem::Requirement
38
+ requirement: &70357890438800 !ruby/object:Gem::Requirement
28
39
  none: false
29
40
  requirements:
30
41
  - - ~>
@@ -32,10 +43,10 @@ dependencies:
32
43
  version: 0.9.2
33
44
  type: :development
34
45
  prerelease: false
35
- version_requirements: *70119687019520
46
+ version_requirements: *70357890438800
36
47
  - !ruby/object:Gem::Dependency
37
48
  name: minitest
38
- requirement: &70119687019020 !ruby/object:Gem::Requirement
49
+ requirement: &70357890438320 !ruby/object:Gem::Requirement
39
50
  none: false
40
51
  requirements:
41
52
  - - ~>
@@ -43,7 +54,7 @@ dependencies:
43
54
  version: '2.6'
44
55
  type: :development
45
56
  prerelease: false
46
- version_requirements: *70119687019020
57
+ version_requirements: *70357890438320
47
58
  description: A Domain Specific Language(DSL) that you can use to talk to Git from
48
59
  Ruby.
49
60
  email:
@@ -54,6 +65,7 @@ extra_rdoc_files: []
54
65
  files:
55
66
  - .gitignore
56
67
  - .travis.yml
68
+ - .yardopts
57
69
  - Gemfile
58
70
  - LICENSE.txt
59
71
  - README.md
@@ -68,6 +80,7 @@ files:
68
80
  - lib/ed/delegator.rb
69
81
  - lib/ed/env.rb
70
82
  - lib/ed/repository.rb
83
+ - lib/ed/repository_copy.rb
71
84
  - lib/ed/version.rb
72
85
  - test/setup.rb
73
86
  - test/test_ed.rb
@@ -80,12 +93,9 @@ require_paths:
80
93
  required_ruby_version: !ruby/object:Gem::Requirement
81
94
  none: false
82
95
  requirements:
83
- - - ! '>='
96
+ - - ~>
84
97
  - !ruby/object:Gem::Version
85
- version: '0'
86
- segments:
87
- - 0
88
- hash: 1406613959917538667
98
+ version: 1.9.1
89
99
  required_rubygems_version: !ruby/object:Gem::Requirement
90
100
  none: false
91
101
  requirements:
@@ -94,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
104
  version: '0'
95
105
  segments:
96
106
  - 0
97
- hash: 1406613959917538667
107
+ hash: -3106733997781854880
98
108
  requirements: []
99
109
  rubyforge_project: Ed
100
110
  rubygems_version: 1.8.15