mmi 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|