reapack-index 1.0beta4 → 1.0rc2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  module ReaPack
2
2
  class Index
3
- VERSION = '1.0beta4'
3
+ VERSION = '1.0rc2'
4
4
  end
5
5
  end
@@ -12,6 +12,10 @@ class ReaPack::Index
12
12
  File.expand_path @repo.workdir
13
13
  end
14
14
 
15
+ def commits
16
+ commits_since nil
17
+ end
18
+
15
19
  def commits_since(sha)
16
20
  return [] if empty?
17
21
 
@@ -39,7 +43,7 @@ class ReaPack::Index
39
43
  return unless remote
40
44
 
41
45
  uri = Gitable::URI.parse remote.url
42
- return unless uri.path =~ /\A\/?(?<user>[^\/]+)\/(?<repo>[^\/]+)\.git\Z/
46
+ return unless uri.path =~ /\A\/?(?<user>[^\/]+)\/(?<repo>[^\/]+)(\.git)?\Z/
43
47
 
44
48
  tpl = uri.to_web_uri
45
49
  tpl.path += '/raw/$commit/$path'
@@ -1,5 +1,5 @@
1
1
  class ReaPack::Index
2
- Provides = Struct.new :file_pattern, :url_template, :platform, :type do
2
+ Provides = Struct.new :file_pattern, :url_template, :platform, :type, :main do
3
3
  PROVIDES_REGEX = /
4
4
  \A
5
5
  ( \[ \s* (?<options> .+? ) \s* \] )?
@@ -9,6 +9,8 @@ class ReaPack::Index
9
9
  \z
10
10
  /x.freeze
11
11
 
12
+ alias :main? :main
13
+
12
14
  class << self
13
15
  def parse_each(input)
14
16
  if block_given?
@@ -28,14 +30,16 @@ class ReaPack::Index
28
30
  user_opt.strip!
29
31
  next if user_opt.empty?
30
32
 
31
- opt = user_opt.downcase.to_sym
33
+ opt = user_opt.downcase
32
34
 
33
35
  if Source.is_platform? opt
34
- instance.platform = opt
36
+ instance.platform = opt.to_sym
35
37
  elsif type = ReaPack::Index.resolve_type(opt)
36
38
  instance.type = type
39
+ elsif opt =~ /\A(no)?main\Z/
40
+ instance.main = !$1
37
41
  else
38
- raise Error, "unknown option (platform or type) '#{user_opt}'"
42
+ raise Error, "unknown option '#{user_opt}'"
39
43
  end
40
44
  }
41
45
 
