Icarus-Mod-Tools 1.3.5 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 28209aff7606ef684d02fae74f71d498986d7d2f9d1628a84bc32dd2670c6515
4
- data.tar.gz: 26264df40cf51c3f13255262669b4615387f90010a3fec39be407c3cf3c1719b
3
+ metadata.gz: 454c2e99f2453a91be33c028cc37cdd9316527aa45aac5f991f289a1e66c7d59
4
+ data.tar.gz: fdd4d5721b78a638f61be06585bb51679472e17ce8085ea4960340aa0f0ddab4
5
5
  SHA512:
6
- metadata.gz: 32b1496f4423e4ad71231b4311061c2baf8f4d053ebbfb3f8461871b1482b589fb4f15defe272da98794157b7ca14b92f9af45c271dedccad5a2dd806078762d
7
- data.tar.gz: bc14687a8e9c9217e486c48f89b63094250119e0d9494027873a56c97daa00b73b2f39315b25cdd413ea2d92cbdfc1da8355276834ea86e4389dbe1af8cab4b8
6
+ metadata.gz: 22ca382cfd35209e8ee6cdf883bdbd51098a7e159c5dfb5bf3f5afdc1a89656989338bf5a3bd1e3df9e4911deef342b4260b63aa4b18c42bd68afff0eddcd511
7
+ data.tar.gz: 99fa6667462a2f5d6e509bb918da9f76bebcde5bf89c41acc9809a1b726251aa189cd37a7d841585534280b4fbfa37c6ad29f8044dcd1a84f871590c53523d78
data/.rubocop.yml CHANGED
@@ -47,3 +47,6 @@ RSpec/MultipleMemoizedHelpers:
47
47
  Style/Documentation:
48
48
  Exclude:
