codependency 0.2.0 → 0.3.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/Guardfile +6 -0
- data/codependency.gemspec +3 -1
- data/lib/codependency.rb +2 -0
- data/lib/codependency/graph.rb +24 -9
- data/lib/codependency/node.rb +13 -1
- data/lib/codependency/parser.rb +5 -0
- data/lib/codependency/version.rb +1 -1
- data/spec/codependency/graph_spec.rb +11 -1
- data/spec/codependency/node_spec.rb +8 -1
- data/spec/spec_helper.rb +0 -2
- data/spec/support/circular_context.rb +25 -0
- metadata +41 -6
data/Guardfile
ADDED
data/codependency.gemspec
CHANGED
@@ -15,5 +15,7 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = Codependency::VERSION
|
17
17
|
|
18
|
-
gem.add_development_dependency 'rspec',
|
18
|
+
gem.add_development_dependency 'rspec', '2.11.0'
|
19
|
+
gem.add_development_dependency 'guard-rspec', '1.2.1'
|
20
|
+
gem.add_development_dependency 'rb-fsevent', '0.9.1'
|
19
21
|
end
|
data/lib/codependency.rb
CHANGED
data/lib/codependency/graph.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
1
3
|
module Codependency
|
2
4
|
class Graph
|
3
5
|
def initialize( start, options={} )
|
@@ -6,24 +8,37 @@ module Codependency
|
|
6
8
|
@start = @nodes[ start ]
|
7
9
|
end
|
8
10
|
|
11
|
+
##
|
12
|
+
# a topologically sorted list of all dependencies of the `start` file.
|
9
13
|
def files
|
10
|
-
|
14
|
+
deps = resolve( @start, [ ] ).map( &:dependencies ).join ' '
|
15
|
+
|
16
|
+
cmd, out, err = Open3.popen3 "echo '#{deps}' | tsort"
|
17
|
+
|
18
|
+
if msg = err.gets
|
19
|
+
raise CircularDependencyError, msg
|
20
|
+
end
|
21
|
+
|
22
|
+
out.readlines.map( &:chomp ).reverse
|
11
23
|
end
|
12
24
|
|
13
25
|
protected
|
14
26
|
|
27
|
+
##
|
28
|
+
# adds a node's dependencies to a list (memo).
|
29
|
+
# intended to be used recursively.
|
15
30
|
def resolve( node, list )
|
16
|
-
list << node
|
17
|
-
|
18
|
-
node.
|
19
|
-
|
20
|
-
list << list.slice!( list.index( dep ) )
|
21
|
-
else
|
22
|
-
resolve dep, list
|
23
|
-
end
|
31
|
+
list << node
|
32
|
+
|
33
|
+
node.edges.map { |filename| @nodes[ filename ] }.each do |dep|
|
34
|
+
resolve dep, list unless list.include?( dep )
|
24
35
|
end
|
36
|
+
|
37
|
+
list
|
25
38
|
end
|
26
39
|
|
40
|
+
##
|
41
|
+
# the parser to use for this graph. shared by all nodes.
|
27
42
|
def parser
|
28
43
|
@parser ||= Parser.new @options
|
29
44
|
end
|
data/lib/codependency/node.rb
CHANGED
@@ -9,8 +9,20 @@ module Codependency
|
|
9
9
|
end
|
10
10
|
attr_reader :filename, :parser
|
11
11
|
|
12
|
+
##
|
13
|
+
# all of this node's edges
|
14
|
+
def edges
|
15
|
+
@edges ||= begin
|
16
|
+
parser.parse( filename ).map do |f|
|
17
|
+
dirname.join( "#{f}#{extname}" ).to_s
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# a string representing this node's edges, formatted for `tsort`.
|
12
24
|
def dependencies
|
13
|
-
|
25
|
+
edges.map { |edge| [ filename, edge ] }.flatten.join ' '
|
14
26
|
end
|
15
27
|
|
16
28
|
protected
|
data/lib/codependency/parser.rb
CHANGED
@@ -6,6 +6,8 @@ module Codependency
|
|
6
6
|
@comment = options.delete( :comment ) || '#'
|
7
7
|
end
|
8
8
|
|
9
|
+
##
|
10
|
+
# determines a file's dependencies based on the configured comment pattern.
|
9
11
|
def parse( file )
|
10
12
|
IO.readlines( file ).take_while do |line|
|
11
13
|
line =~ pattern
|
@@ -14,6 +16,9 @@ module Codependency
|
|
14
16
|
|
15
17
|
protected
|
16
18
|
|
19
|
+
##
|
20
|
+
# the comment pattern to use.
|
21
|
+
# TODO allow this to be more configurable
|
17
22
|
def pattern
|
18
23
|
@pattern ||= /^#{@comment} require (.+)$/
|
19
24
|
end
|
data/lib/codependency/version.rb
CHANGED
@@ -20,7 +20,17 @@ describe Codependency::Graph do
|
|
20
20
|
|
21
21
|
context 'sandwich' do
|
22
22
|
let( :graph ){ 'sandwich.js' }
|
23
|
-
its( :files ){ should eq( %w| butter.js
|
23
|
+
its( :files ){ should eq( %w| butter.js egg.js toast.js sandwich.js | ) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'circular dependencies', :files => :circular do
|
28
|
+
subject { Codependency::Graph.new graph }
|
29
|
+
|
30
|
+
let( :graph ){ 'money.rb' }
|
31
|
+
|
32
|
+
it 'should raise an error' do
|
33
|
+
expect { subject.files }.to raise_error( CircularDependencyError )
|
24
34
|
end
|
25
35
|
end
|
26
36
|
end
|
@@ -5,7 +5,7 @@ describe Codependency::Node do
|
|
5
5
|
|
6
6
|
context 'when the file exists', :files => :planets do
|
7
7
|
subject { Codependency::Node.new 'planet.rb', parser }
|
8
|
-
its( :
|
8
|
+
its( :edges ){ should eq( [ 'body.rb' ] ) }
|
9
9
|
end
|
10
10
|
|
11
11
|
context 'when the file does not exist' do
|
@@ -15,4 +15,11 @@ describe Codependency::Node do
|
|
15
15
|
}.to raise_error( Errno::ENOENT, 'No such file or directory - pluto.rb' )
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
describe 'dependencies', :files => :planets do
|
20
|
+
let( :parser ){ double 'Parser', :parse => [ 'body', 'mars' ] }
|
21
|
+
subject { Codependency::Node.new 'phobos.rb', parser }
|
22
|
+
|
23
|
+
its( :dependencies ){ should eq( 'phobos.rb body.rb phobos.rb mars.rb' ) }
|
24
|
+
end
|
18
25
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
shared_context 'circular dependencies', :files => :circular do
|
2
|
+
|
3
|
+
before do
|
4
|
+
file 'money.rb', <<-EOS
|
5
|
+
# require power
|
6
|
+
|
7
|
+
class Money
|
8
|
+
end
|
9
|
+
EOS
|
10
|
+
|
11
|
+
file 'power.rb', <<-EOS
|
12
|
+
# require respect
|
13
|
+
|
14
|
+
class Power
|
15
|
+
end
|
16
|
+
EOS
|
17
|
+
|
18
|
+
file 'respect.rb', <<-EOS
|
19
|
+
# require money
|
20
|
+
|
21
|
+
class Respect
|
22
|
+
end
|
23
|
+
EOS
|
24
|
+
end
|
25
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: codependency
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,24 +9,56 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-09-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - '='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 2.
|
21
|
+
version: 2.11.0
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - '='
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 2.
|
29
|
+
version: 2.11.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: guard-rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - '='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.2.1
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - '='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.2.1
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rb-fsevent
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - '='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.9.1
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.9.1
|
30
62
|
description: Simple comment-based dependency graph for arbitrary files
|
31
63
|
email:
|
32
64
|
- jeremy.ruppel@gmail.com
|
@@ -36,6 +68,7 @@ extra_rdoc_files: []
|
|
36
68
|
files:
|
37
69
|
- .gitignore
|
38
70
|
- Gemfile
|
71
|
+
- Guardfile
|
39
72
|
- LICENSE
|
40
73
|
- README.md
|
41
74
|
- Rakefile
|
@@ -50,6 +83,7 @@ files:
|
|
50
83
|
- spec/codependency/parser_spec.rb
|
51
84
|
- spec/spec_helper.rb
|
52
85
|
- spec/support/breakfasts_context.rb
|
86
|
+
- spec/support/circular_context.rb
|
53
87
|
- spec/support/file_system_stubs.rb
|
54
88
|
- spec/support/planets_context.rb
|
55
89
|
homepage: ''
|
@@ -82,5 +116,6 @@ test_files:
|
|
82
116
|
- spec/codependency/parser_spec.rb
|
83
117
|
- spec/spec_helper.rb
|
84
118
|
- spec/support/breakfasts_context.rb
|
119
|
+
- spec/support/circular_context.rb
|
85
120
|
- spec/support/file_system_stubs.rb
|
86
121
|
- spec/support/planets_context.rb
|