indexer 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.index +54 -0
- data/HISTORY.md +9 -0
- data/README.md +145 -0
- data/bin/index +7 -0
- data/data/indexer/r2013/index.kwalify +175 -0
- data/data/indexer/r2013/index.yes +172 -0
- data/data/indexer/r2013/index.yesi +67 -0
- data/data/indexer/r2013/ruby.txt +35 -0
- data/data/indexer/r2013/yaml.txt +30 -0
- data/lib/indexer.rb +65 -0
- data/lib/indexer/attributes.rb +171 -0
- data/lib/indexer/command.rb +260 -0
- data/lib/indexer/components.rb +8 -0
- data/lib/indexer/components/author.rb +140 -0
- data/lib/indexer/components/conflict.rb +78 -0
- data/lib/indexer/components/copyright.rb +95 -0
- data/lib/indexer/components/dependency.rb +18 -0
- data/lib/indexer/components/organization.rb +133 -0
- data/lib/indexer/components/repository.rb +140 -0
- data/lib/indexer/components/requirement.rb +360 -0
- data/lib/indexer/components/resource.rb +209 -0
- data/lib/indexer/conversion.rb +14 -0
- data/lib/indexer/conversion/gemfile.rb +44 -0
- data/lib/indexer/conversion/gemspec.rb +114 -0
- data/lib/indexer/conversion/gemspec_exporter.rb +304 -0
- data/lib/indexer/core_ext.rb +4 -0
- data/lib/indexer/error.rb +23 -0
- data/lib/indexer/gemfile.rb +75 -0
- data/lib/indexer/importer.rb +144 -0
- data/lib/indexer/importer/file.rb +94 -0
- data/lib/indexer/importer/gemfile.rb +27 -0
- data/lib/indexer/importer/gemspec.rb +43 -0
- data/lib/indexer/importer/html.rb +289 -0
- data/lib/indexer/importer/markdown.rb +45 -0
- data/lib/indexer/importer/ruby.rb +47 -0
- data/lib/indexer/importer/version.rb +38 -0
- data/lib/indexer/importer/yaml.rb +46 -0
- data/lib/indexer/loadable.rb +159 -0
- data/lib/indexer/metadata.rb +879 -0
- data/lib/indexer/model.rb +237 -0
- data/lib/indexer/revision.rb +43 -0
- data/lib/indexer/valid.rb +287 -0
- data/lib/indexer/validator.rb +313 -0
- data/lib/indexer/version/constraint.rb +124 -0
- data/lib/indexer/version/exceptions.rb +11 -0
- data/lib/indexer/version/number.rb +497 -0
- metadata +141 -0
@@ -0,0 +1,8 @@
|
|
1
|
+
require_relative 'components/author'
|
2
|
+
require_relative 'components/organization'
|
3
|
+
require_relative 'components/copyright'
|
4
|
+
require_relative 'components/conflict'
|
5
|
+
require_relative 'components/resource'
|
6
|
+
require_relative 'components/repository'
|
7
|
+
require_relative 'components/requirement'
|
8
|
+
|
@@ -0,0 +1,140 @@
|
|
1
|
+
module Indexer
|
2
|
+
|
3
|
+
# Author is used to model Authors and Maintainers.
|
4
|
+
#
|
5
|
+
# TODO: Should Author have an `organization` field. If so
|
6
|
+
# is it a map with `name` and `website` fields?
|
7
|
+
#
|
8
|
+
# TODO: Should we have `team` field (think Github)?
|
9
|
+
#
|
10
|
+
class Author < Model
|
11
|
+
|
12
|
+
# Parse `entry` and create Author object.
|
13
|
+
def self.parse(entry)
|
14
|
+
case entry
|
15
|
+
when Author
|
16
|
+
entry
|
17
|
+
when String
|
18
|
+
parse_string(entry)
|
19
|
+
when Array
|
20
|
+
parse_array(entry)
|
21
|
+
when Hash
|
22
|
+
new(entry)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
def self.parse_array(array)
|
28
|
+
data = {}
|
29
|
+
array.each do |value|
|
30
|
+
v = value.strip
|
31
|
+
case v
|
32
|
+
when /^(.*?)\s*\<(.*?@.*?)\>/
|
33
|
+
data[:name] = $1 unless $1.empty?
|
34
|
+
data[:email] = $2
|
35
|
+
when /^(http|https)\:/
|
36
|
+
data[:website] = v
|
37
|
+
when /\@/
|
38
|
+
data[:email] = v
|
39
|
+
else
|
40
|
+
data[:name] = v
|
41
|
+
end
|
42
|
+
end
|
43
|
+
new(data)
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
def self.parse_string(string)
|
48
|
+
if md = /(.*?)\s*\<(.*?)\>/.match(string)
|
49
|
+
new(:name=>md[1], :email=>md[2])
|
50
|
+
else
|
51
|
+
new(:name=>string)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
def initialize(data)
|
57
|
+
super(data)
|
58
|
+
#raise ArgumentError, "person must have a name" unless name
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
def initialize_attributes
|
63
|
+
@data = {
|
64
|
+
:roles => []
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
attr :name
|
70
|
+
|
71
|
+
#
|
72
|
+
def name=(name)
|
73
|
+
Valid.oneline!(name, :name)
|
74
|
+
@data[:name] = name
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
attr :email
|
79
|
+
|
80
|
+
#
|
81
|
+
def email=(email)
|
82
|
+
Valid.email!(email, :email)
|
83
|
+
@data[:email] = email
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
attr :website
|
88
|
+
|
89
|
+
#
|
90
|
+
def website=(website)
|
91
|
+
Valid.url!(website, :website)
|
92
|
+
@data[:website] = website
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
attr :team
|
97
|
+
|
98
|
+
# TODO: validate team
|
99
|
+
def team=(team)
|
100
|
+
@data[:team] = team
|
101
|
+
end
|
102
|
+
|
103
|
+
# List of roles the person plays in the project.
|
104
|
+
# This can be any string or array of strings.
|
105
|
+
attr :roles
|
106
|
+
|
107
|
+
#
|
108
|
+
def roles=(role)
|
109
|
+
@data[:roles] = (
|
110
|
+
r = [role].flatten
|
111
|
+
r.each{ |x| Valid.oneline?(x) }
|
112
|
+
r
|
113
|
+
)
|
114
|
+
end
|
115
|
+
|
116
|
+
alias :role :roles
|
117
|
+
alias :role= :roles=
|
118
|
+
|
119
|
+
alias :group :roles
|
120
|
+
alias :group= :roles=
|
121
|
+
|
122
|
+
#
|
123
|
+
def to_h
|
124
|
+
h = {}
|
125
|
+
h['name'] = name
|
126
|
+
h['email'] = email if email
|
127
|
+
h['website'] = website if website
|
128
|
+
h['roles'] = roles if not roles.empty?
|
129
|
+
h
|
130
|
+
end
|
131
|
+
|
132
|
+
# CONSIDE: Only name has to be equal?
|
133
|
+
def ==(other)
|
134
|
+
return false unless Author === other
|
135
|
+
return false unless name == other.name
|
136
|
+
return true
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Indexer
|
2
|
+
|
3
|
+
# The Conflict class models the name and versions of
|
4
|
+
# packages that have know incompatibilities.
|
5
|
+
#
|
6
|
+
class Conflict < Model
|
7
|
+
|
8
|
+
# Parse `data` into a Dependency instance.
|
9
|
+
#
|
10
|
+
# TODO: What about respond_to?(:to_str) for String, etc.
|
11
|
+
def self.parse(data)
|
12
|
+
case data
|
13
|
+
when String
|
14
|
+
parse_string(data)
|
15
|
+
when Array
|
16
|
+
parse_array(data)
|
17
|
+
when Hash
|
18
|
+
parse_hash(data)
|
19
|
+
else
|
20
|
+
raise(ValidationError, "Conflict")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
#
|
27
|
+
#
|
28
|
+
def self.parse_string(data)
|
29
|
+
name, version = data.split(/\s+/)
|
30
|
+
new(:name=>name, :version=>version)
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
#
|
35
|
+
def self.parse_array(data)
|
36
|
+
name, version = *data
|
37
|
+
new(:name=>name, :version=>version)
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
#
|
42
|
+
def self.parse_hash(data)
|
43
|
+
new(data)
|
44
|
+
end
|
45
|
+
|
46
|
+
public
|
47
|
+
|
48
|
+
#
|
49
|
+
# The name of the package that causes the conflict.
|
50
|
+
#
|
51
|
+
# Yea it's *ALWAYS* THEIR fault ;-)
|
52
|
+
#
|
53
|
+
attr :name
|
54
|
+
|
55
|
+
#
|
56
|
+
# Set the name of the package.
|
57
|
+
#
|
58
|
+
def name=(name)
|
59
|
+
@data[:name] = name.to_s
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# The versions constraint of the conflicting package.
|
64
|
+
# This is used when only certain versions of the package
|
65
|
+
# are the problem.
|
66
|
+
#
|
67
|
+
attr_reader :version
|
68
|
+
|
69
|
+
#
|
70
|
+
# Set the version constraint.
|
71
|
+
#
|
72
|
+
def version=(version)
|
73
|
+
@data[:version] = Version::Constraint.parse(version)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Indexer
|
2
|
+
|
3
|
+
# Copyright class models a copyright holer, the year of copyright
|
4
|
+
# and the accosiated license.
|
5
|
+
#
|
6
|
+
class Copyright < Model
|
7
|
+
|
8
|
+
# Parse copyright entry.
|
9
|
+
#
|
10
|
+
def self.parse(copyright, default_license=nil)
|
11
|
+
case copyright
|
12
|
+
when Array
|
13
|
+
year, holder, license = *copyright
|
14
|
+
when Hash
|
15
|
+
year = copyright['year'] || copyright[:year]
|
16
|
+
holder = copyright['holder'] || copyright[:holder]
|
17
|
+
license = copyright['license'] || copyright[:license]
|
18
|
+
when String
|
19
|
+
case copyright
|
20
|
+
when /(\d\d\d\d)\s+(.*?)\s*\((.*?)\)$/
|
21
|
+
year, holder, license = $1, $2, $3
|
22
|
+
when /(\d\d\d\d)\s+(.*?)\s*$/
|
23
|
+
year, holder, license = $1, $2, nil
|
24
|
+
when /(opyright|\(c\))(.*?)\s*\((.*?)\)$/
|
25
|
+
year, holder, license = nil, $1, $2
|
26
|
+
when /(opyright|\(c\))(.*?)\s*$/
|
27
|
+
year, holder, license = nil, $1, nil
|
28
|
+
end
|
29
|
+
else
|
30
|
+
raise ValidationError, "copyright"
|
31
|
+
end
|
32
|
+
license = license || default_license
|
33
|
+
new(:holder=>holder, :year=>year, :license=>license)
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
def initialize(data)
|
38
|
+
super(data)
|
39
|
+
raise(ValidationError, "copyright must have a holder") unless holder
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
attr :year
|
44
|
+
|
45
|
+
#
|
46
|
+
attr :holder
|
47
|
+
|
48
|
+
#
|
49
|
+
attr :license
|
50
|
+
|
51
|
+
#
|
52
|
+
def year=(year)
|
53
|
+
Valid.copyright_year!(year, "copyright.year")
|
54
|
+
@data[:year] = year
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
def holder=(holder)
|
59
|
+
Valid.oneline!(holder, "copyright.holder")
|
60
|
+
@data[:holder] = holder
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
def license=(license)
|
65
|
+
if license.nil?
|
66
|
+
@data.delete(:license)
|
67
|
+
else
|
68
|
+
Valid.oneline!(license, "copyright.license")
|
69
|
+
@data[:license] = license
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# Standard copyright stamp.
|
75
|
+
#
|
76
|
+
def to_s
|
77
|
+
s = ["Copyright (c)"]
|
78
|
+
s << year if year
|
79
|
+
s << holder
|
80
|
+
s << "(#{license})" if license
|
81
|
+
s.join(' ') + ". All Rights Reserved."
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
def to_h
|
86
|
+
h = {}
|
87
|
+
h['holder'] = holder
|
88
|
+
h['year'] = year if year
|
89
|
+
h['license'] = license if license
|
90
|
+
h
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Indexer
|
2
|
+
|
3
|
+
# Dependency class is essentially the same as {Requirement}, but
|
4
|
+
# a dependency represents a binary package requirement that would
|
5
|
+
# need to be installed using an operating systems own package
|
6
|
+
# management system, or installed manually.
|
7
|
+
#
|
8
|
+
# Dependency is a sublcass of {Requirement}. It only exists as a separate
|
9
|
+
# class becuase an OS package managers MIGHT require some additional
|
10
|
+
# information --but as of yet that's not the case.
|
11
|
+
#
|
12
|
+
# TODO: Why not merge the two and add a field to distinguish them?
|
13
|
+
#
|
14
|
+
class Dependency < Requirement
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,133 @@
|
|
1
|
+
module Indexer
|
2
|
+
|
3
|
+
# Organization is used to model companies involved in project.
|
4
|
+
#
|
5
|
+
class Organization < Model
|
6
|
+
|
7
|
+
# Parse `entry` and create Organization object.
|
8
|
+
def self.parse(entry)
|
9
|
+
case entry
|
10
|
+
when Organization
|
11
|
+
entry
|
12
|
+
when String
|
13
|
+
parse_string(entry)
|
14
|
+
when Array
|
15
|
+
parse_array(entry)
|
16
|
+
when Hash
|
17
|
+
new(entry)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
def self.parse_array(array)
|
23
|
+
data = {}
|
24
|
+
array.each do |value|
|
25
|
+
v = value.strip
|
26
|
+
case v
|
27
|
+
when /^(.*?)\s*\<(.*?@.*?)\>/
|
28
|
+
data[:name] = $1 unless $1.empty?
|
29
|
+
data[:email] = $2
|
30
|
+
when /^(http|https)\:/
|
31
|
+
data[:website] = v
|
32
|
+
when /\@/
|
33
|
+
data[:email] = v
|
34
|
+
else
|
35
|
+
data[:name] = v
|
36
|
+
end
|
37
|
+
end
|
38
|
+
new(data)
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
def self.parse_string(string)
|
43
|
+
if md = /(.*?)\s*\<(.*?)\>/.match(string)
|
44
|
+
new(:name=>md[1], :email=>md[2])
|
45
|
+
else
|
46
|
+
new(:name=>string)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
def initialize(data)
|
52
|
+
super(data)
|
53
|
+
#raise ArgumentError, "person must have a name" unless name
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
def initialize_attributes
|
58
|
+
@data = {
|
59
|
+
:roles => []
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
attr :name
|
65
|
+
|
66
|
+
#
|
67
|
+
def name=(name)
|
68
|
+
Valid.oneline!(name, :name)
|
69
|
+
@data[:name] = name
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
attr :email
|
74
|
+
|
75
|
+
#
|
76
|
+
def email=(email)
|
77
|
+
Valid.email!(email, :email)
|
78
|
+
@data[:email] = email
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
attr :website
|
83
|
+
|
84
|
+
#
|
85
|
+
def website=(website)
|
86
|
+
Valid.url!(website, :website)
|
87
|
+
@data[:website] = website
|
88
|
+
end
|
89
|
+
|
90
|
+
# List of roles the person plays in the project.
|
91
|
+
# This can be any string or array of strings.
|
92
|
+
attr :roles
|
93
|
+
|
94
|
+
#
|
95
|
+
def roles=(roles)
|
96
|
+
@data[:roles] = (
|
97
|
+
r = [roles].flatten
|
98
|
+
r.each{ |x| Valid.oneline?(x) }
|
99
|
+
r
|
100
|
+
)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Signular term for #roles can be used as well.
|
104
|
+
alias :role :roles
|
105
|
+
alias :role= :roles=
|
106
|
+
|
107
|
+
# Group is a synonym for role.
|
108
|
+
alias :group :roles
|
109
|
+
alias :group= :roles=
|
110
|
+
|
111
|
+
# Team is a common synonym for role too.
|
112
|
+
alias :team :roles
|
113
|
+
alias :teams= :roles=
|
114
|
+
|
115
|
+
# Convert to simple Hash represepentation.
|
116
|
+
def to_h
|
117
|
+
h = {}
|
118
|
+
h['name'] = name
|
119
|
+
h['email'] = email if email
|
120
|
+
h['website'] = website if website
|
121
|
+
h['roles'] = roles if not roles.empty?
|
122
|
+
h
|
123
|
+
end
|
124
|
+
|
125
|
+
# CONSIDER: Only name has to be equal?
|
126
|
+
def ==(other)
|
127
|
+
return false unless Organization === other
|
128
|
+
return false unless name == other.name
|
129
|
+
return true
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|