ed 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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