service_template 0.5.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 +7 -0
- data/.gitignore +21 -0
- data/.rubocop.yml +23 -0
- data/.travis.yml +13 -0
- data/CHANGELOG.md +64 -0
- data/Gemfile +4 -0
- data/LICENSE +24 -0
- data/README.md +217 -0
- data/Rakefile +9 -0
- data/bin/service_template +5 -0
- data/lib/service_template.rb +55 -0
- data/lib/service_template/active_record_extensions/notifications_subscriber.rb +17 -0
- data/lib/service_template/active_record_extensions/seeder.rb +14 -0
- data/lib/service_template/active_record_extensions/stats.rb +37 -0
- data/lib/service_template/authentication.rb +8 -0
- data/lib/service_template/cli.rb +111 -0
- data/lib/service_template/deploy.rb +98 -0
- data/lib/service_template/gem_dependency.rb +37 -0
- data/lib/service_template/generators.rb +3 -0
- data/lib/service_template/generators/api_generator.rb +30 -0
- data/lib/service_template/generators/readme_generator.rb +47 -0
- data/lib/service_template/generators/scaffold_generator.rb +29 -0
- data/lib/service_template/generators/templates/api/app/apis/%name_tableize%_api.rb.tt +40 -0
- data/lib/service_template/generators/templates/api/app/models/%name_underscore%.rb.tt +2 -0
- data/lib/service_template/generators/templates/api/app/representers/%name_underscore%_representer.rb.tt +4 -0
- data/lib/service_template/generators/templates/api/spec/apis/%name_tableize%_api_spec.rb.tt +16 -0
- data/lib/service_template/generators/templates/api/spec/models/%name_underscore%_spec.rb.tt +9 -0
- data/lib/service_template/generators/templates/readme/README.md.tt +55 -0
- data/lib/service_template/generators/templates/readme/spec/docs/readme_spec.rb +7 -0
- data/lib/service_template/generators/templates/scaffold/.env.development.tt +9 -0
- data/lib/service_template/generators/templates/scaffold/.env.test.tt +10 -0
- data/lib/service_template/generators/templates/scaffold/.gitignore.tt +13 -0
- data/lib/service_template/generators/templates/scaffold/.rubocop.yml +24 -0
- data/lib/service_template/generators/templates/scaffold/.ruby-version.tt +1 -0
- data/lib/service_template/generators/templates/scaffold/Gemfile.tt +29 -0
- data/lib/service_template/generators/templates/scaffold/README.md +3 -0
- data/lib/service_template/generators/templates/scaffold/Rakefile +21 -0
- data/lib/service_template/generators/templates/scaffold/app.rb +19 -0
- data/lib/service_template/generators/templates/scaffold/app/apis/application_api.rb +9 -0
- data/lib/service_template/generators/templates/scaffold/app/apis/hello_api.rb.tt +10 -0
- data/lib/service_template/generators/templates/scaffold/config.ru.tt +21 -0
- data/lib/service_template/generators/templates/scaffold/config/database.yml.tt +19 -0
- data/lib/service_template/generators/templates/scaffold/config/initializers/active_record.rb +5 -0
- data/lib/service_template/generators/templates/scaffold/db/schema.rb +11 -0
- data/lib/service_template/generators/templates/scaffold/lib/.keep +0 -0
- data/lib/service_template/generators/templates/scaffold/log/.keep +0 -0
- data/lib/service_template/generators/templates/scaffold/spec/apis/hello_api_spec.rb.tt +17 -0
- data/lib/service_template/generators/templates/scaffold/spec/factories/.gitkeep +0 -0
- data/lib/service_template/generators/templates/scaffold/spec/spec_helper.rb +47 -0
- data/lib/service_template/grape_extenders.rb +30 -0
- data/lib/service_template/grape_extensions/error_formatter.rb +18 -0
- data/lib/service_template/grape_extensions/grape_helpers.rb +27 -0
- data/lib/service_template/identity.rb +45 -0
- data/lib/service_template/json_error.rb +24 -0
- data/lib/service_template/logger/log_transaction.rb +17 -0
- data/lib/service_template/logger/logger.rb +42 -0
- data/lib/service_template/logger/parseable.rb +37 -0
- data/lib/service_template/middleware/app_monitor.rb +17 -0
- data/lib/service_template/middleware/authentication.rb +32 -0
- data/lib/service_template/middleware/database_stats.rb +15 -0
- data/lib/service_template/middleware/logger.rb +67 -0
- data/lib/service_template/middleware/request_stats.rb +42 -0
- data/lib/service_template/output_formatters/entity.rb +15 -0
- data/lib/service_template/output_formatters/include_nil.rb +16 -0
- data/lib/service_template/output_formatters/json_api_representer.rb +9 -0
- data/lib/service_template/param_sanitizer.rb +30 -0
- data/lib/service_template/rspec_extensions/response_helpers.rb +46 -0
- data/lib/service_template/setup.rb +36 -0
- data/lib/service_template/sortable_api.rb +17 -0
- data/lib/service_template/stats.rb +43 -0
- data/lib/service_template/stats_d_timer.rb +26 -0
- data/lib/service_template/version.rb +45 -0
- data/lib/tasks/deploy.rake +11 -0
- data/lib/tasks/routes.rake +11 -0
- data/service_template.gemspec +42 -0
- data/spec/active_record_extensions/filter_by_hash_spec.rb +23 -0
- data/spec/active_record_extensions/seeder_spec.rb +13 -0
- data/spec/authentication_spec.rb +17 -0
- data/spec/deprecations/application_api_spec.rb +19 -0
- data/spec/deprecations/entity_spec.rb +9 -0
- data/spec/deprecations/filter_by_hash_spec.rb +9 -0
- data/spec/deprecations/napa_setup_spec.rb +52 -0
- data/spec/generators/api_generator_spec.rb +63 -0
- data/spec/generators/migration_generator_spec.rb +105 -0
- data/spec/generators/readme_generator_spec.rb +35 -0
- data/spec/generators/scaffold_generator_spec.rb +90 -0
- data/spec/grape_extenders_spec.rb +50 -0
- data/spec/grape_extensions/error_formatter_spec.rb +29 -0
- data/spec/grape_extensions/include_nil_spec.rb +23 -0
- data/spec/identity_spec.rb +50 -0
- data/spec/json_error_spec.rb +33 -0
- data/spec/logger/log_transaction_spec.rb +34 -0
- data/spec/logger/logger_spec.rb +14 -0
- data/spec/logger/parseable_spec.rb +16 -0
- data/spec/middleware/authentication_spec.rb +54 -0
- data/spec/middleware/database_stats_spec.rb +64 -0
- data/spec/middleware/request_stats_spec.rb +21 -0
- data/spec/sortable_api_spec.rb +56 -0
- data/spec/spec_helper.rb +45 -0
- data/spec/stats_d_timer_spec.rb +23 -0
- data/spec/stats_spec.rb +66 -0
- data/spec/version_spec.rb +40 -0
- data/tasks/spec.rake +9 -0
- data/tasks/version.rake +51 -0
- metadata +456 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
if defined?(ActiveRecord)
|
|
2
|
+
ActiveSupport::Notifications.subscribe 'sql.active_record' do |name, start, finish, id, payload|
|
|
3
|
+
if payload[:sql].downcase.match(/(select|update|insert|delete)(.+)/i)
|
|
4
|
+
table, action = ServiceTemplate::ActiveRecordStats.extract_sql_content(payload[:sql])
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
if table
|
|
8
|
+
ServiceTemplate::Stats.emitter.timing(
|
|
9
|
+
"sql.query_time",
|
|
10
|
+
(finish - start) * 1000)
|
|
11
|
+
|
|
12
|
+
ServiceTemplate::Stats.emitter.timing(
|
|
13
|
+
"sql.table.#{table}.#{action.downcase}.query_time",
|
|
14
|
+
(finish - start) * 1000)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
if defined?(ActiveRecord)
|
|
2
|
+
module ServiceTemplate
|
|
3
|
+
class ActiveRecordSeeder
|
|
4
|
+
def initialize(seed_file)
|
|
5
|
+
@seed_file = seed_file
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def load_seed
|
|
9
|
+
raise "Seed file '#{@seed_file}' does not exist" unless File.file?(@seed_file)
|
|
10
|
+
load @seed_file
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
if defined?(ActiveSupport) && defined?(ActiveRecord)
|
|
2
|
+
module ServiceTemplate
|
|
3
|
+
module ActiveRecordStats
|
|
4
|
+
SQL_INSERT_DELETE_PARSER_REGEXP = /^(?<action>\w+)\s(\w+)\s\W*(?<table>\w+)/
|
|
5
|
+
SQL_SELECT_REGEXP = /select .*? FROM \W*(?<table>\w+)/i
|
|
6
|
+
SQL_UPDATE_REGEXP = /update \W*(?<table>\w+)/i
|
|
7
|
+
|
|
8
|
+
# Returns the table and query type
|
|
9
|
+
def self.extract_from_sql_inserts_deletes(query)
|
|
10
|
+
m = query.match(SQL_INSERT_DELETE_PARSER_REGEXP)
|
|
11
|
+
[m[:table], m[:action]]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.extract_sql_selects(query)
|
|
15
|
+
m = query.match(SQL_SELECT_REGEXP)
|
|
16
|
+
[m[:table], 'SELECT']
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.extract_sql_updates(query)
|
|
20
|
+
m = query.match(SQL_UPDATE_REGEXP)
|
|
21
|
+
[m[:table], 'UPDATE']
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.extract_sql_content(query)
|
|
25
|
+
table = action = nil
|
|
26
|
+
if query.match(SQL_UPDATE_REGEXP)
|
|
27
|
+
table, action = extract_sql_updates(query)
|
|
28
|
+
elsif query.match(SQL_SELECT_REGEXP)
|
|
29
|
+
table, action = extract_sql_selects(query)
|
|
30
|
+
elsif query.match(SQL_INSERT_DELETE_PARSER_REGEXP)
|
|
31
|
+
table, action = extract_from_sql_inserts_deletes(query)
|
|
32
|
+
end
|
|
33
|
+
[table, action]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
require 'thor'
|
|
2
|
+
require 'service_template/generators'
|
|
3
|
+
require 'service_template/deploy'
|
|
4
|
+
require 'service_template/version'
|
|
5
|
+
|
|
6
|
+
ServiceTemplate.load_environment if defined?(Dotenv)
|
|
7
|
+
|
|
8
|
+
module ServiceTemplate
|
|
9
|
+
class CLI
|
|
10
|
+
class Generate < Thor
|
|
11
|
+
register(
|
|
12
|
+
Generators::ApiGenerator,
|
|
13
|
+
'api',
|
|
14
|
+
'api <api_name>',
|
|
15
|
+
'Create a Grape API, Model and Entity'
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
register(
|
|
19
|
+
Generators::ReadmeGenerator,
|
|
20
|
+
'readme',
|
|
21
|
+
'readme',
|
|
22
|
+
'Create a formatted README'
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class CLI
|
|
28
|
+
class Base < Thor
|
|
29
|
+
desc "version", "Shows the ServiceTemplate version number"
|
|
30
|
+
def version
|
|
31
|
+
say ServiceTemplate::VERSION
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
desc 'console [environment]', 'Start the ServiceTemplate console'
|
|
35
|
+
options aliases: 'c'
|
|
36
|
+
def console(environment = nil)
|
|
37
|
+
ServiceTemplate.env = environment || 'development'
|
|
38
|
+
|
|
39
|
+
require 'racksh/init'
|
|
40
|
+
|
|
41
|
+
begin
|
|
42
|
+
require "pry"
|
|
43
|
+
interpreter = Pry
|
|
44
|
+
rescue LoadError
|
|
45
|
+
require "irb"
|
|
46
|
+
require "irb/completion"
|
|
47
|
+
interpreter = IRB
|
|
48
|
+
# IRB uses ARGV and does not expect these arguments.
|
|
49
|
+
ARGV.delete('console')
|
|
50
|
+
ARGV.delete(environment) if environment
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
Rack::Shell.init
|
|
54
|
+
|
|
55
|
+
$0 = "#{$0} console"
|
|
56
|
+
interpreter.start
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
desc 'server', "Start the ServiceTemplate server"
|
|
60
|
+
options aliases: 's'
|
|
61
|
+
def server
|
|
62
|
+
puts "ServiceTemplate server starting..."
|
|
63
|
+
|
|
64
|
+
require 'pty'
|
|
65
|
+
exit = "... ServiceTemplate server exited!"
|
|
66
|
+
|
|
67
|
+
begin
|
|
68
|
+
PTY.spawn('shotgun') do |stdout, stdin, pid|
|
|
69
|
+
begin
|
|
70
|
+
Signal.trap('INT') { Process.kill('INT', pid) }
|
|
71
|
+
stdout.each { |line| puts line }
|
|
72
|
+
rescue Errno::EIO
|
|
73
|
+
puts exit
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
rescue PTY::ChildExited
|
|
77
|
+
puts exit
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
desc 'deploy [target]', 'Deploys A Service to a given target (i.e. production, staging, etc.)'
|
|
82
|
+
method_options :force => :boolean, :revision => :string, :confirm => :boolean
|
|
83
|
+
def deploy(environment)
|
|
84
|
+
if options[:confirm] || yes?('Are you sure you want to deploy this service?', Thor::Shell::Color::YELLOW)
|
|
85
|
+
deploy = ServiceTemplate::Deploy.new(environment, force: options[:force], revision: options[:revision])
|
|
86
|
+
if deploy.deployable?
|
|
87
|
+
say(deploy.deploy!, Thor::Shell::Color::GREEN)
|
|
88
|
+
else
|
|
89
|
+
say("Deploy Failed:\n#{deploy.errors.join("\n")}", Thor::Shell::Color::RED)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
register(
|
|
95
|
+
Generators::ScaffoldGenerator,
|
|
96
|
+
'new',
|
|
97
|
+
'new <app_name> [app_path]',
|
|
98
|
+
'Create a scaffold for a new ServiceTemplate service'
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
desc "generate api <api_name>", "Create a Grape API, Model and Representer"
|
|
102
|
+
subcommand "generate api", ServiceTemplate::CLI::Generate
|
|
103
|
+
|
|
104
|
+
desc "generate migration <migration_name> [field[:type][:index] field[:type][:index]]", "Create a Database Migration"
|
|
105
|
+
subcommand "generate", ServiceTemplate::CLI::Generate
|
|
106
|
+
|
|
107
|
+
desc "generate readme", "Create a formatted README"
|
|
108
|
+
subcommand "generate readme", ServiceTemplate::CLI::Generate
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
require 'git'
|
|
2
|
+
require 'octokit'
|
|
3
|
+
|
|
4
|
+
module ServiceTemplate
|
|
5
|
+
class Deploy
|
|
6
|
+
attr_reader :errors, :github_login
|
|
7
|
+
|
|
8
|
+
def initialize(environment, revision: nil, force: false, github_repo: nil, github_token: nil)
|
|
9
|
+
ServiceTemplate.load_environment
|
|
10
|
+
|
|
11
|
+
@github_repo = github_repo || ENV['GITHUB_REPO']
|
|
12
|
+
@github_token = github_token || ENV['GITHUB_OAUTH_TOKEN']
|
|
13
|
+
@environment = environment
|
|
14
|
+
@revision = revision || local_head_revision
|
|
15
|
+
@force = force
|
|
16
|
+
|
|
17
|
+
@errors = []
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def deploy!
|
|
21
|
+
if deployable?
|
|
22
|
+
set_github_tag
|
|
23
|
+
"#{@revision} tagged as #{@environment} by #{@github_login} at #{Time.now.to_s(:long)}"
|
|
24
|
+
else
|
|
25
|
+
"Deploy error(s): #{@errors.join(' --- ')}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def set_github_tag
|
|
30
|
+
begin
|
|
31
|
+
github_client.update_ref(
|
|
32
|
+
@github_repo,
|
|
33
|
+
"tags/#{@environment}",
|
|
34
|
+
@revision,
|
|
35
|
+
@force
|
|
36
|
+
)
|
|
37
|
+
rescue Octokit::UnprocessableEntity
|
|
38
|
+
github_client.create_ref(
|
|
39
|
+
@github_repo,
|
|
40
|
+
"tags/#{@environment}",
|
|
41
|
+
@revision
|
|
42
|
+
)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def local_repo
|
|
47
|
+
@local_repo ||= Git.open('.')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def local_repo_status
|
|
51
|
+
@local_repo_status ||= local_repo.status
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def github_client
|
|
55
|
+
return @github_client if @github_client
|
|
56
|
+
@errors << "ENV['GITHUB_REPO'] is not defined" if @github_repo.nil?
|
|
57
|
+
@errors << "ENV['GITHUB_OAUTH_TOKEN'] is not defined" if @github_token.nil?
|
|
58
|
+
|
|
59
|
+
client = Octokit::Client.new(access_token: @github_token)
|
|
60
|
+
begin
|
|
61
|
+
@github_login = client.login
|
|
62
|
+
return @github_client = client
|
|
63
|
+
rescue Octokit::Unauthorized
|
|
64
|
+
@errors << "Access denied for GITHUB_OAUTH_TOKEN"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def local_head_revision
|
|
69
|
+
local_repo.object('HEAD').sha
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def deployable?
|
|
73
|
+
revision_exists_on_github?
|
|
74
|
+
any_local_uncommited_changes?
|
|
75
|
+
any_local_untracked_files?
|
|
76
|
+
|
|
77
|
+
@errors.empty? || @force
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def revision_exists_on_github?
|
|
81
|
+
begin
|
|
82
|
+
github_client.commit(@github_repo, @revision)
|
|
83
|
+
rescue Octokit::NotFound
|
|
84
|
+
@errors << "Revision #{@revision} does not exist on #{@github_repo}, make sure you've merged your changes."
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def any_local_uncommited_changes?
|
|
89
|
+
changes = local_repo_status.changed.collect{|change| change[0]}
|
|
90
|
+
@errors << "#{changes.to_sentence} have been changed and not committed." if changes.any?
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def any_local_untracked_files?
|
|
94
|
+
changes = local_repo_status.untracked.collect{|change| change[0]}
|
|
95
|
+
@errors << "#{changes.to_sentence} file(s) have been added and are not tracked." if changes.any?
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'active_support/json'
|
|
2
|
+
|
|
3
|
+
module ServiceTemplate
|
|
4
|
+
class GemDependency
|
|
5
|
+
def self.log_all
|
|
6
|
+
ServiceTemplate::Logger.logger.info(gems: list_all.as_json)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.list_all
|
|
10
|
+
Gem.loaded_specs.map { |spec| new(spec).to_hash }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def initialize(spec)
|
|
14
|
+
@spec = spec[1]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def name
|
|
18
|
+
@spec.name
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def version
|
|
22
|
+
@spec.version.to_s
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def git_version
|
|
26
|
+
@spec.git_version
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def to_hash
|
|
30
|
+
{}.tap do |h|
|
|
31
|
+
h[:name] = name
|
|
32
|
+
h[:version] = version
|
|
33
|
+
h[:git_version] = git_version if git_version
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'thor'
|
|
2
|
+
require 'active_support/all'
|
|
3
|
+
|
|
4
|
+
module ServiceTemplate
|
|
5
|
+
module Generators
|
|
6
|
+
class ApiGenerator < Thor::Group
|
|
7
|
+
include Thor::Actions
|
|
8
|
+
argument :name
|
|
9
|
+
|
|
10
|
+
def name_underscore
|
|
11
|
+
name.underscore
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def name_tableize
|
|
15
|
+
name.tableize
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def output_directory
|
|
19
|
+
'.'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def api
|
|
23
|
+
self.class.source_root "#{File.dirname(__FILE__)}/templates/api"
|
|
24
|
+
say 'Generating api...'
|
|
25
|
+
directory '.', output_directory
|
|
26
|
+
say 'Done!', :green
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'thor'
|
|
2
|
+
require 'active_support/all'
|
|
3
|
+
require 'service_template/setup'
|
|
4
|
+
require 'service_template/identity'
|
|
5
|
+
require 'dotenv'
|
|
6
|
+
|
|
7
|
+
module ServiceTemplate
|
|
8
|
+
module Generators
|
|
9
|
+
class ReadmeGenerator < Thor::Group
|
|
10
|
+
include Thor::Actions
|
|
11
|
+
|
|
12
|
+
def load_environment
|
|
13
|
+
ServiceTemplate.load_environment
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def service_name
|
|
17
|
+
ServiceTemplate::Identity.name
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def routes
|
|
21
|
+
routes = ""
|
|
22
|
+
|
|
23
|
+
if defined? ApplicationApi
|
|
24
|
+
ApplicationApi.routes.each do |api|
|
|
25
|
+
method = api.route_method.ljust(10)
|
|
26
|
+
path = api.route_path.ljust(40)
|
|
27
|
+
description = api.route_description
|
|
28
|
+
routes += " #{method} #{path} # #{description}"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
routes
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def output_directory
|
|
36
|
+
'.'
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def readme
|
|
40
|
+
self.class.source_root "#{File.dirname(__FILE__)}/templates/readme"
|
|
41
|
+
say 'Generating readme...'
|
|
42
|
+
directory '.', output_directory
|
|
43
|
+
say 'Done!', :green
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'thor'
|
|
2
|
+
require 'active_support/core_ext/string'
|
|
3
|
+
|
|
4
|
+
module ServiceTemplate
|
|
5
|
+
module Generators
|
|
6
|
+
class ScaffoldGenerator < Thor::Group
|
|
7
|
+
include Thor::Actions
|
|
8
|
+
|
|
9
|
+
source_root "#{File.dirname(__FILE__)}/templates/scaffold"
|
|
10
|
+
|
|
11
|
+
argument :app_name
|
|
12
|
+
argument :app_path, optional: true
|
|
13
|
+
class_option :database, default: 'mysql', aliases: '-d', desc: 'Preconfigure for selected database (options: mysql/postgres/pg)'
|
|
14
|
+
|
|
15
|
+
def generate
|
|
16
|
+
say 'Generating scaffold...'
|
|
17
|
+
|
|
18
|
+
@database_gem = ['pg','postgres'].include?(options[:database]) ? 'pg' : 'mysql2'
|
|
19
|
+
@database_adapter = ['pg','postgres'].include?(options[:database]) ? 'postgresql' : 'mysql2'
|
|
20
|
+
@database_encoding = ['pg','postgres'].include?(options[:database]) ? 'unicode' : 'utf8'
|
|
21
|
+
@database_user = ['pg','postgres'].include?(options[:database]) ? '' : 'root'
|
|
22
|
+
|
|
23
|
+
directory ".", (app_path || app_name)
|
|
24
|
+
|
|
25
|
+
say 'Done!', :green
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
class <%= name.classify.pluralize %>Api < Grape::API
|
|
2
|
+
desc 'Get a list of <%= name.underscore.tableize %>'
|
|
3
|
+
params do
|
|
4
|
+
optional :ids, type: Array, desc: 'Array of <%= name.underscore %> ids'
|
|
5
|
+
end
|
|
6
|
+
get do
|
|
7
|
+
<%= name.underscore.tableize %> = params[:ids] ? <%= name.classify %>.where(id: params[:ids]) : <%= name.classify %>.all
|
|
8
|
+
represent <%= name.underscore.tableize %>, with: <%= name.classify %>Representer
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
desc 'Create an <%= name.underscore %>'
|
|
12
|
+
params do
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
post do
|
|
16
|
+
<%= name.underscore %> = <%= name.classify %>.create!(permitted_params)
|
|
17
|
+
represent <%= name.underscore %>, with: <%= name.classify %>Representer
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
params do
|
|
21
|
+
requires :id, desc: 'ID of the <%= name.underscore %>'
|
|
22
|
+
end
|
|
23
|
+
route_param :id do
|
|
24
|
+
desc 'Get an <%= name.underscore %>'
|
|
25
|
+
get do
|
|
26
|
+
<%= name.underscore %> = <%= name.classify %>.find(params[:id])
|
|
27
|
+
represent <%= name.underscore %>, with: <%= name.classify %>Representer
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
desc 'Update an <%= name.underscore %>'
|
|
31
|
+
params do
|
|
32
|
+
end
|
|
33
|
+
put do
|
|
34
|
+
# fetch <%= name.underscore %> record and update attributes. exceptions caught in app.rb
|
|
35
|
+
<%= name.underscore %> = <%= name.classify %>.find(params[:id])
|
|
36
|
+
<%= name.underscore %>.update_attributes!(permitted_params)
|
|
37
|
+
represent <%= name.underscore %>, with: <%= name.classify %>Representer
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|