Icarus-Mod-Tools 2.2.0 → 2.3.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: db2fc2f47e7cb01b3694b407294f2eaf7a309b243ea80f176a81d90f657492e5
4
- data.tar.gz: 876bad1efb1796450f17ea4e9359ccffb51f28df5189050bdc1d077bdeea815f
3
+ metadata.gz: f629740e09031cd9f71c655aa8872e1f9ca80db5e9ca0aaab9e2894d64190c61
4
+ data.tar.gz: '08d27ce72493df462e3d028bdced86a23f5ddc78e1da7f37d0b9f637b2b720c7'
5
5
  SHA512:
6
- metadata.gz: e7ebb4620d99595413206557bc22bd6b34f8199262c337825c69cf19e62e969ede2e7e791b830e3c65451bc778228e1e47d2e6369741a3dbc465579ffb2e6b5c
7
- data.tar.gz: 54c5f97421e4657da914e08f56a606e56668f9d7e42b0bed46d1a4754ee57f37b9bb7659b8474c835b9374a4ee8edeee1f249a00c2fe3333c81b986811f8613e
6
+ metadata.gz: af55744f78e88d220f83578cd1f85ac341f4b1421b1ef44c580737effc249a053a5798b8dc040385f4e08c16e2bd3c8e5a9e038d143f6a36ed14daf68e64816d
7
+ data.tar.gz: a3b2c2f18203a5472236cead6506b060010254828d8a05412863f9979b1c1c2bb4f2d0f19e250e5e320ab72ae496fc5d8c66e29779c86a86db851338b702218b
@@ -0,0 +1,9 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(bundle exec rspec:*)"
5
+ ],
6
+ "deny": [],
7
+ "ask": []
8
+ }
9
+ }
data/CLAUDE.md ADDED
@@ -0,0 +1,152 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ Icarus Mod Tools (`imt`) is a Ruby CLI gem that manages a bidirectional sync between GitHub repositories and Google Firestore for the Icarus game mods database. The tool discovers `modinfo.json` and `toolinfo.json` files across repositories and maintains a centralized Firestore database.
8
+
9
+ ## Development Commands
10
+
11
+ ### Setup & Installation
12
+
13
+ ```bash
14
+ bin/setup # Install dependencies
15
+ bundle install # Install gems
16
+ bundle exec rake install # Install gem locally
17
+ ```
18
+
19
+ ### Testing
20
+
21
+ ```bash
22
+ bundle exec rake # Run tests (default task)
23
+ bundle exec rspec # Run tests only (with Fuubar formatter)
24
+ bundle exec rspec spec/path/to/file_spec.rb # Run single test file
25
+ bundle exec rspec spec/path/to/file_spec.rb:42 # Run single test at line 42
26
+ guard # Auto-run tests on file changes
27
+ ```
28
+
29
+ ### Console & Debugging
30
+
31
+ ```bash
32
+ bin/console # Interactive IRB console with project loaded
33
+ ```
34
+
35
+ ### Running the CLI
36
+
37
+ ```bash
38
+ bundle exec exe/imt [command] # Run CLI during development
39
+ imt [command] # Run installed gem
40
+ ```
41
+
42
+ ## Architecture
43
+
44
+ ### Data Flow Pipeline
45
+
46
+ The tool implements a two-stage sync pipeline:
47
+
48
+ 1. **GitHub → Meta Collections**: Scan repositories for metadata files and sync to `meta/modinfo`, `meta/toolinfo`, `meta/repos`
49
+ 2. **Meta → Entity Collections**: Process meta lists to populate/update `mods` and `tools` collections
50
+
51
+ All operations support `--dry-run` for safe testing.
52
+
53
+ ### Core Components
54
+
55
+ **CLI Layer** (`lib/icarus/mod/cli/`)
56
+
57
+ - `Command`: Main entry point, defines subcommands (sync, list, add, remove, validate)
58
+ - `Base`: Inherited by all commands, provides `--config` and `--version` options
59
+ - `SubcommandBase`: Base for subcommands, adds `--verbose` option
60
+ - Subcommands: `Sync`, `List`, `Add`, `Remove`, `Validate` (all Thor-based)
61
+
62
+ **Data Models** (`lib/icarus/mod/tools/`)
63
+
64
+ - `Baseinfo`: Shared validation/transformation logic for mod and tool data
65
+ - `Modinfo`: Validates and processes mod metadata
66
+ - `Toolinfo`: Validates and processes tool metadata
67
+ - `Validator`: Standalone validation utilities
68
+
69
+ **Sync Operations** (`lib/icarus/mod/tools/sync/`)
70
+
71
+ - `ModinfoList`: GitHub → meta/modinfo sync
72
+ - `ToolinfoList`: GitHub → meta/toolinfo sync
73
+ - `Mods`: meta/modinfo → mods sync
74
+ - `Tools`: meta/toolinfo → tools sync
75
+ - `Helpers`: HTTP utilities with custom SSL verification for Ruby 3.4+ CRL issues
76
+
77
+ **External Services** (`lib/icarus/mod/`)
78
+
79
+ - `Firestore`: Google Cloud Firestore client with collection management
80
+ - `Github`: Octokit wrapper with recursive file discovery
81
+ - `Config`: JSON config reader for `.imtconfig.json`
82
+
83
+ ### Global State
84
+
85
+ The CLI uses a global `$firestore` variable in sync commands to share the Firestore instance across operations. This is set in `CLI::Sync` and used by sync modules.
86
+
87
+ ### Configuration
88
+
89
+ The tool reads from `~/.imtconfig.json` (configurable via `--config`):
90
+
91
+ - Firebase credentials (full JSON object, not path)
92
+ - GitHub OAuth token
93
+ - Collection paths (configurable)
94
+
95
+ See README.md for configuration structure.
96
+
97
+ ## Development Patterns
98
+
99
+ ### CLI Command Structure
100
+
101
+ All commands inherit from `CLI::Base` or `CLI::SubcommandBase`:
102
+
103
+ ```ruby
104
+ class MyCommand < CLI::SubcommandBase
105
+ desc "mycommand ARGS", "Description"
106
+ method_option :my_option, aliases: "-m", type: :string, desc: "Option description"
107
+ def mycommand(args)
108
+ # Config is already loaded by CLI::Command#initialize
109
+ # Access via Icarus::Mod::Config.config
110
+ end
111
+ end
112
+ ```
113
+
114
+ ### Error Handling
115
+
116
+ Domain errors use `Icarus::Mod::Tools::Error`. Validation errors/warnings are stored in `@errors` and `@warnings` arrays on data model instances.
117
+
118
+ ```ruby
119
+ rescue Icarus::Mod::Tools::Error => e
120
+ warn "Error: #{e.message}"
121
+ exit 1
122
+ end
123
+ ```
124
+
125
+ ### Validation Rules
126
+
127
+ All mod/tool data inherits from `Baseinfo`:
128
+
129
+ - Required fields: `name`, `author`, `description`
130
+ - URL validation for `imageURL`, `readmeURL`, file URLs
131
+ - File types must match `/\.(zip|pak|exmodz?)/i`
132
+ - Version strings should match `/^\d+[.\d+]*/`
133
+
134
+ ### SSL Certificate Handling
135
+
136
+ Ruby 3.4+ with newer OpenSSL may fail CRL checking. The codebase handles this in `Sync::Helpers#retrieve_from_url` with a custom `verify_callback` that allows `V_ERR_UNABLE_TO_GET_CRL` errors.
137
+
138
+ ### Testing Patterns
139
+
140
+ - Fixtures in `spec/fixtures/`
141
+ - Tests run in random order (`config.order = :random`)
142
+ - Use `:focus` metadata to run specific tests
143
+ - Fuubar formatter provides progress bar display
144
+
145
+ ## Key Gotchas
146
+
147
+ - **Firestore credentials**: Must be the full JSON object in config, not a file path
148
+ - **GitHub repo format**: `owner/repo` format (URL prefixes are stripped automatically)
149
+ - **Ruby version**: 3.1+ required for pattern matching and modern features
150
+ - **Platform**: WSL2/Linux recommended; not tested on Windows
151
+ - **Require paths**: The gemspec sets `require_paths` to both `lib` and `lib/icarus/mod`, so files use relative requires like `require "cli/base"` instead of `require_relative`
152
+ - **Verbosity**: `-v` and `-vv` flags control output detail in subcommands
data/Gemfile CHANGED
@@ -15,5 +15,4 @@ group :develop do
15
15
  gem "rspec", "~> 3.12"
