lapis-minecraft-versioning 0.5.0 → 0.6.0

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: b5bf6625d5970b1ef1e843dbc6739c336c63e8c9
4
- data.tar.gz: 7c063ac81ca87f18f731780a626f8c6812118c94
3
+ metadata.gz: 875492c8026a073c5e304f467850f1f1716f872a
4
+ data.tar.gz: 9881c4542bbf404d6448766601e07368c8909abc
5
5
  SHA512:
6
- metadata.gz: b3cdce6908cc39176ae0a07f855e0ab25839e03a27d4d8b2c1c13412cf15416f8170446f10417a029324bbf34d8a2a30d4bd132a15207fc5f5a388f83e553167
7
- data.tar.gz: 9a8cdf5b7d0b9be57859457fa6414c2bd68fdddc5123ff63a953590ff1e95114ca2d8ff78635d44a1f532f653ceadf07c1066885a79a27249357307b73b8d995
6
+ metadata.gz: 5499dd5d3cd4a84534dcca77bb0e19bf3769e4b25c388d9980dc7805f9a63139d1b088f4a2ce3982e8f14cae3b099c8b1a56eedc3b7a8a787f6cbe86156fafa5
7
+ data.tar.gz: 12227c1b6777b082fdbc82912f92891a3f7953f36966d5039ed6edc62ec9cbc68788be629d113b8c075fd4e1486c0d0e47313ae9982f83e9d240b46a638f20e7
data/README.md CHANGED
@@ -5,6 +5,7 @@ Minecraft Version Info
5
5
  [![Code Climate](https://codeclimate.com/github/lapis-mc/minecraft-versioning/badges/gpa.svg)](https://codeclimate.com/github/lapis-mc/minecraft-versioning)
6
6
  [![Test Coverage](https://codeclimate.com/github/lapis-mc/minecraft-versioning/badges/coverage.svg)](https://codeclimate.com/github/lapis-mc/minecraft-versioning/coverage)
7
7
  [![Issue Count](https://codeclimate.com/github/lapis-mc/minecraft-versioning/badges/issue_count.svg)](https://codeclimate.com/github/lapis-mc/minecraft-versioning)
8
+ [![Documentation](https://inch-ci.org/github/lapis-mc/minecraft-versioning.svg?branch=master)](http://www.rubydoc.info/github/lapis-mc/minecraft-versioning/master)
8
9
 
9
10
  Retrieves and processes information about versions of Minecraft.
10
11
  Small library for getting version information from Mojang about Minecraft.
@@ -36,13 +37,15 @@ Or install it yourself as:
36
37
  Usage
37
38
  -----
38
39
 
40
+ ### Script usage
41
+
39
42
  Include the gem by adding this to your scripts:
40
43
 
41
44
  ```ruby
42
45
  require 'lapis/minecraft/versioning'
43
46
  ```
44
47
 
45
- ### Accessing Minecraft version data
48
+ #### Accessing Minecraft version data
46
49
 
47
50
  Retrieve the official Minecraft version list:
48
51
 
@@ -64,6 +67,73 @@ Get the client URL for the latest release:
64
67
  list.latest_release.client_download.url
65
68
  ```
66
69
 
70
+ ### Command-line usage
71
+
72
+ This gem comes with a script named `minecraft-versions`.
73
+ It can display most information about versions - some information is too complex to display.
74
+ The following commands are available:
75
+
76
+ ```sh
77
+ minecraft-versions list [TYPE]
78
+ minecraft-versions info <ID>
79
+ minecraft-versions client <ID>
80
+ minecraft-versions server <ID>
81
+ minecraft-versions assets <ID>
82
+ minecraft-versions libraries <ID>
83
+ minecraft-versions latest-id [TYPE]
84
+ minecraft-versions latest [TYPE]
85
+ ```
86
+
87
+ #### `list [TYPE]`
88
+
89
+ Lists the identifiers of all known Minecraft versions.
90
+ These are the IDs used for other commands.
91
+ `TYPE` can be provided to filter which versions are listed.
92
+ `TYPE` can be one of: `alpha`, `beta`, `snapshot`, `release`, or `all`.
93
+ The default is `all`.
94
+
95
+ #### `info <ID>`
96
+
97
+ Displays top-level information about the specified Minecraft version.
98
+ `ID` is the identifier of the version to display information for.
99
+
100
+ #### `client <ID>`
101
+
102
+ Outputs just the client download URL for a specific Minecraft version.
103
+ `ID` is the identifier of the version to get the client for.
104
+
105
+ #### `server <ID>`
106
+
107
+ Outputs just the server download URL for a specific Minecraft version.
108
+ `ID` is the identifier of the version to get the server for.
109
+
110
+ #### `assets <ID>`
111
+
112
+ Displays a list of all the assets used by the client.
113
+ `ID` is the identifier of the version to get an asset list for.
114
+ `ID` is *not* the asset index name.
115
+
116
+ #### `libraries <ID>`
117
+
118
+ Displays a list of all the libraries needed for a specific version of Minecraft.
119
+ `ID` is the identifier of the version to get the libraries for.
120
+
121
+ #### `latest-id [TYPE]`
122
+
123
+ Outputs just the ID of the latest Minecraft version.
124
+ `TYPE` can be specified to filter which versions are considered.
125
+ `TYPE` can be one of: `alpha`, `beta`, `snapshot`, `release`, or `any`.
126
+ When set to `any`, the latest version, regardless of type is displayed.
127
+ The default is `release`.
128
+
129
+ #### `latest [TYPE]`
130
+
131
+ Displays top-level information for the latest Minecraft version.
132
+ `TYPE` can be specified to filter which versions are considered.
133
+ `TYPE` can be one of: `alpha`, `beta`, `snapshot`, `release`, or `any`.
134
+ When set to `any`, the latest version, regardless of type is displayed.
135
+ The default is `release`.
136
+
67
137
  Development
68
138
  -----------
69
139
 
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'lapis/minecraft/versioning'
5
+ require 'lapis/minecraft/versioning/cli'
6
+
7
+ Lapis::Minecraft::Versioning::CLI.start(ARGV)
@@ -22,6 +22,7 @@ Includes a command-line utility as well.}
22
22
  spec.require_paths = ['lib']
23
23
 
24
24
  spec.add_dependency 'httpclient', '~> 2.1'
25
+ spec.add_dependency 'thor'
25
26
 
26
27
  spec.add_development_dependency 'bundler'
27
28
  spec.add_development_dependency 'rake', '~> 10.0'
@@ -0,0 +1,171 @@
1
+ require 'thor'
2
+ require_relative '../versioning'
3
+
4
+ module Lapis
5
+ module Minecraft
6
+ module Versioning
7
+
8
+ # Command-line interface for retrieving version information.
9
+ # @note This class is not included by default with `lapis/minecraft/versioning`.
10
+ class CLI < Thor
11
+
12
+ class_option :url, :aliases => :u, :type => :string, :banner => 'MANIFEST_URL', :desc => 'Custom manifest URL to get version data from', :default => Lapis::Minecraft::Versioning::VersionList::OFFICIAL_MANIFEST_URL
13
+
14
+ desc 'list [TYPE]', 'List all available Minecraft versions'
15
+ long_desc <<-LONG_DESC
16
+ Lists the identifiers of all known Minecraft versions.
17
+ TYPE can be provided to filter which versions are listed.
18
+ TYPE can be one of: alpha, beta, snapshot, release, or all.
19
+ The default is all.
20
+ LONG_DESC
21
+ def list(type = 'all')
22
+ type_sym = type.downcase.to_sym
23
+ versions = case type_sym
24
+ when :alpha, :beta, :snapshot, :release
25
+ filter(type_sym)
26
+ else # all
27
+ version_list
28
+ end
29
+ versions.each do |version|
30
+ puts version.id
31
+ end
32
+ end
33
+
34
+ desc 'info <ID>', 'Display information about a version'
35
+ long_desc <<-LONG_DESC
36
+ Displays top-level information about the specified Minecraft version.
37
+ ID is the identifier of the version to display information for.
38
+ LONG_DESC
39
+ def info(id)
40
+ version = version_list[id]
41
+ display_info(version)
42
+ end
43
+
44
+ desc 'client <ID>', 'Get the URL for the client download'
45
+ long_desc <<-LONG_DESC
46
+ Outputs just the client download URL for a specific Minecraft version.
47
+ ID is the identifier of the version to get the client for.
48
+ LONG_DESC
49
+ def client(id)
50
+ version = version_list[id]
51
+ puts version.client_download.url
52
+ end
53
+
54
+ desc 'server <ID>', 'Get the URL for the server download'
55
+ long_desc <<-LONG_DESC
56
+ Outputs just the server download URL for a specific Minecraft version.
57
+ ID is the identifier of the version to get the server for.
58
+ LONG_DESC
59
+ def server(id)
60
+ version = version_list[id]
61
+ puts version.server_download.url
62
+ end
63
+
64
+ desc 'assets <ID>', 'List assets used by a version'
65
+ long_desc <<-LONG_DESC
66
+ Displays a list of all the assets used by the client.
67
+ ID is the identifier of the version to get an asset list for.
68
+ ID is *not* the asset index name.
69
+ LONG_DESC
70
+ def assets(id)
71
+ version = version_list[id]
72
+ max_size_length = version.assets.map { |asset| asset.size.to_s.length }.max
73
+ version.assets.each do |asset|
74
+ printf("%s %#{max_size_length}d %s\n", asset.sha1, asset.size, asset.path)
75
+ end
76
+ end
77
+
78
+ desc 'libraries <ID>', 'List libraries used by a version'
79
+ long_desc <<-LONG_DESC
80
+ Displays a list of all the libraries needed for a specific version of Minecraft.
81
+ ID is the identifier of the version to get the libraries for.
82
+ LONG_DESC
83
+ def libraries(id)
84
+ version = version_list[id]
85
+ version.libraries.each do |library|
86
+ puts library.name
87
+ end
88
+ end
89
+
90
+ desc 'latest-id [TYPE]', 'Get the ID of the latest version'
91
+ long_desc <<-LONG_DESC
92
+ Outputs just the ID of the latest Minecraft version.
93
+ TYPE can be specified to filter which versions are considered.
94
+ TYPE can be one of: alpha, beta, snapshot, release, or any.
95
+ When set to 'any', the latest version, regardless of type is displayed.
96
+ The default is 'release'.
97
+ LONG_DESC
98
+ def latest_id(type = 'release')
99
+ puts latest_version(type).id
100
+ end
101
+
102
+ desc 'latest [TYPE]', 'Display information about the latest version'
103
+ long_desc <<-LONG_DESC
104
+ Displays top-level information for the latest Minecraft version.
105
+ TYPE can be specified to filter which versions are considered.
106
+ TYPE can be one of: alpha, beta, snapshot, release, or any.
107
+ When set to 'any', the latest version, regardless of type is displayed.
108
+ The default is 'release'.
109
+ LONG_DESC
110
+ def latest(type = 'release')
111
+ version = latest_version(type)
112
+ display_info(version)
113
+ end
114
+
115
+ private
116
+
117
+ # Retrieve and cache the version list.
118
+ # @return [VersionList]
119
+ def version_list
120
+ @version_list ||= Lapis::Minecraft::Versioning::VersionList.new(options[:url])
121
+ end
122
+
123
+ # Retrieve a list of versions based on type.
124
+ # @param type [Symbol] One of: +:alpha+, +:beta+, +:snapshot+, or +:release+.
125
+ # @return [Array<Version>] Filtered version list.
126
+ def filter(type)
127
+ version_list.select do |version|
128
+ version.type == type
129
+ end
130
+ end
131
+
132
+ # Retrieve the latest version of a given type.
133
+ # @param type [String] One of: `alpha`, `beta`, `snapshot`, `release`, or `any`.
134
+ # @return [Version] Latest version of the given type.
135
+ def latest_version(type)
136
+ case type.to_s.downcase
137
+ when 'release'
138
+ version_list.latest_release
139
+ when 'snapshot'
140
+ version_list.latest_snapshot
141
+ when 'beta'
142
+ filter(:beta).max_by { |v| v.time }
143
+ when 'alpha'
144
+ filter(:alpha).max_by { |v| v.time }
145
+ else # any
146
+ version_list.max_by { |v| v.time }
147
+ end
148
+ end
149
+
150
+ # Outputs information about a version.
151
+ # Libraries, assets, and other complex data is omitted.
152
+ # @param version [Version] Version to output information for.
153
+ # @return [void]
154
+ def display_info(version)
155
+ puts <<-END_INFO
156
+ Version: #{version.id}
157
+ Type: #{version.type.to_s.capitalize}
158
+ Released: #{version.time.utc}
159
+ Assets: #{version.asset_index.id}
160
+ Assets Size: #{version.asset_index.total_size}
161
+ Main Class: #{version.launcher_properties.main_class}
162
+ Arguments: #{version.launcher_properties.arguments.join(' ')}
163
+ Min Launcher: #{version.launcher_properties.minimum_version}
164
+ END_INFO
165
+ end
166
+
167
+ end
168
+
169
+ end
170
+ end
171
+ end
@@ -24,6 +24,9 @@ module Lapis
24
24
  @latest_snapshot = versions.find { |version| version.id == latest_snapshot_id }
25
25
  end
26
26
 
27
+ # Iterates over all versions.
28
+ # @yieldparam version [Basic] Next version in the list.
29
+ # @return [Enumerator<Basic>]
27
30
  def each
28
31
  return enum_for(:each) unless block_given?
29
32
 
@@ -32,6 +35,14 @@ module Lapis
32
35
  end
33
36
  end
34
37
 
38
+ # Retrieves version information given a specific ID.
39
+ # @param id [String] ID of the version to retrieve.
40
+ # @return [Basic] Version information.
41
+ # @return [nil] No version with the provided ID exists.
42
+ def [](id)
43
+ @versions.find { |version| version.id == id }
44
+ end
45
+
35
46
  # Compares one manifest to another.
36
47
  # @param other [Manifest] Manifest to compare against.
37
48
  # @return [true] The manifests are the same.
@@ -1,7 +1,7 @@
1
1
  module Lapis
2
2
  module Minecraft
3
3
  module Versioning
4
- VERSION = '0.5.0'
4
+ VERSION = '0.6.0'
5
5
  end
6
6
  end
7
7
  end
@@ -28,7 +28,7 @@ module Lapis
28
28
 
29
29
  # Iterates over all versions.
30
30
  # @yieldparam version [Version] Next version in the list.
31
- # @return [void]
31
+ # @return [Enumerator<Version>]
32
32
  def each
33
33
  return enum_for(:each) unless block_given?
34
34
 
@@ -37,6 +37,18 @@ module Lapis
37
37
  end
38
38
  end
39
39
 
40
+ # Retrieves version information given a specific ID.
41
+ # @param id [String] ID of the version to retrieve.
42
+ # @return [Version] Version information.
43
+ # @return [nil] No version with the provided ID exists.
44
+ def [](id)
45
+ if (basic = manifest[id])
46
+ Version.new(basic, @meta_server)
47
+ else
48
+ nil
49
+ end
50
+ end
51
+
40
52
  # Retrieves the latest released version.
41
53
  # @return [Version] Version information.
42
54
  def latest_release
@@ -0,0 +1,625 @@
1
+ require_relative '../../../spec_helper'
2
+ require_relative '../../../../lib/lapis/minecraft/versioning/cli'
3
+
4
+ # Generate a regular expression that matches all items in a list in any order.
5
+ # The regular expression matches one item per line.
6
+ # @param items [Array] List of items to match.
7
+ # @return [Regexp]
8
+ def any_order_regexp(items)
9
+ Regexp.new(items.map do |item|
10
+ "(?=.*^#{Regexp.escape(item.to_s)}$)"
11
+ end.join, Regexp::MULTILINE)
12
+ end
13
+
14
+ # Generate a regular expression that matches all items in a list in any order.
15
+ # The regular expression matches one item per non-word boundary.
16
+ # @param items [Array] List of items to match.
17
+ # @return [Regexp]
18
+ def any_order_regexp_bounds(items)
19
+ Regexp.new(items.map do |item|
20
+ "(?=.*(\\A|\\W)#{Regexp.escape(item.to_s)}(\\Z|\\W))"
21
+ end.join, Regexp::MULTILINE)
22
+ end
23
+
24
+ RSpec.describe Lapis::Minecraft::Versioning::CLI do
25
+ let(:assets) { build_list(:asset, 20) }
26
+ let(:releases) do
27
+ (1..3).map do |i|
28
+ build(:detailed, :release, :time => (14 + i).days.ago, :assets => assets)
29
+ end
30
+ end
31
+ let(:snapshots) do
32
+ (1..3).map do |i|
33
+ build(:detailed, :snapshot, :time => (7 + i).days.ago, :assets => assets)
34
+ end
35
+ end
36
+ let(:betas) do
37
+ (1..3).map do |i|
38
+ build(:detailed, :beta, :time => (21 + i).days.ago, :assets => assets)
39
+ end
40
+ end
41
+ let(:alphas) do
42
+ (1..3).map do |i|
43
+ build(:detailed, :alpha, :time => (28 + i).days.ago, :assets => assets)
44
+ end
45
+ end
46
+ let(:latest_release) { build(:detailed, :release, :time => 2.days.ago, :assets => assets) }
47
+ let(:latest_snapshot) { build(:detailed, :snapshot, :time => 1.days.ago, :assets => assets) }
48
+ let(:versions) { releases + snapshots + betas + alphas << latest_release << latest_snapshot }
49
+ let(:manifest) { build(:manifest, :versions => versions, :latest_release_id => latest_release.id, :latest_snapshot_id => latest_snapshot.id) }
50
+ let(:manifest_document) { build(:manifest_document, :source => manifest).document }
51
+ subject(:cli) { Lapis::Minecraft::Versioning::CLI.start(argv) }
52
+
53
+ before(:each) do
54
+ stub_request(:get, Lapis::Minecraft::Versioning::VersionList::OFFICIAL_MANIFEST_URL).to_return(status: 200, body: manifest_document, headers: {})
55
+ versions.each do |version|
56
+ version_document = build(:version_document, :source => version).document
57
+ stub_request(:get, version.url).to_return(status: 200, body: version_document, headers: {})
58
+ asset_index_document = build(:asset_index_document, :assets => assets).document
59
+ stub_request(:get, version.asset_index.url).to_return(status: 200, body: asset_index_document, headers: {})
60
+ end
61
+ end
62
+
63
+ describe '#list' do
64
+ let(:argv) { %w(list) }
65
+
66
+ it 'outputs all versions' do
67
+ regexp = any_order_regexp(versions.map(&:id))
68
+ expect { cli }.to output(regexp).to_stdout
69
+ end
70
+
71
+ context 'with release type' do
72
+ let(:argv) { %w(list release) }
73
+
74
+ it 'outputs all release versions' do
75
+ regexp = any_order_regexp(releases.map(&:id))
76
+ expect { cli }.to output(regexp).to_stdout
77
+ end
78
+
79
+ it 'does not output non-release versions' do
80
+ versions = snapshots + betas + alphas
81
+ regexp = any_order_regexp(versions.map(&:id))
82
+ expect { cli }.to_not output(regexp).to_stdout
83
+ end
84
+ end
85
+
86
+ context 'with snapshot type' do
87
+ let(:argv) { %w(list snapshot) }
88
+
89
+ it 'outputs all snapshot versions' do
90
+ regexp = any_order_regexp(snapshots.map(&:id))
91
+ expect { cli }.to output(regexp).to_stdout
92
+ end
93
+
94
+ it 'does not output non-snapshot versions' do
95
+ versions = releases + betas + alphas
96
+ regexp = any_order_regexp(versions.map(&:id))
97
+ expect { cli }.to_not output(regexp).to_stdout
98
+ end
99
+ end
100
+
101
+ context 'with beta type' do
102
+ let(:argv) { %w(list beta) }
103
+
104
+ it 'outputs all beta versions' do
105
+ regexp = any_order_regexp(betas.map(&:id))
106
+ expect { cli }.to output(regexp).to_stdout
107
+ end
108
+
109
+ it 'does not output non-beta versions' do
110
+ versions = releases + snapshots + alphas
111
+ regexp = any_order_regexp(versions.map(&:id))
112
+ expect { cli }.to_not output(regexp).to_stdout
113
+ end
114
+ end
115
+
116
+ context 'with alpha type' do
117
+ let(:argv) { %w(list alpha) }
118
+
119
+ it 'outputs all alpha versions' do
120
+ regexp = any_order_regexp(alphas.map(&:id))
121
+ expect { cli }.to output(regexp).to_stdout
122
+ end
123
+
124
+ it 'does not output non-release versions' do
125
+ versions = releases + snapshots + betas
126
+ regexp = any_order_regexp(versions.map(&:id))
127
+ expect { cli }.to_not output(regexp).to_stdout
128
+ end
129
+ end
130
+
131
+ context 'with all type' do
132
+ let(:argv) { %w(list all) }
133
+
134
+ it 'outputs all versions' do
135
+ regexp = any_order_regexp(versions.map(&:id))
136
+ expect { cli }.to output(regexp).to_stdout
137
+ end
138
+ end
139
+ end
140
+
141
+ describe '#info' do
142
+ let(:version) { releases.first }
143
+ let(:argv) { ['info', version.id] }
144
+
145
+ it 'outputs the version ID' do
146
+ regexp = Regexp.new(Regexp.escape(version.id))
147
+ expect { cli }.to output(regexp).to_stdout
148
+ end
149
+
150
+ it 'outputs the type' do
151
+ expect { cli }.to output(/#{version.type}/i).to_stdout
152
+ end
153
+
154
+ it 'outputs the time' do
155
+ regexp = Regexp.new(Regexp.escape(version.time.to_s))
156
+ expect { cli }.to output(regexp).to_stdout
157
+ end
158
+
159
+ context 'asset index' do
160
+ let(:index) { version.asset_index }
161
+
162
+ it 'outputs the index name' do
163
+ regexp = Regexp.new("assets?\\W+(index\\W+)?" + Regexp.escape(index.id), Regexp::IGNORECASE)
164
+ expect { cli }.to output(regexp).to_stdout
165
+ end
166
+
167
+ it 'outputs the total size' do
168
+ expect { cli }.to output(/size\W+#{index.total_size}/i).to_stdout
169
+ end
170
+ end
171
+
172
+ context 'launcher properties' do
173
+ let(:launcher) { version.launcher_properties }
174
+
175
+ it 'outputs the main class' do
176
+ regexp = Regexp.new(Regexp.escape(launcher.main_class))
177
+ expect { cli }.to output(regexp).to_stdout
178
+ end
179
+
180
+ it 'outputs the arguments' do
181
+ arg_str = launcher.arguments.join(' ')
182
+ regexp = Regexp.new(Regexp.escape(arg_str))
183
+ expect { cli }.to output(regexp).to_stdout
184
+ end
185
+
186
+ it 'outputs the minimum version' do
187
+ regexp = Regexp.new("launcher\\W+(version\\W+)?" + Regexp.escape(launcher.minimum_version.to_s), Regexp::IGNORECASE)
188
+ expect { cli }.to output(regexp).to_stdout
189
+ end
190
+ end
191
+ end
192
+
193
+ describe '#client' do
194
+ let(:version) { releases.first }
195
+ let(:argv) { ['client', version.id] }
196
+
197
+ it 'outputs the client URL' do
198
+ expect { cli }.to output(version.client_download.url + "\n").to_stdout
199
+ end
200
+ end
201
+
202
+ describe '#server' do
203
+ let(:version) { releases.first }
204
+ let(:argv) { ['server', version.id] }
205
+
206
+ it 'outputs the server URL' do
207
+ expect { cli }.to output(version.server_download.url + "\n").to_stdout
208
+ end
209
+ end
210
+
211
+ describe '#assets' do
212
+ let(:version) { releases.first }
213
+ let(:argv) { ['assets', version.id] }
214
+
215
+ it 'outputs all asset paths' do
216
+ regexp = any_order_regexp_bounds(assets.map(&:path))
217
+ expect { cli }.to output(regexp).to_stdout
218
+ end
219
+
220
+ it 'outputs all asset sizes' do
221
+ regexp = any_order_regexp_bounds(assets.map(&:size))
222
+ expect { cli }.to output(regexp).to_stdout
223
+ end
224
+
225
+ it 'outputs all asset hashes' do
226
+ regexp = any_order_regexp_bounds(assets.map(&:sha1))
227
+ expect { cli }.to output(regexp).to_stdout
228
+ end
229
+ end
230
+
231
+ describe '#libraries' do
232
+ let(:version) { releases.first }
233
+ let(:argv) { ['libraries', version.id] }
234
+
235
+ it 'outputs all library names' do
236
+ regexp = any_order_regexp(version.libraries.map(&:name))
237
+ expect { cli }.to output(regexp).to_stdout
238
+ end
239
+ end
240
+
241
+ describe '#latest_id' do
242
+ let(:version) { latest_release }
243
+ let(:argv) { %w(latest-id) }
244
+
245
+ it 'outputs the latest release ID' do
246
+ expect { cli }.to output(version.id + "\n").to_stdout
247
+ end
248
+
249
+ context 'with release type' do
250
+ let(:argv) { %w(latest-id release) }
251
+
252
+ it 'outputs the latest release ID' do
253
+ expect { cli }.to output(version.id + "\n").to_stdout
254
+ end
255
+ end
256
+
257
+ context 'with snapshot type' do
258
+ let(:version) { latest_snapshot }
259
+ let(:argv) { %w(latest-id snapshot) }
260
+
261
+ it 'outputs the latest snapshot ID' do
262
+ expect { cli }.to output(version.id + "\n").to_stdout
263
+ end
264
+ end
265
+
266
+ context 'with beta type' do
267
+ let(:version) { betas.max_by { |v| v.time } }
268
+ let(:argv) { %w(latest-id beta) }
269
+
270
+ it 'outputs the latest beta ID' do
271
+ expect { cli }.to output(version.id + "\n").to_stdout
272
+ end
273
+ end
274
+
275
+ context 'with alpha type' do
276
+ let(:version) { alphas.max_by { |v| v.time } }
277
+ let(:argv) { %w(latest-id alpha) }
278
+
279
+ it 'outputs the latest alpha ID' do
280
+ expect { cli }.to output(version.id + "\n").to_stdout
281
+ end
282
+ end
283
+
284
+ context 'with any type' do
285
+ let(:version) { versions.max_by { |v| v.time } }
286
+ let(:argv) { %w(latest-id any) }
287
+
288
+ it 'outputs the latest version ID' do
289
+ expect { cli }.to output(version.id + "\n").to_stdout
290
+ end
291
+ end
292
+ end
293
+
294
+ describe '#latest' do
295
+ let(:version) { latest_release }
296
+ let(:argv) { %w(latest) }
297
+
298
+ it 'outputs the version ID' do
299
+ regexp = Regexp.new(Regexp.escape(version.id))
300
+ expect { cli }.to output(regexp).to_stdout
301
+ end
302
+
303
+ it 'outputs the type' do
304
+ expect { cli }.to output(/#{version.type}/i).to_stdout
305
+ end
306
+
307
+ it 'outputs the time' do
308
+ regexp = Regexp.new(Regexp.escape(version.time.to_s))
309
+ expect { cli }.to output(regexp).to_stdout
310
+ end
311
+
312
+ context 'asset index' do
313
+ let(:index) { version.asset_index }
314
+
315
+ it 'outputs the index name' do
316
+ regexp = Regexp.new("assets?\\W+(index\\W+)?" + Regexp.escape(index.id), Regexp::IGNORECASE)
317
+ expect { cli }.to output(regexp).to_stdout
318
+ end
319
+
320
+ it 'outputs the total size' do
321
+ expect { cli }.to output(/size\W+#{index.total_size}/i).to_stdout
322
+ end
323
+ end
324
+
325
+ context 'launcher properties' do
326
+ let(:launcher) { version.launcher_properties }
327
+
328
+ it 'outputs the main class' do
329
+ regexp = Regexp.new(Regexp.escape(launcher.main_class))
330
+ expect { cli }.to output(regexp).to_stdout
331
+ end
332
+
333
+ it 'outputs the arguments' do
334
+ arg_str = launcher.arguments.join(' ')
335
+ regexp = Regexp.new(Regexp.escape(arg_str))
336
+ expect { cli }.to output(regexp).to_stdout
337
+ end
338
+
339
+ it 'outputs the minimum version' do
340
+ regexp = Regexp.new("launcher\\W+(version\\W+)?" + Regexp.escape(launcher.minimum_version.to_s), Regexp::IGNORECASE)
341
+ expect { cli }.to output(regexp).to_stdout
342
+ end
343
+ end
344
+
345
+ context 'with release type' do
346
+ let(:version) { latest_release }
347
+ let(:argv) { %w(latest release) }
348
+
349
+ it 'outputs the version ID' do
350
+ regexp = Regexp.new(Regexp.escape(version.id))
351
+ expect { cli }.to output(regexp).to_stdout
352
+ end
353
+
354
+ it 'outputs the type' do
355
+ expect { cli }.to output(/#{version.type}/i).to_stdout
356
+ end
357
+
358
+ it 'outputs the time' do
359
+ regexp = Regexp.new(Regexp.escape(version.time.to_s))
360
+ expect { cli }.to output(regexp).to_stdout
361
+ end
362
+
363
+ context 'asset index' do
364
+ let(:index) { version.asset_index }
365
+
366
+ it 'outputs the index name' do
367
+ regexp = Regexp.new("assets?\\W+(index\\W+)?" + Regexp.escape(index.id), Regexp::IGNORECASE)
368
+ expect { cli }.to output(regexp).to_stdout
369
+ end
370
+
371
+ it 'outputs the total size' do
372
+ expect { cli }.to output(/size\W+#{index.total_size}/i).to_stdout
373
+ end
374
+ end
375
+
376
+ context 'launcher properties' do
377
+ let(:launcher) { version.launcher_properties }
378
+
379
+ it 'outputs the main class' do
380
+ regexp = Regexp.new(Regexp.escape(launcher.main_class))
381
+ expect { cli }.to output(regexp).to_stdout
382
+ end
383
+
384
+ it 'outputs the arguments' do
385
+ arg_str = launcher.arguments.join(' ')
386
+ regexp = Regexp.new(Regexp.escape(arg_str))
387
+ expect { cli }.to output(regexp).to_stdout
388
+ end
389
+
390
+ it 'outputs the minimum version' do
391
+ regexp = Regexp.new("launcher\\W+(version\\W+)?" + Regexp.escape(launcher.minimum_version.to_s), Regexp::IGNORECASE)
392
+ expect { cli }.to output(regexp).to_stdout
393
+ end
394
+ end
395
+ end
396
+
397
+ context 'with snapshot type' do
398
+ let(:version) { latest_snapshot }
399
+ let(:argv) { %w(latest snapshot) }
400
+
401
+ it 'outputs the version ID' do
402
+ regexp = Regexp.new(Regexp.escape(version.id))
403
+ expect { cli }.to output(regexp).to_stdout
404
+ end
405
+
406
+ it 'outputs the type' do
407
+ expect { cli }.to output(/#{version.type}/i).to_stdout
408
+ end
409
+
410
+ it 'outputs the time' do
411
+ regexp = Regexp.new(Regexp.escape(version.time.to_s))
412
+ expect { cli }.to output(regexp).to_stdout
413
+ end
414
+
415
+ context 'asset index' do
416
+ let(:index) { version.asset_index }
417
+
418
+ it 'outputs the index name' do
419
+ regexp = Regexp.new("assets?\\W+(index\\W+)?" + Regexp.escape(index.id), Regexp::IGNORECASE)
420
+ expect { cli }.to output(regexp).to_stdout
421
+ end
422
+
423
+ it 'outputs the total size' do
424
+ expect { cli }.to output(/size\W+#{index.total_size}/i).to_stdout
425
+ end
426
+ end
427
+
428
+ context 'launcher properties' do
429
+ let(:launcher) { version.launcher_properties }
430
+
431
+ it 'outputs the main class' do
432
+ regexp = Regexp.new(Regexp.escape(launcher.main_class))
433
+ expect { cli }.to output(regexp).to_stdout
434
+ end
435
+
436
+ it 'outputs the arguments' do
437
+ arg_str = launcher.arguments.join(' ')
438
+ regexp = Regexp.new(Regexp.escape(arg_str))
439
+ expect { cli }.to output(regexp).to_stdout
440
+ end
441
+
442
+ it 'outputs the minimum version' do
443
+ regexp = Regexp.new("launcher\\W+(version\\W+)?" + Regexp.escape(launcher.minimum_version.to_s), Regexp::IGNORECASE)
444
+ expect { cli }.to output(regexp).to_stdout
445
+ end
446
+ end
447
+ end
448
+
449
+ context 'with beta type' do
450
+ let(:version) { betas.max_by { |v| v.time } }
451
+ let(:argv) { %w(latest beta) }
452
+
453
+ it 'outputs the version ID' do
454
+ regexp = Regexp.new(Regexp.escape(version.id))
455
+ expect { cli }.to output(regexp).to_stdout
456
+ end
457
+
458
+ it 'outputs the type' do
459
+ expect { cli }.to output(/#{version.type}/i).to_stdout
460
+ end
461
+
462
+ it 'outputs the time' do
463
+ regexp = Regexp.new(Regexp.escape(version.time.to_s))
464
+ expect { cli }.to output(regexp).to_stdout
465
+ end
466
+
467
+ context 'asset index' do
468
+ let(:index) { version.asset_index }
469
+
470
+ it 'outputs the index name' do
471
+ regexp = Regexp.new("assets?\\W+(index\\W+)?" + Regexp.escape(index.id), Regexp::IGNORECASE)
472
+ expect { cli }.to output(regexp).to_stdout
473
+ end
474
+
475
+ it 'outputs the total size' do
476
+ expect { cli }.to output(/size\W+#{index.total_size}/i).to_stdout
477
+ end
478
+ end
479
+
480
+ context 'launcher properties' do
481
+ let(:launcher) { version.launcher_properties }
482
+
483
+ it 'outputs the main class' do
484
+ regexp = Regexp.new(Regexp.escape(launcher.main_class))
485
+ expect { cli }.to output(regexp).to_stdout
486
+ end
487
+
488
+ it 'outputs the arguments' do
489
+ arg_str = launcher.arguments.join(' ')
490
+ regexp = Regexp.new(Regexp.escape(arg_str))
491
+ expect { cli }.to output(regexp).to_stdout
492
+ end
493
+
494
+ it 'outputs the minimum version' do
495
+ regexp = Regexp.new("launcher\\W+(version\\W+)?" + Regexp.escape(launcher.minimum_version.to_s), Regexp::IGNORECASE)
496
+ expect { cli }.to output(regexp).to_stdout
497
+ end
498
+ end
499
+ end
500
+
501
+ context 'with alpha type' do
502
+ let(:version) { alphas.max_by { |v| v.time } }
503
+ let(:argv) { %w(latest alpha) }
504
+
505
+ it 'outputs the version ID' do
506
+ regexp = Regexp.new(Regexp.escape(version.id))
507
+ expect { cli }.to output(regexp).to_stdout
508
+ end
509
+
510
+ it 'outputs the type' do
511
+ expect { cli }.to output(/#{version.type}/i).to_stdout
512
+ end
513
+
514
+ it 'outputs the time' do
515
+ regexp = Regexp.new(Regexp.escape(version.time.to_s))
516
+ expect { cli }.to output(regexp).to_stdout
517
+ end
518
+
519
+ context 'asset index' do
520
+ let(:index) { version.asset_index }
521
+
522
+ it 'outputs the index name' do
523
+ regexp = Regexp.new("assets?\\W+(index\\W+)?" + Regexp.escape(index.id), Regexp::IGNORECASE)
524
+ expect { cli }.to output(regexp).to_stdout
525
+ end
526
+
527
+ it 'outputs the total size' do
528
+ expect { cli }.to output(/size\W+#{index.total_size}/i).to_stdout
529
+ end
530
+ end
531
+
532
+ context 'launcher properties' do
533
+ let(:launcher) { version.launcher_properties }
534
+
535
+ it 'outputs the main class' do
536
+ regexp = Regexp.new(Regexp.escape(launcher.main_class))
537
+ expect { cli }.to output(regexp).to_stdout
538
+ end
539
+
540
+ it 'outputs the arguments' do
541
+ arg_str = launcher.arguments.join(' ')
542
+ regexp = Regexp.new(Regexp.escape(arg_str))
543
+ expect { cli }.to output(regexp).to_stdout
544
+ end
545
+
546
+ it 'outputs the minimum version' do
547
+ regexp = Regexp.new("launcher\\W+(version\\W+)?" + Regexp.escape(launcher.minimum_version.to_s), Regexp::IGNORECASE)
548
+ expect { cli }.to output(regexp).to_stdout
549
+ end
550
+ end
551
+ end
552
+
553
+ context 'with any type' do
554
+ let(:version) { versions.max_by { |v| v.time } }
555
+ let(:argv) { %w(latest any) }
556
+
557
+ it 'outputs the version ID' do
558
+ regexp = Regexp.new(Regexp.escape(version.id))
559
+ expect { cli }.to output(regexp).to_stdout
560
+ end
561
+
562
+ it 'outputs the type' do
563
+ expect { cli }.to output(/#{version.type}/i).to_stdout
564
+ end
565
+
566
+ it 'outputs the time' do
567
+ regexp = Regexp.new(Regexp.escape(version.time.to_s))
568
+ expect { cli }.to output(regexp).to_stdout
569
+ end
570
+
571
+ context 'asset index' do
572
+ let(:index) { version.asset_index }
573
+
574
+ it 'outputs the index name' do
575
+ regexp = Regexp.new("assets?\\W+(index\\W+)?" + Regexp.escape(index.id), Regexp::IGNORECASE)
576
+ expect { cli }.to output(regexp).to_stdout
577
+ end
578
+
579
+ it 'outputs the total size' do
580
+ expect { cli }.to output(/size\W+#{index.total_size}/i).to_stdout
581
+ end
582
+ end
583
+
584
+ context 'launcher properties' do
585
+ let(:launcher) { version.launcher_properties }
586
+
587
+ it 'outputs the main class' do
588
+ regexp = Regexp.new(Regexp.escape(launcher.main_class))
589
+ expect { cli }.to output(regexp).to_stdout
590
+ end
591
+
592
+ it 'outputs the arguments' do
593
+ arg_str = launcher.arguments.join(' ')
594
+ regexp = Regexp.new(Regexp.escape(arg_str))
595
+ expect { cli }.to output(regexp).to_stdout
596
+ end
597
+
598
+ it 'outputs the minimum version' do
599
+ regexp = Regexp.new("launcher\\W+(version\\W+)?" + Regexp.escape(launcher.minimum_version.to_s), Regexp::IGNORECASE)
600
+ expect { cli }.to output(regexp).to_stdout
601
+ end
602
+ end
603
+ end
604
+ end
605
+
606
+ describe '--url' do
607
+ let(:url) { 'http://example.com/foobar/baz/manifest.json' }
608
+ let(:argv) { ['list', '--url', url] }
609
+
610
+ before(:each) do
611
+ stub_request(:get, url).to_return(status: 200, body: manifest_document, headers: {})
612
+ end
613
+
614
+ it 'uses the specified URL' do
615
+ expect { cli }.to output.to_stdout # Not important expectation to capture output.
616
+ expect(cli).to have_requested(:get, url)
617
+ end
618
+
619
+ it 'does not use the default URL' do
620
+ expect { cli }.to output.to_stdout # Not important expectation to capture output.
621
+ expect(cli).to_not have_requested(:get, Lapis::Minecraft::Versioning::VersionList::OFFICIAL_MANIFEST_URL)
622
+ end
623
+ end
624
+
625
+ end
@@ -30,6 +30,27 @@ RSpec.describe Lapis::Minecraft::Versioning::Manifest do
30
30
  end
31
31
  end
32
32
 
33
+ describe '#[]' do
34
+ subject { manifest[id] }
35
+
36
+ context 'with an existing version' do
37
+ let(:version) { versions.last }
38
+ let(:id) { version.id }
39
+
40
+ it 'returns the version' do
41
+ is_expected.to eq version
42
+ end
43
+ end
44
+
45
+ context 'with a non-existent version' do
46
+ let(:id) { 'Foobarbaz-non-existent' }
47
+
48
+ it 'returns nil' do
49
+ is_expected.to eq nil
50
+ end
51
+ end
52
+ end
53
+
33
54
  describe '#latest_release' do
34
55
  subject { manifest.latest_release }
35
56
 
@@ -47,6 +47,27 @@ RSpec.describe Lapis::Minecraft::Versioning::VersionList do
47
47
  end
48
48
  end
49
49
 
50
+ describe '#[]' do
51
+ subject { version_list[id] }
52
+
53
+ context 'with an existing version' do
54
+ let(:version) { betas.first }
55
+ let(:id) { version.id }
56
+
57
+ it 'returns the version' do
58
+ expect(subject.id).to eq version.id
59
+ end
60
+ end
61
+
62
+ context 'with a non-existent version' do
63
+ let(:id) { 'Foobarbaz-non-existent' }
64
+
65
+ it 'returns nil' do
66
+ is_expected.to eq nil
67
+ end
68
+ end
69
+ end
70
+
50
71
  describe '#latest_release' do
51
72
  subject { version_list.latest_release }
52
73
 
data/spec/spec_helper.rb CHANGED
@@ -80,7 +80,7 @@ end
80
80
  require_relative '../lib/lapis/minecraft/versioning'
81
81
 
82
82
  # Mock web requests.
83
- WebMock.disable_net_connect!
83
+ WebMock.disable_net_connect!(:allow => 'codeclimate.com')
84
84
 
85
85
  # Include helpers.
86
86
  require_relative 'time_helper'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lapis-minecraft-versioning
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Miller
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-10 00:00:00.000000000 Z
11
+ date: 2016-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpclient
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: thor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -155,7 +169,8 @@ description: |-
155
169
  Includes a command-line utility as well.
156
170
  email:
157
171
  - bluepixelmike@gmail.com
158
- executables: []
172
+ executables:
173
+ - minecraft-versions
159
174
  extensions: []
160
175
  extra_rdoc_files: []
161
176
  files:
@@ -169,6 +184,7 @@ files:
169
184
  - README.md
170
185
  - Rakefile
171
186
  - bin/console
187
+ - bin/minecraft-versions
172
188
  - bin/setup
173
189
  - lapis-minecraft-versioning.gemspec
174
190
  - lib/lapis/minecraft/version.rb
@@ -176,6 +192,7 @@ files:
176
192
  - lib/lapis/minecraft/versioning/asset.rb
177
193
  - lib/lapis/minecraft/versioning/asset_index.rb
178
194
  - lib/lapis/minecraft/versioning/basic.rb
195
+ - lib/lapis/minecraft/versioning/cli.rb
179
196
  - lib/lapis/minecraft/versioning/detailed.rb
180
197
  - lib/lapis/minecraft/versioning/launcher_properties.rb
181
198
  - lib/lapis/minecraft/versioning/library.rb
@@ -211,6 +228,7 @@ files:
211
228
  - spec/lapis/minecraft/versioning/asset_index_spec.rb
212
229
  - spec/lapis/minecraft/versioning/asset_spec.rb
213
230
  - spec/lapis/minecraft/versioning/basic_spec.rb
231
+ - spec/lapis/minecraft/versioning/cli_spec.rb
214
232
  - spec/lapis/minecraft/versioning/detailed_spec.rb
215
233
  - spec/lapis/minecraft/versioning/launcher_properties_spec.rb
216
234
  - spec/lapis/minecraft/versioning/library_spec.rb
@@ -271,6 +289,7 @@ test_files:
271
289
  - spec/lapis/minecraft/versioning/asset_index_spec.rb
272
290
  - spec/lapis/minecraft/versioning/asset_spec.rb
273
291
  - spec/lapis/minecraft/versioning/basic_spec.rb
292
+ - spec/lapis/minecraft/versioning/cli_spec.rb
274
293
  - spec/lapis/minecraft/versioning/detailed_spec.rb
275
294
  - spec/lapis/minecraft/versioning/launcher_properties_spec.rb
276
295
  - spec/lapis/minecraft/versioning/library_spec.rb