ru.Bee 1.6.0 → 1.7.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: 400c70fb533f9935fb838941de26bd78875f64a62e1d86bed2a817904ca63a7d
4
- data.tar.gz: 23fe0b3b9334a0c34b5fb671806a58dfa0e7f2aeb48f487fe988eec2354bcdc0
3
+ metadata.gz: d4ecb77e79daf38768a10a5da26f7f1e3013734c864774e128ffb767d5d6d9a1
4
+ data.tar.gz: 1f9a6de22160db7ac4deb411278f4bb53bb94ee0a58893a9089a5eb99fd061fa
5
5
  SHA512:
6
- metadata.gz: c2d8526cbce129652658679cc1edf861e33f8479b2c8e9e3849c640fc527dd6116dfe314fc7f1fa79f8d188655a1463320a701dc46f13166b870733ef1d3bc35
7
- data.tar.gz: 386b45c69e6513448adf1ab10f6b9caf4cfc15d588b26f920dc6518489cbf6c9abc5f6404b007d65b6e9aaf71cb806cac391b3023156113e8f3e5958f3430868
6
+ metadata.gz: 312f2143e4244dec12bdd6e40a815eeb9a2cf70af31bea3ef2c5211ae4a491dc8532931ca4d0ef4529979d579f2c17e3ade73fd09c3f9f75a0b79697e3c93200
7
+ data.tar.gz: d53621c81d31e8b7e48b030762d5f58726756e3946da14a2774fd8c6239f96ccb87a4f8d4c533b862981a792a5c90a0755d22a66d6b5b5428d4df75d46ac8265
data/bin/rubee CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'fileutils'
4
-
4
+ require 'rubygems'
5
5
  require_relative '../lib/inits/print_colors'
6
6
  require_relative '../lib/rubee'
7
7
 
@@ -19,304 +19,10 @@ LOGO = <<-'LOGO'
19
19
  Ver: %s
20
20
  LOGO
21
21
 