16
16
  gem "rubocop", "~> 1.41"
17
17
  gem "rubocop-rspec", "~> 2.16", require: false
18
- gem "standard", ">= 1.35.1"
19
18
  end
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- Icarus-Mod-Tools (2.2.0)
4
+ Icarus-Mod-Tools (2.3.0)
5
5
  google-cloud-firestore (~> 2.7)
6
6
  octokit (~> 6.0)
7
7
  paint (~> 2.3)
@@ -26,8 +26,17 @@ GEM
26
26
  net-http (~> 0.5)
27
27
  faraday-retry (2.3.2)
28
28
  faraday (~> 2.0)
29
+ ffi (1.17.2)
30
+ ffi (1.17.2-aarch64-linux-gnu)
31
+ ffi (1.17.2-aarch64-linux-musl)
32
+ ffi (1.17.2-arm-linux-gnu)
33
+ ffi (1.17.2-arm-linux-musl)
34
+ ffi (1.17.2-arm64-darwin)
35
+ ffi (1.17.2-x86-linux-gnu)
36
+ ffi (1.17.2-x86-linux-musl)
29
37
  ffi (1.17.2-x86_64-darwin)
30
38
  ffi (1.17.2-x86_64-linux-gnu)
39
+ ffi (1.17.2-x86_64-linux-musl)
31
40
  formatador (1.2.2)
