factorix 0.9.1 → 0.10.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 +8 -0
- data/doc/factorix.1 +47 -0
- data/lib/factorix/api/category.rb +3 -0
- data/lib/factorix/api/license.rb +75 -19
- data/lib/factorix/api/tag.rb +3 -0
- data/lib/factorix/cli/commands/mod/edit.rb +1 -1
- data/lib/factorix/version.rb +1 -1
- data/sig/factorix/api/category.rbs +1 -0
- data/sig/factorix/api/license.rbs +2 -1
- data/sig/factorix/api/tag.rbs +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1f669f6ec36e75ef8f9720e7e09337627d56bc84453233484157643f22a55aa9
|
|
4
|
+
data.tar.gz: 2029ef6d075978429ddd533c7ba5aa68eb0c16bf77e9c1802bcbfd159844f767
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f9a17f3a9a83fdf498555deac57a3d9d99b0b33d77a36c8242e5d78e8e85923ed535f4457bf5976e2e3f1b7209214c84e4eda1f9bf00425657b1c8eb471f34de
|
|
7
|
+
data.tar.gz: 0e6c5bfc9e7a09d4ff3529e976b0f7f90cba03d49d2e98ef70ae9eae07031e1c2de90e7f4235dbeb8d68b32d852afa5a674ecc76bcfb048684f9e229454c9c83
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.10.0] - 2026-02-21
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Refactor `License` to use flyweight pattern for standard licenses with `.for(id)` method
|
|
8
|
+
- Add `.identifiers` class method to `Category`, `License`, and `Tag`
|
|
9
|
+
- Replace `License.identifier_values` with `License.identifiers`
|
|
10
|
+
|
|
3
11
|
## [0.9.1] - 2026-02-20
|
|
4
12
|
|
|
5
13
|
### Added
|
data/doc/factorix.1
CHANGED
|
@@ -184,6 +184,53 @@ Skip confirmation prompts.
|
|
|
184
184
|
.TP
|
|
185
185
|
.BR \-j ", " \-\-jobs =\fIVALUE\fR
|
|
186
186
|
Number of parallel downloads (default: 4).
|
|
187
|
+
.SS factorix mod changelog add ENTRY
|
|
188
|
+
Add an entry to MOD changelog.
|
|
189
|
+
.TP
|
|
190
|
+
.BR \-\-version =\fIVALUE\fR
|
|
191
|
+
Version (X.Y.Z or Unreleased, default: Unreleased).
|
|
192
|
+
.TP
|
|
193
|
+
.BR \-\-category =\fIVALUE\fR
|
|
194
|
+
Category (e.g., Features, Bugfixes). Required.
|
|
195
|
+
.TP
|
|
196
|
+
.BR \-\-changelog =\fIVALUE\fR
|
|
197
|
+
Path to changelog file (default: changelog.txt).
|
|
198
|
+
.SS factorix mod changelog extract
|
|
199
|
+
Extract a changelog section for a specific version.
|
|
200
|
+
.TP
|
|
201
|
+
.BR \-\-version =\fIVALUE\fR
|
|
202
|
+
Version (X.Y.Z or Unreleased). Required.
|
|
203
|
+
.TP
|
|
204
|
+
.B \-\-json
|
|
205
|
+
Output in JSON format.
|
|
206
|
+
.TP
|
|
207
|
+
.BR \-\-changelog =\fIVALUE\fR
|
|
208
|
+
Path to changelog file (default: changelog.txt).
|
|
209
|
+
.SS factorix mod changelog check
|
|
210
|
+
Validate MOD changelog structure.
|
|
211
|
+
.TP
|
|
212
|
+
.B \-\-release
|
|
213
|
+
Disallow Unreleased section.
|
|
214
|
+
.TP
|
|
215
|
+
.BR \-\-changelog =\fIVALUE\fR
|
|
216
|
+
Path to changelog file (default: changelog.txt).
|
|
217
|
+
.TP
|
|
218
|
+
.BR \-\-info\-json =\fIVALUE\fR
|
|
219
|
+
Path to info.json file (default: info.json).
|
|
220
|
+
.SS factorix mod changelog release
|
|
221
|
+
Convert Unreleased changelog section to a versioned section.
|
|
222
|
+
.TP
|
|
223
|
+
.BR \-\-version =\fIVALUE\fR
|
|
224
|
+
Version (X.Y.Z, default: from info.json).
|
|
225
|
+
.TP
|
|
226
|
+
.BR \-\-date =\fIVALUE\fR
|
|
227
|
+
Release date (YYYY-MM-DD, default: today UTC).
|
|
228
|
+
.TP
|
|
229
|
+
.BR \-\-changelog =\fIVALUE\fR
|
|
230
|
+
Path to changelog file (default: changelog.txt).
|
|
231
|
+
.TP
|
|
232
|
+
.BR \-\-info\-json =\fIVALUE\fR
|
|
233
|
+
Path to info.json file (default: info.json).
|
|
187
234
|
.SH MOD PORTAL COMMANDS
|
|
188
235
|
These commands interact with the Factorio MOD Portal and require authentication.
|
|
189
236
|
.SS factorix mod upload FILE
|
|
@@ -53,6 +53,9 @@ module Factorix
|
|
|
53
53
|
}.freeze
|
|
54
54
|
private_constant :CATEGORIES
|
|
55
55
|
|
|
56
|
+
# @return [Array<String>] all category identifiers
|
|
57
|
+
def self.identifiers = CATEGORIES.keys
|
|
58
|
+
|
|
56
59
|
# Get Category instance for the given value
|
|
57
60
|
#
|
|
58
61
|
# Returns predefined instance for known categories (flyweight pattern).
|
data/lib/factorix/api/license.rb
CHANGED
|
@@ -9,10 +9,11 @@ module Factorix
|
|
|
9
9
|
# License object from MOD Portal API
|
|
10
10
|
#
|
|
11
11
|
# Represents a MOD license information.
|
|
12
|
+
# Uses flyweight pattern for standard licenses.
|
|
12
13
|
# Also provides valid license identifiers for edit_details API.
|
|
13
14
|
#
|
|
14
15
|
# @see https://wiki.factorio.com/Mod_portal_API
|
|
15
|
-
# @see https://wiki.factorio.com/Mod_details_API
|
|
16
|
+
# @see https://wiki.factorio.com/Mod_details_API#License
|
|
16
17
|
class License
|
|
17
18
|
# @!attribute [r] id
|
|
18
19
|
# @return [String] license ID
|
|
@@ -25,37 +26,92 @@ module Factorix
|
|
|
25
26
|
# @!attribute [r] url
|
|
26
27
|
# @return [URI::HTTPS] license URL
|
|
27
28
|
|
|
28
|
-
#
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
# Predefined standard license instances
|
|
30
|
+
DEFAULT_MIT = new(
|
|
31
|
+
id: "default_mit",
|
|
32
|
+
name: "MIT",
|
|
33
|
+
title: "MIT License",
|
|
34
|
+
description: "A permissive license that is short and to the point. It lets people do anything with your code with proper attribution and without warranty.",
|
|
35
|
+
url: "https://raw.githubusercontent.com/spdx/license-list-data/main/text/MIT.txt"
|
|
36
|
+
)
|
|
37
|
+
private_constant :DEFAULT_MIT
|
|
38
|
+
DEFAULT_GNUGPLV3 = new(
|
|
39
|
+
id: "default_gnugplv3",
|
|
40
|
+
name: "GNU GPLv3",
|
|
41
|
+
title: "GNU General Public License v3.0",
|
|
42
|
+
description: "The GNU GPL is the most widely used free software license and has a strong copyleft requirement.",
|
|
43
|
+
url: "https://raw.githubusercontent.com/spdx/license-list-data/main/text/GPL-3.0-or-later.txt"
|
|
44
|
+
)
|
|
45
|
+
private_constant :DEFAULT_GNUGPLV3
|
|
46
|
+
DEFAULT_GNULGPLV3 = new(
|
|
47
|
+
id: "default_gnulgplv3",
|
|
48
|
+
name: "GNU LGPLv3",
|
|
49
|
+
title: "GNU Lesser General Public License v3.0",
|
|
50
|
+
description: "Version 3 of the GNU LGPL is an additional set of permissions to the GNU GPLv3 license that requires derived works use the same license.",
|
|
51
|
+
url: "https://raw.githubusercontent.com/spdx/license-list-data/main/text/LGPL-3.0-or-later.txt"
|
|
52
|
+
)
|
|
53
|
+
private_constant :DEFAULT_GNULGPLV3
|
|
54
|
+
DEFAULT_MOZILLA2 = new(
|
|
55
|
+
id: "default_mozilla2",
|
|
56
|
+
name: "Mozilla Public License 2.0",
|
|
57
|
+
title: "Mozilla Public License Version 2.0",
|
|
58
|
+
description: "The Mozilla Public License (MPL 2.0) attempts to be a compromise between the permissive BSD license and the reciprocal GPL license.",
|
|
59
|
+
url: "https://raw.githubusercontent.com/spdx/license-list-data/main/text/MPL-2.0.txt"
|
|
60
|
+
)
|
|
61
|
+
private_constant :DEFAULT_MOZILLA2
|
|
62
|
+
DEFAULT_APACHE2 = new(
|
|
63
|
+
id: "default_apache2",
|
|
64
|
+
name: "Apache License 2.0",
|
|
65
|
+
title: "Apache License, Version 2.0",
|
|
66
|
+
description: "A permissive license that also provides an express grant of patent rights from contributors to users.",
|
|
67
|
+
url: "https://raw.githubusercontent.com/spdx/license-list-data/main/text/Apache-2.0.txt"
|
|
68
|
+
)
|
|
69
|
+
private_constant :DEFAULT_APACHE2
|
|
70
|
+
DEFAULT_UNLICENSE = new(
|
|
71
|
+
id: "default_unlicense",
|
|
72
|
+
name: "The Unlicense",
|
|
73
|
+
title: "The Unlicense",
|
|
74
|
+
description: "The Unlicense is a template to waive copyright interest in software and dedicate it to the public domain.",
|
|
75
|
+
url: "https://raw.githubusercontent.com/spdx/license-list-data/main/text/Unlicense.txt"
|
|
76
|
+
)
|
|
77
|
+
private_constant :DEFAULT_UNLICENSE
|
|
78
|
+
|
|
79
|
+
# Lookup table for flyweight pattern
|
|
80
|
+
LICENSES = {
|
|
81
|
+
"default_mit" => DEFAULT_MIT,
|
|
82
|
+
"default_gnugplv3" => DEFAULT_GNUGPLV3,
|
|
83
|
+
"default_gnulgplv3" => DEFAULT_GNULGPLV3,
|
|
84
|
+
"default_mozilla2" => DEFAULT_MOZILLA2,
|
|
85
|
+
"default_apache2" => DEFAULT_APACHE2,
|
|
86
|
+
"default_unlicense" => DEFAULT_UNLICENSE
|
|
37
87
|
}.freeze
|
|
38
|
-
private_constant :
|
|
88
|
+
private_constant :LICENSES
|
|
39
89
|
|
|
40
90
|
# Pattern for custom license identifiers (custom_ + 24 lowercase hex chars)
|
|
41
91
|
CUSTOM_LICENSE_PATTERN = /\Acustom_[0-9a-f]{24}\z/
|
|
42
92
|
private_constant :CUSTOM_LICENSE_PATTERN
|
|
43
93
|
|
|
94
|
+
# @return [Array<String>] all license identifiers
|
|
95
|
+
def self.identifiers = LICENSES.keys
|
|
96
|
+
|
|
97
|
+
# Get License instance for the given identifier
|
|
98
|
+
#
|
|
99
|
+
# Returns predefined instance for known licenses (flyweight pattern).
|
|
100
|
+
# Raises an error for unknown license identifiers.
|
|
101
|
+
#
|
|
102
|
+
# @param id [String] license identifier
|
|
103
|
+
# @return [License] License instance
|
|
104
|
+
# @raise [KeyError] if license identifier is unknown
|
|
105
|
+
def self.for(id) = LICENSES.fetch(id.to_s)
|
|
106
|
+
|
|
44
107
|
# Check if the given value is a valid license identifier
|
|
45
108
|
#
|
|
46
109
|
# @param value [String] license identifier
|
|
47
110
|
# @return [Boolean] true if valid (standard or custom license)
|
|
48
111
|
def self.valid_identifier?(value)
|
|
49
|
-
|
|
112
|
+
LICENSES.key?(value) || CUSTOM_LICENSE_PATTERN.match?(value)
|
|
50
113
|
end
|
|
51
114
|
|
|
52
|
-
# List all valid license identifier values
|
|
53
|
-
#
|
|
54
|
-
# @return [Array<String>] array of license identifiers
|
|
55
|
-
def self.identifier_values = IDENTIFIERS.keys
|
|
56
|
-
|
|
57
|
-
# Create License from API response hash
|
|
58
|
-
#
|
|
59
115
|
# @param id [String] license ID
|
|
60
116
|
# @param name [String] license name
|
|
61
117
|
# @param title [String] license title
|
data/lib/factorix/api/tag.rb
CHANGED
|
@@ -79,6 +79,9 @@ module Factorix
|
|
|
79
79
|
}.freeze
|
|
80
80
|
private_constant :TAGS
|
|
81
81
|
|
|
82
|
+
# @return [Array<String>] all tag identifiers
|
|
83
|
+
def self.identifiers = TAGS.keys
|
|
84
|
+
|
|
82
85
|
# Get Tag instance for the given value
|
|
83
86
|
#
|
|
84
87
|
# Returns predefined instance for known tags (flyweight pattern).
|
|
@@ -100,7 +100,7 @@ module Factorix
|
|
|
100
100
|
return if API::License.valid_identifier?(license)
|
|
101
101
|
|
|
102
102
|
say "Invalid license identifier: #{license}", prefix: :error
|
|
103
|
-
say "Valid identifiers: #{API::License.
|
|
103
|
+
say "Valid identifiers: #{API::License.identifiers.join(", ")}"
|
|
104
104
|
say "Custom licenses: custom_<24 hex chars> (e.g., custom_0123456789abcdef01234567)"
|
|
105
105
|
raise InvalidArgumentError, "Invalid license identifier"
|
|
106
106
|
end
|
data/lib/factorix/version.rb
CHANGED
|
@@ -11,8 +11,9 @@ module Factorix
|
|
|
11
11
|
attr_reader description: String
|
|
12
12
|
attr_reader url: URI::HTTPS
|
|
13
13
|
|
|
14
|
+
def self.identifiers: () -> Array[String]
|
|
15
|
+
def self.for: (String id) -> License
|
|
14
16
|
def self.valid_identifier?: (String value) -> bool
|
|
15
|
-
def self.identifier_values: () -> Array[String]
|
|
16
17
|
|
|
17
18
|
def initialize: (id: String, name: String, title: String, description: String, url: String) -> void
|
|
18
19
|
end
|
data/sig/factorix/api/tag.rbs
CHANGED
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.10.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: 2026-02-
|
|
11
|
+
date: 2026-02-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: concurrent-ruby
|