22
- command = ARGV.first
23
-
24
- def print_logo
25
- puts "\e[36m#{LOGO % Rubee::VERSION}\e[0m" # Cyan color
26
- end
27
-
28
- if command =~ /^(start)$|^(start:(\d+))$/
29
- _, port = ARGV.first&.split(':')
30
-
31
- port ||= '7000'
32
- print_logo
33
- color_puts "Starting takeoff of ruBee server on port #{port}...", color: :yellow
34
- exec("rackup #{ENV['RACKUP_FILE']} -p #{port}")
35
- elsif command =~ /^(start_dev)$|^(start_dev:(\d+))$/
36
- _, port = ARGV.first&.split(':')
37
-
38
- port ||= '7000'
39
- print_logo
40
-
41
- color_puts "Starting takeoff of ruBee server on port #{port} in dev mode...", color: :yellow
42
-
43
- exec("rerun -- rackup --port #{port} #{ENV['RACKUP_FILE']}")
44
- elsif command == 'stop'
45
- exec('pkill -f rubee')
46
- elsif command == 'status'
47
- exec('ps aux | grep rubee')
48
- elsif command == 'react'
49
- case ARGV[1]
50
- when 'prepare'
51
- if Rubee::PROJECT_NAME == 'rubee'
52
- exec('cd ./lib && npm run prepare')
53
- else
54
- exec('npm run prepare')
55
- end
56
- when 'watch'
57
- if Rubee::PROJECT_NAME == 'rubee'
58
- exec('cd ./lib && npm run watch')
59
- else
60
- exec('npm run watch')
61
- end
62
- else
63
- color_puts("Unknown command: #{command}", color: :red)
64
- exit(1)
65
- end
66
- elsif command == 'project'
67
- project_name = ARGV[1]
68
- if project_name.nil?
69
- color_puts 'Please indicate project name.', color: :red
70
- exit 1
71
- end
72
-
73
- if project_name == 'rubee'
74
- color_puts "Error: Project 'rubee' is reserved", color: :red
75
- exit 1
76
- end
77
-
78
- source_dir = File.expand_path('../lib', __dir__)
79
- target_dir = File.expand_path("./#{project_name}", Dir.pwd)
80
-
81
- if Dir.exist?(target_dir)
82
- color_puts "Error: Project #{project_name} already exists!", color: :red
83
- exit 1
84
- end
85
-
86
- # Create target directory
87
- FileUtils.mkdir_p(target_dir)
88
-
89
- # Define blacklist
90
- blacklist_files = %w[rubee.rb print_colors.rb version.rb config.ru test_helper.rb Gemfile.lock test.yml test.db
91
- development.db production.db]
92
- blacklist_dirs = %w[rubee tests .git .github .idea node_modules db inits]
93
-
94
- # Copy files, excluding blacklisted ones
95
- Dir.glob("#{source_dir}/**/*", File::FNM_DOTMATCH).each do |file|
96
- relative_path = file.sub("#{source_dir}/", '')
97
-
98
- # Skip blacklisted directories
99
- next if blacklist_dirs.any? { |dir| relative_path.split('/').include?(dir) }
100
-
101
- # Skip blacklisted files
102
- next if blacklist_files.include?(File.basename(file))
103
-
104
- target_path = File.join(target_dir, relative_path)
105
-
106
- if File.directory?(file)
107
- FileUtils.mkdir_p(target_path)
108
- else
109
- FileUtils.cp(file, target_path)
110
- end
111
- end
112
-
113
- # create tests dir and copy test_helper.rb and user_model_test.rb
114
- FileUtils.mkdir_p("#{target_dir}/tests")
115
- FileUtils.mkdir_p("#{target_dir}/tests/models")
116
- FileUtils.mkdir_p("#{target_dir}/tests/controllers")
117
- FileUtils.cp("#{source_dir}/tests/models/user_model_test.rb", "#{target_dir}/tests/models/user_model_test.rb")
118
-
119
- # create db dir
120
- FileUtils.mkdir_p("#{target_dir}/db")
121
- FileUtils.cp("#{source_dir}/db/structure.rb", "#{target_dir}/db/structure.rb")
122
- FileUtils.cp("#{source_dir}/db/create_users.rb", "#{target_dir}/db/create_users.rb")
123
-
124
- # create inits dir
125
- FileUtils.mkdir_p("#{target_dir}/inits")
126
-
127
- # create a gemfile context
128
- gemfile = <<~GEMFILE
129
- source 'https://rubygems.org'
130
-
131
- gem 'ru.Bee'
132
- gem 'sequel'
133
- gem 'sqlite3'
134
- gem 'rake'
135
- gem 'rack'
136
- gem 'rackup'
137
- gem 'pry'
138
- gem 'pry-byebug'
139
- gem 'puma'
140
- gem 'json'
141
-
142
- group :development do
143
- gem 'rerun'
144
- gem 'minitest'
145
- gem 'rack-test'
146
- end
147
- GEMFILE
148
- # create a gemfile
149
- File.open("#{target_dir}/Gemfile", 'w') do |file|
150
- file.puts gemfile
151
- end
152
-
153
- # create test_helper.rb file
154
- test_helper = <<~TESTHELPER
155
- require "bundler/setup"
156
- Bundler.require(:test)
157
-
158
- require 'minitest/autorun'
159
- require 'rack/test'
160
- require 'rubee'
161
-
162
- Rubee::Autoload.call
163
- TESTHELPER
164
-
165
- File.open("#{target_dir}/tests/test_helper.rb", 'w') do |file|
166
- file.puts test_helper
167
- end
168
-
169
- color_puts "Project #{project_name} created successfully at #{target_dir}", color: :green
170
-
171
- elsif command == 'version'
172
- color_puts "ruBee v#{Rubee::VERSION}", color: :yellow
173
- elsif command == 'routes'
174
- file = Rubee::PROJECT_NAME == 'rubee' ? File.join('/lib', 'config/routes.rb') : 'config/routes.rb'
175
- routes = eval(File.read(file))
176
-
177
- puts routes
178
- elsif command == 'test'
179
-
180
- ENV['RACK_ENV'] = 'test'
181
- file_name = ARGV[1] # Get the first argument
182
- lib = Rubee::PROJECT_NAME == 'rubee' ? '/lib' : ''
183
- if file_name
184
- color_puts "Running #{file_name} test ...", color: :yellow
185
- exec("ruby -Itest -e \"require '.#{lib}/tests/#{file_name}'\"")
186
- else
187
- color_puts 'Running all tests ...', color: :yellow
188
- exec("ruby -Itest -e \"Dir.glob('.#{lib}/tests/**/*_test.rb').each { |file| require file }\"")
189
- end
190
- elsif %w[generate gen].include?(command)
191
- method, path = ARGV[1..2]
192
- ENV['RACK_ENV'] ||= 'development'
193
- file = Rubee::PROJECT_NAME == 'rubee' ? File.join('/lib', 'config/routes.rb') : 'config/routes.rb'
194
- routes = eval(File.read(file))
195
- route = routes.find { |route| route[:path] == path.to_s && route[:method] == method.to_sym }
196
- color_puts("Route not found with path: #{path} and method: #{method}", color: :red) unless route
197
- Rubee::Generator.new(
198
- route[:model]&.[](:name),
199
- route[:model]&.[](:attributes),
200
- "#{route[:controller]&.capitalize}Controller",
201
- route[:action],
202
- react: route[:react]
203
- ).call
204
- elsif command == 'db'
205
- Rubee::Autoload.call
206
- ENV['RACK_ENV'] ||= 'development'
207
-
208
- command, file_name = ARGV[1]&.split(':')
209
- if Rubee::PROJECT_NAME == 'rubee'
210
- Rubee::Configuration.setup(env = :test) do |config|
211
- config.database_url = { url: 'sqlite://lib/tests/test.db', env: }
212
- end
213
- Rubee::SequelObject.reconnect! unless command == 'init'
214
- end
215
-
216
- def ensure_database_exists(db_url)
217
- uri = URI.parse(db_url)
218
- case uri.scheme
219
- when 'sqlite'
220
- begin
221
- Sequel.connect(db_url)
222
- color_puts("Database #{ENV['RACK_ENV']} exists", color: :cyan)
223
- rescue Exception
224
- if File.exist?(db_path = db_url.sub(%r{^sqlite://}, ''))
225
- color_puts("Database #{ENV['RACK_ENV']} exists", color: :cyan)
226
- else
227
- Sequel.sqlite(db_path)
228
- color_puts("Database #{ENV['RACK_ENV']} created", color: :green)
229
- end
230
- end
231
- when 'postgres'
232
- begin
233
- Sequel.connect(db_url)
234
- color_puts("Database #{ENV['RACK_ENV']} exists", color: :cyan)
235
- rescue StandardError => _e
236
- con = Sequel.connect(Rubee::Configuration.get_database_url.gsub(%r{(/test|/development|/production)}, ''))
237
- con.run("CREATE DATABASE #{ENV['RACK_ENV']}")
238
- color_puts("Database #{ENV['RACK_ENV']} created", color: :green)
239
- end
240
- else
241
- color_puts("Unsupported database type: #{db_url}", color: :red)
242
- end
243
- end
244
-
245
- def generate_structure
246
- schema_hash = {}
247
-
248
- Rubee::SequelObject::DB.tables.each do |table|
249
- schema_hash[table] = {}
250
-
251
- Rubee::SequelObject::DB.schema(table).each do |column, details|
252
- schema_hash[table][column] = details
253
- end
254
- end
255
- formatted_hash = JSON.pretty_generate(schema_hash)
256
- .gsub(/"(\w+)":/, '\1:') # Convert keys to symbols
257
- .gsub(': null', ': nil') # Convert `null` to `nil`
258
-
259
- File.open('db/structure.rb', 'w') do |file|
260
- file.puts "STRUCTURE = #{formatted_hash}"
261
- end
262
-
263
- color_puts('db/structure.rb updated', color: :green)
264
- end
265
-
266
- case command
267
- when 'run'
268
- Rubee::Autoload.call
269
- file_names = if file_name == 'all'
270
- lib = Rubee::PROJECT_NAME == 'rubee' ? '/lib' : ''
271
- Dir.glob(".#{lib}/db/*.rb").map do |file|
272
- File.basename(file, '.rb')
273
- end.reject { |file| file == 'structure' }
274
- else
275
- [file_name]
276
- end
277
- Rubee::Configuration.envs.each do |env|
278
- ENV['RACK_ENV'] = env.to_s
279
- file_names.each do |file_name|
280
- color_puts("Run #{file_name} file for #{env} env", color: :cyan)
281
- Object.const_get(file_name.split('_').map(&:capitalize).join).new.call
282
- end
283
- end
284
- color_puts("Migration for #{file_name} completed", color: :green)
285
- unless Rubee::PROJECT_NAME == 'rubee'
286
- color_puts('Regenerate schema file', color: :cyan)
287
- generate_structure
288
- end
289
- when 'init'
290
- ensure_database_exists(Rubee::Configuration.get_database_url)
291
- when 'structure'
292
- generate_structure
293
- else
294
- color_puts("Unknown command: #{command}", color: :red)
295
- end
296
- elsif ['console'].include?(command)
297
- ARGV.clear
298
- ENV['RACK_ENV'] ||= 'development'
299
-
300
- Rubee::Autoload.call
301
- if Rubee::PROJECT_NAME == 'rubee'
302
- Rubee::Configuration.setup(env = :test) do |config|
303
- config.database_url = { url: 'sqlite://lib/tests/test.db', env: }
304
- end
305
- Rubee::Autoload.call
306
- Rubee::SequelObject.reconnect!
307
- end
308
-
309
- def reload
310
- app_files = Dir["./#{Rubee::APP_ROOT}/**/*.rb"]
311
- app_files.each { |file| load(file) }
312
- color_puts('Reloaded ..', color: :green)
313
- end
314
- begin
315
- # Start IRB
316
- IRB.start
317
- rescue Exception
318
- IRB.start
319
- end
22
+ if ['version', 'react', 'project'].include?(ARGV[0])
23
+ Rubee::Autoload.call([], white_list_dirs: ['rubee/cli'])
320
24
  else
321
- color_puts "Unknown command: #{command}", color: :red
25
+ Rubee::Autoload.call
322
26
  end
27
+
28
+ Rubee::CLI::Command.new(ARGV).call
@@ -6,7 +6,7 @@
6
6
  <title>React App</title>
7
7
  </head>
8
8
  <body>
9
- <div id="app"></div>
9
+ <div id="App"></div>
10
10
  <script type="module" src="/js/bundle.js"></script>
11
11
  </body>
12
12
  </html>
@@ -0,0 +1,16 @@
1
+ module ChargedHash
2
+ refine Hash do
3
+ def [](key)
4
+ return wrap(super(key)) if key?(key)
5
+
6
+ alt_key = key.is_a?(Symbol) ? key.to_s : key.to_sym
7
+ wrap(super(alt_key))
8
+ end
9
+
10
+ private
11
+
12
+ def wrap(value)
13
+ value.is_a?(Hash) ? value.extend(ChargedHash) : value
14
+ end
15
+ end
16
+ end
@@ -20,6 +20,18 @@ module ChargedString
20
20
  !plural?
21
21
  end
22
22
 
23
+ def camelize
24
+ self.split('_').map { _1.capitalize }.join
25
+ end
26
+
27
+ def snakeize
28
+ self.gsub(/::/, '_')
29
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
30
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
31
+ .tr('-', '_')
32
+ .downcase
33
+ end
34
+
23
35
  def singularize
24
36
  if end_with?('ies') && length > 3
25
37
  "#{self[0..-4]}y" # Convert "ies" to "y"
data/lib/js/app.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import React from "react";
2
2
  import { createRoot } from "react-dom/client";
3
- import { App } from "../app/views/app.tsx";
3
+ import { App } from "../app/views/App.tsx";
4
4
 
5
5
  document.addEventListener("DOMContentLoaded", () => {
6
- const container = document.getElementById("app");
6
+ const container = document.getElementById("App");
7
7
  if (container) {
8
8
  const root = createRoot(container);
9
9
  root.render(<App />);
10
10
  } else {
11
- console.error('React root element "#app" not found in DOM.');
11
+ console.error('React root element "#App" not found in DOM.');
12
12
  }
13
13
  });
@@ -1,7 +1,7 @@
1
1
  module Rubee
2
2
  class ThreadAsync
3
3
  def perform_async(**args)
4
- color_puts('WARN: ThreadAsync engine is not yet recommended for production', color: :yellow)
4
+ color_puts('WARN: ThreadAsync engine is experimental!', color: :yellow)
5
5
  ThreadPool.instance.enqueue(args[:_class], args[:options])
6
6
  end
7
7
  end
@@ -3,8 +3,8 @@ require 'singleton'
3
3
  module Rubee
4
4
  class ThreadPool
5
5
  include Singleton
6
- THREADS_LIMIT = Rubee::Configuration.get_threads_limit || 4
7
- FIBERS_LIMIT = Rubee::Configuration.get_fibers_limit || 4
6
+ THREADS_LIMIT = Rubee::Configuration.get_threads_limit || 4 unless defined?(THREADS_LIMIT)
7
+ FIBERS_LIMIT = Rubee::Configuration.get_fibers_limit || 4 unless defined?(FIBERS_LIMIT)
8
8
 
9
9
  def initialize
10
10
  @tasks = Queue.new
@@ -1,14 +1,15 @@
1
1
  module Rubee
2
2
  class Autoload
3
3
  class << self
4
- def call(black_list = [])
4
+ def call(black_list = [], **options)
5
+ load_whitelisted(options[:white_list_dirs]) && return if options[:white_list_dirs]
5
6
  # autoload all rbs
6
- root_directory = File.expand_path(File.join(__dir__, '..',))
7
+ root_directory = File.join(Rubee::ROOT_PATH, '/lib')
7
8
  priority_order_require(root_directory, black_list)
8
9
  # ensure sequel object is connected
9
10
  Rubee::SequelObject.reconnect!
10
11
 
11
- Dir.glob(File.join(APP_ROOT, '**', '*.rb')).sort.each do |file|
12
+ Dir.glob(File.join(Rubee::APP_ROOT, '**', '*.rb')).sort.each do |file|
12
13
  base_name = File.basename(file)
13
14
 
14
15
  unless base_name.end_with?('_test.rb') || (black_list + ['rubee.rb', 'test_helper.rb']).include?(base_name)
@@ -17,13 +18,21 @@ module Rubee
17
18
  end
18
19
  end
19
20
 
21
+ def load_whitelisted(white_list_dirs)
22
+ white_list_dirs.each do |dir|
23
+ Dir[File.join(Rubee::ROOT_PATH, '/lib', "#{dir}/**", '*.rb')].each do |file|
24
+ require_relative file
25
+ end
26
+ end
27
+ end
28
+
20
29
  def priority_order_require(root_directory, black_list)
21
30
  # rubee inits
22
31
  Dir[File.join(root_directory, 'inits/**', '*.rb')].each do |file|
23
32
  require_relative file unless black_list.include?("#{file}.rb")
24
33
  end
25
34
  # app inits
26
- Dir[File.join(APP_ROOT, 'inits/**', '*.rb')].each do |file|
35
+ Dir[File.join(Rubee::APP_ROOT, 'inits/**', '*.rb')].each do |file|
27
36
  require_relative file unless black_list.include?("#{file}.rb")
28
37
  end
29
38
  # rubee async
@@ -32,17 +41,17 @@ module Rubee
32
41
  end
33
42
  # app config and routes
34
43
  unless black_list.include?('base_configuration.rb')
35
- require_relative File.join(APP_ROOT, LIB,
44
+ require_relative File.join(Rubee::APP_ROOT, Rubee::LIB,
36
45
  'config/base_configuration')
37
46
  end
38
47
  # This is necessary prerequisitedb init step
39
- if !defined?(Rubee::SequelObject::DB) && (PROJECT_NAME == 'rubee')
48
+ if Rubee::PROJECT_NAME == 'rubee'
40
49
  Rubee::Configuration.setup(env = :test) do |config|
41
50
  config.database_url = { url: 'sqlite://lib/tests/test.db', env: }
42
51
  end
43
52
  end
44
53
 
45
- require_relative File.join(APP_ROOT, LIB, 'config/routes') unless black_list.include?('routes.rb')
54
+ require_relative File.join(Rubee::APP_ROOT, Rubee::LIB, 'config/routes') unless black_list.include?('routes.rb')
46
55
  # rubee extensions
47
56
  Dir[File.join(root_directory, 'rubee/extensions/**', '*.rb')].each do |file|
48
57
  require_relative file unless black_list.include?("#{file}.rb")
@@ -67,7 +76,11 @@ module Rubee
67
76
 
68
77
  require_relative File.join(root_directory,
69
78
  'rubee/models/sequel_object')
79
+
80
+ Dir[File.join(root_directory, 'rubee/cli/**', '*.rb')].each do |file|
81
+ require_relative file
82
+ end
70
83
  end
71
84
  end
72
85
  end
73
- end
86
+ end
@@ -0,0 +1,124 @@
1
+ module Rubee
2
+ module CLI
3
+ class Attach
4
+ using ChargedString
5
+
6
+ class << self
7
+ def call(command, argv)
8
+ send(command, argv)
9
+ end
10
+
11
+ def attach(argv)
12
+ new_app_name = argv[1]
13
+
14
+ # create project folde
15
+ if new_app_name.nil?
16
+ color_puts('Please indicate app name.', color: :red)
17
+ exit(1)
18
+ end
19
+
20
+ if new_app_name == 'rubee'
21
+ color_puts("Error: App 'rubee' name is reserved", color: :red)
22
+ exit(1)
23
+ end
24
+ target_dir = File.join(Rubee::APP_ROOT, new_app_name)
25
+
26
+ if Dir.exist?(target_dir)
27
+ color_puts("Error: App #{new_app_name} already exists!", color: :red)
28
+ exit(1)
29
+ end
30
+
31
+ # create controllers models view folders
32
+ FileUtils.mkdir_p(target_dir)
33
+ # creare controllers models views dirs
34
+ ['controllers', 'models', 'views'].each do |dir|
35
+ FileUtils.mkdir_p("#{target_dir}/#{dir}")
36
+ end
37
+
38
+ config_file = <<~CONFIG_FILE
39
+ Rubee::Configuration.setup(env = :test, app = :#{new_app_name}) do |config|
40
+ end
41
+ Rubee::Configuration.setup(env = :developmenti, app = :#{new_app_name}) do |config|
42
+ end
43
+ Rubee::Configuration.setup(env = :production, app = :#{new_app_name}) do |config|
44
+ end
45
+ CONFIG_FILE
46
+
47
+ File.open("#{target_dir}/#{new_app_name}_configuration.rb", 'w') do |file|
48
+ file.puts config_file
49
+ end
50
+
51
+ # create app routes.rb file
52
+ route_file = <<~ROUTE_FILE
53
+ Rubee::Router.draw do |router|
54
+ end
55
+ ROUTE_FILE
56
+
57
+ File.open("#{target_dir}/#{new_app_name}_routes.rb", 'w') do |file|
58
+ file.puts route_file
59
+ end
60
+
61
+ # copy views
62
+ copy_files(
63
+ File.join(Rubee::ROOT_PATH, '/lib/app/views'),
64
+ "#{target_dir}/views",
65
+ %w[welcome_header.erb welcome_show.erb App.tsx],
66
+ %w[utils],
67
+ app_name: new_app_name
68
+ )
69
+
70
+ # create namespace module
71
+ module_content = <<~RUBY
72
+ module #{new_app_name.camelize}
73
+ end
74
+ RUBY
75
+
76
+ File.open("#{target_dir}/#{new_app_name.snakeize}_namespace.rb", 'w') { |file| file.write(module_content) }
77
+ color_puts("App #{new_app_name} attached!", color: :green)
78
+
79
+ # create react app file
80
+ react_app_file = <<~REACT_APP_FILE
81
+ import React from 'react';
82
+
83
+ export function #{new_app_name.camelize}App() {
84
+ return (
85
+ <h1>#{new_app_name.camelize}App</h1>
86
+ );
87
+ }
88
+ REACT_APP_FILE
89
+
90
+ File.open("#{target_dir}/views/#{new_app_name.camelize}App.tsx", 'w') do |file|
91
+ file.puts react_app_file
92
+ end
93
+ end
94
+
95
+ private
96
+
97
+ def copy_files(source_dir, target_dir, blacklist_files = [], blacklist_dirs = [], **options)
98
+ Dir.glob("#{source_dir}/**/*", File::FNM_DOTMATCH).each do |file|
99
+ relative_path = file.sub("#{source_dir}/", '')
100
+ next if blacklist_dirs.any? { |dir| relative_path.split('/').include?(dir) }
101
+ next if blacklist_files.include?(File.basename(file))
102
+
103
+ target_path = File.join(target_dir, relative_path)
104
+ if File.directory?(file)
105
+ FileUtils.mkdir_p(target_path)
106
+ else
107
+ FileUtils.cp(file, target_path)
108
+ end
109
+ end
110
+ return unless options[:app_name]
111
+ # rename copied file with prefixing base name with app_name
112
+ Dir["#{target_dir}/**/*"].each do |f|
113
+ ext = File.extname(f).delete('.')
114
+ if %w[ts tsx js jsx].include?(ext)
115
+ File.rename(f, f.gsub(File.basename(f), "#{options[:app_name].camelize}#{File.basename(f)}"))
116
+ else
117
+ File.rename(f, f.gsub(File.basename(f), "#{options[:app_name].snakeize}_#{File.basename(f)}"))
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,41 @@
1
+ module Rubee
2
+ module CLI
3
+ class Command
4
+ def initialize(argv)
5
+ @command = argv[0]
6
+ @argv = argv
7
+ end
8
+
9
+ def call
10
+ factory.call(@command, @argv)
11
+ end
12
+
13
+ def factory
14
+ case @command
15
+ in /^(start|start_dev|stop|status)$/
16
+ Rubee::CLI::Server
17
+ in /^react$/
18
+ Rubee::CLI::React
19
+ in /^project$/
20
+ Rubee::CLI::Project
21
+ in /^version$/
22
+ Rubee::CLI::Version
23
+ in /^routes$/
24
+ Rubee::CLI::Routes
25
+ in /^test$/
26
+ Rubee::CLI::Test
27
+ in /^(generate|gen)$/
28
+ Rubee::CLI::Generate
29
+ in /^db$/
30
+ Rubee::CLI::Db
31
+ in /^(console|c)$/
32
+ Rubee::CLI::Console
33
+ in /^(attach|att)$/
34
+ Rubee::CLI::Attach
35
+ else
36
+ proc { color_puts("Unknown command: #{@command}", color: :red) }
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end