32
41
  reline
33
42
  fuubar (2.5.1)
@@ -64,12 +73,33 @@ GEM
64
73
  gapic-common (~> 1.2)
65
74
  google-cloud-errors (~> 1.0)
66
75
  google-logging-utils (0.2.0)
76
+ google-protobuf (4.33.0)
77
+ bigdecimal
78
+ rake (>= 13)
79
+ google-protobuf (4.33.0-aarch64-linux-gnu)
80
+ bigdecimal
81
+ rake (>= 13)
82
+ google-protobuf (4.33.0-aarch64-linux-musl)
83
+ bigdecimal
84
+ rake (>= 13)
85
+ google-protobuf (4.33.0-arm64-darwin)
86
+ bigdecimal
87
+ rake (>= 13)
88
+ google-protobuf (4.33.0-x86-linux-gnu)
89
+ bigdecimal
90
+ rake (>= 13)
91
+ google-protobuf (4.33.0-x86-linux-musl)
92
+ bigdecimal
93
+ rake (>= 13)
67
94
  google-protobuf (4.33.0-x86_64-darwin)
68
95
  bigdecimal
69
96
  rake (>= 13)
70
97
  google-protobuf (4.33.0-x86_64-linux-gnu)
71
98
  bigdecimal
72
99
  rake (>= 13)
100
+ google-protobuf (4.33.0-x86_64-linux-musl)
101
+ bigdecimal
102
+ rake (>= 13)
73
103
  googleapis-common-protos (1.9.0)
74
104
  google-protobuf (~> 4.26)
75
105
  googleapis-common-protos-types (~> 1.21)
@@ -84,12 +114,33 @@ GEM
84
114
  multi_json (~> 1.11)
85
115
  os (>= 0.9, < 2.0)
86
116
  signet (>= 0.16, < 2.a)
