ed 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,7 +3,10 @@ rvm:
3
3
  - 1.8.7 # (current default)
4
4
  - 1.9.2
5
5
  - 1.9.3
6
- - rbx-2.0
6
+ - jruby-18mode
7
+ - jruby-19mode
8
+ - rbx-18mode
9
+ - rbx-19mode
7
10
  - ruby-head
8
11
  - ree
9
12
 
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
- So, for example, you might want to check out tag 'v0.1.0' and tag 'v0.2.0' to
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.
@@ -1,10 +1,17 @@
1
1
  require "ed"
2
2
  require "pry"
3
3
 
4
- Repository "git://github.com/robgleeson/barney.git" do
5
- before :each do |path|
6
- $: << File.join(path, "lib/")
7
- require "barney"
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.configure do |config|
16
- # config.fork = true
17
- # end
15
+ # (see Ed::Config.change)
18
16
  #
19
- # @yieldparam config
17
+ # @yieldparam
20
18
  # (see Ed::Config.change)
21
19
  #
22
- # @return [void]
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 before the block for {#commit}, {#tag} or #{branch} is run.
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 before stage, &block
60
- add_observer(:before_filter, &block)
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 'commit'.
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.fork?
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(:before_filter, @repo.path)
102
+ notify_observers(:setup_block, @repo.path)
101
103
  block.call(@repo.path)
102
104
  end
103
105
  private :switch
@@ -11,7 +11,7 @@ module Ed::Config
11
11
  # @example
12
12
  #
13
13
  # Ed::Config.change do |config|
14
- # config.fork = false
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 when storing cloned repositories.
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
- # The path being used to store cloned repositories.
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
- # Enable or disable the creation of a subprocess to check out a commit.
42
+ # If true is given, a subprocess is created to check out a commit.
42
43
  #
43
44
  # @return [Boolean]
44
45
  #
45
- def fork= value
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
- @fork = value
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 fork
58
- @fork
58
+ def should_fork
59
+ @should_fork
59
60
  end
60
- alias_method :fork?, :fork
61
+ alias_method :should_fork?, :should_fork
61
62
 
62
63
  end
63
64
 
64
65
  change do |config|
65
- config.fork = false
66
+ config.should_fork = false
66
67
 
67
68
  if Ed::Env.windows?
68
69
  config.repo_dir = ::ENV["TEMP"]
@@ -1,22 +1,15 @@
1
1
  #
2
- # @param [String] path
3
- # The URI to a git repository.
2
+ # @param
3
+ # (see Ed#initialize)
4
4
  #
5
- # @param [Proc] &block
6
- # Executed in the calling scope, or within the scope of {Ed::Delegator}.
5
+ # @yieldparam
6
+ # (see Ed#initialize)
7
7
  #
8
- # @yieldparam [Ed] repo
9
- # Optionally yields an instance of {Ed}.
10
- #
11
- # @return [void]
8
+ # @return
9
+ # (see Ed#initialize)
12
10
  #
13
11
  def Repository path, &block
14
- if block.arity == 1
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
 
@@ -10,13 +10,13 @@ class Ed::Delegator
10
10
 
11
11
  #
12
12
  # @param block
13
- # (see Ed#before)
13
+ # (see Ed#setup)
14
14
  #
15
15
  # @return
16
- # (see Ed#before)
16
+ # (see Ed#setup)
17
17
  #
18
- def before stage, &block
19
- @__delegate__.before(stage, &block)
18
+ def setup &block
19
+ @__delegate__.setup(&block)
20
20
  end
21
21
 
22
22
  #
@@ -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 :path
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
- # @param [Boolean] copy
23
- # If true, a copy of the repository is created.
56
+ # @return [Ed::Repository]
57
+ # Returns a instance of {Ed::Repository}.
24
58
  #
25
- def initialize path, copy = true
26
- if copy
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
- ObjectSpace.define_finalizer(self) do
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 path to copy from.
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! from
61
- to = File.join(Ed::Config.repo_dir, "ed/#{Process.pid}/#{object_id}")
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
- unless File.exists? to
64
- FileUtils.mkdir_p(to)
65
- system 'git', 'clone', '-q', from, to
94
+ sha, _ =
95
+ remotes.find do |_, ref|
96
+ ref == 'HEAD'
97
+ end
66
98
  end
67
-
68
- to
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
- Dir.chdir(@path) do
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
 
@@ -1,3 +1,3 @@
1
1
  class Ed
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.0"
3
3
  end
@@ -1,14 +1,37 @@
1
1
  context Ed do
2
2
 
3
3
  context 'initialize' do
4
- it 'must instance_eval when given a block with no block parameters.' do
4
+ it 'must call a block (if given).' do
5
5
  mock = MiniTest::Mock.new
6
- mock.expect(:ok, nil)
6
+ mock.expect(:message, nil)
7
7
 
8
8
  Ed.new 'git://github.com/robgleeson/IProcess.git' do
9
- before :each do
10
- mock.ok
11
- end
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.before :each do |path|
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.6.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-23 00:00:00.000000000 Z
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: &70220677377500 !ruby/object:Gem::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: *70220677377500
24
+ version_requirements: *70119687020140
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &70220677376880 !ruby/object:Gem::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: *70220677376880
35
+ version_requirements: *70119687019520
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: minitest
38
- requirement: &70220677376400 !ruby/object:Gem::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: *70220677376400
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: -3748924748542527421
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: -3748924748542527421
97
+ hash: 1406613959917538667
98
98
  requirements: []
99
99
  rubyforge_project: Ed
100
100
  rubygems_version: 1.8.15