ed 0.6.0 → 0.7.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 +4 -1
- data/README.md +1 -7
- data/examples/pry.rb +11 -4
- data/lib/ed.rb +14 -12
- data/lib/ed/config.rb +11 -10
- data/lib/ed/core_ext/object.rb +7 -14
- data/lib/ed/delegator.rb +4 -4
- data/lib/ed/repository.rb +79 -34
- data/lib/ed/version.rb +1 -1
- data/test/test_ed.rb +29 -6
- metadata +10 -10
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -16,13 +16,7 @@ __DESCRIPTION__
|
|
16
16
|
one that you can use to check out commits and then run Ruby code in the
|
17
17
|
context of those commits.
|
18
18
|
|
19
|
-
|
20
|
-
run the tests of both tags, or benchmark code from one commit against another,
|
21
|
-
those kind of tasks.
|
22
|
-
|
23
|
-
__WHY?__
|
24
|
-
|
25
|
-
So I could:
|
19
|
+
__USE CASES__
|
26
20
|
|
27
21
|
* Run test suites against different tags, commits, and branches inside Ruby.
|
28
22
|
* Profile different tags, commits, and branches against one another inside Ruby.
|
data/examples/pry.rb
CHANGED
@@ -1,10 +1,17 @@
|
|
1
1
|
require "ed"
|
2
2
|
require "pry"
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
Ed.configure do |config|
|
5
|
+
# Create a subprocess for each tag we switch to.
|
6
|
+
# It keeps the address space clean, and allows us to
|
7
|
+
# 'require "barney"' twice.
|
8
|
+
config.should_fork = true
|
9
|
+
end
|
10
|
+
|
11
|
+
Ed.new "git://github.com/robgleeson/barney.git" do
|
12
|
+
setup do |path|
|
13
|
+
$LOAD_PATH << File.join(path, "lib/")
|
14
|
+
require 'barney'
|
8
15
|
end
|
9
16
|
|
10
17
|
tag "0.1.0" do
|
data/lib/ed.rb
CHANGED
@@ -12,14 +12,13 @@ class Ed
|
|
12
12
|
|
13
13
|
#
|
14
14
|
# @example
|
15
|
-
# Ed.
|
16
|
-
# config.fork = true
|
17
|
-
# end
|
15
|
+
# (see Ed::Config.change)
|
18
16
|
#
|
19
|
-
# @yieldparam
|
17
|
+
# @yieldparam
|
20
18
|
# (see Ed::Config.change)
|
21
19
|
#
|
22
|
-
# @return
|
20
|
+
# @return
|
21
|
+
# (see Ed::Config.change)
|
23
22
|
#
|
24
23
|
def self.configure &block
|
25
24
|
Ed::Config.change(&block)
|
@@ -29,8 +28,11 @@ class Ed
|
|
29
28
|
# @param [String] path
|
30
29
|
# The path to a git repository.
|
31
30
|
#
|
31
|
+
# @param [Proc] &block
|
32
|
+
# Executed in the scope of {Ed::Delegator}.
|
33
|
+
#
|
32
34
|
# @yieldparam [Ed] _self
|
33
|
-
# Yields self, if a block is given.
|
35
|
+
# Yields self, if a block parameter is given.
|
34
36
|
#
|
35
37
|
# @return [Ed]
|
36
38
|
#
|
@@ -49,15 +51,15 @@ class Ed
|
|
49
51
|
|
50
52
|
#
|
51
53
|
# @param [Proc] block
|
52
|
-
# Executed
|
54
|
+
# Executed each time {#commit}, {#tag} or {#branch} is called.
|
53
55
|
#
|
54
56
|
# @yieldparam [String] path
|
55
57
|
# The path to the repository on local disk.
|
56
58
|
#
|
57
59
|
# @return [void]
|
58
60
|
#
|
59
|
-
def
|
60
|
-
add_observer(:
|
61
|
+
def setup &block
|
62
|
+
add_observer(:setup_block, &block)
|
61
63
|
end
|
62
64
|
|
63
65
|
#
|
@@ -65,7 +67,7 @@ class Ed
|
|
65
67
|
# A valid git commit, or git commit reference(tag or branch name).
|
66
68
|
#
|
67
69
|
# @param [Proc] block
|
68
|
-
# Executed while the repository has switched to
|
70
|
+
# Executed while the repository has switched to _commit_.
|
69
71
|
#
|
70
72
|
# @yieldparam [String] path
|
71
73
|
# The path to the repository on local disk.
|
@@ -73,7 +75,7 @@ class Ed
|
|
73
75
|
# @return [void]
|
74
76
|
#
|
75
77
|
def commit commit, &block
|
76
|
-
if Ed::Config.
|
78
|
+
if Ed::Config.should_fork?
|
77
79
|
pid = fork do
|
78
80
|
switch(commit, &block)
|
79
81
|
end
|
@@ -97,7 +99,7 @@ class Ed
|
|
97
99
|
#
|
98
100
|
def switch commit, &block
|
99
101
|
@repo.checkout '-q', commit
|
100
|
-
notify_observers(:
|
102
|
+
notify_observers(:setup_block, @repo.path)
|
101
103
|
block.call(@repo.path)
|
102
104
|
end
|
103
105
|
private :switch
|
data/lib/ed/config.rb
CHANGED
@@ -11,7 +11,7 @@ module Ed::Config
|
|
11
11
|
# @example
|
12
12
|
#
|
13
13
|
# Ed::Config.change do |config|
|
14
|
-
# config.
|
14
|
+
# config.should_fork = true
|
15
15
|
# end
|
16
16
|
#
|
17
17
|
def change
|
@@ -20,7 +20,7 @@ module Ed::Config
|
|
20
20
|
|
21
21
|
#
|
22
22
|
# @param [String, #to_s] path
|
23
|
-
# The path to use
|
23
|
+
# The path to use for storing cloned repositories.
|
24
24
|
#
|
25
25
|
# @return [Pathname]
|
26
26
|
#
|
@@ -30,7 +30,8 @@ module Ed::Config
|
|
30
30
|
|
31
31
|
#
|
32
32
|
# @return [Pathname]
|
33
|
-
#
|
33
|
+
# The path being used to store cloned repositories.
|
34
|
+
#
|
34
35
|
#
|
35
36
|
def repo_dir
|
36
37
|
@repo_dir
|
@@ -38,31 +39,31 @@ module Ed::Config
|
|
38
39
|
|
39
40
|
#
|
40
41
|
# @param [Boolean] value
|
41
|
-
#
|
42
|
+
# If true is given, a subprocess is created to check out a commit.
|
42
43
|
#
|
43
44
|
# @return [Boolean]
|
44
45
|
#
|
45
|
-
def
|
46
|
+
def should_fork= value
|
46
47
|
if value && Ed::Env.fork_unavailable?
|
47
48
|
raise ArgumentError, 'Kernel#fork is not available on your platform.'
|
48
49
|
end
|
49
50
|
|
50
|
-
@
|
51
|
+
@should_fork = value
|
51
52
|
end
|
52
53
|
|
53
54
|
#
|
54
55
|
# @return [Boolean]
|
55
56
|
# Returns true if a subprocess is created to check out a commit.
|
56
57
|
#
|
57
|
-
def
|
58
|
-
@
|
58
|
+
def should_fork
|
59
|
+
@should_fork
|
59
60
|
end
|
60
|
-
alias_method :
|
61
|
+
alias_method :should_fork?, :should_fork
|
61
62
|
|
62
63
|
end
|
63
64
|
|
64
65
|
change do |config|
|
65
|
-
config.
|
66
|
+
config.should_fork = false
|
66
67
|
|
67
68
|
if Ed::Env.windows?
|
68
69
|
config.repo_dir = ::ENV["TEMP"]
|
data/lib/ed/core_ext/object.rb
CHANGED
@@ -1,22 +1,15 @@
|
|
1
1
|
#
|
2
|
-
# @param
|
3
|
-
#
|
2
|
+
# @param
|
3
|
+
# (see Ed#initialize)
|
4
4
|
#
|
5
|
-
# @
|
6
|
-
#
|
5
|
+
# @yieldparam
|
6
|
+
# (see Ed#initialize)
|
7
7
|
#
|
8
|
-
# @
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# @return [void]
|
8
|
+
# @return
|
9
|
+
# (see Ed#initialize)
|
12
10
|
#
|
13
11
|
def Repository path, &block
|
14
|
-
|
15
|
-
block.call Ed.new(path)
|
16
|
-
else
|
17
|
-
delegator = Ed::Delegator.new Ed.new(path)
|
18
|
-
delegator.instance_eval(&block)
|
19
|
-
end
|
12
|
+
Ed.new path, &block
|
20
13
|
end
|
21
14
|
|
22
15
|
|
data/lib/ed/delegator.rb
CHANGED
@@ -10,13 +10,13 @@ class Ed::Delegator
|
|
10
10
|
|
11
11
|
#
|
12
12
|
# @param block
|
13
|
-
# (see Ed#
|
13
|
+
# (see Ed#setup)
|
14
14
|
#
|
15
15
|
# @return
|
16
|
-
# (see Ed#
|
16
|
+
# (see Ed#setup)
|
17
17
|
#
|
18
|
-
def
|
19
|
-
@__delegate__.
|
18
|
+
def setup &block
|
19
|
+
@__delegate__.setup(&block)
|
20
20
|
end
|
21
21
|
|
22
22
|
#
|
data/lib/ed/repository.rb
CHANGED
@@ -2,38 +2,66 @@ require 'fileutils'
|
|
2
2
|
|
3
3
|
class Ed::Repository
|
4
4
|
|
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
|
24
|
+
|
25
|
+
output = `git ls-remote #{args.join(' ')}`
|
26
|
+
|
27
|
+
output.each_line do |line|
|
28
|
+
sha, ref = line.split(/\s+/, 2)
|
29
|
+
yield sha, ref.chomp
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
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
|
43
|
+
|
44
|
+
end
|
45
|
+
|
5
46
|
#
|
6
47
|
# @return [String]
|
7
48
|
# The path to the repository on local disk.
|
8
49
|
#
|
9
|
-
attr_reader
|
10
|
-
|
11
|
-
#
|
12
|
-
# @return [Boolean]
|
13
|
-
# Has the repository been copied?
|
14
|
-
#
|
15
|
-
attr_reader :copy
|
16
|
-
alias_method :copy?, :copy
|
50
|
+
attr_reader :path
|
17
51
|
|
18
52
|
#
|
19
53
|
# @param [String, #to_s] path
|
20
54
|
# The URI to a git repository.
|
21
55
|
#
|
22
|
-
# @
|
23
|
-
#
|
56
|
+
# @return [Ed::Repository]
|
57
|
+
# Returns a instance of {Ed::Repository}.
|
24
58
|
#
|
25
|
-
def initialize path
|
26
|
-
|
27
|
-
@path = copy!(path.to_s)
|
28
|
-
@copy = true
|
29
|
-
else
|
30
|
-
@path = path.to_s
|
31
|
-
@copy = false
|
32
|
-
end
|
59
|
+
def initialize path
|
60
|
+
@path = copy!(path.to_s)
|
33
61
|
|
34
62
|
parent = Process.pid
|
35
63
|
|
36
|
-
|
64
|
+
at_exit do
|
37
65
|
if parent == Process.pid
|
38
66
|
FileUtils.rm_rf(@path)
|
39
67
|
end
|
@@ -42,7 +70,7 @@ class Ed::Repository
|
|
42
70
|
|
43
71
|
#
|
44
72
|
# @param [String] *options
|
45
|
-
# The same commands given to 'git checkout'
|
73
|
+
# The same commands given to 'git checkout'
|
46
74
|
#
|
47
75
|
# @return [void]
|
48
76
|
#
|
@@ -51,32 +79,49 @@ class Ed::Repository
|
|
51
79
|
end
|
52
80
|
|
53
81
|
#
|
54
|
-
# @param [String] from
|
55
|
-
# The
|
82
|
+
# @param [String] from
|
83
|
+
# The URI to copy from.
|
56
84
|
#
|
57
85
|
# @return [String]
|
58
86
|
# The path to the copied repository.
|
59
87
|
#
|
60
|
-
def copy!
|
61
|
-
|
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)
|
62
93
|
|
63
|
-
|
64
|
-
|
65
|
-
|
94
|
+
sha, _ =
|
95
|
+
remotes.find do |_, ref|
|
96
|
+
ref == 'HEAD'
|
97
|
+
end
|
66
98
|
end
|
67
|
-
|
68
|
-
|
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
|
69
116
|
end
|
70
117
|
private :copy!
|
71
118
|
|
72
|
-
#
|
73
|
-
# Provides low-level access to the git binary in the context of {#path}.
|
119
|
+
#
|
120
|
+
# Provides low-level access to the git binary in the context of {#path}.
|
74
121
|
# @return [void]
|
75
122
|
#
|
76
123
|
def git *args
|
77
|
-
|
78
|
-
system "git", *args
|
79
|
-
end
|
124
|
+
system "git", "--git-dir=#{@path}/.git", "--work-tree=#{@path}", *args
|
80
125
|
end
|
81
126
|
private :git
|
82
127
|
|
data/lib/ed/version.rb
CHANGED
data/test/test_ed.rb
CHANGED
@@ -1,14 +1,37 @@
|
|
1
1
|
context Ed do
|
2
2
|
|
3
3
|
context 'initialize' do
|
4
|
-
it 'must
|
4
|
+
it 'must call a block (if given).' do
|
5
5
|
mock = MiniTest::Mock.new
|
6
|
-
mock.expect(:
|
6
|
+
mock.expect(:message, nil)
|
7
7
|
|
8
8
|
Ed.new 'git://github.com/robgleeson/IProcess.git' do
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
mock.message
|
10
|
+
end
|
11
|
+
|
12
|
+
mock.verify
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'must call a block with parameters (if given).' do
|
16
|
+
mock = MiniTest::Mock.new
|
17
|
+
mock.expect(:message, nil)
|
18
|
+
|
19
|
+
Ed.new 'git://github.com/robgleeson/IProcess.git' do |ed|
|
20
|
+
mock.message
|
21
|
+
end
|
22
|
+
|
23
|
+
mock.verify
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'must yield a instance of Ed as block parameter (if given.)' do
|
27
|
+
Ed.new 'git://github.com/robgleeson/IProcess.git' do |ed|
|
28
|
+
ed.must_be_instance_of(Ed)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'must instance_eval when given a block with no block parameters.' do
|
33
|
+
Ed.new 'git://github.com/robgleeson/IProcess.git' do
|
34
|
+
self.must_be_instance_of(Ed::Delegator)
|
12
35
|
end
|
13
36
|
end
|
14
37
|
end
|
@@ -25,7 +48,7 @@ context Ed do
|
|
25
48
|
|
26
49
|
it 'must checkout the "0.1.0" tag.' do
|
27
50
|
Tempfile.open "assertion" do |tmpfile|
|
28
|
-
@ed.
|
51
|
+
@ed.setup do |path|
|
29
52
|
$: << File.join(path, "lib")
|
30
53
|
require 'thread'
|
31
54
|
require 'barney'
|
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.7.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-01-
|
12
|
+
date: 2012-01-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: observe
|
16
|
-
requirement: &
|
16
|
+
requirement: &70119687020140 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.2.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70119687020140
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &70119687019520 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 0.9.2
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70119687019520
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: minitest
|
38
|
-
requirement: &
|
38
|
+
requirement: &70119687019020 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '2.6'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70119687019020
|
47
47
|
description: A Domain Specific Language(DSL) that you can use to talk to Git from
|
48
48
|
Ruby.
|
49
49
|
email:
|
@@ -85,7 +85,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
85
85
|
version: '0'
|
86
86
|
segments:
|
87
87
|
- 0
|
88
|
-
hash:
|
88
|
+
hash: 1406613959917538667
|
89
89
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
90
|
none: false
|
91
91
|
requirements:
|
@@ -94,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
94
94
|
version: '0'
|
95
95
|
segments:
|
96
96
|
- 0
|
97
|
-
hash:
|
97
|
+
hash: 1406613959917538667
|
98
98
|
requirements: []
|
99
99
|
rubyforge_project: Ed
|
100
100
|
rubygems_version: 1.8.15
|