mmi 0.2.2 → 0.2.3
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.adoc +5 -9
- data/exe/mmi +1 -1
- data/lib/mmi/asset.rb +16 -0
- data/lib/mmi/assets_processor.rb +13 -44
- data/lib/mmi/constants.rb +14 -0
- data/lib/mmi/content_hash/base.rb +9 -0
- data/lib/mmi/content_hash/sha512.rb +25 -0
- data/lib/mmi/install_record.rb +72 -0
- data/lib/mmi/install_utils.rb +24 -0
- data/lib/mmi/interactive/assets.rb +62 -54
- data/lib/mmi/interactive/modloader.rb +16 -16
- data/lib/mmi/interactive/updater.rb +1 -1
- data/lib/mmi/mod_file_processor.rb +7 -59
- data/lib/mmi/modloader/fabric.rb +38 -47
- data/lib/mmi/modloader/none.rb +5 -1
- data/lib/mmi/property_attributes.rb +192 -0
- data/lib/mmi/source/github.rb +13 -54
- data/lib/mmi/source/modrinth.rb +18 -51
- data/lib/mmi/source/url.rb +8 -37
- data/lib/mmi/version.rb +1 -1
- data/lib/mmi.rb +0 -11
- metadata +14 -93
- data/lib/mmi/cached_download.rb +0 -59
- data/lib/mmi/option_attributes.rb +0 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84c944c267d13afff856179fd1a089d1ff6213a865e256f6c2678ed7f24e09ee
|
4
|
+
data.tar.gz: 3da84073781c7e7a185e3e9f03fba104649c1b695b25bc4aa74e90b6cdc8e6da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1bf673321a3ccdef9c310af18e841b0a74278154ee83f5cc37c777a56ba1a370edf77b9f2d589f62b153ed0f12884f527e0ce6ba7045711be17fcaf77e1874ea
|
7
|
+
data.tar.gz: 3fdd21c1b7f0e002e12d4851f7369697fb2d5b61685ef26b44a54643ef48ffb87b2a7297c639def93c5e30972da147ecca10918235d2d63bb625768dc04ef23e
|
data/README.adoc
CHANGED
@@ -115,15 +115,11 @@ There, within the same minor version, backwards compatibility can be expected, b
|
|
115
115
|
|
116
116
|
== Contributing
|
117
117
|
|
118
|
-
Contributions are very welcome,
|
119
|
-
|
120
|
-
In case you want to implement a feature, it would be best to create an issue beforehand so that we can discuss it.
|
121
|
-
This reduces the chance of a pull request being rejected.
|
118
|
+
Contributions are very welcome, including feature/bug requests.
|
119
|
+
Before implementing a (larger) feature, consider opening a ticket to discuss the implementation or feature.
|
122
120
|
|
123
121
|
If you intend to create a pull request, please choose a branch name describing its changes (i.e. not some generic term like `master` or `fix`, but e.g. `fix_typo` or `add_interactive_update_command`).
|
124
122
|
|
125
|
-
Please
|
126
|
-
Some basic rules are specified in the `.editorconfig` file,
|
127
|
-
|
128
|
-
There most likely are a lot of Rubocop rules that are currently not triggered and therefore not configured.
|
129
|
-
In such a case, either try to derive a style from existing code or feel free to ask.
|
123
|
+
Please try to follow the existing coding style as close as possible.
|
124
|
+
Some basic rules are specified in the `.editorconfig` file, and Rubocop is also available to help.
|
125
|
+
Every commit should pass Rubocop’s inspection.
|
data/exe/mmi
CHANGED
data/lib/mmi/asset.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'mmi/property_attributes'
|
2
|
+
require 'mmi/source/github'
|
3
|
+
require 'mmi/source/modrinth'
|
4
|
+
require 'mmi/source/url'
|
5
|
+
|
6
|
+
module Mmi
|
7
|
+
class Asset
|
8
|
+
prepend Mmi::PropertyAttributes
|
9
|
+
|
10
|
+
property :source, type: {field: 'type', types: {'github' => Source::Github, 'modrinth' => Source::Modrinth, 'url' => Source::Url}}
|
11
|
+
|
12
|
+
def install(install_record)
|
13
|
+
source.install(install_record)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/mmi/assets_processor.rb
CHANGED
@@ -1,53 +1,22 @@
|
|
1
|
-
require 'mmi/
|
2
|
-
require 'mmi/
|
3
|
-
require 'mmi/
|
4
|
-
require 'mmi/
|
1
|
+
require 'mmi/constants'
|
2
|
+
require 'mmi/property_attributes'
|
3
|
+
require 'mmi/asset'
|
4
|
+
require 'mmi/install_record'
|
5
5
|
|
6
6
|
module Mmi
|
7
7
|
class AssetsProcessor
|
8
|
-
|
8
|
+
prepend PropertyAttributes
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
attr_reader :parsed_items
|
14
|
-
|
15
|
-
def initialize(options)
|
16
|
-
@options = options
|
17
|
-
|
18
|
-
parse!
|
19
|
-
end
|
20
|
-
|
21
|
-
def parse!
|
22
|
-
if self.items.is_a?(Array)
|
23
|
-
@parsed_items = self.items.map.with_index do |asset, index|
|
24
|
-
source = asset['source']
|
25
|
-
|
26
|
-
if source
|
27
|
-
type = source['type']
|
28
|
-
|
29
|
-
case type
|
30
|
-
when 'github'
|
31
|
-
Source::Github.new(source)
|
32
|
-
when 'modrinth'
|
33
|
-
Source::Modrinth.new(source)
|
34
|
-
when 'url'
|
35
|
-
Source::Url.new(source)
|
36
|
-
else
|
37
|
-
raise Mmi::InvalidAttributeError, %Q(Invalid "source.type" in asset #{index.inspect}: #{type.inspect})
|
38
|
-
end
|
39
|
-
else
|
40
|
-
raise Mmi::MissingAttributeError, %Q(Missing "source" in asset #{index.inspect}.)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
else
|
44
|
-
raise Mmi::InvalidAttributeError, %Q(Invalid "assets": expected Array or nothing, got #{self.items.inspect}.)
|
45
|
-
end
|
46
|
-
end
|
10
|
+
property :profile_dir, default: Mmi::Constants.minecraft_dir
|
11
|
+
property :items, type: Asset, default: []
|
47
12
|
|
48
13
|
def install
|
49
|
-
|
50
|
-
|
14
|
+
InstallRecord.new.tap do |install_record|
|
15
|
+
self.items.each do |asset|
|
16
|
+
asset.install(install_record)
|
17
|
+
end
|
18
|
+
|
19
|
+
install_record.install(self.profile_dir)
|
51
20
|
end
|
52
21
|
end
|
53
22
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'digest'
|
2
|
+
|
3
|
+
require 'mmi/content_hash/base'
|
4
|
+
|
5
|
+
module Mmi
|
6
|
+
module ContentHash
|
7
|
+
class Sha512 < Base
|
8
|
+
attr_accessor :hex_digest
|
9
|
+
|
10
|
+
def initialize(hex_digest)
|
11
|
+
super()
|
12
|
+
|
13
|
+
self.hex_digest = hex_digest
|
14
|
+
end
|
15
|
+
|
16
|
+
def match_file?(file_path)
|
17
|
+
Digest::SHA512.hexdigest(File.read(file_path)) == self.hex_digest
|
18
|
+
end
|
19
|
+
|
20
|
+
def ==(other)
|
21
|
+
self.class == other.class && self.hex_digest == other.hex_digest
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'psych'
|
2
|
+
|
3
|
+
require 'mmi/content_hash/base'
|
4
|
+
|
5
|
+
module Mmi
|
6
|
+
class InstallRecord
|
7
|
+
RecordEntry = Struct.new(:url, :content_hash)
|
8
|
+
|
9
|
+
RECORD_FILE = '.mmi_install_record'.freeze
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@record = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def add(url, relative_path, content_hash:)
|
16
|
+
raise 'content_hash must be nil or an instance of Mmi::ContentHash::Base' unless content_hash.nil? || content_hash.is_a?(Mmi::ContentHash::Base)
|
17
|
+
|
18
|
+
@record[relative_path] = RecordEntry.new(url, content_hash)
|
19
|
+
end
|
20
|
+
|
21
|
+
def install(dir)
|
22
|
+
old_record = self.class.parse_record_file(dir) || {}
|
23
|
+
|
24
|
+
@record.each do |relative_path, entry|
|
25
|
+
target_file = File.expand_path(relative_path, dir)
|
26
|
+
|
27
|
+
if old_record[relative_path] != entry || (File.exist?(target_file) && !entry.content_hash&.match_file?(target_file))
|
28
|
+
Mmi.info "Downloading #{entry.url.inspect} into #{target_file.inspect}."
|
29
|
+
|
30
|
+
begin
|
31
|
+
Mmi::InstallUtils.download_to_file(entry.url, target_file, entry.content_hash)
|
32
|
+
rescue OpenURI::HTTPError => e
|
33
|
+
Mmi.fail! "Error when requesting asset.\n#{e.inspect}"
|
34
|
+
end
|
35
|
+
else
|
36
|
+
Mmi.info "Skipping #{entry.url.inspect} because it is already present at #{target_file.inspect}."
|
37
|
+
end
|
38
|
+
|
39
|
+
old_record.delete(relative_path)
|
40
|
+
end
|
41
|
+
|
42
|
+
old_record.each do |relative_path, _|
|
43
|
+
target_file = File.expand_path(relative_path, dir)
|
44
|
+
|
45
|
+
File.delete(target_file) if File.exist?(target_file)
|
46
|
+
end
|
47
|
+
|
48
|
+
File.write(File.expand_path(RECORD_FILE, dir), to_yaml)
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_yaml
|
52
|
+
Psych.dump(@record)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.parse_record_file(dir)
|
56
|
+
record_file = File.expand_path(RECORD_FILE, dir)
|
57
|
+
|
58
|
+
if File.exist?(record_file)
|
59
|
+
parsed_record = Psych.unsafe_load_file(record_file)
|
60
|
+
|
61
|
+
unless !parsed_record.is_a?(Hash) || parsed_record.keys.any?{|k| !k.is_a?(String)} && parsed_record.values.any?{|v| !v.is_a?(Record)}
|
62
|
+
parsed_record
|
63
|
+
else
|
64
|
+
Mmi.warn("Found invalid install record at #{record_file}. The file will be ignored.")
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
else
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'digest'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'open-uri'
|
4
|
+
|
5
|
+
require 'mmi/constants'
|
6
|
+
require 'mmi/content_hash/base'
|
7
|
+
|
8
|
+
module Mmi
|
9
|
+
module InstallUtils
|
10
|
+
class << self
|
11
|
+
def download_to_file(url, target_file, content_hash=nil)
|
12
|
+
raise 'content_hash must be nil or an instance of Mmi::ContentHash::Base' unless content_hash.nil? || content_hash.is_a?(Mmi::ContentHash::Base)
|
13
|
+
|
14
|
+
FileUtils.mkdir_p(File.dirname(target_file))
|
15
|
+
|
16
|
+
stream = URI.parse(url).open
|
17
|
+
|
18
|
+
IO.copy_stream(stream, target_file)
|
19
|
+
|
20
|
+
raise "Failed to match #{target_file} with #{content_hash.inspect}!" if content_hash && !content_hash.match_file?(target_file)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -8,12 +8,12 @@ module Mmi
|
|
8
8
|
module Assets
|
9
9
|
def update_assets
|
10
10
|
loop do
|
11
|
-
assets = processor.
|
11
|
+
assets = processor.assets.items
|
12
12
|
|
13
13
|
choice = CLI::UI::Prompt.ask('Which asset do you want to change?') do |handler|
|
14
14
|
assets.each do |asset|
|
15
|
-
handler.option(asset.display_name) do
|
16
|
-
asset
|
15
|
+
handler.option(asset.source.display_name) do
|
16
|
+
asset.source
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -27,12 +27,27 @@ module Mmi
|
|
27
27
|
when :add
|
28
28
|
add_asset
|
29
29
|
else
|
30
|
-
|
30
|
+
update_asset_source_version(choice)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
35
|
def add_asset
|
36
|
+
if (source = create_source)
|
37
|
+
asset = Mmi::Asset.parse({
|
38
|
+
'source' => source.to_h,
|
39
|
+
})
|
40
|
+
|
41
|
+
self.processor.assets['items'].push(asset.to_h)
|
42
|
+
self.processor.assets.parse!
|
43
|
+
else
|
44
|
+
CLI::UI.puts('Aborting asset addition. No change will be made.')
|
45
|
+
|
46
|
+
false
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def create_source
|
36
51
|
source_type = CLI::UI::Prompt.ask('Choose a source type.') do |handler|
|
37
52
|
%w[
|
38
53
|
github
|
@@ -45,80 +60,68 @@ module Mmi
|
|
45
60
|
handler.option('quit', &:to_sym)
|
46
61
|
end
|
47
62
|
|
48
|
-
|
63
|
+
source =
|
49
64
|
case source_type
|
50
65
|
when :quit
|
51
66
|
return false
|
52
67
|
when :github
|
53
68
|
options = {
|
54
|
-
'
|
55
|
-
|
56
|
-
'asset_id' => 0,
|
57
|
-
},
|
69
|
+
'type' => 'github',
|
70
|
+
'asset_id' => 0,
|
58
71
|
}
|
59
72
|
|
60
|
-
options['
|
61
|
-
options['
|
62
|
-
options['
|
63
|
-
options['
|
73
|
+
options['owner' ] = CLI::UI::Prompt.ask('Who is the owner of the source repository?').strip
|
74
|
+
options['repo' ] = CLI::UI::Prompt.ask('What is the name of the source repository?').strip
|
75
|
+
options['install_dir'] = CLI::UI::Prompt.ask('In which directory should the asset be placed?', default: 'mods').strip
|
76
|
+
options['filename' ] = CLI::UI::Prompt.ask('Under which filename should the asset be saved? (leave empty for release asset name)', allow_empty: true).strip.then do |filename|
|
64
77
|
filename == '' ? nil : filename
|
65
78
|
end
|
66
79
|
|
67
|
-
options
|
80
|
+
options.compact!
|
68
81
|
|
69
|
-
|
82
|
+
Mmi::Source::Github.parse(options)
|
70
83
|
when :modrinth
|
71
84
|
options = {
|
72
|
-
'
|
73
|
-
|
74
|
-
|
75
|
-
'version_file' => '0',
|
76
|
-
},
|
85
|
+
'type' => 'modrinth',
|
86
|
+
'version' => '0',
|
87
|
+
'version_file' => '0',
|
77
88
|
}
|
78
89
|
|
79
|
-
options['
|
80
|
-
options['
|
81
|
-
options['
|
90
|
+
options['name' ] = CLI::UI::Prompt.ask('What is the name of the mod in the Modrinth URL?').strip
|
91
|
+
options['install_dir'] = CLI::UI::Prompt.ask('In which directory should the asset be placed?', default: 'mods').strip
|
92
|
+
options['filename' ] = CLI::UI::Prompt.ask('Under which filename should the asset be saved? (leave empty for release asset name)', allow_empty: true).strip.then do |filename|
|
82
93
|
filename == '' ? nil : filename
|
83
94
|
end
|
84
95
|
|
85
|
-
options
|
96
|
+
options.compact!
|
86
97
|
|
87
|
-
|
98
|
+
Mmi::Source::Modrinth.parse(options)
|
88
99
|
when :url
|
89
100
|
options = {
|
90
|
-
'
|
91
|
-
'type' => 'url',
|
92
|
-
'url' => '',
|
93
|
-
},
|
101
|
+
'type' => 'url',
|
94
102
|
}
|
95
103
|
|
96
|
-
options['
|
97
|
-
options['
|
104
|
+
options['install_dir'] = CLI::UI::Prompt.ask('In which directory should the asset be placed?', default: 'mods').strip
|
105
|
+
options['filename' ] = CLI::UI::Prompt.ask('Under which filename should the asset be saved? (leave empty for release asset name)', allow_empty: true).strip.then do |filename|
|
98
106
|
filename == '' ? nil : filename
|
99
107
|
end
|
100
108
|
|
101
|
-
options
|
109
|
+
options.compact!
|
102
110
|
|
103
|
-
|
111
|
+
Mmi::Source::Url.parse(options)
|
104
112
|
end
|
105
113
|
|
106
|
-
if
|
107
|
-
|
108
|
-
self.processor.parsed_assets.parsed_items.push(source)
|
109
|
-
|
110
|
-
true
|
114
|
+
if update_asset_source_version(source)
|
115
|
+
source
|
111
116
|
else
|
112
|
-
|
113
|
-
|
114
|
-
false
|
117
|
+
nil
|
115
118
|
end
|
116
119
|
end
|
117
120
|
|
118
|
-
def
|
119
|
-
case
|
121
|
+
def update_asset_source_version(source)
|
122
|
+
case source
|
120
123
|
when Mmi::Source::Github
|
121
|
-
github_releases = Mmi::GithubApi.client.releases("#{
|
124
|
+
github_releases = Mmi::GithubApi.client.releases("#{source.owner}/#{source.repo}")
|
122
125
|
|
123
126
|
github_release = CLI::UI::Prompt.ask('Choose a release.') do |handler|
|
124
127
|
github_releases.select do |release|
|
@@ -150,10 +153,11 @@ module Mmi
|
|
150
153
|
when :quit
|
151
154
|
false
|
152
155
|
else
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
156
|
+
source.update_properties!({
|
157
|
+
release: nil,
|
158
|
+
file: nil,
|
159
|
+
asset_id: release_asset.id,
|
160
|
+
})
|
157
161
|
|
158
162
|
true
|
159
163
|
end
|
@@ -161,17 +165,17 @@ module Mmi
|
|
161
165
|
when Mmi::Source::Modrinth
|
162
166
|
mod_version = CLI::UI::Prompt.ask('Choose a version.') do |handler|
|
163
167
|
version_filter_parameters =
|
164
|
-
case processor.
|
168
|
+
case processor.modloader
|
165
169
|
when Mmi::Modloader::Fabric
|
166
170
|
{
|
167
171
|
loader: 'fabric',
|
168
|
-
game_version: processor.
|
172
|
+
game_version: processor.modloader.minecraft_version,
|
169
173
|
}
|
170
174
|
else
|
171
175
|
{}
|
172
176
|
end
|
173
177
|
|
174
|
-
|
178
|
+
source.cached_mod_versions(**version_filter_parameters).select do |version|
|
175
179
|
version['files'].any?
|
176
180
|
end.each do |version|
|
177
181
|
handler.option("#{version['name']} (for game versions #{version['game_versions'].join('/')})") do
|
@@ -200,14 +204,18 @@ module Mmi
|
|
200
204
|
when :quit
|
201
205
|
false
|
202
206
|
else
|
203
|
-
|
204
|
-
|
207
|
+
source.update_properties!({
|
208
|
+
version: mod_version['name'],
|
209
|
+
version_file: version_file['filename'],
|
210
|
+
})
|
205
211
|
|
206
212
|
true
|
207
213
|
end
|
208
214
|
end
|
209
215
|
when Mmi::Source::Url
|
210
|
-
|
216
|
+
url = CLI::UI::Prompt.ask('What is the URL of the file that should be downloaded?', default: source.url).strip
|
217
|
+
|
218
|
+
source.update_properties!({url: url})
|
211
219
|
else
|
212
220
|
CLI::UI.puts('This asset cannot be updated.', color: CLI::UI::Color::RED)
|
213
221
|
|
@@ -9,7 +9,7 @@ module Mmi
|
|
9
9
|
def update_modloader
|
10
10
|
choice = CLI::UI::Prompt.ask('What do you want to do?') do |handler|
|
11
11
|
[
|
12
|
-
(["Update current modloader #{self.processor.modloader['name']}", :update_current] unless self.processor.
|
12
|
+
(["Update current modloader #{self.processor.modloader['name']}", :update_current] unless self.processor.modloader.is_a?(Mmi::Modloader::None)),
|
13
13
|
['quit', :quit ],
|
14
14
|
].each do |name, result|
|
15
15
|
handler.option(name) do
|
@@ -29,7 +29,7 @@ module Mmi
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def update_modloader_current
|
32
|
-
ml = self.processor.
|
32
|
+
ml = self.processor.modloader
|
33
33
|
|
34
34
|
case ml
|
35
35
|
when Mmi::Modloader::None
|
@@ -38,12 +38,12 @@ module Mmi
|
|
38
38
|
loop do
|
39
39
|
choice = CLI::UI::Prompt.ask('What do you want to update?') do |handler|
|
40
40
|
[
|
41
|
-
['Installer version', :version
|
42
|
-
['Minecraft version', :
|
43
|
-
['Download Minecraft?', :
|
44
|
-
['Install directory', :install_dir
|
45
|
-
['Install type', :install_type],
|
46
|
-
['quit', :quit
|
41
|
+
['Installer version', :version ],
|
42
|
+
['Minecraft version', :minecraft_version ],
|
43
|
+
['Download Minecraft?', :download_minecraft],
|
44
|
+
['Install directory', :install_dir ],
|
45
|
+
['Install type', :install_type ],
|
46
|
+
['quit', :quit ],
|
47
47
|
].each do |name, result|
|
48
48
|
handler.option(name) do
|
49
49
|
result
|
@@ -65,9 +65,9 @@ module Mmi
|
|
65
65
|
when :quit
|
66
66
|
# Pass.
|
67
67
|
else
|
68
|
-
ml.version
|
68
|
+
ml.update_properties!({version: choice2})
|
69
69
|
end
|
70
|
-
when :
|
70
|
+
when :minecraft_version
|
71
71
|
choice2 =
|
72
72
|
begin
|
73
73
|
CLI::UI::Prompt.ask('Which Minecraft version do you need?')
|
@@ -79,12 +79,12 @@ module Mmi
|
|
79
79
|
when :quit
|
80
80
|
# Pass.
|
81
81
|
else
|
82
|
-
ml.
|
82
|
+
ml.update_properties!({minecraft_version: choice2})
|
83
83
|
end
|
84
|
-
when :
|
84
|
+
when :download_minecraft
|
85
85
|
choice2 =
|
86
86
|
begin
|
87
|
-
CLI::UI::Prompt.confirm('Download minecraft when installing the modloader? (Ctrl+C for no change)', default: ml.
|
87
|
+
CLI::UI::Prompt.confirm('Download minecraft when installing the modloader? (Ctrl+C for no change)', default: ml.download_minecraft)
|
88
88
|
rescue Interrupt
|
89
89
|
:quit
|
90
90
|
end
|
@@ -93,7 +93,7 @@ module Mmi
|
|
93
93
|
when :quit
|
94
94
|
# Pass.
|
95
95
|
else
|
96
|
-
ml.
|
96
|
+
ml.update_properties!({download_minecraft: choice2})
|
97
97
|
end
|
98
98
|
when :install_dir
|
99
99
|
choice2 =
|
@@ -107,7 +107,7 @@ module Mmi
|
|
107
107
|
when :quit
|
108
108
|
# Pass.
|
109
109
|
else
|
110
|
-
ml.install_dir
|
110
|
+
ml.update_properties!({install_dir: choice2.strip.empty? ? nil : choice2})
|
111
111
|
end
|
112
112
|
when :install_type
|
113
113
|
choice2 = CLI::UI::Prompt.ask('What type of installation do you want?') do |handler|
|
@@ -122,7 +122,7 @@ module Mmi
|
|
122
122
|
when :quit
|
123
123
|
# Pass.
|
124
124
|
else
|
125
|
-
ml.install_type
|
125
|
+
ml.update_properties!({install_type: choice2})
|
126
126
|
end
|
127
127
|
when :quit
|
128
128
|
break
|
@@ -39,7 +39,7 @@ module Mmi
|
|
39
39
|
update_assets
|
40
40
|
when :quit_save
|
41
41
|
file_path = CLI::UI::Prompt.ask('Filename', default: self.file_path, is_file: true)
|
42
|
-
yaml = self.processor.
|
42
|
+
yaml = self.processor.to_h.to_yaml
|
43
43
|
|
44
44
|
File.write(File.expand_path(file_path, Dir.pwd), yaml)
|
45
45
|
break
|
@@ -1,72 +1,20 @@
|
|
1
1
|
require 'mmi/assets_processor'
|
2
2
|
require 'mmi/modloader/none'
|
3
3
|
require 'mmi/modloader/fabric'
|
4
|
-
require 'mmi/
|
4
|
+
require 'mmi/property_attributes'
|
5
5
|
require 'mmi/semver'
|
6
6
|
|
7
7
|
module Mmi
|
8
8
|
class ModFileProcessor
|
9
|
-
|
9
|
+
prepend PropertyAttributes
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
attr_reader :parsed_modloader
|
16
|
-
attr_reader :parsed_assets
|
17
|
-
|
18
|
-
def initialize(options)
|
19
|
-
@options = options
|
20
|
-
|
21
|
-
parse!
|
22
|
-
end
|
23
|
-
|
24
|
-
def parse!
|
25
|
-
version = Semver.parse(self.version)
|
26
|
-
lib_version = Semver.parse(Mmi::VERSION)
|
27
|
-
|
28
|
-
if self.version
|
29
|
-
if version.major <= lib_version.major
|
30
|
-
if version.minor > lib_version.minor
|
31
|
-
Mmi.warn %Q(Config file specified "version" #{version}, but MMI is at #{lib_version}. Some features might not be supported.)
|
32
|
-
end
|
33
|
-
|
34
|
-
ml = self.modloader
|
35
|
-
@parsed_modloader =
|
36
|
-
if ml
|
37
|
-
case ml['name']
|
38
|
-
when 'none'
|
39
|
-
Modloader::None.new(ml)
|
40
|
-
when 'fabric'
|
41
|
-
Modloader::Fabric.new(ml)
|
42
|
-
else
|
43
|
-
raise Mmi::InvalidAttributeError, "Unkown modloader #{ml['name'].inspect}."
|
44
|
-
end
|
45
|
-
else
|
46
|
-
Modloader::None.new
|
47
|
-
end
|
48
|
-
|
49
|
-
|
50
|
-
if self.assets
|
51
|
-
if self.assets.is_a?(Hash)
|
52
|
-
@parsed_assets = AssetsProcessor.new(self.assets)
|
53
|
-
else
|
54
|
-
raise Mmi::InvalidAttributeError, %Q(Invalid "assets": expected Hash but received #{self.assets.inspect})
|
55
|
-
end
|
56
|
-
else
|
57
|
-
raise Mmi::MissingAttributeError, 'Missing "assets".'
|
58
|
-
end
|
59
|
-
else
|
60
|
-
raise Mmi::InvalidAttributeError, %Q(Config file specified "version" #{version}, but MMI is at #{lib_version}.)
|
61
|
-
end
|
62
|
-
else
|
63
|
-
raise Mmi::MissingAttributeError, 'Missing "version".'
|
64
|
-
end
|
65
|
-
end
|
11
|
+
property :version, type: Semver
|
12
|
+
property :modloader, type: {field: 'name', types: {'none' => Modloader::None, 'fabric' => Modloader::Fabric}}
|
13
|
+
property :assets, type: AssetsProcessor
|
66
14
|
|
67
15
|
def install
|
68
|
-
self.
|
69
|
-
self.
|
16
|
+
self.modloader.install
|
17
|
+
self.assets.install
|
70
18
|
end
|
71
19
|
end
|
72
20
|
end
|