DEV: improves rails plugin generator (#7949)

Fixes bugs, simplifies code, more default files. General idea, more is more here as it's easier to just delete things than reading and passing all the options.
This commit is contained in:
Joffrey JAFFEUX 2019-07-27 18:21:44 +02:00 committed by GitHub
parent 3324747afe
commit d83f99fc2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 193 additions and 95 deletions

View File

@ -3,75 +3,99 @@
require 'rails/generators/named_base' require 'rails/generators/named_base'
class PluginGenerator < Rails::Generators::NamedBase class PluginGenerator < Rails::Generators::NamedBase
attr_writer :about
attr_writer :github_username attr_writer :github_username
desc 'This generator creates a Discourse plugin skeleton' desc 'This generator creates a Discourse plugin skeleton'
source_root File.expand_path('templates', __dir__) source_root File.expand_path('templates', __dir__)
class_option :controller, type: :boolean, desc: "Generate controller", default: true class_option :no_license, type: :boolean, desc: "No license", default: false
class_option :spec, type: :boolean, desc: "Generate spec", default: true
class_option :acceptance, type: :boolean, desc: "Generate acceptance test", default: true
class_option :stylesheet, type: :boolean, desc: "Generate Stylesheet", default: true
class_option :javascript, type: :boolean, desc: "Generate Javascript initializer", default: true
class_option :scheduled_job, type: :boolean, desc: "Generate scheduled job", default: false
class_option :help, type: :boolean, desc: "Adds help comments in generated files", default: true
def create_acceptance_file def create_plugin
return unless @options['acceptance'] @about ||= ask("What is the purpose of your plugin?")
@github_username ||= ask("Github username?")
template 'acceptance-test.js.es6.erb', File.join('plugins', dasherized_name, "test/javascripts/acceptance", "#{dasherized_name}-test.js.es6") readme_file
routes_file
engine_file
plugin_file
controller_file
license_file
stylesheet_file
javascript_file
settings_file
locales_file
end end
def create_spec_file def controller_file
return if !@options['spec'] || !@options['controller'] template 'plugin_controller.rb.erb', File.join('plugins', dasherized_name, "app/controllers/#{dasherized_name}/#{underscored_name}_controller.rb")
template 'controller.rb.erb', File.join('plugins', dasherized_name, "app/controllers/#{dasherized_name}/actions_controller.rb")
template 'controller_spec.rb.erb', File.join('plugins', dasherized_name, "spec/requests/actions_controller_spec.rb") template 'controller_spec.rb.erb', File.join('plugins', dasherized_name, "spec/requests/actions_controller_spec.rb")
end end
def create_scheduled_job_file def readme_file
return unless @options['scheduled_job']
path = File.join('plugins', dasherized_name, 'jobs/scheduled', "check_#{underscored_name}.rb")
template 'scheduled_job.rb.erb', path
end
def create_readme_file
ensure_github_username
template 'README.md.erb', File.join('plugins', dasherized_name, "README.md") template 'README.md.erb', File.join('plugins', dasherized_name, "README.md")
end end
def create_license_file def license_file
ensure_github_username return if @options['no_license']
template 'LICENSE.erb', File.join('plugins', dasherized_name, "LICENSE") template 'LICENSE.erb', File.join('plugins', dasherized_name, "LICENSE")
end end
def create_plugin_file def engine_file
ensure_github_username template 'engine.rb.erb', File.join('plugins', dasherized_name, "lib", dasherized_name, "engine.rb")
end
def routes_file
template 'routes.rb.erb', File.join('plugins', dasherized_name, "config", "routes.rb")
template 'route_constraint.rb.erb', File.join('plugins', dasherized_name, "lib", "#{underscored_name}_constraint.rb")
end
def plugin_file
template 'plugin.rb.erb', File.join('plugins', dasherized_name, "plugin.rb") template 'plugin.rb.erb', File.join('plugins', dasherized_name, "plugin.rb")
end end
def create_stylesheet_file def stylesheet_file
return unless @options['stylesheet']
template 'stylesheet.scss.erb', File.join('plugins', dasherized_name, 'assets/stylesheets/common', "#{dasherized_name}.scss") template 'stylesheet.scss.erb', File.join('plugins', dasherized_name, 'assets/stylesheets/common', "#{dasherized_name}.scss")
template 'stylesheet.scss.erb', File.join('plugins', dasherized_name, 'assets/stylesheets/desktop', "#{dasherized_name}.scss")
template 'stylesheet.scss.erb', File.join('plugins', dasherized_name, 'assets/stylesheets/mobile', "#{dasherized_name}.scss")
end end
def create_javascript_file def javascript_file
return unless @options['javascript'] template 'acceptance-test.js.es6.erb', File.join('plugins', dasherized_name, "test/javascripts/acceptance", "#{dasherized_name}-test.js.es6")
template 'javascript.js.es6.erb', File.join('plugins', dasherized_name, 'assets/javascripts/initializers', "#{dasherized_name}.js.es6")
template 'route-map.js.es6.erb', File.join('plugins', dasherized_name, 'assets/javascripts/discourse', "#{dasherized_name}-route-map.js.es6")
template 'javascript.es6.erb', File.join('plugins', dasherized_name, 'assets/javascripts/initializers', "#{dasherized_name}.es6") folder = 'assets/javascripts/discourse/templates'
template "#{folder}/template.hbs.erb", path(folder, "actions.hbs")
template "#{folder}/template-show.hbs.erb", path(folder, "actions-show.hbs")
template "#{folder}/template-index.hbs.erb", path(folder, "actions-index.hbs")
folder = 'assets/javascripts/discourse/routes'
template "#{folder}/route.js.es6.erb", path(folder, "#{dasherized_name}-actions.js.es6")
template "#{folder}/route-show.js.es6.erb", path(folder, "#{dasherized_name}-actions-show.js.es6")
template "#{folder}/route-index.js.es6.erb", path(folder, "#{dasherized_name}-actions-index.js.es6")
folder = 'assets/javascripts/discourse/controllers'
template "#{folder}/controller.js.es6.erb", path(folder, "actions.js.es6")
template "#{folder}/controller-show.js.es6.erb", path(folder, "actions-show.js.es6")
template "#{folder}/controller-index.js.es6.erb", path(folder, "actions-index.js.es6")
folder = 'assets/javascripts/discourse/models'
template "#{folder}/model.js.es6.erb", path(folder, "action.js.es6")
folder = 'assets/javascripts/discourse/adapters'
template "#{folder}/adapter.js.es6.erb", path(folder, "action.js.es6")
end end
def create_settings_file def settings_file
template 'settings.yml.erb', File.join('plugins', dasherized_name, 'config', 'settings.yml') template 'settings.yml.erb', File.join('plugins', dasherized_name, 'config', 'settings.yml')
end end
def create_locales_file def locales_file
template 'client.en.yml.erb', File.join('plugins', dasherized_name, 'config/locales', 'client.en.yml') template 'client.en.yml.erb', path('config/locales/client.en.yml')
template 'server.en.yml.erb', File.join('plugins', dasherized_name, 'config/locales', 'server.en.yml') template 'server.en.yml.erb', File.join('plugins', dasherized_name, 'config/locales', 'server.en.yml')
end end
@ -83,10 +107,6 @@ class PluginGenerator < Rails::Generators::NamedBase
end end
end end
def ensure_github_username
@github_username ||= ask("Github username?")
end
def underscored_name def underscored_name
name.underscore name.underscore
end end
@ -98,4 +118,8 @@ class PluginGenerator < Rails::Generators::NamedBase
def classified_name def classified_name
name.tableize.classify name.tableize.classify
end end
def path(*args)
File.join('plugins', dasherized_name, args)
end
end end

View File

@ -0,0 +1,7 @@
import RestAdapter from "discourse/adapters/rest";
export default RestAdapter.extend({
basePath() {
return "/<%= dasherized_name %>/";
}
});

View File

@ -0,0 +1,4 @@
export default Ember.Controller.extend({
actions: {
}
});

View File

@ -0,0 +1,4 @@
export default Ember.Controller.extend({
actions: {
}
});

View File

@ -0,0 +1 @@
export default Ember.Controller.extend({});

View File

@ -0,0 +1,3 @@
import RestModel from "discourse/models/rest";
export default RestModel.extend({});

View File

@ -0,0 +1,11 @@
export default Discourse.Route.extend({
controllerName: "actions-index",
model(params) {
return this.store.findAll("action");
},
renderTemplate() {
this.render("actions-index");
}
});

View File

@ -0,0 +1,11 @@
export default Discourse.Route.extend({
controllerName: "actions-show",
model(params) {
return this.store.find("action", params.id);
},
renderTemplate() {
this.render("actions-show");
}
});

View File

@ -0,0 +1,7 @@
export default Discourse.Route.extend({
controllerName: "actions",
renderTemplate() {
this.render("actions");
}
});

View File

@ -0,0 +1 @@
controller-show.hbs id: {{model.id}}

View File

@ -0,0 +1,3 @@
controller.hbs
{{outlet}}

View File

@ -0,0 +1,15 @@
module <%= classified_name %>
class ActionsController < ::ApplicationController
requires_plugin <%= classified_name %>
before_action :ensure_logged_in
def index
render_json_dump({ actions: [] })
end
def show
render_json_dump({ action: { id: params[:id] } })
end
end
end

View File

@ -0,0 +1,12 @@
module <%= classified_name %>
class Engine < ::Rails::Engine
engine_name "<%= classified_name %>".freeze
isolate_namespace <%= classified_name %>
config.after_initialize do
Discourse::Application.routes.append do
mount ::<%= classified_name %>::Engine, at: "/<%= dasherized_name %>"
end
end
end
end

View File

@ -1,16 +0,0 @@
import { withPluginApi } from "discourse/lib/plugin-api";
function initialize<%= classified_name %>(api) {
<% if @options['help'] %>
// see app/assets/javascripts/discourse/lib/plugin-api
// for the functions available via the api object
<% end %>
}
export default {
name: "<%= dasherized_name %>",
initialize() {
withPluginApi("0.8.24", initialize<%= classified_name %>);
}
};

View File

@ -0,0 +1,13 @@
import { withPluginApi } from "discourse/lib/plugin-api";
function initialize<%= classified_name %>(api) {
// https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/lib/plugin-api.js.es6
}
export default {
name: "<%= dasherized_name %>",
initialize() {
withPluginApi("0.8.31", initialize<%= classified_name %>);
}
};

View File

@ -1,51 +1,19 @@
# name: <%= name %> # name: <%= name %>
# about: # about: <%= @about %>
# version: 0.1 # version: 0.1
# authors: <%= @github_username %> # authors: <%= @github_username %>
# url: https://github.com/<%= @github_username %> # url: https://github.com/<%= @github_username %>
<% if @options["stylesheet"] %>
register_asset "stylesheets/common/<%= dasherized_name %>.scss" register_asset "stylesheets/common/<%= dasherized_name %>.scss"
<% end %> register_asset "stylesheets/desktop/<%= dasherized_name %>.scss"
register_asset "stylesheets/mobile/<%= dasherized_name %>.scss"
enabled_site_setting :<%= underscored_name %>_enabled enabled_site_setting :<%= underscored_name %>_enabled
PLUGIN_NAME ||= "<%= name %>".freeze PLUGIN_NAME ||= "<%= classified_name %>".freeze
load File.expand_path('../lib/<%= dasherized_name %>/engine.rb', __FILE__)
after_initialize do after_initialize do
<% if @options['help'] %> # https://github.com/discourse/discourse/blob/master/lib/plugin/instance.rb
# see lib/plugin/instance.rb for the methods available in this context
<% end %>
module ::<%= classified_name %>
class Engine < ::Rails::Engine
engine_name PLUGIN_NAME
isolate_namespace <%= classified_name %>
end
end
<% if @options["scheduled_job"] %>
require File.expand_path("../jobs/scheduled/check_<%= underscored_name %>.rb", __FILE__)
<% end %>
<% if @options["controller"] %>
require_dependency "application_controller"
class <%= name %>::ActionsController < ::ApplicationController
requires_plugin PLUGIN_NAME
before_action :ensure_logged_in
def list
render json: success_json
end
end
<%= name %>::Engine.routes.draw do
get "/list" => "actions#list"
end
Discourse::Application.routes.append do
mount ::<%= name %>::Engine, at: "/<%= dasherized_name %>"
end
<% end %>
end end

View File

@ -0,0 +1,10 @@
module <%= classified_name %>
class <%= classified_name %>Controller < ::ApplicationController
requires_plugin <%= classified_name %>
before_action :ensure_logged_in
def index
end
end
end

View File

@ -0,0 +1,7 @@
export default function() {
this.route("<%= dasherized_name %>", function() {
this.route("actions", function() {
this.route("show", { path: "/:id" });
});
});
};

View File

@ -0,0 +1,5 @@
class <%= classified_name %>Constraint
def matches?(request)
SiteSetting.<%= underscored_name %>_enabled
end
end

View File

@ -0,0 +1,7 @@
require_dependency "<%= underscored_name %>_constraint"
<%= classified_name %>::Engine.routes.draw do
get "/" => "<%= dasherized_name %>#index", constraints: <%= classified_name %>Constraint.new
get "/actions" => "actions#index", constraints: <%= classified_name %>Constraint.new
get "/actions/:id" => "actions#show", constraints: <%= classified_name %>Constraint.new
end