117
+ grpc (1.76.0)
118
+ google-protobuf (>= 3.25, < 5.0)
119
+ googleapis-common-protos-types (~> 1.0)
120
+ grpc (1.76.0-aarch64-linux-gnu)
121
+ google-protobuf (>= 3.25, < 5.0)
122
+ googleapis-common-protos-types (~> 1.0)
123
+ grpc (1.76.0-aarch64-linux-musl)
124
+ google-protobuf (>= 3.25, < 5.0)
125
+ googleapis-common-protos-types (~> 1.0)
126
+ grpc (1.76.0-arm64-darwin)
127
+ google-protobuf (>= 3.25, < 5.0)
128
+ googleapis-common-protos-types (~> 1.0)
129
+ grpc (1.76.0-x86-linux-gnu)
130
+ google-protobuf (>= 3.25, < 5.0)
131
+ googleapis-common-protos-types (~> 1.0)
132
+ grpc (1.76.0-x86-linux-musl)
133
+ google-protobuf (>= 3.25, < 5.0)
134
+ googleapis-common-protos-types (~> 1.0)
87
135
  grpc (1.76.0-x86_64-darwin)
88
136
  google-protobuf (>= 3.25, < 5.0)
89
137
  googleapis-common-protos-types (~> 1.0)
90
138
  grpc (1.76.0-x86_64-linux-gnu)
91
139
  google-protobuf (>= 3.25, < 5.0)
92
140
  googleapis-common-protos-types (~> 1.0)
141
+ grpc (1.76.0-x86_64-linux-musl)
142
+ google-protobuf (>= 3.25, < 5.0)
143
+ googleapis-common-protos-types (~> 1.0)
93
144
  guard (2.19.1)
94
145
  formatador (>= 0.2.4)
95
146
  listen (>= 2.7, < 4.0)
@@ -148,7 +199,7 @@ GEM
148
199
  ffi (~> 1.0)
149
200
  rbtree (0.4.6)
150
201
  regexp_parser (2.11.3)
151
- reline (0.6.2)
202
+ reline (0.6.3)
152
203
  io-console (~> 0.5)
153
204
  rspec (3.13.2)
154
205
  rspec-core (~> 3.13.0)
@@ -163,7 +214,7 @@ GEM
163
214
  diff-lcs (>= 1.2.0, < 2.0)
164
215
  rspec-support (~> 3.13.0)
165
216
  rspec-support (3.13.6)
166
- rubocop (1.80.2)
217
+ rubocop (1.81.7)
167
218
  json (~> 2.3)
168
219
  language_server-protocol (~> 3.17.0.2)
169
220
  lint_roller (~> 1.1.0)
@@ -171,7 +222,7 @@ GEM
171
222
  parser (>= 3.3.0.2)
172
223
  rainbow (>= 2.2.2, < 4.0)
173
224
  regexp_parser (>= 2.9.3, < 3.0)
174
- rubocop-ast (>= 1.46.0, < 2.0)
225
+ rubocop-ast (>= 1.47.1, < 2.0)
175
226
  ruby-progressbar (~> 1.7)
176
227
  unicode-display_width (>= 2.4.0, < 4.0)
177
228
  rubocop-ast (1.48.0)
@@ -183,10 +234,6 @@ GEM
183
234
  rubocop-factory_bot (2.27.1)
184
235
  lint_roller (~> 1.1)
185
236
  rubocop (~> 1.72, >= 1.72.1)
186
- rubocop-performance (1.25.0)
187
- lint_roller (~> 1.1)
188
- rubocop (>= 1.75.0, < 2.0)
189
- rubocop-ast (>= 1.38.0, < 2.0)
190
237
  rubocop-rspec (2.31.0)
191
238
  rubocop (~> 1.40)
192
239
  rubocop-capybara (~> 2.17)
@@ -204,18 +251,6 @@ GEM
204
251
  faraday (>= 0.17.5, < 3.a)
205
252
  jwt (>= 1.5, < 4.0)
206
253
  multi_json (~> 1.10)
207
- standard (1.51.1)
208
- language_server-protocol (~> 3.17.0.2)
209
- lint_roller (~> 1.0)
210
- rubocop (~> 1.80.2)
211
- standard-custom (~> 1.0.0)
212
- standard-performance (~> 1.8)
213
- standard-custom (1.0.2)
214
- lint_roller (~> 1.0)
215
- rubocop (~> 1.50)
216
- standard-performance (1.8.0)
217
- lint_roller (~> 1.1)
218
- rubocop-performance (~> 1.25.0)
219
254
  thor (1.4.0)
