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 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