factorix 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 +4 -4
- data/CHANGELOG.md +25 -0
- data/README.md +1 -1
- data/lib/factorix/api/mod_download_api.rb +1 -1
- data/lib/factorix/api/mod_info.rb +2 -2
- data/lib/factorix/api/mod_management_api.rb +1 -1
- data/lib/factorix/api_credential.rb +1 -1
- data/lib/factorix/cli/commands/backup_support.rb +1 -1
- data/lib/factorix/cli/commands/base.rb +3 -3
- data/lib/factorix/cli/commands/cache/evict.rb +3 -3
- data/lib/factorix/cli/commands/cache/stat.rb +15 -15
- data/lib/factorix/cli/commands/command_wrapper.rb +5 -5
- data/lib/factorix/cli/commands/completion.rb +2 -3
- data/lib/factorix/cli/commands/confirmable.rb +1 -1
- data/lib/factorix/cli/commands/download_support.rb +2 -2
- data/lib/factorix/cli/commands/mod/check.rb +1 -1
- data/lib/factorix/cli/commands/mod/disable.rb +1 -1
- data/lib/factorix/cli/commands/mod/download.rb +5 -4
- data/lib/factorix/cli/commands/mod/edit.rb +9 -9
- data/lib/factorix/cli/commands/mod/enable.rb +1 -1
- data/lib/factorix/cli/commands/mod/image/add.rb +2 -2
- data/lib/factorix/cli/commands/mod/image/edit.rb +1 -1
- data/lib/factorix/cli/commands/mod/image/list.rb +4 -4
- data/lib/factorix/cli/commands/mod/install.rb +5 -4
- data/lib/factorix/cli/commands/mod/list.rb +7 -7
- data/lib/factorix/cli/commands/mod/search.rb +11 -9
- data/lib/factorix/cli/commands/mod/settings/dump.rb +3 -3
- data/lib/factorix/cli/commands/mod/settings/restore.rb +2 -2
- data/lib/factorix/cli/commands/mod/show.rb +20 -20
- data/lib/factorix/cli/commands/mod/sync.rb +6 -5
- data/lib/factorix/cli/commands/mod/uninstall.rb +1 -1
- data/lib/factorix/cli/commands/mod/update.rb +7 -6
- data/lib/factorix/cli/commands/mod/upload.rb +6 -6
- data/lib/factorix/cli/commands/path.rb +2 -2
- data/lib/factorix/cli/commands/version.rb +1 -1
- data/lib/factorix/{application.rb → container.rb} +8 -85
- data/lib/factorix/dependency/parser.rb +1 -1
- data/lib/factorix/http/client.rb +3 -3
- data/lib/factorix/info_json.rb +2 -2
- data/lib/factorix/mod_list.rb +2 -2
- data/lib/factorix/mod_settings.rb +2 -2
- data/lib/factorix/runtime/user_configurable.rb +9 -9
- data/lib/factorix/service_credential.rb +3 -3
- data/lib/factorix/version.rb +1 -1
- data/lib/factorix.rb +118 -1
- data/sig/factorix/container.rbs +15 -0
- data/sig/factorix.rbs +99 -0
- metadata +4 -4
- data/sig/factorix/application.rbs +0 -86
data/lib/factorix.rb
CHANGED
|
@@ -1,13 +1,86 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "dry/auto_inject"
|
|
4
|
+
require "dry/configurable"
|
|
4
5
|
require "zeitwerk"
|
|
5
6
|
require_relative "factorix/errors"
|
|
6
7
|
require_relative "factorix/version"
|
|
7
8
|
|
|
8
9
|
# Factorix provides a CLI for Factorio MOD management, settings synchronization,
|
|
9
10
|
# and MOD Portal integration.
|
|
11
|
+
#
|
|
12
|
+
# @example Configure Factorix
|
|
13
|
+
# Factorix.configure do |config|
|
|
14
|
+
# config.log_level = :debug
|
|
15
|
+
# config.http.connect_timeout = 10
|
|
16
|
+
# end
|
|
10
17
|
module Factorix
|
|
18
|
+
extend Dry::Configurable
|
|
19
|
+
|
|
20
|
+
# Log level (:debug, :info, :warn, :error, :fatal)
|
|
21
|
+
setting :log_level, default: :info
|
|
22
|
+
|
|
23
|
+
# Runtime settings (optional overrides for auto-detection)
|
|
24
|
+
setting :runtime do
|
|
25
|
+
setting :executable_path, constructor: ->(v) { v ? Pathname(v) : nil }
|
|
26
|
+
setting :user_dir, constructor: ->(v) { v ? Pathname(v) : nil }
|
|
27
|
+
setting :data_dir, constructor: ->(v) { v ? Pathname(v) : nil }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# HTTP timeout settings
|
|
31
|
+
setting :http do
|
|
32
|
+
setting :connect_timeout, default: 5
|
|
33
|
+
setting :read_timeout, default: 30
|
|
34
|
+
setting :write_timeout, default: 30
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Cache settings
|
|
38
|
+
setting :cache do
|
|
39
|
+
# Download cache settings (for MOD files)
|
|
40
|
+
setting :download do
|
|
41
|
+
setting :dir, constructor: ->(value) { Pathname(value) }
|
|
42
|
+
setting :ttl, default: nil # nil for unlimited (MOD files are immutable)
|
|
43
|
+
setting :max_file_size, default: nil # nil for unlimited
|
|
44
|
+
setting :compression_threshold, default: nil # nil for no compression (binary files)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# API cache settings (for API responses)
|
|
48
|
+
setting :api do
|
|
49
|
+
setting :dir, constructor: ->(value) { Pathname(value) }
|
|
50
|
+
setting :ttl, default: 3600 # 1 hour (API responses may change)
|
|
51
|
+
setting :max_file_size, default: 10 * 1024 * 1024 # 10MiB (JSON responses)
|
|
52
|
+
setting :compression_threshold, default: 0 # always compress (JSON is highly compressible)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# info.json cache settings (for MOD metadata from ZIP files)
|
|
56
|
+
setting :info_json do
|
|
57
|
+
setting :dir, constructor: ->(value) { Pathname(value) }
|
|
58
|
+
setting :ttl, default: nil # nil for unlimited (info.json is immutable within a MOD ZIP)
|
|
59
|
+
setting :max_file_size, default: nil # nil for unlimited (info.json is small)
|
|
60
|
+
setting :compression_threshold, default: 0 # always compress (JSON is highly compressible)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Load configuration from file
|
|
65
|
+
#
|
|
66
|
+
# @param path [Pathname, nil] configuration file path
|
|
67
|
+
# @return [void]
|
|
68
|
+
# @raise [ConfigurationError] if explicitly specified path does not exist
|
|
69
|
+
def self.load_config(path=nil)
|
|
70
|
+
if path
|
|
71
|
+
# Explicitly specified path must exist
|
|
72
|
+
raise ConfigurationError, "Configuration file not found: #{path}" unless path.exist?
|
|
73
|
+
|
|
74
|
+
config_path = path
|
|
75
|
+
else
|
|
76
|
+
# Default path is optional
|
|
77
|
+
config_path = Container.resolve(:runtime).factorix_config_path
|
|
78
|
+
return unless config_path.exist?
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
instance_eval(config_path.read, config_path.to_s)
|
|
82
|
+
end
|
|
83
|
+
|
|
11
84
|
loader = Zeitwerk::Loader.for_gem
|
|
12
85
|
loader.ignore("#{__dir__}/factorix/version.rb")
|
|
13
86
|
loader.ignore("#{__dir__}/factorix/errors.rb")
|
|
@@ -33,6 +106,50 @@ module Factorix
|
|
|
33
106
|
)
|
|
34
107
|
loader.setup
|
|
35
108
|
|
|
36
|
-
Import = Dry::AutoInject(
|
|
109
|
+
Import = Dry::AutoInject(Container)
|
|
37
110
|
public_constant :Import
|
|
111
|
+
|
|
112
|
+
# Initialize cache directory defaults after Container is loaded
|
|
113
|
+
runtime = Container.resolve(:runtime)
|
|
114
|
+
config.cache.download.dir = runtime.factorix_cache_dir / "download"
|
|
115
|
+
config.cache.api.dir = runtime.factorix_cache_dir / "api"
|
|
116
|
+
config.cache.info_json.dir = runtime.factorix_cache_dir / "info_json"
|
|
117
|
+
|
|
118
|
+
# @deprecated Use {Container} for DI and {Factorix} for configuration. Will be removed in v1.0.
|
|
119
|
+
class Application
|
|
120
|
+
# @!method [](key)
|
|
121
|
+
# @deprecated Use {Container.[]} instead
|
|
122
|
+
def self.[](key)
|
|
123
|
+
warn "[factorix] Factorix::Application is deprecated, use Factorix::Container for DI"
|
|
124
|
+
Container[key]
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# @!method resolve(key)
|
|
128
|
+
# @deprecated Use {Container.resolve} instead
|
|
129
|
+
def self.resolve(key)
|
|
130
|
+
warn "[factorix] Factorix::Application is deprecated, use Factorix::Container for DI"
|
|
131
|
+
Container.resolve(key)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# @!method register(...)
|
|
135
|
+
# @deprecated Use {Container.register} instead
|
|
136
|
+
def self.register(...)
|
|
137
|
+
warn "[factorix] Factorix::Application is deprecated, use Factorix::Container for DI"
|
|
138
|
+
Container.register(...)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# @!method config
|
|
142
|
+
# @deprecated Use {Factorix.config} instead
|
|
143
|
+
def self.config
|
|
144
|
+
warn "[factorix] Factorix::Application is deprecated, use Factorix.config for configuration"
|
|
145
|
+
Factorix.config
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# @!method configure(&block)
|
|
149
|
+
# @deprecated Use {Factorix.configure} instead
|
|
150
|
+
def self.configure(&)
|
|
151
|
+
warn "[factorix] Factorix::Application is deprecated, use Factorix.configure for configuration"
|
|
152
|
+
Factorix.configure(&)
|
|
153
|
+
end
|
|
154
|
+
end
|
|
38
155
|
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# RBS type signature file
|
|
2
|
+
# NOTE: Do not include private method definitions in RBS files.
|
|
3
|
+
# Only public interfaces should be documented here.
|
|
4
|
+
|
|
5
|
+
module Factorix
|
|
6
|
+
class Container
|
|
7
|
+
extend Dry::Core::Container::Mixin
|
|
8
|
+
|
|
9
|
+
def self.register: (Symbol, ?memoize: bool) { () -> untyped } -> void
|
|
10
|
+
|
|
11
|
+
def self.resolve: (Symbol) -> untyped
|
|
12
|
+
|
|
13
|
+
def self.[]: (Symbol) -> untyped
|
|
14
|
+
end
|
|
15
|
+
end
|
data/sig/factorix.rbs
CHANGED
|
@@ -6,4 +6,103 @@ module Factorix
|
|
|
6
6
|
VERSION: String
|
|
7
7
|
|
|
8
8
|
Import: Dry::AutoInject::_Builder
|
|
9
|
+
|
|
10
|
+
extend Dry::Configurable
|
|
11
|
+
|
|
12
|
+
def self.config: () -> Config
|
|
13
|
+
|
|
14
|
+
def self.configure: () { (Config) -> void } -> void
|
|
15
|
+
|
|
16
|
+
def self.load_config: (?Pathname? path) -> void
|
|
17
|
+
|
|
18
|
+
class Config
|
|
19
|
+
def log_level: () -> Symbol
|
|
20
|
+
|
|
21
|
+
def log_level=: (Symbol) -> void
|
|
22
|
+
|
|
23
|
+
def credential: () -> CredentialConfig
|
|
24
|
+
|
|
25
|
+
def runtime: () -> RuntimeConfig
|
|
26
|
+
|
|
27
|
+
def http: () -> HttpConfig
|
|
28
|
+
|
|
29
|
+
def cache: () -> CacheConfig
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class CredentialConfig
|
|
33
|
+
def source: () -> Symbol
|
|
34
|
+
|
|
35
|
+
def source=: (Symbol) -> void
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class RuntimeConfig
|
|
39
|
+
def executable_path: () -> Pathname?
|
|
40
|
+
|
|
41
|
+
def executable_path=: (Pathname | String | nil) -> void
|
|
42
|
+
|
|
43
|
+
def user_dir: () -> Pathname?
|
|
44
|
+
|
|
45
|
+
def user_dir=: (Pathname | String | nil) -> void
|
|
46
|
+
|
|
47
|
+
def data_dir: () -> Pathname?
|
|
48
|
+
|
|
49
|
+
def data_dir=: (Pathname | String | nil) -> void
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
class HttpConfig
|
|
53
|
+
def connect_timeout: () -> Integer
|
|
54
|
+
|
|
55
|
+
def connect_timeout=: (Integer) -> void
|
|
56
|
+
|
|
57
|
+
def read_timeout: () -> Integer
|
|
58
|
+
|
|
59
|
+
def read_timeout=: (Integer) -> void
|
|
60
|
+
|
|
61
|
+
def write_timeout: () -> Integer
|
|
62
|
+
|
|
63
|
+
def write_timeout=: (Integer) -> void
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
class CacheConfig
|
|
67
|
+
def download: () -> CacheInstanceConfig
|
|
68
|
+
|
|
69
|
+
def api: () -> CacheInstanceConfig
|
|
70
|
+
|
|
71
|
+
def info_json: () -> CacheInstanceConfig
|
|
72
|
+
|
|
73
|
+
def values: () -> Hash[Symbol, CacheInstanceConfig]
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
class CacheInstanceConfig
|
|
77
|
+
def dir: () -> Pathname
|
|
78
|
+
|
|
79
|
+
def dir=: (Pathname | String) -> void
|
|
80
|
+
|
|
81
|
+
def ttl: () -> Integer?
|
|
82
|
+
|
|
83
|
+
def ttl=: (Integer?) -> void
|
|
84
|
+
|
|
85
|
+
def max_file_size: () -> Integer?
|
|
86
|
+
|
|
87
|
+
def max_file_size=: (Integer?) -> void
|
|
88
|
+
|
|
89
|
+
def compression_threshold: () -> Integer?
|
|
90
|
+
|
|
91
|
+
def compression_threshold=: (Integer?) -> void
|
|
92
|
+
|
|
93
|
+
def to_h: () -> Hash[Symbol, untyped]
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# @deprecated Use Container for DI and Factorix for configuration
|
|
97
|
+
class Application
|
|
98
|
+
def self.[]: (Symbol) -> untyped
|
|
99
|
+
|
|
100
|
+
def self.resolve: (Symbol) -> untyped
|
|
101
|
+
|
|
102
|
+
def self.register: (Symbol, ?memoize: bool) { () -> untyped } -> void
|
|
103
|
+
|
|
104
|
+
def self.config: () -> Config
|
|
105
|
+
|
|
106
|
+
def self.configure: () { (Config) -> void } -> void
|
|
107
|
+
end
|
|
9
108
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: factorix
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- OZAWA Sakuro
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-01-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: concurrent-ruby
|
|
@@ -221,7 +221,6 @@ files:
|
|
|
221
221
|
- lib/factorix/api/release.rb
|
|
222
222
|
- lib/factorix/api/tag.rb
|
|
223
223
|
- lib/factorix/api_credential.rb
|
|
224
|
-
- lib/factorix/application.rb
|
|
225
224
|
- lib/factorix/cache/file_system.rb
|
|
226
225
|
- lib/factorix/cli.rb
|
|
227
226
|
- lib/factorix/cli/commands/backup_support.rb
|
|
@@ -255,6 +254,7 @@ files:
|
|
|
255
254
|
- lib/factorix/cli/commands/path.rb
|
|
256
255
|
- lib/factorix/cli/commands/requires_game_stopped.rb
|
|
257
256
|
- lib/factorix/cli/commands/version.rb
|
|
257
|
+
- lib/factorix/container.rb
|
|
258
258
|
- lib/factorix/dependency/edge.rb
|
|
259
259
|
- lib/factorix/dependency/entry.rb
|
|
260
260
|
- lib/factorix/dependency/graph.rb
|
|
@@ -322,7 +322,6 @@ files:
|
|
|
322
322
|
- sig/factorix/api/release.rbs
|
|
323
323
|
- sig/factorix/api/tag.rbs
|
|
324
324
|
- sig/factorix/api_credential.rbs
|
|
325
|
-
- sig/factorix/application.rbs
|
|
326
325
|
- sig/factorix/cache/file_system.rbs
|
|
327
326
|
- sig/factorix/cli.rbs
|
|
328
327
|
- sig/factorix/cli/commands/base.rbs
|
|
@@ -353,6 +352,7 @@ files:
|
|
|
353
352
|
- sig/factorix/cli/commands/path.rbs
|
|
354
353
|
- sig/factorix/cli/commands/requires_game_stopped.rbs
|
|
355
354
|
- sig/factorix/cli/commands/version.rbs
|
|
355
|
+
- sig/factorix/container.rbs
|
|
356
356
|
- sig/factorix/dependency/edge.rbs
|
|
357
357
|
- sig/factorix/dependency/entry.rbs
|
|
358
358
|
- sig/factorix/dependency/graph.rbs
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
# RBS type signature file
|
|
2
|
-
# NOTE: Do not include private method definitions in RBS files.
|
|
3
|
-
# Only public interfaces should be documented here.
|
|
4
|
-
|
|
5
|
-
module Factorix
|
|
6
|
-
class Application
|
|
7
|
-
extend Dry::Core::Container::Mixin
|
|
8
|
-
extend Dry::Configurable
|
|
9
|
-
|
|
10
|
-
def self.register: (Symbol, ?memoize: bool) { () -> untyped } -> void
|
|
11
|
-
|
|
12
|
-
def self.resolve: (Symbol) -> untyped
|
|
13
|
-
|
|
14
|
-
def self.[]: (Symbol) -> untyped
|
|
15
|
-
|
|
16
|
-
def self.config: () -> Config
|
|
17
|
-
|
|
18
|
-
def self.configure: () { (Config) -> void } -> void
|
|
19
|
-
|
|
20
|
-
def self.load_config: (?String? path) -> void
|
|
21
|
-
|
|
22
|
-
class Config
|
|
23
|
-
def log_level: () -> Symbol
|
|
24
|
-
|
|
25
|
-
def log_level=: (Symbol) -> void
|
|
26
|
-
|
|
27
|
-
def credential: () -> CredentialConfig
|
|
28
|
-
|
|
29
|
-
def runtime: () -> RuntimeConfig
|
|
30
|
-
|
|
31
|
-
def http: () -> HttpConfig
|
|
32
|
-
|
|
33
|
-
def cache: () -> CacheConfig
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
class CredentialConfig
|
|
37
|
-
def source: () -> Symbol
|
|
38
|
-
|
|
39
|
-
def source=: (Symbol) -> void
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
class RuntimeConfig
|
|
43
|
-
def executable_path: () -> Pathname?
|
|
44
|
-
|
|
45
|
-
def executable_path=: (Pathname | String | nil) -> void
|
|
46
|
-
|
|
47
|
-
def user_dir: () -> Pathname?
|
|
48
|
-
|
|
49
|
-
def user_dir=: (Pathname | String | nil) -> void
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
class HttpConfig
|
|
53
|
-
def connect_timeout: () -> Integer
|
|
54
|
-
|
|
55
|
-
def connect_timeout=: (Integer) -> void
|
|
56
|
-
|
|
57
|
-
def read_timeout: () -> Integer
|
|
58
|
-
|
|
59
|
-
def read_timeout=: (Integer) -> void
|
|
60
|
-
|
|
61
|
-
def write_timeout: () -> Integer
|
|
62
|
-
|
|
63
|
-
def write_timeout=: (Integer) -> void
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
class CacheConfig
|
|
67
|
-
def download: () -> CacheInstanceConfig
|
|
68
|
-
|
|
69
|
-
def api: () -> CacheInstanceConfig
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
class CacheInstanceConfig
|
|
73
|
-
def dir: () -> Pathname
|
|
74
|
-
|
|
75
|
-
def dir=: (Pathname | String) -> void
|
|
76
|
-
|
|
77
|
-
def ttl: () -> Integer?
|
|
78
|
-
|
|
79
|
-
def ttl=: (Integer?) -> void
|
|
80
|
-
|
|
81
|
-
def max_file_size: () -> Integer?
|
|
82
|
-
|
|
83
|
-
def max_file_size=: (Integer?) -> void
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|