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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5212e69bd41c45ceffb0fd42e889868b706b0481e6a07567c98b2cce439bb5fc
4
- data.tar.gz: e2386ba4154617497efbeddea3537b58eb164dd5af66e963c325d06626536895
3
+ metadata.gz: 1f669f6ec36e75ef8f9720e7e09337627d56bc84453233484157643f22a55aa9
4
+ data.tar.gz: 2029ef6d075978429ddd533c7ba5aa68eb0c16bf77e9c1802bcbfd159844f767
5
5
  SHA512:
6
- metadata.gz: 62ece69fa0e7028367dff967cfb6e5d93ba4c5413be84b9a38cd13466687202a9417b57c09b4b137ca26e149a556b1063d086342747ae95590ace736c492efa6
7
- data.tar.gz: 8687814b5cb8f3af5e695db5765117c113de95d09fa361a87e04222f106e30abb935be426eb775751410d0181ee73c9171af9380fea5358d2ae936e9c12ec267
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).
@@ -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
- # Valid license identifiers for edit_details API
29
- # Custom licenses (custom_$ID) are not included
30
- IDENTIFIERS = {
31
- "default_mit" => "MIT",
32
- "default_gnugplv3" => "GNU GPLv3",
33
- "default_gnulgplv3" => "GNU LGPLv3",
34
- "default_mozilla2" => "Mozilla Public License 2.0",
35
- "default_apache2" => "Apache License 2.0",
36
- "default_unlicense" => "The Unlicense"
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 :IDENTIFIERS
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
- IDENTIFIERS.key?(value) || CUSTOM_LICENSE_PATTERN.match?(value)
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
@@ -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.identifier_values.join(", ")}"
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
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Factorix
4
- VERSION = "0.9.1"
4
+ VERSION = "0.10.0"
5
5
  public_constant :VERSION
6
6
  end
@@ -9,6 +9,7 @@ module Factorix
9
9
  attr_reader name: String
10
10
  attr_reader description: String
11
11
 
12
+ def self.identifiers: () -> Array[String]
12
13
  def self.for: (String value) -> Category
13
14
  end
14
15
  end
@@ -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
@@ -9,6 +9,7 @@ module Factorix
9
9
  attr_reader name: String
10
10
  attr_reader description: String
11
11
 
12
+ def self.identifiers: () -> Array[String]
12
13
  def self.for: (String value) -> Tag
13
14
  end
14
15
  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.9.1
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-20 00:00:00.000000000 Z
11
+ date: 2026-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby