drakkon 0.0.3

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.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +50 -0
  3. data/bin/drakkon +16 -0
  4. data/lib/drakkon/build.rb +126 -0
  5. data/lib/drakkon/cli.rb +64 -0
  6. data/lib/drakkon/gem/bundle.rb +116 -0
  7. data/lib/drakkon/gem/cli.rb +46 -0
  8. data/lib/drakkon/gem/configure.rb +73 -0
  9. data/lib/drakkon/gem/gem.rb +56 -0
  10. data/lib/drakkon/gem/helpers/check.rb +110 -0
  11. data/lib/drakkon/gem/helpers/files.rb +57 -0
  12. data/lib/drakkon/gem/helpers/general.rb +21 -0
  13. data/lib/drakkon/gem/helpers/modules.rb +51 -0
  14. data/lib/drakkon/gem/helpers/source.rb +43 -0
  15. data/lib/drakkon/gem/install.rb +24 -0
  16. data/lib/drakkon/init.rb +85 -0
  17. data/lib/drakkon/lib/hub.rb +112 -0
  18. data/lib/drakkon/lib/images/biggest.rb +43 -0
  19. data/lib/drakkon/lib/images/blur.rb +76 -0
  20. data/lib/drakkon/lib/images/bulk_rename.rb +86 -0
  21. data/lib/drakkon/lib/images/canvas.rb +74 -0
  22. data/lib/drakkon/lib/images/cli.rb +78 -0
  23. data/lib/drakkon/lib/images/desaturate.rb +58 -0
  24. data/lib/drakkon/lib/images/flip_flop.rb +76 -0
  25. data/lib/drakkon/lib/images/gif.rb +61 -0
  26. data/lib/drakkon/lib/images/index.rb +185 -0
  27. data/lib/drakkon/lib/images/list.rb +56 -0
  28. data/lib/drakkon/lib/images/modulate.rb +69 -0
  29. data/lib/drakkon/lib/images/resize.rb +83 -0
  30. data/lib/drakkon/lib/images/roll.rb +68 -0
  31. data/lib/drakkon/lib/images/rotate.rb +60 -0
  32. data/lib/drakkon/lib/images/scale.rb +86 -0
  33. data/lib/drakkon/lib/images/sepia.rb +64 -0
  34. data/lib/drakkon/lib/images/shift.rb +89 -0
  35. data/lib/drakkon/lib/images/split.rb +93 -0
  36. data/lib/drakkon/lib/images/spritesheet.rb +85 -0
  37. data/lib/drakkon/lib/images/trim.rb +56 -0
  38. data/lib/drakkon/lib/images/white.rb +56 -0
  39. data/lib/drakkon/lib/logbot.rb +86 -0
  40. data/lib/drakkon/lib/manifest.rb +74 -0
  41. data/lib/drakkon/lib/pastel.rb +49 -0
  42. data/lib/drakkon/lib/settings.rb +130 -0
  43. data/lib/drakkon/lib/shims.rb +8 -0
  44. data/lib/drakkon/lib/version.rb +79 -0
  45. data/lib/drakkon/release.rb +3 -0
  46. data/lib/drakkon/run/commands/images.rb +14 -0
  47. data/lib/drakkon/run/commands/log.rb +57 -0
  48. data/lib/drakkon/run/commands/restart.rb +14 -0
  49. data/lib/drakkon/run/helpers.rb +60 -0
  50. data/lib/drakkon/run/reader_shim.rb +110 -0
  51. data/lib/drakkon/run/tty.rb +119 -0
  52. data/lib/drakkon/run.rb +80 -0
  53. data/lib/drakkon/setup.rb +31 -0
  54. data/lib/drakkon/skeleton/cli.rb +46 -0
  55. data/lib/drakkon/skeleton/deploy.rb +105 -0
  56. data/lib/drakkon/skeleton/helpers/check.rb +143 -0
  57. data/lib/drakkon/skeleton/helpers/general.rb +21 -0
  58. data/lib/drakkon/skeleton/helpers/source.rb +43 -0
  59. data/lib/drakkon/skeleton/install.rb +31 -0
  60. data/lib/drakkon/skeleton/template.rb +14 -0
  61. data/lib/drakkon/web.rb +68 -0
  62. data/lib/drakkon.rb +43 -0
  63. metadata +302 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: fe3b0f0a63a77864c2d03aef71e713d3200108e461f828507cc93ddf2813e2d9