@@ -0,0 +1,129 @@
1
+ class ReaPack::Index
2
+ class Scanner
3
+ PROVIDES_VALIDATOR = proc {|value|
4
+ begin
5
+ Provides.parse_each(value).to_a and nil
6
+ rescue Error => e
7
+ e.message
8
+ end
9
+ }
10
+
11
+ HEADER_RULES = {
12
+ # package-wide tags
13
+ :version => [
14
+ MetaHeader::REQUIRED, MetaHeader::VALUE, MetaHeader::SINGLELINE, /\d/],
15
+
16
+ # 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],
22
+ }.freeze
23
+
24
+ WITH_MAIN = [:script, :effect].freeze
25
+
26
+ def initialize(cat, pkg, mh, index)
27
+ @cat, @pkg, @mh, @index = cat, pkg, mh, index
28
+ @is_main = !@mh[:metapackage] && WITH_MAIN.include?(pkg.type)
29
+ @cselector = @index.cdetector[pkg.path]
30
+ end
31
+
32
+ def run
33
+ if errors = @mh.validate(HEADER_RULES)
34
+ raise Error, errors.join("\n")
35
+ end
36
+
37
+ @pkg.version @mh[:version] do |ver|
38
+ next unless ver.is_new? || @index.amend
39
+
40
+ @ver = ver
41
+
42
+ ver.author = @mh[:author]
43
+ ver.time = @index.time if @index.time && ver.is_new?
44
+ ver.changelog = @mh[:changelog]
45
+
46
+ ver.replace_sources do
47
+ @cselector.clear
48
+ sources = parse_provides @mh[:provides]
49
+
50
+ if @is_main && sources.none? {|src| src.file.nil? }
51
+ # add the package itself as a main source
52
+ src = Source.new make_url(@pkg.path), true
53
+ sources.unshift src
54
+
55
+ @cselector.push @pkg.type, src.platform, @pkg.path
56
+ end
57
+
58
+ sources.each {|src| ver.add_source src }
59
+ end
60
+ end
61
+
62
+ if cons = @cselector.resolve
63
+ raise Error, cons.first unless cons.empty?
64
+ end
65
+ end
66
+
67
+ def make_url(path, template = nil)
68
+ unless template
69
+ unless template = @index.url_template
70
+ raise Error, 'unable to generate download links: empty url template'
71
+ end
72
+
73
+ unless @index.files.include? path
74
+ raise Error, "file not found '#{path}'"
75
+ end
76
+ end
77
+
78
+ template
79
+ .gsub('$path', path)
80
+ .gsub('$commit', @index.commit || 'master')
81
+ .gsub('$version', @ver.name)
82
+ .gsub('$package', @pkg.path)
83
+ end
84
+
85
+ def parse_provides(provides)
86
+ pathdir = Pathname.new @pkg.category
87
+
88
+ Provides.parse_each(provides).map {|line|
89
+ line.file_pattern = @pkg.name if line.file_pattern == '.'
90
+
91
+ expanded = ReaPack::Index.expand line.file_pattern, @pkg.category
92
+
93
+ if expanded == @pkg.path
94
+ # always resolve path even when an url template is set
95
+ files = [expanded]
96
+ elsif line.url_template.nil?
97
+ files = @index.files.select {|f|
98
+ File.fnmatch expanded, f, File::FNM_PATHNAME | File::FNM_EXTGLOB
99
+ }
100
+ raise Error, "file not found '#{line.file_pattern}'" if files.empty?
101
+ else
102
+ # use the relative path for external urls
103
+ files = [line.file_pattern]
104
+ end
105
+
106
+ files.map {|file|
107
+ src = Source.new make_url(file, line.url_template), line.main?
108
+ src.platform = line.platform
109
+ src.type = line.type
110
+
111
+ @cselector.push src.type || @pkg.type, src.platform,
112
+ line.url_template ? expanded : file
113
+
114
+ if file == @pkg.path
115
+ src.main = @is_main if line.main.nil?
116
+ else
117
+ if line.url_template
118
+ src.file = file
119
+ else
120
+ src.file = Pathname.new(file).relative_path_from(pathdir).to_s
121
+ end
122
+ end
123
+
124
+ src
125
+ }
126
+ }.flatten
127
+ end
128
+ end
129
+ end
@@ -4,6 +4,7 @@ class ReaPack::Index
4
4
  PLATFORM = 'platform'.freeze
5
5
  TYPE = 'type'.freeze
6
6
  FILE = 'file'.freeze
7
+ MAIN = 'main'.freeze
7
8
 