220
255
  unicode-display_width (3.2.0)
221
256
  unicode-emoji (~> 4.1)
@@ -223,8 +258,17 @@ GEM
223
258
  uri (1.1.1)
224
259
 
225
260
  PLATFORMS
226
- x86_64-darwin-22
227
- x86_64-linux
261
+ aarch64-linux-gnu
262
+ aarch64-linux-musl
263
+ arm-linux-gnu
264
+ arm-linux-musl
265
+ arm64-darwin
266
+ ruby
267
+ x86-linux-gnu
268
+ x86-linux-musl
269
+ x86_64-darwin
270
+ x86_64-linux-gnu
271
+ x86_64-linux-musl
228
272
 
229
273
  DEPENDENCIES
230
274
  Icarus-Mod-Tools!
@@ -236,7 +280,6 @@ DEPENDENCIES
236
280
  rspec (~> 3.12)
237
281
  rubocop (~> 1.41)
238
282
  rubocop-rspec (~> 2.16)
239
- standard (>= 1.35.1)
240
283
 
241
284
  BUNDLED WITH
242
- 2.3.26
285
+ 2.6.9
data/README.md CHANGED
@@ -58,6 +58,7 @@ Commands:
58
58
  imt add # Adds entries to the databases
59
59
  imt help [COMMAND] # Describe available commands or one specific command
60
60
  imt list # Lists the databases
61
+ imt remove # Removes entries from the databases
61
62
  imt sync # Syncs the databases
62
63
  imt validate # Validates various entries
63
64
 
@@ -104,6 +105,23 @@ Options:
104
105
  # Default: [true]
105
106
  ```
106
107
 
108
+ #### `imt remove`
109
+
110
+ ```sh
111
+ Commands:
112
+ imt remove help [COMMAND] # Describe subcommands or one specific subcommand
113
+ imt remove modinfo ITEM # Removes an entry from 'meta/modinfo/list'
114
+ imt remove toolinfo ITEM # Removes an entry from 'meta/toolinfo/list'
115
+ imt remove repos REPO # Removes an entry from 'meta/repos/list'
116
+
117
+ Options:
118
+ -C, [--config=CONFIG] # Path to the config file
119
+ # Default: /Users/dyoung/.imtconfig.json
120
+ -V, [--version], [--no-version] # Print the version and exit
121
+ -v, [--verbose], [--no-verbose] # Increase verbosity. May be repeated for even more verbosity.
122
+ # Default: [true]
123
+ ```
124
+
107
125
  #### `imt sync`
108
126
 
109
127
  ```sh
@@ -132,4 +150,4 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
132
150
 
133
151
  ## Contributing
134
152
 
135
- Bug reports and pull requests are welcome on GitHub at https://github.com/DonovanMods/icarus-mod-tools.
153
+ Bug reports and pull requests are welcome on GitHub at <https://github.com/DonovanMods/icarus-mod-tools>.
data/Rakefile CHANGED
@@ -3,10 +3,9 @@
3
3
  require "bundler/gem_tasks"
4
4
  require "rake/testtask"
5
5
  require "rspec/core/rake_task"
6
- require "standard/rake"
7
6
 
8
7
  RSpec::Core::RakeTask.new(:spec) do |task|
9
8
  task.rspec_opts = ["--color", "--format", "Fuubar"]
10
9
  end
11
10
 
12
- task default: %i[spec standard]
11
+ task default: %i[spec]
@@ -5,6 +5,7 @@ require "cli/subcommand_base"
5
5
  require "cli/sync"
6
6
  require "cli/list"
7
7
  require "cli/add"
8
+ require "cli/remove"
8
9
  require "cli/validate"
9
10
 
10
11
  module Icarus
@@ -37,6 +38,9 @@ module Icarus
37
38
  desc "add", "Adds entries to the databases"
38
39
  subcommand "add", Add
39
40
 
41
+ desc "remove", "Removes entries from the databases"
42
+ subcommand "remove", Remove
43
+
40
44
  desc "validate", "Validates various entries"