4
+ data.tar.gz: 7377e89e87729eba3a86d116964838863020be2bc5f863a8d89ace95262a742a
5
+ SHA512:
6
+ metadata.gz: 9da3704ab83a2ca35cb0bf61502339580b8895a8a13008d271e5969a99da945a37000ef684507d8933cea3bdda837cb06fdd5a9ae2d0db6e3b6a403fb1cf8b49
7
+ data.tar.gz: c5e4ac342e42a7ca6498987430b9311df618033c7fa50f0ad92cbf020a8bd1cdf3871e434631c733c6f66faded93664c9092b0548ce44d68a5269ce2d1649e9f
data/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # Drakkon
2
+
3
+ Runtime Helper for DragonRuby Games!
4
+
5
+ # Requirements
6
+
7
+ - Lots
8
+
9
+ ### Ubuntu
10
+
11
+ I'm Sure there's something
12
+
13
+ ## Installation
14
+
15
+ ```
16
+ gem install drakkon
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ```
22
+ drakkon .
23
+ ```
24
+
25
+ ## Testing
26
+
27
+ ```
28
+ bundle exec rake
29
+ ```
30
+
31
+ ## Release Process
32
+
33
+ - Update CHANGELOG
34
+ - Increment `release.rb`
35
+ - Create MR
36
+ - Merge to Master
37
+
38
+ ```
39
+ # Build and Push
40
+ bundle exec rake build
41
+ gem push pkg/drakkon-1.x.x.gem
42
+ ```
43
+
44
+ ## TODO
45
+
46
+ - See Issues (Readme Todo's suck)
47
+
48
+ ## License
49
+
50
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/bin/drakkon ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'drakkon'
4
+
5
+ # Signal.trap('INT') { exit }
6
+
7
+ flair = <<~FLAIR
8
+ _______________________________________
9
+ | ___ ____ ____ _ _ _ _ ____ __ _ |
10
+ | |__> |--< |--| |-:_ |-:_ [__] | \\| |
11
+ |_______________________________________|
12
+ FLAIR
13
+
14
+ puts flair.pastel(:bright_red)
15
+
16
+ Drakkon::CLI.init
@@ -0,0 +1,126 @@
1
+ module Drakkon
2
+ # Run Command for CLI
3
+ module Build
4
+ def self.args(raw = nil)
5
+ @args ||= raw
6
+
7
+ @args
8
+ end
9
+
10
+ # General Run
11
+ # rubocop:disable Metrics/AbcSize
12
+ def self.go!(raw, publish = '--package')
13
+ Settings.ready?
14
+ args(raw)
15
+
16
+ Settings.update(:platforms, platform_setup) unless Settings.platforms?
17
+
18
+ builder = if args.empty?
19
+ Settings.platforms
20
+ else
21
+ platforms.select { |i| args.any? { |a| i.include? a } }
22
+ end
23
+
24
+ if builder.empty?
25
+ LogBot.fatal('Build',
26
+ "No valid platforms found! #{args.inspect.pastel(:red)} : #{builder.inspect.pastel(:red)}")
27
+ exit(0)
28
+ end
29
+
30
+ list = builder.join(',')
31
+ LogBot.info('Build', "Building for platforms: #{list}")
32
+
33
+ # Save Current Directory before changing to Version Directory
34
+ context = Dir.pwd
35
+ context_name = File.basename(context)
36
+ version = metadata_version(context)
37
+
38
+ # Yes... build.build! :D
39
+ Dir.chdir(version_dir) do
40
+ # Clean Up Accidental Leftovers
41
+ FileUtils.rm_r(context_name) if Dir.exist? context_name
42
+
43
+ # DragonRuby Publish doesn't like symlinks or PATH...
44
+ FileUtils.cp_r(context, context_name)
45
+
46
+ # Clean Builds Dir
47
+ FileUtils.rm_r(Dir['builds/*'])
48
+
49
+ # Remove Project's Builds Directory / Copied Version
50
+ FileUtils.rm_r("#{context_name}/builds") if Dir.exist? "#{context_name}/builds"
51
+
52
+ # Execute
53
+ system build!(list, context_name, publish)
54
+
55
+ # Preflight
56
+ FileUtils.mkdir_p("#{context}/builds")
57
+ FileUtils.mkdir_p("#{context}/builds/#{version}")
58
+
59
+ # Copy back to Project Dir
60
+ FileUtils.cp_r(Dir['builds/*'], "#{context}/builds/#{version}/")
61
+
62
+ # Copy Settings
63
+ copy = Settings.config.dig(:builds, :copy)
64
+
65
+ if copy
66
+ FileUtils.mkdir_p("#{copy}/#{version}")
67
+ FileUtils.cp(Dir['builds/*.zip'], "#{copy}/#{version}/")
68
+ end
69
+
70
+ # Clean Up
71
+ FileUtils.rm_r(context_name)
72
+ end
73
+ end
74
+ # rubocop:enable Metrics/AbcSize
75
+
76
+ def self.metadata_version(context)
77
+ File.read("#{context}/metadata/game_metadata.txt").split("\n").find { |y| y.include? 'version' }.split('=').last
78
+ end
79
+
80
+ # DEW THE BUILD
81
+ def self.build!(list, context, package = '--package')
82
+ "PATH=#{version_dir}:$PATH dragonruby-publish #{package} --platforms=#{list} #{context}"
83
+ end
84
+
85
+ def self.version_dir
86
+ "#{Hub.dir}/#{Settings.version}"
87
+ end
88
+
89
+ def self.force_images?
90
+ args.include?('images')
91
+ end
92
+
93
+ def self.force_manifest?
94
+ args.include?('manifest')
95
+ end
96
+
97
+ def self.platform_setup
98
+ prompt.multi_select('Select Platforms to build for (these will be the future default):', platforms, filter: true)
99
+ end
100
+
101
+ def self.platforms
102
+ %w[
103
+ windows-amd64
104
+ linux-amd64
105
+ macos
106
+ android-0
107
+ android
108
+ googleplay-0
109
+ googleplay
110
+ html5-0
111
+ html5
112
+ linux-raspberrypi
113
+ mac-0
114
+ oculusquest-0
115
+ oculusquest
116
+ ]
117
+ end
118
+
119
+ def self.prompt
120
+ TTY::Prompt.new(active_color: :cyan)
121
+ end
122
+
123
+ #=======================================================
124
+ end
125
+ #=======================================================
126
+ end
@@ -0,0 +1,64 @@
1
+ module Drakkon
2
+ # General Entrypoint for CLI
3
+ module CLI
4
+ # Entrypoint for the CLI
5
+ def self.init
6
+ # Home Directory Handling
7
+ Hub.init
8
+
9
+ # Split up CLI Args
10
+ cmd = ARGV[0]
11
+ args = ARGV[1..]
12
+
13
+ start(cmd&.to_sym, args)
14
+ end
15
+
16
+ def self.start(cmd, args)
17
+ case cmd
18
+ when :init then Init.go!(args)
19
+ when :setup then Setup.go!(args)
20
+ when :run then Run.go!(args)
21
+ when :build then Build.go!(args)
22
+ when :publish then Build.go!([], '')
23
+ when :images then Images::CLI.run!(args)
24
+ when :install then Version.install!(args)
25
+ when :gem then Gems::CLI.init!(args)
26
+ when :skeleton then Skeleton::CLI.init!(args)
27
+ when :versions then Version.list
28
+ when :console then console
29
+ when :web then Web.run!(args)
30
+ when :exit then exit(0)
31
+ else
32
+ start(menu, args)
33
+ end
34
+ end
35
+
36
+ def self.prompt
37
+ TTY::Prompt.new(active_color: :cyan)
38
+ end
39
+
40
+ def self.console
41
+ binding.pry
42
+ end
43
+
44
+ def self.menu
45
+ prompt.select('Wat do?', filter: true, per_page: 100) do |menu|
46
+ menu.choice name: 'run', value: :run
47
+ menu.choice name: 'setup (config/initialization)', value: :setup
48
+ menu.choice name: 'build', value: :build
49
+ menu.choice name: 'publish', value: :publish
50
+ menu.choice name: 'install (DragonRuby Versions)', value: :install
51
+ menu.choice name: 'images', value: :images
52
+ menu.choice name: 'gem (Shared Code)', value: :gem
53
+ menu.choice name: 'skeleton (Templates)', value: :skeleton
54
+ menu.choice name: 'console (pry)', value: :console
55
+ menu.choice name: 'exit', value: :exit
56
+ end
57
+ rescue TTY::Reader::InputInterrupt
58
+ exit 0
59
+ end
60
+
61
+ #=======================================================
62
+ end
63
+ #=======================================================
64
+ end
@@ -0,0 +1,116 @@
1
+ module Drakkon
2
+ module Gems
3
+ # Run Command for CLI
4
+ module Bundle
5
+ def self.build!(args, context)
6
+ return if Settings.gems.empty?
7
+
8
+ @context = context
9
+
10
+ if Settings.config[:bundle_digest] == digest && !args.include?('bundle')
11
+ LogBot.info('Gems Bundle', 'Nothing New')
12
+ return unless args.include?('bundle')
13
+ else
14
+ LogBot.info('Gems Bundle', 'Bundling')
15
+ end
16
+
17
+ idx = collect
18
+
19
+ do_the_bundle(idx)
20
+
21
+ Settings.update(:bundle_digest, digest)
22
+ rescue TTY::Reader::InputInterrupt
23
+ exit 0
24
+ end
25
+
26
+ def self.do_the_bundle(idx)
27
+ # Make Directory `app/drakkon` if it doesn't exist
28
+ FileUtils.mkdir_p('app/drakkon') unless File.directory?('app/drakkon')
29
+
30
+ # Touch the file if it doesn't exist
31
+ FileUtils.touch(bundle_file) unless File.exist?(bundle_file)
32
+
33
+ File.open(bundle_file, 'w') do |f|
34
+ # Index Writer
35
+ idx.keys.sort.reverse.each do |i|
36
+ idx[i].each do |file|
37
+ f << File.read(file)
38
+ f << "\n"
39
+ end
40
+ end
41
+
42
+ # Include other files
43
+ f << "require 'app/drakkon/image_index.rb' \n" if Settings.image_index?
44
+ f << "require 'app/drakkon/manifest.rb' \n" if Settings.manifest?
45
+
46
+ # File Close
47
+ end
48
+ end
49
+
50
+ def self.collect
51
+ idx = {}
52
+ Settings.gems.each_value do |gem|
53
+ case gem[:source].to_sym
54
+ when :local then collect_local_source(idx, gem)
55
+ else
56
+ LogBot.fatal('Bundle', "Invalid Source: #{gem[:source].pastel(:red)}")
57
+ end
58
+ end
59
+
60
+ idx
61
+ end
62
+
63
+ def self.collect_local_source(idx, gem)
64
+ path = gem[:data][:path]
65
+
66
+ # Modules
67
+ gem[:data][:modules].each do |mod|
68
+ idx[mod.weight] ||= []
69
+ mod.files.each do |file|
70
+ file_name = "#{path}/#{file}.rb"
71
+ unless File.exist?(file_name)
72
+ LogBot.fatal('Bundle',
73
+ "Module File not found #{mod.name.pastel(:bright_blue)}, #{file_name.pastel(:red)}")
74
+ next
75
+ end
76
+
77
+ idx[mod.weight].push file_name
78
+ end
79
+ end
80
+
81
+ # Files
82
+ if gem[:data].key?(:files)
83
+ gem[:data][:files].each_value do |f|
84
+ idx[f.weight] ||= []
85
+ idx[f.weight].push "#{path}/#{f.file}"
86
+ end
87
+
88
+ end
89
+
90
+ # Return
91
+ end
92
+
93
+ # ====================================================
94
+ # General Helpers
95
+ # ====================================================
96
+ def self.bundle_file
97
+ "#{drakkon_dir}/bundle.rb"
98
+ end
99
+
100
+ def self.drakkon_dir
101
+ "#{@context}/app/drakkon"
102
+ end
103
+
104
+ def self.prompt
105
+ TTY::Prompt.new(active_color: :cyan)
106
+ end
107
+
108
+ def self.digest
109
+ Digest::MD5.hexdigest Settings.gems.to_s
110
+ end
111
+
112
+ #=======================================================
113
+ end
114
+ #=======================================================
115
+ end
116
+ end
@@ -0,0 +1,46 @@
1
+ module Drakkon
2
+ module Gems
3
+ # Run Command for CLI
4
+ module CLI
5
+ def self.args(raw = [])
6
+ @args ||= raw
7
+
8
+ @args
9
+ end
10
+
11
+ # General Run
12
+ def self.init!(raw)
13
+ args(raw)
14
+ cmd = args.shift
15
+
16
+ start(cmd&.to_sym)
17
+ end
18
+
19
+ def self.start(cmd)
20
+ case cmd
21
+ when :install then Gems::Install.start(args)
22
+ when :configure then Gems::Configure.start(args)
23
+
24
+ else
25
+ start(menu)
26
+ end
27
+ end
28
+
29
+ def self.prompt
30
+ TTY::Prompt.new(active_color: :cyan)
31
+ end
32
+
33
+ def self.menu
34
+ prompt.select('Wat do?', filter: true) do |menu|
35
+ menu.choice name: 'install (New Gem)', value: :install
36
+ menu.choice name: 'configure', value: :configure unless Settings.gems.empty?
37
+ end
38
+ rescue TTY::Reader::InputInterrupt
39
+ exit 0
40
+ end
41
+
42
+ #=======================================================
43
+ end
44
+ #=======================================================
45
+ end
46
+ end
@@ -0,0 +1,73 @@
1
+ module Drakkon
2
+ module Gems
3
+ # Run Command for CLI
4
+ module Configure
5
+ def self.opts
6
+ @opts
7
+ end
8
+
9
+ def self.start(args)
10
+ if Settings.gems.empty?
11
+ LogBot.fatal('Gem Configure', 'No gems! Install one first!')
12
+ return
13
+ end
14
+
15
+ # Allow CLI/Gem Edit
16
+ # TODO: Refactor
17
+ # This feels pretty icky, would probably be good to refactor when my brain is working
18
+ gem_name = args.shift&.to_sym
19
+ gem_name = nil if !gem_name.nil? && !Settings.gems.keys.include?(gem_name)
20
+
21
+ gem_name = gem_select if gem_name.nil?
22
+ # ======================================================================
23
+
24
+ # Initial Opts
25
+ initial_opt = args.shift&.to_sym
26
+
27
+ case initial_opt || modify_options(gem_name)
28
+ when :modules
29
+ gem = Gem.new
30
+ gem.edit(gem_name, Settings.gems[gem_name], :modules)
31
+ when :files
32
+ gem = Gem.new
33
+ gem.edit(gem_name, Settings.gems[gem_name], :files)
34
+
35
+ when :delete
36
+ LogBot.info('Gem', "Removing #{gem_name.pastel(:bright_blue)}")
37
+ Settings.gems.delete gem_name
38
+ Settings.write
39
+ when :refresh
40
+ LogBot.info('Gem', "Refreshing #{gem_name.pastel(:bright_blue)} Modules")
41
+ gem = Gem.new
42
+ gem.edit(gem_name, Settings.gems[gem_name], :refresh)
43
+ end
44
+ rescue TTY::Reader::InputInterrupt
45
+ exit 0
46
+ end
47
+
48
+ def self.gem_select
49
+ prompt.select('Which gem do you want to edit?:', filter: true) do |menu|
50
+ Settings.gems.each_key do |gem|
51
+ menu.choice name: gem, value: gem
52
+ end
53
+ end
54
+ end
55
+
56
+ def self.modify_options(gem_name)
57
+ prompt.select("Editing #{gem_name.pastel(:bright_blue)}. What do you want to do?", filter: true) do |menu|
58
+ menu.choice name: 'Edit Modules', value: :modules
59
+ menu.choice name: 'Edit Files', value: :files
60
+ menu.choice name: 'Refresh Modules', value: :refresh
61
+ menu.choice name: 'Remove', value: :remove
62
+ end
63
+ end
64
+
65
+ def self.prompt
66
+ TTY::Prompt.new(active_color: :cyan)
67
+ end
68
+
69
+ #=======================================================
70
+ end
71
+ #=======================================================
72
+ end
73
+ end
@@ -0,0 +1,56 @@
1
+ module Drakkon
2
+ module Gems
3
+ # Placeholders
4
+ module GemHelpers
5
+ end
6
+
7
+ # General Encompasing thingy
8
+ class Gem
9
+ include GemHelpers
10
+ attr_accessor :args, :opts, :name, :data, :source, :config, :modules
11
+
12
+ def initialize(opts = {})
13
+ @opts = opts
14
+ @data = {}
15
+ end
16
+
17
+ def edit(name, details, action = :modules)
18
+ @name = name.to_sym
19
+ @source = details[:source]
20
+ @data = details[:data]
21
+ do_the_check(installing: false)
22
+
23
+ case action
24
+ when :modules then select_modules
25
+ when :files then select_files
26
+ when :refresh then refresh_modules
27
+ end
28
+
29
+ update_gem_data
30
+ end
31
+
32
+ def intall_setup(args)
33
+ @args = args
34
+ source_setup
35
+ do_the_check
36
+ select_modules
37
+
38
+ update_gem_data
39
+ end
40
+
41
+ def update_gem_data
42
+ gem_data = {
43
+ source:,
44
+ data:
45
+ }
46
+
47
+ Settings.gems[name.to_sym] = gem_data
48
+ Settings.write
49
+ end
50
+
51
+ def prompt_source; end
52
+ # ========================================================================
53
+ end
54
+ # ========================================================================
55
+ end
56
+ end
@@ -0,0 +1,110 @@
1
+ module Drakkon
2
+ module Gems
3
+ # General Helpers for Gem Class
4
+ module GemHelpers
5
+ def do_the_check(installing: true)
6
+ unless File.exist? config_file
7
+ LogBot.fatal('Gem', "Drakkon config file not found! #{config_file}")
8
+ exit 0
9
+ end
10
+
11
+ # Validate Config Structure
12
+ read_config
13
+
14
+ # Valid Structure - Name
15
+ valid_structure?
16
+
17
+ # Validate / Find Valid Modules
18
+ load_modules
19
+
20
+ # Check for Conflict
21
+ return if installing == false
22
+
23
+ if Settings.config[:gems].key?(name)
24
+ LogBot.fatal('Gem', 'Duplicate Gem already installed')
25
+ exit 0
26
+ end
27
+
28
+ # I hate the other syntax
29
+ :return
30
+ end
31
+
32
+ def valid_structure?
33
+ unless config.key? :name
34
+ LogBot.fatal('Gem', 'Name not found!')
35
+ exit 0
36
+ end
37
+
38
+ @name = config[:name].to_sym
39
+
40
+ # Validate Versioning
41
+ valid_version?
42
+ end
43
+
44
+ def valid_version?
45
+ unless config.key? :version
46
+ LogBot.fatal('Gem', 'Version not found')
47
+ exit 0
48
+ end
49
+
50
+ Semantic::Version.new config[:version]
51
+ rescue StandardError => e
52
+ LogBot.fatal('Gem',
53
+ "Invalid Version: #{config[:version].pastel.to_s.pastel(:green)}; #{e.message.pastel(:yellow)}")
54
+ exit 0
55
+ end
56
+
57
+ def load_modules
58
+ @modules = config[:modules].select do |mod|
59
+ valid_mod?(mod)
60
+ end
61
+
62
+ return unless module_duplicates?
63
+
64
+ LogBot.fatal('Gem', "Duplicate Modules: #{module_duplicates}")
65
+ exit 0
66
+ end
67
+
68
+ def valid_mod?(mod)
69
+ unless mod.key?(:name)
70
+ LogBot.fatal('Gem', "Invalid Mod. No name found: #{mod}")
71
+ return false
72
+ end
73
+
74
+ unless files_exist?(mod[:files])
75
+ LogBot.fatal('Gem', "Invalid Mod: Not all files found: #{mod}")
76
+ return false
77
+ end
78
+
79
+ true
80
+ end
81
+
82
+ def files_exist?(files)
83
+ files.all? do |file|
84
+ if File.exist?("#{data[:path]}/#{file}.rb")
85
+ true
86
+ else
87
+ LogBot.fatal('Gem', "Missing File: #{file.pastel(:red)}")
88
+ exit 1
89
+ end
90
+ end
91
+ end
92
+
93
+ def module_index
94
+ modules.map(&:name)
95
+ end
96
+
97
+ # Helper to make easier to identify dupes
98
+ def module_duplicates
99
+ module_index.tally.select { |_, count| count > 1 }.keys
100
+ end
101
+
102
+ def module_duplicates?
103
+ module_index.count != module_index.uniq.count
104
+ end
105
+
106
+ # =============================================================
107
+ end
108
+ # =============================================================
109
+ end
110
+ end