8
9
  PLATFORMS = {
9
10
  all: nil,
@@ -17,13 +18,17 @@ class ReaPack::Index
17
18
  end
18
19
  end
19
20
 
20
- def initialize(url = nil)
21
+ def initialize(url, main = false)
21
22
  @url = url
23
+ @main = main
22
24
  @platform = :all
23
25
  end
24
26
 
25
27
  attr_reader :platform, :type
26
28
  attr_accessor :file, :url
29
+ attr_writer :main
30
+
31
+ def main?; @main; end
27
32
 
28
33
  def platform=(new_platform)
29
34
  new_platform ||= :all
@@ -47,10 +52,11 @@ class ReaPack::Index
47
52
 
48
53
  def make_node(parent)
49
54
  @node = Nokogiri::XML::Node.new TAG, parent.document
50
- @node[PLATFORM] = @platform
55
+ @node[MAIN] = true if @main
56
+ @node[PLATFORM] = @platform if @platform != :all
51
57
  @node[TYPE] = @type if @type
52
58
  @node[FILE] = @file if @file
53
- @node.content = Addressable::URI.encode @url
59
+ @node.content = Addressable::URI.parse(@url).normalize.to_s
54
60
  @node.parent = parent
55
61
  rescue Addressable::URI::InvalidURIError => e
56
62
  raise Error, e.message
@@ -75,7 +75,7 @@ class ReaPack::Index
75
75
  private
76
76
  def hash_sources(nodes)
77
77
  nodes.map {|src|
78
- [src[Source::PLATFORM], src[Source::FILE], src.content]
78
+ [src[Source::PLATFORM] || 'all', src[Source::FILE], src.content]
79
79
  }
80
80
  end
81
81
  end
@@ -29,8 +29,9 @@ Gem::Specification.new do |spec|
29
29
  spec.add_runtime_dependency 'addressable', '~> 2.4'
30
30
  spec.add_runtime_dependency 'colorize', '~> 0.7'
31
31
  spec.add_runtime_dependency 'gitable', '~> 0.3'
32
- spec.add_runtime_dependency 'metaheader', '~> 1.1'
32
+ spec.add_runtime_dependency 'metaheader', '~> 1.2'
33
33
  spec.add_runtime_dependency 'nokogiri', '~> 1.6.8.rc2'
34
34
  spec.add_runtime_dependency 'pandoc-ruby', '~> 2.0'
35
35
  spec.add_runtime_dependency 'rugged', '~> 0.24'
36
+ spec.add_runtime_dependency 'stable_sort', '~> 1.1'
36
37
  end
@@ -2,11 +2,11 @@
2
2
  !include Sections.nsh
3
3
  !include StrRep.nsh
4
4
 
5
- !define VERSION "1.0beta4"
5
+ !define VERSION "1.0rc2"
6
6
  !define NAME "ReaPack Index ${VERSION}"
7
7
  !define LONG_VERSION "0.1.0.0"
8
8
 
9
- !define RUBY_VERSION "2.3.0"
9
+ !define RUBY_VERSION "2.3.1"
10
10
  !define RUBYINSTALLER_FILE "rubyinstaller-${RUBY_VERSION}.exe"
11
11
  !define RUBYINSTALLER_URL \
12
12
  "http://dl.bintray.com/oneclick/rubyinstaller/${RUBYINSTALLER_FILE}"
@@ -86,6 +86,19 @@ Section /o "Ruby for Windows" InstallRuby
86
86
  !insertmacro EXEC_GUI '"$R0" /VERYSILENT /TASKS=MODPATH' ${RUBYINSTALLER_FILE}
87
87
 
88
88
  !insertmacro RELOAD_PATH
89
+
90
+ nsExec::ExecToStack 'ruby -v'
91
+ Pop $0
92
+
93
+ StrCmp $0 "error" 0 +6 ; failed to launch ruby
94
+ MessageBox MB_YESNO|MB_ICONQUESTION "This computer need to be rebooted \
95
+ in order to complete the installation process. Reboot now?" IDNO +3
96
+ WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\RunOnce" \
97
+ "reapack-index installer" "$EXEPATH"
98
+ Reboot
99
+
100
+ DetailPrint "Relaunch reapack-index installer after rebooting your computer."
101
+ Abort
89
102
  SectionEnd
90
103
 
91
104
  Section /o "Rugged (libgit2)" InstallRugged
@@ -15,8 +15,8 @@ Finished checks for 2 packages with 0 failures
15
15
  setup = proc { mkfile 'index.xml', '<index name="test"/>' }
16
16
 
17
17
  wrapper ['--check'], setup: setup do
18
- mkfile 'test1.lua', '@version 1.0'
19
- mkfile 'test2.lua', '@version 1.0'
18
+ mkfile 'cat/test1.lua', '@version 1.0'
19
+ mkfile 'cat/test2.lua', '@version 1.0'
20
20
 
21
21
  assert_output nil, expected do
22
22
  assert_equal true, @cli.run
@@ -47,22 +47,16 @@ Finished checks for 2 packages with 1 failure
47
47
  end
48
48
  end
49
49
 
50
- def test_uses_scan
51
- expected = <<-STDERR
52
- F
53
-
54
- 1) Hello/World.lua failed:
55
- file not found 'background.png'
56
-
57
- Finished checks for 1 package with 1 failure
58
- STDERR
59
-
50
+ def test_ignore_current_index
60
51
  setup = proc {
52
+ mkfile 'background.png'
61
53
  mkfile 'index.xml', <<-XML
62
54
  <index name="test">
63
55
  <category name="Hello">
64
56
  <reapack name="World.lua" type="script">
65
- <version name="1.0"/>
57
+ <version name="1.0">
58
+ <source file="../background.png"/>
59
+ </version>
66
60
  </reapack>
67
61
  </category>
68
62
  </index>
@@ -70,11 +64,9 @@ Finished checks for 1 package with 1 failure
70
64
  }
71
65
 
72
66
  wrapper ['--check'], setup: setup do
73
- mkfile 'Hello/World.lua', "@version 1.0\n@provides background.png"
67
+ mkfile 'Chunky/Bacon.lua', "@version 1.0\n@provides ../background.png"
74
68
 
75
- assert_output nil, expected do
76
- assert_equal false, @cli.run
77
- end
69
+ capture_io { assert_equal true, @cli.run }
78
70
  end
79
71
  end
80
72
 
@@ -165,7 +157,7 @@ Finished checks for 1 package with 0 failures
165
157
  def test_verbose
166
158
  expected = <<-STDERR
167
159
  Path/To/test1.lua: failed
168
- test2.lua: passed
160
+ cat/test2.lua: passed
169
161
 
170
162
  1) Path/To/test1.lua failed:
171
163
  missing tag 'version'
@@ -179,7 +171,7 @@ Finished checks for 2 packages with 1 failure
179
171
  _, stderr = capture_io do
180
172
  wrapper ['--check', '--verbose'], setup: setup do
181
173
  mkfile 'Path/To/test1.lua', '@author'
182
- mkfile 'test2.lua', '@version 1.0'
174
+ mkfile 'cat/test2.lua', '@version 1.0'
183
175
 
184
176
  assert_equal false, @cli.run
185
177
  end
@@ -187,4 +179,18 @@ Finished checks for 2 packages with 1 failure
187
179
 
188
180
  assert_match expected, stderr
189
181
  end
182
+
183
+ def test_ignore_root
184
+ setup = proc { mkfile 'index.xml', '<index name="test"/>' }
185
+
186
+ _, stderr = capture_io do
187
+ wrapper ['--check'], setup: setup do
188
+ mkfile 'test.lua', '@version 1.0'
189
+
190
+ assert_equal true, @cli.run
191
+ end
192
+ end
193
+
194
+ assert_match 'Finished checks for 0 packages with 0 failures', stderr
195
+ end
190
196
  end
@@ -225,7 +225,7 @@ processing [a-f0-9]{7}: third commit
225
225
  end
226
226
 
227
227
  def test_specify_commit
228
- # --progress to check for FloatDomainError: Infinity errors
228
+ # --progress is enabled to check for FloatDomainError: Infinity errors
229
229
  options = ['--progress', '--scan']
230
230
 
231
231
  setup = proc {
@@ -320,6 +320,64 @@ processing [a-f0-9]{7}: third commit
320
320
  }
321
321
  end
322
322
 
323
+ def test_rebuild
324
+ setup = proc {
325
+ @git.create_commit 'initial commit',
326
+ [mkfile('cat/test1.lua', '@version 1.0')]
327
+
328
+ mkfile 'index.xml', <<-XML
329
+ <?xml version="1.0" encoding="utf-8"?>
330
+ <index version="1" name="hello" commit="#{@git.last_commit.id}">
331
+ <category name="Other">
332
+ <reapack name="Hello.lua" type="script" />
333
+ </category>
334
+ </index>
335
+ XML
336
+ }
337
+
338
+ wrapper ['--rebuild'], setup: setup do
339
+ @git.create_commit 'second commit',
340
+ [mkfile('cat/test2.lua', '@version 1.0')]
341
+
342
+ assert_output nil, '' do
343
+ assert_equal true, @cli.run
344
+ end
345
+
346
+ contents = read_index
347
+ assert_match 'test1.lua', contents
348
+ refute_match 'Hello.lua', contents
349
+ end
350
+ end
351
+
352
+ def test_rebuild_override
353
+ setup = proc {
354
+ @git.create_commit 'initial commit',
355
+ [mkfile('cat/test1.lua', '@version 1.0')]
356
+
357
+ mkfile 'index.xml', <<-XML
358
+ <?xml version="1.0" encoding="utf-8"?>
359
+ <index version="1" name="hello" commit="#{@git.last_commit.id}">
360
+ <category name="Other">
361
+ <reapack name="Hello.lua" type="script" />
362
+ </category>
363
+ </index>
364
+ XML
365
+ }
366
+
367
+ wrapper ['--rebuild', '--scan'], setup: setup do
368
+ @git.create_commit 'second commit',
369
+ [mkfile('cat/test2.lua', '@version 1.0')]
370
+
371
+ assert_output nil, '' do
372
+ assert_equal true, @cli.run
373
+ end
374
+
375
+ contents = read_index
376
+ refute_match 'test1.lua', contents
377
+ assert_match 'Hello.lua', contents
378
+ end
379
+ end
380
+
323
381
  def test_no_arguments
324
382
  wrapper ['--scan'] do; end
325
383
  end