depression 0.0.1
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/Gemfile +7 -0
- data/Gemfile.lock +22 -0
- data/README.rdoc +7 -0
- data/Rakefile +10 -0
- data/depression.gemspec +27 -0
- data/lib/depression.rb +90 -0
- data/lib/depression/version.rb +3 -0
- data/test/depression_test.rb +82 -0
- data/test/helper.rb +9 -0
- metadata +109 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
depression (0.0.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://rubygems.org/
|
8
|
+
specs:
|
9
|
+
awesome_print (0.3.1)
|
10
|
+
mocha (0.9.9)
|
11
|
+
rake
|
12
|
+
rake (0.8.7)
|
13
|
+
test-unit (2.1.1)
|
14
|
+
|
15
|
+
PLATFORMS
|
16
|
+
ruby
|
17
|
+
|
18
|
+
DEPENDENCIES
|
19
|
+
awesome_print
|
20
|
+
depression!
|
21
|
+
mocha
|
22
|
+
test-unit
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
data/depression.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "depression/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "depression"
|
7
|
+
s.version = Depression::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Lars Gierth"]
|
10
|
+
s.email = ["lars.gierth@gmail.com"]
|
11
|
+
s.homepage = "http://rubygems.org/gems/depression"
|
12
|
+
s.summary = %q{Easy resolution of before/after relations for Ruby}
|
13
|
+
s.description = %q{depression resolves before/after relations ny forming a
|
14
|
+
graph of them and flattening it. Simple before/after
|
15
|
+
relations are supported as well as "greedy" relations
|
16
|
+
(before/after all other items) with simple relations being
|
17
|
+
more important in the case of a conflict. Circular
|
18
|
+
dependencies are detected and cause an exception.}
|
19
|
+
|
20
|
+
s.add_development_dependency "test-unit"
|
21
|
+
s.add_development_dependency "mocha"
|
22
|
+
|
23
|
+
s.files = `git ls-files`.split("\n") - [".gitignore", ".rvmrc"]
|
24
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
25
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
26
|
+
s.require_paths = ["lib"]
|
27
|
+
end
|
data/lib/depression.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
class Depression
|
2
|
+
def self.process(items)
|
3
|
+
graph = new(items)
|
4
|
+
graph.process
|
5
|
+
graph.result
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :items, :result
|
9
|
+
|
10
|
+
def initialize(items)
|
11
|
+
@items, @result, @changed = items, [], false
|
12
|
+
end
|
13
|
+
|
14
|
+
def process
|
15
|
+
items.each do |item|
|
16
|
+
unless item.respond_to?(:name) && item.name
|
17
|
+
raise "Items need to have a name."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
@data = Hash[*items.map do |item|
|
22
|
+
[item.name, Data.new(0, [])]
|
23
|
+
end.flatten]
|
24
|
+
|
25
|
+
build_dependencies
|
26
|
+
|
27
|
+
@data.each do |name, data|
|
28
|
+
increment(name) unless data.relations.empty?
|
29
|
+
data.relations.each do |rel|
|
30
|
+
increment(rel.name) if @data[rel.name].weight <= data.weight
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
@result = items.sort do |item, other|
|
35
|
+
@data[item.name].weight.<=>(@data[other.name].weight)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
def increment(name)
|
42
|
+
@stack ||= []
|
43
|
+
raise "Circular dep: #{@stack.inspect}" if @stack.include?(name)
|
44
|
+
|
45
|
+
@stack.push(name)
|
46
|
+
|
47
|
+
@data[name].weight += 1
|
48
|
+
@data[name].relations.each {|dep| increment(dep.name) }
|
49
|
+
|
50
|
+
@stack.delete(name)
|
51
|
+
end
|
52
|
+
|
53
|
+
def build_dependencies
|
54
|
+
items.each do |item|
|
55
|
+
data = @data[item.name]
|
56
|
+
|
57
|
+
item.relations[:before] ||= []
|
58
|
+
if item.relations[:before] == :all
|
59
|
+
rels = items.map do |item2|
|
60
|
+
next if item.name == item2.name
|
61
|
+
Relation.new(item2.name, :greedy_reverse)
|
62
|
+
end
|
63
|
+
rels.delete(nil)
|
64
|
+
data.relations.push(*deps)
|
65
|
+
else
|
66
|
+
item.relations[:before].each do |name|
|
67
|
+
next unless @data[name]
|
68
|
+
data.relations << Relation.new(name, :normal_reverse)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
item.relations[:after] ||= []
|
73
|
+
if item.relations[:after] == :all
|
74
|
+
@data.each do |name, data2|
|
75
|
+
next if item.name == name
|
76
|
+
data2.relations << Relation.new(item.name, :greedy)
|
77
|
+
end
|
78
|
+
else
|
79
|
+
item.relations[:after].each do |name|
|
80
|
+
next unless @data[name]
|
81
|
+
@data[name].relations << Relation.new(item.name, :normal)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class Data < Struct.new(:weight, :relations); end
|
88
|
+
|
89
|
+
class Relation < Struct.new(:name, :type); end
|
90
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/helper.rb"
|
2
|
+
|
3
|
+
class DepressionTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@item = Proc.new do |n, r|
|
6
|
+
r ||= {}
|
7
|
+
Struct.new(:name, :relations).new(n, r)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
test "has items" do
|
12
|
+
items = [@item.call(:foo), @item.call(:bar)]
|
13
|
+
graph = Depression.new(items)
|
14
|
+
assert_equal items, graph.items
|
15
|
+
|
16
|
+
assert_raise(NoMethodError) { graph.items = [] }
|
17
|
+
end
|
18
|
+
|
19
|
+
test "expects items to have a name" do
|
20
|
+
assert_raise(RuntimeError) { Depression.new([:foo]).process }
|
21
|
+
|
22
|
+
Depression.new([@item.call(:foo)]).process
|
23
|
+
end
|
24
|
+
|
25
|
+
test "provides a shorthand method for processing items" do
|
26
|
+
items = [@item.call(:foo)]
|
27
|
+
|
28
|
+
instance = stub("instance")
|
29
|
+
Depression.expects(:new).with(items).returns(instance)
|
30
|
+
instance.expects(:process)
|
31
|
+
instance.expects(:result)
|
32
|
+
|
33
|
+
Depression.process(items)
|
34
|
+
end
|
35
|
+
|
36
|
+
test "resolves simple before/after relations" do
|
37
|
+
items = [
|
38
|
+
@item.call(:foo, :before => [:baz]),
|
39
|
+
@item.call(:bar, :after => [:foo]),
|
40
|
+
@item.call(:baz, :after => [:bar]),
|
41
|
+
@item.call(:asd, :before => [:foo]),
|
42
|
+
@item.call(:sdf, :before => [:foo, :baz], :after => [:asd])
|
43
|
+
]
|
44
|
+
|
45
|
+
result = Depression.process(items).map {|i| i.name }
|
46
|
+
assert_equal [:asd, :sdf, :foo, :bar, :baz], result
|
47
|
+
end
|
48
|
+
|
49
|
+
test "resolves greedy before/after relations" do
|
50
|
+
items = [
|
51
|
+
@item.call(:foo, :before => [:bar]),
|
52
|
+
@item.call(:bar, :after => [:all]),
|
53
|
+
@item.call(:baz, :before => [:all])
|
54
|
+
]
|
55
|
+
|
56
|
+
result = Depression.process(items).map {|i| i.name }
|
57
|
+
assert_equal [:baz, :foo, :bar], result
|
58
|
+
end
|
59
|
+
|
60
|
+
test "detects circular relations" do
|
61
|
+
items = [
|
62
|
+
@item.call(:foo, :before => [:bar]),
|
63
|
+
@item.call(:bar, :before => [:baz]),
|
64
|
+
@item.call(:baz, :before => [:asd]),
|
65
|
+
@item.call(:asd, :before => [:foo])
|
66
|
+
]
|
67
|
+
|
68
|
+
begin
|
69
|
+
Depression.process(items)
|
70
|
+
rescue => e
|
71
|
+
end
|
72
|
+
assert e.message =~ /^Circular dep:/
|
73
|
+
end
|
74
|
+
|
75
|
+
test "drops greedy relations in favor of simple relations" do
|
76
|
+
pend("Not yet implemented.")
|
77
|
+
end
|
78
|
+
|
79
|
+
test "can drop 'older' relations until a circular relation is resolved" do
|
80
|
+
pend("Not yet implemented.")
|
81
|
+
end
|
82
|
+
end
|
data/test/helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: depression
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Lars Gierth
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-11-17 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: test-unit
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: mocha
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id002
|
49
|
+
description: |-
|
50
|
+
depression resolves before/after relations ny forming a
|
51
|
+
graph of them and flattening it. Simple before/after
|
52
|
+
relations are supported as well as "greedy" relations
|
53
|
+
(before/after all other items) with simple relations being
|
54
|
+
more important in the case of a conflict. Circular
|
55
|
+
dependencies are detected and cause an exception.
|
56
|
+
email:
|
57
|
+
- lars.gierth@gmail.com
|
58
|
+
executables: []
|
59
|
+
|
60
|
+
extensions: []
|
61
|
+
|
62
|
+
extra_rdoc_files: []
|
63
|
+
|
64
|
+
files:
|
65
|
+
- Gemfile
|
66
|
+
- Gemfile.lock
|
67
|
+
- README.rdoc
|
68
|
+
- Rakefile
|
69
|
+
- depression.gemspec
|
70
|
+
- lib/depression.rb
|
71
|
+
- lib/depression/version.rb
|
72
|
+
- test/depression_test.rb
|
73
|
+
- test/helper.rb
|
74
|
+
has_rdoc: true
|
75
|
+
homepage: http://rubygems.org/gems/depression
|
76
|
+
licenses: []
|
77
|
+
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options: []
|
80
|
+
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
hash: 3
|
89
|
+
segments:
|
90
|
+
- 0
|
91
|
+
version: "0"
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
hash: 3
|
98
|
+
segments:
|
99
|
+
- 0
|
100
|
+
version: "0"
|
101
|
+
requirements: []
|
102
|
+
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 1.3.7
|
105
|
+
signing_key:
|
106
|
+
specification_version: 3
|
107
|
+
summary: Easy resolution of before/after relations for Ruby
|
108
|
+
test_files: []
|
109
|
+
|