41
45
  subcommand "validate", Validate
42
46
  end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "firestore"
4
+ require "cli/subcommand_base"
5
+
6
+ module Icarus
7
+ module Mod
8
+ module CLI
9
+ # Remove CLI command definitions
10
+ # rubocop:disable Style/GlobalVars
11
+ class Remove < SubcommandBase
12
+ class_option :dry_run, type: :boolean, default: false, desc: "Dry run (no changes will be made)"
13
+
14
+ desc "repos REPO", "Removes an entry from 'meta/repos/list'"
15
+ def repos(repo)
16
+ repo_name = repo.gsub(%r{https?://.*github\.com/}, "")
17
+ remove_item(
18
+ :repositories,
19
+ repo_name,
20
+ "Repository",
21
+ "Repository not found: #{repo_name}",
22
+ "Successfully removed repository: #{repo_name}",
23
+ "Failed to remove repository: #{repo_name}"
24
+ )
25
+ end
26
+
27
+ desc "modinfo ITEM", "Removes an entry from 'meta/modinfo/list'"
28
+ def modinfo(item)
29
+ remove_item(
30
+ :modinfo,
31
+ item,
32
+ "Modinfo entry",
33
+ "Modinfo entry not found: #{item}",
34
+ "Successfully removed modinfo entry: #{item}",
35
+ "Failed to remove modinfo entry: #{item}"
36
+ )
37
+ end
38
+
39
+ desc "toolinfo ITEM", "Removes an entry from 'meta/toolinfo/list'"
40
+ def toolinfo(item)
41
+ remove_item(
42
+ :toolinfo,
43
+ item,
44
+ "Toolinfo entry",
45
+ "Toolinfo entry not found: #{item}",
46
+ "Successfully removed toolinfo entry: #{item}",
47
+ "Failed to remove toolinfo entry: #{item}"
48
+ )
49
+ end
50
+
51
+ private
52
+
53
+ def remove_item(type, item, display_name, not_found_msg, success_msg, failure_msg)
54
+ # Check existence
55
+ collection = case type
56
+ when :repositories then firestore.repositories
57
+ when :modinfo then firestore.modinfo
58
+ when :toolinfo then firestore.toolinfo
59
+ else []
60
+ end
61
+ unless collection.include?(item)
62
+ warn not_found_msg
63
+ exit 1
64
+ end
65
+
66
+ puts Paint["Removing #{display_name.downcase}: #{item}", :black] if verbose?
67
+
68
+ if options[:dry_run]
69
+ puts Paint["Dry run; no changes will be made", :yellow]
70
+ return
71
+ end
72
+
73
+ if firestore.delete(type, item)
74
+ puts Paint[success_msg, :green]
75
+ else
76
+ warn Paint[failure_msg, :red]
77
+ exit 1
78
+ end
79
+ end
80
+
81
+ def firestore
82
+ $firestore ||= Firestore.new
83
+ end
84
+ end
85
+ # rubocop:enable Style/GlobalVars
86
+ end
87
+ end
88
+ end
@@ -62,7 +62,7 @@ module Icarus
62
62
  end
63
63
 
64
64
  def sync_info(type)
65
- sync = ((type == :modinfo) ? Icarus::Mod::Tools::Sync::ModinfoList : Icarus::Mod::Tools::Sync::ToolinfoList).new(client: firestore)
65
+ sync = (type == :modinfo ? Icarus::Mod::Tools::Sync::ModinfoList : Icarus::Mod::Tools::Sync::ToolinfoList).new(client: firestore)
66
66
 
67
67
  puts "Retrieving repository Data..." if verbose?
68
68
  repositories = sync.repositories
@@ -75,19 +75,21 @@ module Icarus
75
75
  raise Icarus::Mod::Tools::Error, "no .json files found for #{type}" unless info_array&.any?
76
76
 
77
77
  if options[:dry_run]
78
- puts Paint["Dry run; no changes will be made", :orange, :bright]
78
+ puts Paint["Dry run; no changes will be made", :yellow]
79
79
  return
80
80
  end
81
81
 
82
82
  puts Paint["Saving to Firestore...", :black] if verbose?
83
83
  response = sync.update(info_array)
84
- puts response ? Paint["Success", :green, :bright] : Paint["Failure (may be no changes)", :red, :bright] if verbose?
84
+ if verbose?
85
+ puts response ? Paint["Success", :green, :bright] : Paint["Failure (may be no changes)", :red, :bright]
86
+ end
85
87
  rescue Icarus::Mod::Tools::Error => e
86
88
  warn e.message
87
89
  end
88
90
 
89
91
  def sync_list(type)
90
- sync = ((type == :mods) ? Icarus::Mod::Tools::Sync::Mods : Icarus::Mod::Tools::Sync::Tools).new(client: firestore)
92
+ sync = (type == :mods ? Icarus::Mod::Tools::Sync::Mods : Icarus::Mod::Tools::Sync::Tools).new(client: firestore)
91
93
 
92
94
  puts "Syncing #{type} to #{Config.firebase.collections.send(type)}" if verbose > 1
93
95
 
@@ -106,9 +108,7 @@ module Icarus
106
108
  puts "Validating Info Data for #{list.uniq_name}..." if verbose > 2
107
109
  unless list.valid?
108
110
  warn Paint["Skipping List #{list.uniq_name} due to validation errors", :yellow, :bright]
109
- if verbose > 1
110
- warn list.errors.map { |error| Paint[error, :red] }.join("\n")
111
- end
111
+ warn list.errors.map { |error| Paint[error, :red] }.join("\n") if verbose > 1
112
112
 
113
113
  next
114
114
  end
@@ -120,7 +120,10 @@ module Icarus
120
120
  verb = "Updating"
121
121
  end
122
122
 
123
- print format("#{verb} %-<name>60s", name: "'#{list.author || "NoOne"}/#{list.name || "Unnamed"}'") if verbose > 1
123
+ if verbose > 1
124
+ print format("#{verb} %-<name>60s",
125
+ name: "'#{list.author || 'NoOne'}/#{list.name || 'Unnamed'}'")
126
+ end
124
127
 
125
128
  if options[:dry_run]
126
129
  puts Paint["Dry run; no changes will be made", :yellow] if verbose > 1
@@ -144,7 +147,7 @@ module Icarus
144
147
 
145
148
  puts "Deleting outdated items..." if verbose?
146
149
  delete_array.each do |list|
147
- print "Deleting '#{list.author || "NoOne"}/#{list.name || "Unnamed'"}'#{" " * 20}" if verbose > 1
150
+ print "Deleting '#{list.author || 'NoOne'}/#{list.name || 'Unnamed'}'#{' ' * 20}" if verbose > 1
148
151
  response = sync.delete(list)
149
152
  puts success_or_failure(status: response) if verbose > 1
150
153
  end
@@ -41,23 +41,23 @@ module Icarus
41
41
  end
42
42
 
43
43
  def find_by_type(type:, name:, author:)
44
- instance_variable_get("@#{type}").find { |obj| obj.name == name && obj.author == author }
44
+ instance_variable_get(:"@#{type}").find { |obj| obj.name == name && obj.author == author }
45
45
  end
46
46
 
47
47
  def update(type, payload, merge: false)
48
48
  raise "You must specify a payload to update" if payload&.empty? || payload.nil?
49
49
 
50
50
  response = case type.to_sym
51
- when :modinfo, :toolinfo
52
- update_array = (send(type) + [payload]).flatten.uniq
53
- @client.doc(collections.meta.send(type)).set({list: update_array}, merge:) if update_array.any?
54
- when :repositories
55
- @client.doc(collections.meta.repositories).set({list: payload}, merge:)
56
- when :mod, :tool
57
- create_or_update(pluralize(type), payload, merge:)
58
- else
59
- raise "Invalid type: #{type}"
60
- end
51
+ when :modinfo, :toolinfo
52
+ update_array = (send(type) + [payload]).flatten.uniq
53
+ @client.doc(collections.meta.send(type)).set({ list: update_array }, merge:) if update_array.any?
54
+ when :repositories
55
+ @client.doc(collections.meta.repositories).set({ list: payload }, merge:)
56
+ when :mod, :tool
57
+ create_or_update(pluralize(type), payload, merge:)
58
+ else
59
+ raise "Invalid type: #{type}"
60
+ end
61
61
 
62
62
  response.is_a?(Google::Cloud::Firestore::DocumentReference) || response.is_a?(Google::Cloud::Firestore::CommitResponse::WriteResult)
63
63
  end
@@ -66,6 +66,12 @@ module Icarus
66
66
  case type.to_sym
67
67
  when :mod, :tool
68
68
  response = @client.doc("#{collections.send(pluralize(type))}/#{payload.id}").delete
69
+ when :modinfo, :toolinfo, :repositories
70
+ update_array = (send(type) - [payload]).flatten.uniq
71
+
72
+ response = @client.doc(collections.meta.send(type)).set({ list: update_array })
73
+ # Invalidate cache if Firestore update was successful
74
+ instance_variable_set(:"@#{type}", update_array) if response.is_a?(Google::Cloud::Firestore::CommitResponse::WriteResult)
69
75
  else
70
76
  raise "Invalid type: #{type}"
71
77
  end
@@ -81,7 +87,7 @@ module Icarus
81
87
  @client.doc(collections.meta.send(type)).get[:list]
82
88
  when :mods, :tools
83
89
  @client.col(collections.send(type)).get.map do |doc|
84
- klass = (type == :mods) ? Icarus::Mod::Tools::Modinfo : Icarus::Mod::Tools::Toolinfo
90
+ klass = type == :mods ? Icarus::Mod::Tools::Modinfo : Icarus::Mod::Tools::Toolinfo
85
91
  klass.new(doc.data, id: doc.document_id, created: doc.create_time, updated: doc.update_time)
86
92
  end
87
93
  else
@@ -44,6 +44,8 @@ module Icarus
44
44
 
45
45
  block&.call(entry)
46
46
  @resources << entry # cache the file
47
+ rescue Octokit::NotFound
48
+ warn "WARNING: Could not access #{repository}: 404 - not found"
47
49
  end
48
50
  end
49
51
 
@@ -53,10 +55,6 @@ module Icarus
53
55
  def find(pattern)
54
56
  all_files { |file| return file if /#{pattern}/i.match?(file[:name]) }
55
57
  end
56
-
57
- def get_contents(url)
58
- @client.contents(url)
59
- end
60
58
  end
61
59
  end
62
60
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Icarus
4
4
  module Mod
5
- VERSION = "2.2.0"
5
+ VERSION = "2.3.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Icarus-Mod-Tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Donovan Young
@@ -73,11 +73,11 @@ executables:
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
+ - ".claude/settings.local.json"
76
77
  - ".rspec"
77
78
  - ".ruby-version"
78
- - ".standard.yml"
79
- - ".standard_rubocop_extensions.yml"
80
79
  - CHANGELOG.md
80
+ - CLAUDE.md
81
81
  - Gemfile
82
82
  - Gemfile.lock
83
83
  - Guardfile
@@ -91,6 +91,7 @@ files:
91
91
  - lib/icarus/mod/cli/base.rb
92
92
  - lib/icarus/mod/cli/command.rb
93
93
  - lib/icarus/mod/cli/list.rb
94
+ - lib/icarus/mod/cli/remove.rb
94
95
  - lib/icarus/mod/cli/subcommand_base.rb
95
96
  - lib/icarus/mod/cli/sync.rb
96
97
  - lib/icarus/mod/cli/validate.rb
data/.standard.yml DELETED
@@ -1,2 +0,0 @@
1
- extend_config:
2
- - .standard_rubocop_extensions.yml
@@ -1,10 +0,0 @@
1
- require:
2
- - rubocop-rspec
3
-
4
- AllCops:
5
- TargetRubyVersion: 3.1
6
- NewCops: enable
7
- SuggestExtensions: false
8
-
9
- RSpec/MultipleMemoizedHelpers:
10
- Max: 10