Last active
March 6, 2023 06:00
-
-
Save xiaohui-zhangxh/6d1fd342bb1d6ca6f0caf706ff9aaf61 to your computer and use it in GitHub Desktop.
Rails 项目在 engines/ 目录下生成子模块 engine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
name = ARGV[0] | |
if name.to_s.strip.empty? | |
puts "usage: bin/create_engine <name>" | |
exit(1) | |
end | |
cmd = <<-CMD | |
bin/rails plugin new engines/#{name}_engine \ | |
-m plugin_template.rb \ | |
--full \ | |
--database postgresql \ | |
--javascript esbuild \ | |
--css tailwind \ | |
--asset-pipeline propshaft \ | |
--skip-jbuilder \ | |
-T \ | |
--dummy-path spec/dummy | |
CMD | |
Dir.chdir(File.expand_path('..', __dir__)) do | |
system(cmd) | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 1. 把这两个文件复制在 Rails 项目目录 | |
# 2. 下载之后,把 create_engine 放入 bin/目录,赋予可执行权限,执行 | |
# | |
# chmod +x bin/create_engine | |
# | |
# 3. 执行以下命令创建 engine | |
# | |
# bin/create_engine <name> | |
# | |
bin/create_engine cms |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 通过 bin/create_engine xxx 创建的 engine 项目,会使用 plugin_template.rb 作为模板。 | |
engine_name = @name.sub('_engine', '') | |
remove_dir '.git' | |
# remove TODO comments | |
gsub_file "#{@name}.gemspec", %(TODO: Set to 'http://mygemserver.com'), '' | |
gsub_file "#{@name}.gemspec", %("TODO: Put your gem's public repo URL here."), 'spec.homepage' | |
gsub_file "#{@name}.gemspec", %("TODO: Put your gem's CHANGELOG.md URL here."), 'spec.homepage' | |
gsub_file "#{@name}.gemspec", %(spec.homepage = "TODO"), %(spec.homepage = "http://www.tanmer.com") | |
gsub_file "#{@name}.gemspec", /\s*TODO:\s*/, '' | |
inject_into_file "#{@name}.gemspec", after: "Gem::Specification.new do |spec|\n" do | |
" spec.required_ruby_version = '~> 3.2.0' | |
" | |
end | |
append_file '.gitignore', "/node_modules/\n" | |
# add gems | |
gem 'rspec-rails' | |
gem 'factory_bot_rails' | |
gem 'shoulda-matchers' | |
gem 'annotate' | |
gem 'faker' | |
gem 'guard' | |
gem 'guard-rspec' | |
gem 'pry-remote' | |
# install gems | |
bundle_path = Gem.bin_path("bundler", "bundle") | |
require 'bundler' | |
Bundler.with_unbundled_env do | |
exec_bundle_command bundle_path, 'install', '' | |
# config gems | |
generate 'rspec:install' | |
generate 'annotate:install' | |
run 'bundle exec guard init rspec' | |
end | |
create_file 'bin/pry-remote', <<~CODE | |
#!/usr/bin/env ruby | |
puts "Starting pry-remote, keep watching remote pry..." | |
while system("pry-remote -w"); end | |
CODE | |
chmod 'bin/pry-remote', 0755 # rubocop: disable Style/NumericLiteralPrefix | |
gsub_file 'spec/rails_helper.rb', "require_relative '../config/environment'", "require_relative './dummy/config/environment'" | |
inject_into_file 'spec/rails_helper.rb', before: "ActiveRecord::Migration.maintain_test_schema!" do | |
"ActiveRecord::Migrator.migrations_paths = [File.expand_path('../dummy/db/migrate', __dir__)] | |
" | |
end | |
inject_into_file 'spec/rails_helper.rb', before: "RSpec.configure do |config|" do | |
" | |
Shoulda::Matchers.configure do |config| | |
config.integrate do |with| | |
with.test_framework :rspec | |
with.library :rails | |
end | |
end | |
" | |
end | |
inject_into_file 'spec/rails_helper.rb', after: "RSpec.configure do |config|\n" do | |
" config.include FactoryBot::Syntax::Methods | |
" | |
end | |
# add admin route path | |
inject_into_module "lib/#{@name}.rb", @camelized do | |
" mattr_accessor :admin_route_path, default: 'admin' | |
mattr_accessor :admin_base_controller, default: 'ApplicationController' | |
mattr_accessor :desk_base_controller, default: 'ApplicationController' | |
" | |
end | |
inject_into_file "lib/#{@name}/engine.rb", after: "Engine < ::Rails::Engine\n" do | |
" engine_name '#{engine_name}' | |
config.#{@name} = ActiveSupport::OrderedOptions.new | |
config.generators do |g| | |
g.test_framework :rspec | |
g.fixture_replacement :factory_bot | |
g.factory_bot dir: 'spec/factories' | |
end | |
initializer '#{@name}.set_factory_paths', after: 'factory_bot.set_factory_paths' do |_app| | |
FactoryBot.definition_file_paths += [File.expand_path('../../spec/factories', __dir__)] if defined?(FactoryBotRails) | |
end | |
initializer '#{@name}.add_migration_paths', before: :before_initialize do |app| | |
app.config.paths['db/migrate'] << root.join('db/migrate') unless app.root.to_s.match?(root.to_s) | |
end | |
initializer '#{@name}.add_routing_paths', before: :add_routing_paths do |app| | |
app.config.paths['config/routes'] << root.join('config/routes') | |
end | |
initializer '#{@name}.add_assets_paths', before: :before_initialize do |app| | |
app.config.paths['app/assets'] << root.join('app/assets') | |
end | |
config.after_initialize do | |
config.after_initialize do | |
%i[admin_route_path admin_base_controller desk_base_controller].each do |key| | |
#{@camelized}.send \"\#{key}=\", config.#{@name}[key] if config.#{@name}.key?(key) | |
end | |
end | |
end | |
config.to_prepare do | |
ActiveSupport.on_load 'models.organization.associations' do | |
# has_many :communities, dependent: :destroy | |
end | |
end | |
" | |
end | |
# rename dummy database names | |
remove_file "#{dummy_path}/config/database.yml" | |
create_file "#{dummy_path}/config/database.yml", <<~YAML | |
default: &default | |
adapter: postgresql | |
encoding: unicode | |
development: | |
<<: *default | |
database: #{@name}_dummy_development | |
test: | |
<<: *default | |
database: #{@name}_dummy_test | |
YAML | |
# create routes directory | |
remove_file 'config/routes.rb' | |
empty_directory 'config/routes' | |
create_file 'config/routes.rb', <<~RUBY | |
Rails.application.routes.draw do | |
# !!! usually you don't need to define route from here. | |
end | |
RUBY | |
create_file "config/routes/#{@name}.rb", <<~RUBY | |
# place your routes here, usually draw all routes from sub directories | |
draw '#{@name}/admin' | |
draw '#{@name}/desk' | |
draw '#{@name}/portal' | |
RUBY | |
empty_directory "config/routes/#{@name}" | |
create_file "config/routes/#{@name}/admin.rb", <<~RUBY | |
# place your admin routes here | |
scope #{@camelized}.admin_route_path do | |
namespace :#{engine_name} do | |
namespace :admin, patgh: '' do | |
# root to: 'dashboard#index' | |
# resources :users | |
end | |
end | |
end | |
RUBY | |
create_file "config/routes/#{@name}/desk.rb", <<~RUBY | |
# place your desk routes here | |
namespace :#{engine_name} do | |
# setup your app resources | |
root to: redirect("/#{engine_name}/apps") | |
resources :apps, except: [:show] | |
namespace :desk, path: ':#{engine_name}_identifier' do | |
root to: 'dashboard#index' | |
scope '-' do | |
# resources :users | |
end | |
end | |
end | |
RUBY | |
create_file "config/routes/#{@name}/portal.rb", <<~RUBY | |
# place your portal routes here | |
namespace :#{engine_name}, path: '' do | |
namespace :portal, path: '' do | |
# get '(/*path)', to: 'pages#show', as: :page | |
end | |
end | |
RUBY | |
inject_into_file "#{dummy_path}/config/routes.rb", after: "Rails.application.routes.draw do\n" do | |
" draw '#{@name}' | |
" | |
end | |
create_file "#{dummy_path}/config/initializers/#{@name}.rb", <<~RUBY | |
Rails.application.config.#{@name}.admin_route_path = '/admin' | |
RUBY |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment