Class: Factorix::InfoJSON
- Inherits:
-
Data
- Object
- Data
- Factorix::InfoJSON
- Defined in:
- lib/factorix/info_json.rb,
lib/factorix/info_json.rb
Overview
Factorio MOD info.json representation
Represents the metadata file that must be present in every Factorio MOD. Only required fields (name, version, title, author) are enforced.
Instance Attribute Summary collapse
-
#author ⇒ Object
readonly
Returns the value of attribute author.
-
#dependencies ⇒ Object
readonly
Returns the value of attribute dependencies.
-
#description ⇒ Object
readonly
Returns the value of attribute description.
-
#factorio_version ⇒ Object
readonly
Returns the value of attribute factorio_version.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#title ⇒ Object
readonly
Returns the value of attribute title.
-
#version ⇒ Object
readonly
Returns the value of attribute version.
Class Method Summary collapse
-
.from_json(json_string) ⇒ InfoJSON
Parse info.json from JSON string.
-
.from_zip(zip_path) ⇒ InfoJSON
Extract from zip file.
Instance Attribute Details
#author ⇒ Object (readonly)
Returns the value of attribute author
8 9 10 |
# File 'lib/factorix/info_json.rb', line 8 def @author end |
#dependencies ⇒ Object (readonly)
Returns the value of attribute dependencies
8 9 10 |
# File 'lib/factorix/info_json.rb', line 8 def dependencies @dependencies end |
#description ⇒ Object (readonly)
Returns the value of attribute description
8 9 10 |
# File 'lib/factorix/info_json.rb', line 8 def description @description end |
#factorio_version ⇒ Object (readonly)
Returns the value of attribute factorio_version
8 9 10 |
# File 'lib/factorix/info_json.rb', line 8 def factorio_version @factorio_version end |
#name ⇒ Object (readonly)
Returns the value of attribute name
8 9 10 |
# File 'lib/factorix/info_json.rb', line 8 def name @name end |
#title ⇒ Object (readonly)
Returns the value of attribute title
8 9 10 |
# File 'lib/factorix/info_json.rb', line 8 def title @title end |
#version ⇒ Object (readonly)
Returns the value of attribute version
8 9 10 |
# File 'lib/factorix/info_json.rb', line 8 def version @version end |
Class Method Details
.from_json(json_string) ⇒ InfoJSON
Parse info.json from JSON string
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/factorix/info_json.rb', line 22 def self.from_json(json_string) data = JSON.parse(json_string) required_fields = %w[name version title author] missing = required_fields - data.keys raise FileFormatError, "Missing required fields: #{missing.join(", ")}" unless missing.empty? parser = Dependency::Parser.new dependencies = (data["dependencies"] || []).map {|dep_str| parser.parse(dep_str) } new(name: data["name"], version: MODVersion.from_string(data["version"]), title: data["title"], author: data["author"], description: data["description"] || "", factorio_version: data["factorio_version"], dependencies:) rescue JSON::ParserError => e raise FileFormatError, "Invalid JSON: #{e.}" rescue VersionParseError, DependencyParseError => e raise FileFormatError, e. end |
.from_zip(zip_path) ⇒ InfoJSON
Extract from zip file
Uses caching to avoid repeated ZIP extraction for the same file. Cache key is based on file path (MOD ZIPs are immutable after download). Uses double-checked locking to prevent concurrent extraction while avoiding lock overhead on cache hits.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/factorix/info_json.rb', line 49 def self.from_zip(zip_path) cache = Container.resolve(:info_json_cache) logger = Container.resolve(:logger) cache_key = zip_path.to_s if (cached_json = cache.read(cache_key)) logger.debug("info.json cache hit", path: zip_path.to_s) return from_json((+cached_json).force_encoding(Encoding::UTF_8)) end logger.debug("info.json cache miss", path: zip_path.to_s) cache.with_lock(cache_key) do if (cached_json = cache.read(cache_key)) logger.debug("info.json cache hit (after lock)", path: zip_path.to_s) return from_json((+cached_json).force_encoding(Encoding::UTF_8)) end json_string = Zip::File.open(zip_path) {|zip_file| info_entry = zip_file.find {|entry| entry.name.end_with?("/info.json") } raise FileFormatError, "info.json not found in #{zip_path}" unless info_entry info_entry.get_input_stream.read } temp_file = Tempfile.new("info_json_cache") begin temp_file.write(json_string) temp_file.close cache.store(cache_key, Pathname(temp_file.path)) logger.debug("Stored info.json in cache", path: zip_path.to_s) ensure temp_file.unlink end from_json(json_string) end rescue Zip::Error => e raise FileFormatError, "Invalid zip file: #{e.}" end |