reapack-index 1.0 → 1.1beta1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 964b4eb388703e4a06e0ca2ccf5a6844f4042b63
4
- data.tar.gz: b6d72c01fc0fb7429df1d9aa48934edb6e84ede6
3
+ metadata.gz: 74ff4d70819b98251948bbe5a7e7767e7b9e3b0c
4
+ data.tar.gz: 1887659545c7d20019c17e740a1aaa48f078ae6f
5
5
  SHA512:
6
- metadata.gz: ef2e717131435f7062eccaad5a9957f5326f11b24b81cf838aabd45d685335dd2705ffa5bc022c20e3c77e6a587630c35ad45af4dbe812f055cefec170a0769b
7
- data.tar.gz: a92eb953f094cfb2dc1c1d4fde180576d9cd7213eace67bd376a153073aa635c25de15d51539c57136b9fa6faf4831580a6c401fa4e6b235bd023b55021b0dba
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
- separator = input.index('=')
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 description
189
- @metadata.description
185
+ def about
186
+ @metadata.about
190
187
  end
191
188
 
192
- def description=(content)
193
- old = @metadata.description
194
- @metadata.description = content
189
+ def about=(content)
190
+ old = @metadata.about
191
+ @metadata.about = content
195
192
 
196
- log_change 'modified metadata' if old != @metadata.description
193
+ log_change 'modified metadata' if old != @metadata.about
197
194
  end
198
195
 
199
196
  def url_template=(tpl)
@@ -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.description
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.description = String.new if @opts[:rmabout]
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.description = File.read(path)
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]
@@ -1,5 +1,5 @@
1
1
  module ReaPack
2
2
  class Index
3
- VERSION = '1.0'
3
+ VERSION = '1.1beta1'
4
4
  end
5
5
  end
@@ -1,7 +1,7 @@
1
1
  class ReaPack::Index
2
2
  class Git
3
3
  def initialize(path)
4
- @repo = Rugged::Repository.discover path
4
+ @repo = Rugged::Repository.discover path.encode(Encoding::UTF_8)
5
5
  end
6
6
 
7
7
  def empty?
@@ -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 description
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 description=(content)
81
- return if content == description
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
- read_versions
14
+ @metadata = Metadata.new node
14
15
  end
15
16
 
17
+ attr_reader :metadata
18
+
16
19
  def modified?
17
- super || @versions.values.any? {|ver| ver.modified? }
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
- Version.find_all(@node).each {|ver|
68
- @versions[ver.name] = ver
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
- :version => [
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
- :author => [MetaHeader::VALUE, MetaHeader::SINGLELINE],
18
- :changelog => [MetaHeader::VALUE],
19
- :provides => [MetaHeader::VALUE, PROVIDES_VALIDATOR],
20
- :noindex => [MetaHeader::BOOLEAN],
21
- :metapackage => [MetaHeader::BOOLEAN],
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 !@mh[:metapackage] && sources.none? {|src| src.file.nil? }
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 = !@mh[:metapackage] if line.main.nil?
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