reapack-index 1.0 → 1.1beta1
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.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/lib/reapack/index.rb +10 -13
- data/lib/reapack/index/cli.rb +6 -3
- data/lib/reapack/index/cli/options.rb +22 -12
- data/lib/reapack/index/gem_version.rb +1 -1
- data/lib/reapack/index/git.rb +1 -1
- data/lib/reapack/index/metadata.rb +46 -6
- data/lib/reapack/index/package.rb +31 -6
- data/lib/reapack/index/scanner.rb +54 -13
- data/lib/reapack/index/version.rb +3 -4
- data/reapack-index.gemspec +1 -1
- data/setup/reapack-index.nsi +2 -2
- data/test/cli/test_metadata.rb +13 -0
- data/test/cli/test_scan.rb +14 -0
- data/test/data/index.xml +1 -1
- data/test/index/test_metadata.rb +5 -5
- data/test/index/test_scan.rb +31 -103
- data/test/scanner/test_makeurl.rb +102 -0
- data/test/scanner/test_validation.rb +126 -0
- data/test/test_git.rb +10 -0
- data/test/test_index.rb +35 -25
- data/test/test_metadata.rb +115 -19
- data/test/test_package.rb +55 -5
- data/test/test_scanner.rb +113 -140
- data/test/test_source.rb +16 -0
- metadata +10 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74ff4d70819b98251948bbe5a7e7767e7b9e3b0c
|
4
|
+
data.tar.gz: 1887659545c7d20019c17e740a1aaa48f078ae6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f47b75ad09e4f08962a52b6ea2ac13e94778086fd7107d9fe550d48516e19553417ddbf281796143c83d64a78c5afa198375abba74419fd30ecf749b638c341
|
7
|
+
data.tar.gz: 11f2b3596583affdc178428867a03a8bf094ae2701c84f2db4cca1d96d6bad479dda5adc6a368df7d1e31b8841efced68cfa16fa420524616951e89bcdea5e82
|
data/README.md
CHANGED
@@ -34,11 +34,13 @@ Modes:
|
|
34
34
|
Indexer options:
|
35
35
|
-a, --[no-]amend Reindex existing versions
|
36
36
|
-i, --ignore PATH Don't check or index any file starting with PATH
|
37
|
-
-U, --url-template TEMPLATE=auto Set the template for implicit download links
|
38
37
|
-o, --output FILE=./index.xml Set the output filename and path for the index
|
38
|
+
--[no-]strict Enable strict validation mode
|
39
|
+
-U, --url-template TEMPLATE=auto Set the template for implicit download links
|
39
40
|
Repository metadata:
|
40
41
|
-n, --name NAME Set the name shown in ReaPack for this repository
|
41
42
|
-l, --link LINK Add or remove a website link
|
43
|
+
--screenshot-link LINK Add or remove a screenshot link
|
42
44
|
--donation-link LINK Add or remove a donation link
|
43
45
|
--ls-links Display the link list then exit
|
44
46
|
-A, --about=FILE Set the about content from a file
|
data/lib/reapack/index.rb
CHANGED
@@ -36,12 +36,13 @@ class ReaPack::Index
|
|
36
36
|
extension: %w{ext},
|
37
37
|
effect: %w{jsfx},
|
38
38
|
data: %w{data},
|
39
|
+
theme: %w{theme},
|
39
40
|
}.freeze
|
40
41
|
|
41
42
|
FS_ROOT = File.expand_path('/').freeze
|
42
43
|
|
43
44
|
attr_reader :path, :url_template, :cdetector
|
44
|
-
attr_accessor :amend, :commit, :files, :time
|
45
|
+
attr_accessor :amend, :commit, :files, :time, :strict
|
45
46
|
|
46
47
|
class << self
|
47
48
|
def is_type?(input)
|
@@ -107,6 +108,7 @@ class ReaPack::Index
|
|
107
108
|
return unless type
|
108
109
|
|
109
110
|
mh = MetaHeader.parse contents
|
111
|
+
mh.strict = @strict
|
110
112
|
|
111
113
|
if mh[:noindex]
|
112
114
|
remove path
|
@@ -171,12 +173,7 @@ class ReaPack::Index
|
|
171
173
|
return
|
172
174
|
end
|
173
175
|
|
174
|
-
|
175
|
-
if separator&.< input.index('://')
|
176
|
-
input = [input[0...separator], input[separator+1..-1]]
|
177
|
-
end
|
178
|
-
|
179
|
-
link = @metadata.push_link type, *input
|
176
|
+
link = @metadata.push_link type, *Link.split(input)
|
180
177
|
|
181
178
|
if link.is_new?
|
182
179
|
log_change "new #{type} link"
|
@@ -185,15 +182,15 @@ class ReaPack::Index
|
|
185
182
|
end
|
186
183
|
end
|
187
184
|
|
188
|
-
def
|
189
|
-
@metadata.
|
185
|
+
def about
|
186
|
+
@metadata.about
|
190
187
|
end
|
191
188
|
|
192
|
-
def
|
193
|
-
old = @metadata.
|
194
|
-
@metadata.
|
189
|
+
def about=(content)
|
190
|
+
old = @metadata.about
|
191
|
+
@metadata.about = content
|
195
192
|
|
196
|
-
log_change 'modified metadata' if old != @metadata.
|
193
|
+
log_change 'modified metadata' if old != @metadata.about
|
197
194
|
end
|
198
195
|
|
199
196
|
def url_template=(tpl)
|
data/lib/reapack/index/cli.rb
CHANGED
@@ -17,6 +17,7 @@ class ReaPack::Index::CLI
|
|
17
17
|
|
18
18
|
@index = ReaPack::Index.new expand_path(@opts[:output])
|
19
19
|
@index.amend = @opts[:amend]
|
20
|
+
@index.strict = @opts[:strict]
|
20
21
|
set_url_template
|
21
22
|
rescue Rugged::OSError, Rugged::RepositoryError, ReaPack::Index::Error => e
|
22
23
|
$stderr.puts e.message
|
@@ -36,7 +37,7 @@ class ReaPack::Index::CLI
|
|
36
37
|
end
|
37
38
|
|
38
39
|
if @opts[:dump_about]
|
39
|
-
print @index.
|
40
|
+
print @index.about
|
40
41
|
return true
|
41
42
|
end
|
42
43
|
|
@@ -145,6 +146,8 @@ private
|
|
145
146
|
'--link'
|
146
147
|
when :donation
|
147
148
|
'--donation-link'
|
149
|
+
when :screenshot
|
150
|
+
'--screenshot-link'
|
148
151
|
end
|
149
152
|
|
150
153
|
warn "#{opt}: " + e.message
|
@@ -181,14 +184,14 @@ private
|
|
181
184
|
path = @opts[:about]
|
182
185
|
|
183
186
|
unless path
|
184
|
-
@index.
|
187
|
+
@index.about = String.new if @opts[:rmabout]
|
185
188
|
return
|
186
189
|
end
|
187
190
|
|
188
191
|
log "converting #{path} into RTF..."
|
189
192
|
|
190
193
|
# look for the file in the working directory, not on the repository root
|
191
|
-
@index.
|
194
|
+
@index.about = File.read(path)
|
192
195
|
rescue Errno::ENOENT => e
|
193
196
|
warn '--about: ' + e.message.sub(' @ rb_sysopen', '')
|
194
197
|
rescue ReaPack::Index::Error => e
|
@@ -8,16 +8,17 @@ class ReaPack::Index::CLI
|
|
8
8
|
|
9
9
|
DEFAULTS = {
|
10
10
|
check: false,
|
11
|
-
scan: [],
|
12
|
-
rebuild: false,
|
13
|
-
verbose: false,
|
14
|
-
warnings: true,
|
15
|
-
progress: true,
|
16
|
-
quiet: false,
|
17
11
|
commit: nil,
|
18
|
-
output: './index.xml',
|
19
12
|
ignore: [],
|
13
|
+
output: './index.xml',
|
14
|
+
progress: true,
|
15
|
+
quiet: false,
|
16
|
+
rebuild: false,
|
17
|
+
scan: [],
|
18
|
+
strict: false,
|
20
19
|
url_template: 'auto',
|
20
|
+
verbose: false,
|
21
|
+
warnings: true,
|
21
22
|
}.freeze
|
22
23
|
|
23
24
|
def read_config
|
@@ -80,16 +81,20 @@ class ReaPack::Index::CLI
|
|
80
81
|
opts[:ignore] << expand_path(path)
|
81
82
|
end
|
82
83
|
|
83
|
-
op.on '-U', "--url-template TEMPLATE=#{DEFAULTS[:url_template]}",
|
84
|
-
'Set the template for implicit download links' do |tpl|
|
85
|
-
opts[:url_template] = tpl.strip
|
86
|
-
end
|
87
|
-
|
88
84
|
op.on '-o', "--output FILE=#{DEFAULTS[:output]}",
|
89
85
|
'Set the output filename and path for the index' do |file|
|
90
86
|
opts[:output] = file.strip
|
91
87
|
end
|
92
88
|
|
89
|
+
op.on '--[no-]strict', 'Enable strict validation mode' do |bool|
|
90
|
+
opts[:strict] = bool
|
91
|
+
end
|
92
|
+
|
93
|
+
op.on '-U', "--url-template TEMPLATE=#{DEFAULTS[:url_template]}",
|
94
|
+
'Set the template for implicit download links' do |tpl|
|
95
|
+
opts[:url_template] = tpl.strip
|
96
|
+
end
|
97
|
+
|
93
98
|
op.separator 'Repository metadata:'
|
94
99
|
|
95
100
|
op.on '-n', '--name NAME', 'Set the name shown in ReaPack for this repository' do |name|
|
@@ -101,6 +106,11 @@ class ReaPack::Index::CLI
|
|
101
106
|
opts[:links] << [:website, link.strip]
|
102
107
|
end
|
103
108
|
|
109
|
+
op.on '--screenshot-link LINK', 'Add or remove a screenshot link' do |link|
|
110
|
+
opts[:links] ||= Array.new
|
111
|
+
opts[:links] << [:screenshot, link.strip]
|
112
|
+
end
|
113
|
+
|
104
114
|
op.on '--donation-link LINK', 'Add or remove a donation link' do |link|
|
105
115
|
opts[:links] ||= Array.new
|
106
116
|
opts[:links] << [:donation, link.strip]
|
data/lib/reapack/index/git.rb
CHANGED
@@ -9,6 +9,10 @@ class ReaPack::Index
|
|
9
9
|
@root = parent.element_children.find {|node| node.name == TAG }
|
10
10
|
end
|
11
11
|
|
12
|
+
def modified?
|
13
|
+
!!@dirty
|
14
|
+
end
|
15
|
+
|
12
16
|
def links(type)
|
13
17
|
Link.find_all(type, @root).map {|node| Link.from_node node }
|
14
18
|
.select {|link| link.url.index('http') == 0 }
|
@@ -54,6 +58,8 @@ class ReaPack::Index
|
|
54
58
|
node.content = url
|
55
59
|
end
|
56
60
|
|
61
|
+
@dirty = true if link.modified?
|
62
|
+
|
57
63
|
link
|
58
64
|
end
|
59
65
|
|
@@ -64,9 +70,23 @@ class ReaPack::Index
|
|
64
70
|
|
65
71
|
node.remove
|
66
72
|
auto_remove
|
73
|
+
|
74
|
+
@dirty = true
|
75
|
+
end
|
76
|
+
|
77
|
+
def replace_links(type)
|
78
|
+
was_dirty = @dirty
|
79
|
+
|
80
|
+
old_links = hash_links Link.find_all(type, @root)
|
81
|
+
.each {|node| node.remove }
|
82
|
+
|
83
|
+
yield
|
84
|
+
|
85
|
+
new_links = hash_links Link.find_all(type, @root)
|
86
|
+
@dirty = old_links != new_links unless was_dirty
|
67
87
|
end
|
68
88
|
|
69
|
-
def
|
89
|
+
def about
|
70
90
|
cdata = nil
|
71
91
|
|
72
92
|
if @root
|
@@ -77,18 +97,24 @@ class ReaPack::Index
|
|
77
97
|
cdata ? cdata.content : String.new
|
78
98
|
end
|
79
99
|
|
80
|
-
def
|
81
|
-
|
100
|
+
def about=(content)
|
101
|
+
content = content.to_s
|
102
|
+
|
103
|
+
if !content.empty? && !content.start_with?("{\\rtf")
|
104
|
+
content = make_rtf content
|
105
|
+
end
|
106
|
+
|
107
|
+
return if content == self.about
|
82
108
|
|
83
109
|
make_root
|
84
110
|
desc = @root.element_children.find {|node| node.name == DESC }
|
85
111
|
|
112
|
+
@dirty = true
|
113
|
+
|
86
114
|
if content.empty?
|
87
115
|
desc.remove
|
88
116
|
auto_remove
|
89
117
|
return
|
90
|
-
elsif content.index("{\\rtf") != 0
|
91
|
-
content = make_rtf content
|
92
118
|
end
|
93
119
|
|
94
120
|
if desc
|
@@ -125,6 +151,10 @@ class ReaPack::Index
|
|
125
151
|
"Try again after installing pandoc from <http://pandoc.org/>."
|
126
152
|
].join("\n")
|
127
153
|
end
|
154
|
+
|
155
|
+
def hash_links(nodes)
|
156
|
+
nodes.map {|node| [node[Link::REL], node[Link::URL]] }
|
157
|
+
end
|
128
158
|
end
|
129
159
|
|
130
160
|
class Link
|
@@ -133,7 +163,17 @@ class ReaPack::Index
|
|
133
163
|
URL = 'href'.freeze
|
134
164
|
|
135
165
|
# the first type will be the default one
|
136
|
-
VALID_TYPES = [:website, :donation].freeze
|
166
|
+
VALID_TYPES = [:website, :screenshot, :donation].freeze
|
167
|
+
|
168
|
+
LINK_REGEX = /\A(.+?)(?:\s|=)(\w+?:\/\/.+)\Z/.freeze
|
169
|
+
|
170
|
+
def self.split(input)
|
171
|
+
if input =~ LINK_REGEX
|
172
|
+
[$1, $2]
|
173
|
+
else
|
174
|
+
[input]
|
175
|
+
end
|
176
|
+
end
|
137
177
|
|
138
178
|
def self.from_node(node)
|
139
179
|
name, url = node.text.to_s, node[URL].to_s
|
@@ -7,14 +7,17 @@ class ReaPack::Index
|
|
7
7
|
@tag = 'reapack'.freeze
|
8
8
|
|
9
9
|
TYPE_ATTR = 'type'.freeze
|
10
|
+
DESC_ATTR = 'desc'.freeze
|
10
11
|
|
11
12
|
def initialize(node)
|
12
13
|
super
|
13
|
-
|
14
|
+
@metadata = Metadata.new node
|
14
15
|
end
|
15
16
|
|
17
|
+
attr_reader :metadata
|
18
|
+
|
16
19
|
def modified?
|
17
|
-
super ||
|
20
|
+
super || versions.any? {|ver| ver.modified? } || @metadata.modified?
|
18
21
|
end
|
19
22
|
|
20
23
|
def category
|
@@ -38,11 +41,31 @@ class ReaPack::Index
|
|
38
41
|
@dirty = true
|
39
42
|
end
|
40
43
|
|
44
|
+
def description
|
45
|
+
@node[DESC_ATTR].to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
def description=(new_desc)
|
49
|
+
new_desc ||= String.new
|
50
|
+
|
51
|
+
return if description == new_desc
|
52
|
+
|
53
|
+
if new_desc.empty?
|
54
|
+
@node.remove_attribute DESC_ATTR
|
55
|
+
else
|
56
|
+
@node[DESC_ATTR] = new_desc
|
57
|
+
end
|
58
|
+
|
59
|
+
@dirty = true
|
60
|
+
end
|
61
|
+
|
41
62
|
def has_version?(name)
|
63
|
+
read_versions
|
42
64
|
@versions.has_key? name
|
43
65
|
end
|
44
66
|
|
45
67
|
def versions
|
68
|
+
read_versions
|
46
69
|
@versions.values
|
47
70
|
end
|
48
71
|
|
@@ -62,11 +85,13 @@ class ReaPack::Index
|
|
62
85
|
|
63
86
|
private
|
64
87
|
def read_versions
|
65
|
-
@versions
|
88
|
+
@versions || begin
|
89
|
+
@versions = {}
|
66
90
|
|
67
|
-
|
68
|
-
|
69
|
-
|
91
|
+
Version.find_all(@node).each {|ver|
|
92
|
+
@versions[ver.name] = ver
|
93
|
+
}
|
94
|
+
end
|
70
95
|
end
|
71
96
|
end
|
72
97
|
end
|
@@ -8,34 +8,58 @@ class ReaPack::Index
|
|
8
8
|
end
|
9
9
|
}
|
10
10
|
|
11
|
+
VERSION_SEGMENT_MAX = (2 ** 16) - 1
|
12
|
+
|
13
|
+
SIMPLE_TAG = [MetaHeader::VALUE, MetaHeader::SINGLELINE].freeze
|
14
|
+
|
11
15
|
HEADER_RULES = {
|
12
16
|
# package-wide tags
|
13
|
-
:
|
14
|
-
MetaHeader::REQUIRED, MetaHeader::VALUE, MetaHeader::SINGLELINE, /\A\d
|
17
|
+
version: [
|
18
|
+
MetaHeader::REQUIRED, MetaHeader::VALUE, MetaHeader::SINGLELINE, /\A\d/,
|
19
|
+
proc {|v|
|
20
|
+
s = v.scan(/\d+/).find {|s| s.to_i > VERSION_SEGMENT_MAX }
|
21
|
+
'segment overflow (%d > %d)' % [s, VERSION_SEGMENT_MAX] if s
|
22
|
+
}
|
23
|
+
],
|
24
|
+
description: SIMPLE_TAG,
|
25
|
+
about: MetaHeader::VALUE,
|
26
|
+
website: MetaHeader::VALUE,
|
27
|
+
screenshot: MetaHeader::VALUE,
|
28
|
+
donation: MetaHeader::VALUE,
|
15
29
|
|
16
30
|
# version-specific tags
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
31
|
+
author: SIMPLE_TAG,
|
32
|
+
changelog: MetaHeader::VALUE,
|
33
|
+
provides: [MetaHeader::VALUE, PROVIDES_VALIDATOR],
|
34
|
+
noindex: MetaHeader::BOOLEAN,
|
35
|
+
metapackage: MetaHeader::BOOLEAN,
|
36
|
+
}.freeze
|
37
|
+
|
38
|
+
HEADER_ALIASES = {
|
39
|
+
[:reascript_name, :desc] => :description,
|
22
40
|
}.freeze
|
23
41
|
|
24
|
-
META_TYPES = [:extension, :data].freeze
|
42
|
+
META_TYPES = [:extension, :data, :theme].freeze
|
25
43
|
|
26
44
|
def initialize(cat, pkg, mh, index)
|
27
45
|
@cat, @pkg, @mh, @index = cat, pkg, mh, index
|
28
|
-
|
29
|
-
@mh[:metapackage] = META_TYPES.include?(pkg.type) if mh[:metapackage].nil?
|
30
|
-
|
31
46
|
@cselector = @index.cdetector[pkg.path]
|
32
47
|
end
|
33
48
|
|
34
49
|
def run
|
50
|
+
@mh.alias HEADER_ALIASES
|
51
|
+
|
35
52
|
if errors = @mh.validate(HEADER_RULES)
|
36
53
|
raise Error, errors.join("\n")
|
37
54
|
end
|
38
55
|
|
56
|
+
@pkg.description = @mh[:description]
|
57
|
+
@pkg.metadata.about = @mh[:about]
|
58
|
+
|
59
|
+
eval_links :website
|
60
|
+
eval_links :screenshot
|
61
|
+
eval_links :donation
|
62
|
+
|
39
63
|
@pkg.version @mh[:version] do |ver|
|
40
64
|
next unless ver.is_new? || @index.amend
|
41
65
|
|
@@ -49,7 +73,7 @@ class ReaPack::Index
|
|
49
73
|
@cselector.clear
|
50
74
|
sources = parse_provides @mh[:provides]
|
51
75
|
|
52
|
-
if
|
76
|
+
if !metapackage? && sources.none? {|src| src.file.nil? }
|
53
77
|
# add the package itself as a main source
|
54
78
|
src = Source.new make_url(@pkg.path), true
|
55
79
|
sources.unshift src
|
@@ -114,7 +138,7 @@ class ReaPack::Index
|
|
114
138
|
line.url_template ? expanded : file
|
115
139
|
|
116
140
|
if file == @pkg.path
|
117
|
-
src.main =
|
141
|
+
src.main = !metapackage? if line.main.nil?
|
118
142
|
else
|
119
143
|
if line.url_template
|
120
144
|
src.file = file
|
@@ -127,5 +151,22 @@ class ReaPack::Index
|
|
127
151
|
}
|
128
152
|
}.flatten
|
129
153
|
end
|
154
|
+
|
155
|
+
def eval_links(type)
|
156
|
+
@pkg.metadata.replace_links type do
|
157
|
+
@mh[type].to_s.lines {|l|
|
158
|
+
l.chomp!
|
159
|
+
@pkg.metadata.push_link type, *Link.split(l)
|
160
|
+
}
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def metapackage?
|
165
|
+
@metapackage ||= if @mh[:metapackage].nil?
|
166
|
+
META_TYPES.include? @pkg.type
|
167
|
+
else
|
168
|
+
@mh[:metapackage]
|
169
|
+
end
|
170
|
+
end
|
130
171
|
end
|
131
172
|
end
|