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.
- data/.travis.yml +0 -8
- data/.yardopts +1 -0
- data/README.md +10 -24
- data/ed.gemspec +4 -1
- data/lib/ed.rb +8 -1
- data/lib/ed/config.rb +18 -0
- data/lib/ed/repository.rb +66 -83
- data/lib/ed/repository_copy.rb +96 -0
- data/lib/ed/version.rb +1 -1
- data/test/test_ed.rb +2 -2
- metadata +24 -14
data/.travis.yml
CHANGED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
-m markdown
|
data/README.md
CHANGED
@@ -11,40 +11,28 @@ __OVERVIEW__
|
|
11
11
|
|
12
12
|
__DESCRIPTION__
|
13
13
|
|
14
|
-
|
15
|
-
It
|
16
|
-
|
17
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
*
|
56
|
-
|
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
|
-
|
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
|
data/lib/ed/config.rb
CHANGED
@@ -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"]
|
data/lib/ed/repository.rb
CHANGED
@@ -1,46 +1,68 @@
|
|
1
|
-
|
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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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 =
|
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
|
-
#
|
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
|
-
|
89
|
-
|
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
|
-
#
|
121
|
-
# @return [void]
|
101
|
+
# @return [ShellCommand::Command]
|
122
102
|
#
|
123
103
|
def git *args
|
124
|
-
|
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
|
data/lib/ed/version.rb
CHANGED
data/test/test_ed.rb
CHANGED
@@ -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.
|
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-
|
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: &
|
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: *
|
35
|
+
version_requirements: *70357890439280
|
25
36
|
- !ruby/object:Gem::Dependency
|
26
37
|
name: rake
|
27
|
-
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: *
|
46
|
+
version_requirements: *70357890438800
|
36
47
|
- !ruby/object:Gem::Dependency
|
37
48
|
name: minitest
|
38
|
-
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: *
|
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:
|
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:
|
107
|
+
hash: -3106733997781854880
|
98
108
|
requirements: []
|
99
109
|
rubyforge_project: Ed
|
100
110
|
rubygems_version: 1.8.15
|