drakkon 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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