49
49
  - lib/icarus/mod/cli/*.rb # Thor command files
50
+
51
+ Style/OpenStructUse:
52
+ Enabled: false
data/CHANGES.md CHANGED
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  ## History (reverse chronological order)
6
6
 
7
+ ### v1.4 - 2023-03
8
+
9
+ **BREAKING CHANGES!**
10
+
11
+ You'll need to move your ENV variables to a config file. See the README for more details.
12
+
13
+ - Read configuration from `~/.imtconfig.json`
14
+ - bugfixes
15
+
7
16
  ### v1.3 - 2023-02
8
17
 
9
18
  - First public release
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- Icarus-Mod-Tools (1.3.5)
4
+ Icarus-Mod-Tools (1.4.0)
5
5
  google-cloud-firestore (~> 2.7)
6
6
  octokit (~> 6.0)
7
7
  thor (~> 1.2)
data/README.md CHANGED
@@ -2,22 +2,49 @@
2
2
 
3
3
  a CLI tool for managing the Icarus Mods Database
4
4
 
5
- ## Installation
5
+ ## Requirements
6
6
 
7
- `gem install icarus-mod-tools`
7
+ To use this app, you'll need to obtain the following:
8
8
 
9
- To use this app, you'll need to obtain and create the following ENV environment variables:
10
-
11
- ```sh
12
- export GITHUB_TOKEN=your_github_token
13
- export GOOGLE_APPLICATION_CREDENTIALS="path/to/your/Google-keyfile"
14
- ```
9
+ - A Github ACCESS_TOKEN (doesn't need access to any repos, this is used purely to make API calls)
10
+ - A Google Cloud Platform credentials `keyfile.json`
11
+ - Ruby 3.1 (or greater)
15
12
 
16
13
  If you aren't sure how to obtain these credentials, please see:
17
14
 
18
15
  - [Google Cloud Platform](https://cloud.google.com/docs/authentication/getting-started)
19
16
  - [GitHub](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token)
20
17
 
18
+ I _highly_ recommend using WSL2 on Windows, or a Linux distro on your machine. This app has not been tested on Windows.
19
+
20
+ ## Installation
21
+
22
+ `gem install Icarus-Mod-Tools`
23
+
24
+ ## Configuration
25
+
26
+ Create a file called `.imtconfig.json` in your home directory with the following, replacing the CAPITALIZED values with the values provided by the above links:
27
+
28
+ ```json
29
+ {
30
+ "firebase": {
31
+ "credentials": {
32
+ "copy your Google Cloud Platform keyfile.json here and remove this line": null
33
+ },
34
+ "collections": {
35
+ "modinfo": "meta/modinfo",
36
+ "repositories": "meta/repos",
37
+ "mods": "mods"
38
+ }
39
+ },
40
+ "github": {
41
+ "token": "YOUR-GITHUB-TOKEN"
42
+ }
43
+ }
44
+ ```
45
+
46
+ _Hint: Copy the contents of your Google Cloud Platform `keyfile.json` into the `credentials` section of the above file._
47
+
21
48
  ## Usage
22
49
 
23
50
  imt [options] [command]
data/exe/imt CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require "cli/base"
4
+ require "cli/command"
5
5
 
6
- Icarus::Mod::CLI::Base.start
6
+ Icarus::Mod::CLI::Command.start
@@ -0,0 +1,24 @@
1
+ {
2
+ "firebase": {
3
+ "credentials": {
4
+ "type": "service_account",
5
+ "project_id": "projectdaedalus-fb09f",
6
+ "private_key_id": "YOUR-PRIVATE-KEY-ID",
7
+ "private_key": "YOUR-PRIVATE-KEY",
8
+ "client_email": "YOUR-CLIENT-EMAIL",
9
+ "client_id": "YOUR-CLIENT-ID",
10
+ "auth_uri": "https://accounts.google.com/o/oauth2/auth",
11
+ "token_uri": "https://oauth2.googleapis.com/token",
12
+ "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
13
+ "client_x509_cert_url": "YOUR-x509-CERT-URL"
14
+ },
15
+ "collections": {
16
+ "modinfo": "meta/modinfo",
17
+ "repositories": "meta/repos",
18
+ "mods": "mods"
19
+ }
20
+ },
21
+ "github": {
22
+ "token": "YOUR-GITHUB-TOKEN"
23
+ }
24
+ }
@@ -6,7 +6,7 @@ module Icarus
6
6
  module Mod
7
7
  module CLI
8
8
  # Sync CLI command definitions
9
- class Add < SubCommandBase
9
+ class Add < SubcommandBase
10
10
  desc "modinfo", "Adds an entry to 'meta/modinfo/list'"
11
11
  def modinfo(item)
12
12
  firestore = Firestore.new
@@ -7,66 +7,19 @@ require "thor"
7
7
  module Icarus
8
8
  module Mod
9
9
  module CLI
10
- # Base class for all subcommands
11
- class SubCommandBase < Thor
12
- class_option :verbose,
13
- aliases: "-v",
14
- type: :boolean,
15
- repeatable: true,
16
- default: [true],
17
- desc: "Increase verbosity. May be repeated for even more verbosity."
18
-
19
- no_commands do
20
- def check_false
21
- options[:verbose] = [] if options[:verbose].include?(false)
22
- end
23
-
24
- def verbose
25
- check_false
26
- options[:verbose]&.count || 0
27
- end
28
-
29
- def verbose?
30
- check_false
31
- options[:verbose]&.count&.positive?
32
- end
33
- end
34
-
35
- def self.banner(command, _namespace = nil, _subcommand = false) # rubocop:disable Style/OptionalBooleanParameter
36
- "#{basename} #{subcommand_prefix} #{command.usage}"
37
- end
38
-
39
- def self.subcommand_prefix
40
- name.gsub(/.*::/, "").gsub(/^[A-Z]/) { |match| match[0].downcase }.gsub(/[A-Z]/) { |match| "-#{match[0].downcase}" }
41
- end
42
- end
10
+ # The Base CLI class for Icarus Mod Tools. This is inherited by all subcommands.
11
+ class Base < Thor
12
+ class_option :config,
13
+ aliases: "-C", type: :string, default: File.join(Dir.home, "/.imtconfig.json"),
14
+ desc: "Path to the config file"
43
15
 
44
- # Require subcommands after the SubCommandBase class is defined
45
- require "cli/sync"
46
- require "cli/list"
47
- require "cli/add"
16
+ class_option :version,
17
+ aliases: "-V", type: :boolean,
18
+ desc: "Print the version and exit"
48
19
 
49
- # The main CLI for Icarus Mod Tools
50
- class Base < Thor
51
20
  def self.exit_on_failure?
52
21
  true
53
22
  end
54
-
55
- map %w[--version -V] => :__print_version
56
-
57
- desc "--version, -V", "print the version and exit"
58
- def __print_version
59
- puts "IcarusModTool (imt) v#{Icarus::Mod::VERSION}"
60
- end
61
-
62
- desc "sync", "Syncs the databases"
63
- subcommand "sync", Sync
64
-
65
- desc "list", "Lists the databases"
66
- subcommand "list", List
67
-
68
- desc "add", "Adds entries to the databases"
69
- subcommand "add", Add
70
23
  end
71
24
  end
72
25
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cli/base"
4
+ require "cli/subcommand_base"
5
+ require "cli/sync"
6
+ require "cli/list"
7
+ require "cli/add"
8
+
9
+ module Icarus
10
+ module Mod
11
+ module CLI
12
+ # The main CLI Command class for Icarus Mod Tools
13
+ class Command < Base
14
+ def initialize(*args)
15
+ super
16
+
17
+ if options[:version]
18
+ puts "IcarusModTool (imt) v#{Icarus::Mod::VERSION}"
19
+ exit 0
20
+ end
21
+
22
+ unless File.exist?(options[:config])
23
+ warn "Could not find or read Config from '#{options[:config]}' - please create it or specify a different path with -C"
24
+ exit 1
25
+ end
26
+
27
+ Icarus::Mod::Config.read(options[:config])
28
+ end
29
+
30
+ desc "sync", "Syncs the databases"
31
+ subcommand "sync", Sync
32
+
33
+ desc "list", "Lists the databases"
34
+ subcommand "list", List
35
+
36
+ desc "add", "Adds entries to the databases"
37
+ subcommand "add", Add
38
+ end
39
+ end
40
+ end
41
+ end
@@ -7,15 +7,19 @@ module Icarus
7
7
  module Mod
8
8
  module CLI
9
9
  # Sync CLI command definitions
10
- class List < SubCommandBase
10
+ class List < SubcommandBase
11
11
  desc "modinfo", "Displays data from 'meta/modinfo/list'"
12
12
  def modinfo
13
- puts Firestore.new.list(:modinfo)
13
+ modinfos = Firestore.new.list(:modinfo)
14
+ puts modinfos
15
+ puts "Total: #{modinfos.count}" if verbose > 1
14
16
  end
15
17
 
16
18
  desc "repos", "Displays data from 'meta/repos/list'"
17
19
  def repos
18
- puts Firestore.new.list(:repositories)
20
+ repos = Firestore.new.list(:repositories)
21
+ puts repos
22
+ puts "Total: #{repos.count}" if verbose > 1
19
23
  end
20
24
 
21
25
  desc "mods", "Displays data from 'mods'"
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cli/base"
4
+
5
+ module Icarus
6
+ module Mod
7
+ module CLI
8
+ # Base class for all subcommands
9
+ class SubcommandBase < Base
10
+ class_option :verbose,
11
+ aliases: "-v", type: :boolean, repeatable: true, default: [true],
12
+ desc: "Increase verbosity. May be repeated for even more verbosity."
13
+
14
+ no_commands do
15
+ def check_false
16
+ options[:verbose] = [] if options[:verbose].include?(false)
17
+ end
18
+
19
+ def verbose
20
+ check_false
21
+ options[:verbose]&.count || 0
22
+ end
23
+
24
+ def verbose?
25
+ check_false
26
+ options[:verbose]&.count&.positive?
27
+ end
28
+ end
29
+
30
+ # rubocop:disable Style/OptionalBooleanParameter
31
+ def self.banner(command, _namespace = nil, _subcommand = false)
32
+ "#{basename} #{subcommand_prefix} #{command.usage}"
33
+ end
34
+ # rubocop:enable Style/OptionalBooleanParameter
35
+
36
+ def self.subcommand_prefix
37
+ name.gsub(/.*::/, "").gsub(/^[A-Z]/) { |match| match[0].downcase }.gsub(/[A-Z]/) { |match| "-#{match[0].downcase}" }
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -7,7 +7,7 @@ module Icarus
7
7
  module Mod
8
8
  module CLI
9
9
  # Sync CLI command definitions
10
- class Sync < SubCommandBase
10
+ class Sync < SubcommandBase
11
11
  desc "modinfo", "Reads from 'meta/repos/list' and Syncs any modinfo files we find (github only for now)"
12
12
  def modinfo
13
13
  modinfo_sync = Icarus::Mod::Tools::ModinfoSync.new
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module Icarus
6
+ module Mod
7
+ # Reads the configuration file
8
+ class Config
9
+ class << self
10
+ def config
11
+ return @config if @config
12
+
13
+ read
14
+ end
15
+
16
+ def read(config_file = self.config_file)
17
+ @config = JSON.parse(File.read(config_file), object_class: OpenStruct)
18
+ end
19
+
20
+ def firebase
21
+ @config.firebase
22
+ end
23
+
24
+ def github
25
+ @config.github
26
+ end
27
+
28
+ private
29
+
30
+ def config_file
31
+ @config_file ||= File.join(Dir.home, "/.imtconfig.json")
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -7,16 +7,11 @@ module Icarus
7
7
  module Mod
8
8
  # Helper methods for interacting with the Firestore API
9
9
  class Firestore
10
- attr_reader :client
11
-
12
- COLLECTIONS = {
13
- modinfo: "meta/modinfo",
14
- repositories: "meta/repos",
15
- mods: "mods"
16
- }.freeze
10
+ attr_reader :client, :collections
17
11
 
18
12
  def initialize
19
- @client = Google::Cloud::Firestore.new(project_id: "projectdaedalus-fb09f", credentials: ENV.fetch("GOOGLE_APPLICATION_CREDENTIALS", nil))
13
+ @client = Google::Cloud::Firestore.new(credentials: Config.firebase.credentials.to_h)
14
+ @collections = Config.firebase.collections
20
15
  end
21
16
 
22
17
  def repos
@@ -31,18 +26,18 @@ module Icarus
31
26
  @mods ||= list(:mods)
32
27
  end
33
28
 
34
- def find_mod(field, value)
35
- mods.find { |mod| mod.send(field) == value }
29
+ def find_mod(name:, author:)
30
+ mods.find { |mod| mod.name == name && mod.author == author }
36
31
  end
37
32
 
38
33
  def list(type)
39
34
  case type
40
35
  when :modinfo
41
- @client.doc(COLLECTIONS[:modinfo]).get[:list]
36
+ @client.doc(collections.modinfo).get[:list]
42
37
  when :repositories
43
- @client.doc(COLLECTIONS[:repositories]).get[:list]
38
+ @client.doc(collections.repositories).get[:list]
44
39
  when :mods
45
- @client.col(COLLECTIONS[:mods]).get.map do |doc|
40
+ @client.col(collections.mods).get.map do |doc|
46
41
  Icarus::Mod::Tools::Modinfo.new(doc.data, id: doc.document_id, created: doc.create_time, updated: doc.update_time)
47
42
  end
48
43
  else
@@ -51,11 +46,11 @@ module Icarus
51
46
  end
52
47
 
53
48
  def update_or_create_mod(payload, merge:)
54
- doc_id = payload.id || find_mod(:name, payload.name)&.id
49
+ doc_id = payload.id || find_mod(name: payload.name, author: payload.author)&.id
55
50
 
56
- return @client.doc("#{COLLECTIONS[:mods]}/#{doc_id}").set(payload.to_h, merge:) if doc_id
51
+ return @client.doc("#{collections.mods}/#{doc_id}").set(payload.to_h, merge:) if doc_id
57
52
 
58
- @client.col(COLLECTIONS[:mods]).add(payload.to_h)
53
+ @client.col(collections.mods).add(payload.to_h)
59
54
  end
60
55
 
61
56
  def update(type, payload, merge: false)
@@ -64,9 +59,9 @@ module Icarus
64
59
  case type
65
60
  when :modinfo
66
61
  update_array = (modinfo_array + [payload]).flatten.uniq
67
- response = @client.doc(COLLECTIONS[:modinfo]).set({ list: update_array }, merge:) if update_array.any?
62
+ response = @client.doc(collections.modinfo).set({ list: update_array }, merge:) if update_array.any?
68
63
  when :repositories
69
- response = @client.doc(COLLECTIONS[:repositories]).set({ list: payload }, merge:)
64
+ response = @client.doc(collections.repositories).set({ list: payload }, merge:)
70
65
  when :mod
71
66
  response = update_or_create_mod(payload, merge:)
72
67
  else
@@ -79,7 +74,7 @@ module Icarus
79
74
  def delete(type, payload)
80
75
  case type
81
76
  when :mod
82
- response = @client.doc("#{COLLECTIONS[:mods]}/#{payload.id}").delete
77
+ response = @client.doc("#{collections.mods}/#{payload.id}").delete
83
78
  else
84
79
  raise "Invalid type: #{type}"
85
80
  end
@@ -10,7 +10,7 @@ module Icarus
10
10
 
11
11
  def initialize(repo = nil)
12
12
  self.repository = repo if repo
13
- @client = Octokit::Client.new(access_token: ENV.fetch("GITHUB_TOKEN", nil))
13
+ @client = Octokit::Client.new(access_token: Config.github.token)
14
14
  @resources = []
15
15
  end
16
16
 
@@ -28,7 +28,7 @@ module Icarus
28
28
  end
29
29
 
30
30
  def find_mod(modinfo)
31
- @firestore.find_mod(:name, modinfo.name)&.id
31
+ @firestore.find_mod(name: modinfo.name, author: modinfo.author)&.id
32
32
  end
33
33
 
34
34
  def find_modinfo(modinfo)
@@ -20,6 +20,12 @@ module Icarus
20
20
  @data = data.is_a?(String) ? JSON.parse(data, symbolize_names: true) : data
21
21
  end
22
22
 
23
+ # rubocop:disable Naming/MethodName
24
+ def fileType
25
+ @data[:fileType] || "pak"
26
+ end
27
+ # rubocop:enable Naming/MethodName
28
+
23
29
  def to_json(*args)
24
30
  JSON.generate(@data, *args)
25
31
  end
@@ -28,13 +34,6 @@ module Icarus
28
34
  @data || {}
29
35
  end
30
36
 
31
- def to_s
32
- format(
33
- "%-<name>30s %-<author>20s v%-<version>10s %<description>s",
34
- name:, author:, version: (version || "None"), description:
35
- )
36
- end
37
-
38
37
  def method_missing(method_name, *_args, &)
39
38
  to_h[method_name.to_sym]&.strip
40
39
  end
@@ -7,14 +7,14 @@ require "json"
7
7
  module Icarus
8
8
  module Mod
9
9
  module Tools
10
+ class RequestFailed < StandardError; end
11
+
10
12
  # Sync helper methods
11
13
  module SyncHelpers
12
- class RequestFailed < StandardError; end
13
-
14
14
  def retrieve_from_url(url)
15
15
  res = Net::HTTP.get_response(URI(url))
16
16
 
17
- raise RequestFailed, "HTTP Request failed for #{url} (#{res.code}): #{res.message}" unless res&.code == "200"
17
+ raise Icarus::Mod::Tools::RequestFailed, "HTTP Request failed for #{url} (#{res.code}): #{res.message}" unless res&.code == "200"
18
18
 
19
19
  JSON.parse(res.body, symbolize_names: true)
20
20
  end
@@ -1,12 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "firestore"
4
- require "github"
3
+ require "config"
5
4
 
6
5
  module Icarus
7
6
  module Mod
8
7
  module Tools
9
8
  class Error < StandardError; end
9
+
10
+ # Icarus::Mod::Config.read
10
11
  end
11
12
  end
12
13
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Icarus
4
4
  module Mod
5
- VERSION = "1.3.5"
5
+ VERSION = "1.4.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Icarus-Mod-Tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.5
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Donovan Young
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-02 00:00:00.000000000 Z
11
+ date: 2023-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-cloud-firestore
@@ -71,10 +71,14 @@ files:
71
71
  - Rakefile
72
72
  - exe/imt
73
73
  - icarus-mod-tools.gemspec
74
+ - imtconfig.sample.json
74
75
  - lib/icarus/mod/cli/add.rb
75
76
  - lib/icarus/mod/cli/base.rb
77
+ - lib/icarus/mod/cli/command.rb
76
78
  - lib/icarus/mod/cli/list.rb
79
+ - lib/icarus/mod/cli/subcommand_base.rb
77
80
  - lib/icarus/mod/cli/sync.rb
81
+ - lib/icarus/mod/config.rb
78
82
  - lib/icarus/mod/firestore.rb
79
83
  - lib/icarus/mod/github.rb
80
84
  - lib/icarus/mod/tools.rb