grapethor 0.2.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.
Files changed (92) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.travis.yml +22 -0
  4. data/CHANGELOG.md +13 -0
  5. data/CODE_OF_CONDUCT.md +76 -0
  6. data/Gemfile +3 -0
  7. data/Gemfile.lock +53 -0
  8. data/LICENSE +19 -0
  9. data/README.md +165 -0
  10. data/Rakefile +9 -0
  11. data/_config.yml +1 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/exe/grapethor +5 -0
  15. data/grapethor.gemspec +47 -0
  16. data/lib/grapethor.rb +10 -0
  17. data/lib/grapethor/generators/api.rb +78 -0
  18. data/lib/grapethor/generators/cli.rb +35 -0
  19. data/lib/grapethor/generators/endpoint.rb +168 -0
  20. data/lib/grapethor/generators/new.rb +161 -0
  21. data/lib/grapethor/generators/resource.rb +89 -0
  22. data/lib/grapethor/templates/api/api/%api_version%/base.rb.tt +19 -0
  23. data/lib/grapethor/templates/api_minitest/test/support/api_%api_version%_test_case.rb.tt +12 -0
  24. data/lib/grapethor/templates/api_rspec/.gitkeep +0 -0
  25. data/lib/grapethor/templates/docker/Dockerfile.tt +18 -0
  26. data/lib/grapethor/templates/docker/docker-compose.yml.tt +43 -0
  27. data/lib/grapethor/templates/endpoint.rb.erb +14 -0
  28. data/lib/grapethor/templates/endpoint/api/%api_version%/%end_resource_plural%.rb.tt +14 -0
  29. data/lib/grapethor/templates/endpoint_minitest.rb.erb +13 -0
  30. data/lib/grapethor/templates/endpoint_minitest/test/api/%api_version%/%end_resource_plural%_test.rb.tt +14 -0
  31. data/lib/grapethor/templates/endpoint_rspec.rb.erb +11 -0
  32. data/lib/grapethor/templates/endpoint_rspec/spec/api/%api_version%/%end_resource_plural%_spec.rb.tt +12 -0
  33. data/lib/grapethor/templates/license/apache2/LICENSE.tt +13 -0
  34. data/lib/grapethor/templates/license/cddl1/LICENSE.tt +316 -0
  35. data/lib/grapethor/templates/license/epl1/LICENSE.tt +200 -0
  36. data/lib/grapethor/templates/license/freebsd/LICENSE.tt +22 -0
  37. data/lib/grapethor/templates/license/gpl2/LICENSE.tt +17 -0
  38. data/lib/grapethor/templates/license/gpl3/LICENSE.tt +16 -0
  39. data/lib/grapethor/templates/license/mit/LICENSE.tt +19 -0
  40. data/lib/grapethor/templates/license/mpl2/LICENSE.tt +5 -0
  41. data/lib/grapethor/templates/license/newbsd/LICENSE.tt +26 -0
  42. data/lib/grapethor/templates/minitest/lib/tasks/test.rake +14 -0
  43. data/lib/grapethor/templates/minitest/test/support/reporters.rb +11 -0
  44. data/lib/grapethor/templates/minitest/test/support/test_case.rb +18 -0
  45. data/lib/grapethor/templates/minitest/test/test_helper.rb +12 -0
  46. data/lib/grapethor/templates/mysql/config/database.yml.tt +33 -0
  47. data/lib/grapethor/templates/new/.gitignore +7 -0
  48. data/lib/grapethor/templates/new/.grapethor.yml.tt +13 -0
  49. data/lib/grapethor/templates/new/Gemfile.tt +44 -0
  50. data/lib/grapethor/templates/new/README.md.tt +138 -0
  51. data/lib/grapethor/templates/new/Rakefile.tt +30 -0
  52. data/lib/grapethor/templates/new/api/base.rb.tt +19 -0
  53. data/lib/grapethor/templates/new/app/exceptions/not_found_error.rb +1 -0
  54. data/lib/grapethor/templates/new/bin/console +13 -0
  55. data/lib/grapethor/templates/new/bin/server.tt +14 -0
  56. data/lib/grapethor/templates/new/bin/setup.tt +8 -0
  57. data/lib/grapethor/templates/new/config.ru.tt +19 -0
  58. data/lib/grapethor/templates/new/config/application.rb.tt +18 -0
  59. data/lib/grapethor/templates/new/config/boot.rb +2 -0
  60. data/lib/grapethor/templates/new/config/environment.rb +3 -0
  61. data/lib/grapethor/templates/new/db/seeds.rb +7 -0
  62. data/lib/grapethor/templates/new/lib/tasks/routes.rake +8 -0
  63. data/lib/grapethor/templates/postgresql/config/database.yml.tt +38 -0
  64. data/lib/grapethor/templates/resource/api/%api_version%/%res_name_plural%.rb.tt +95 -0
  65. data/lib/grapethor/templates/resource/api/entities/%res_name%.rb.tt +10 -0
  66. data/lib/grapethor/templates/resource/app/models/%res_name%.rb.tt +6 -0
  67. data/lib/grapethor/templates/resource/db/migrations/%res_migration%.rb.tt +10 -0
  68. data/lib/grapethor/templates/resource_minitest/test/api/%api_version%/%res_name_plural%_test.rb.tt +82 -0
  69. data/lib/grapethor/templates/resource_minitest/test/fixtures/%res_name_plural%.yml.tt +9 -0
  70. data/lib/grapethor/templates/resource_minitest/test/models/%res_name%_test.rb.tt +17 -0
  71. data/lib/grapethor/templates/resource_rspec/spec/api/%api_version%/%res_name_plural%_spec.rb.tt +91 -0
  72. data/lib/grapethor/templates/resource_rspec/spec/factories/%res_name_plural%.rb.tt +7 -0
  73. data/lib/grapethor/templates/resource_rspec/spec/models/%res_name%_spec.rb.tt +9 -0
  74. data/lib/grapethor/templates/rspec/.rspec +1 -0
  75. data/lib/grapethor/templates/rspec/lib/tasks/spec.rake +4 -0
  76. data/lib/grapethor/templates/rspec/spec/spec_helper.rb +24 -0
  77. data/lib/grapethor/templates/sqlite/config/database.yml.tt +22 -0
  78. data/lib/grapethor/templates/swagger/swagger-ui/favicon-16x16.png +0 -0
  79. data/lib/grapethor/templates/swagger/swagger-ui/favicon-32x32.png +0 -0
  80. data/lib/grapethor/templates/swagger/swagger-ui/index.html.tt +60 -0
  81. data/lib/grapethor/templates/swagger/swagger-ui/oauth2-redirect.html +67 -0
  82. data/lib/grapethor/templates/swagger/swagger-ui/swagger-ui-bundle.js +93 -0
  83. data/lib/grapethor/templates/swagger/swagger-ui/swagger-ui-bundle.js.map +1 -0
  84. data/lib/grapethor/templates/swagger/swagger-ui/swagger-ui-standalone-preset.js +14 -0
  85. data/lib/grapethor/templates/swagger/swagger-ui/swagger-ui-standalone-preset.js.map +1 -0
  86. data/lib/grapethor/templates/swagger/swagger-ui/swagger-ui.css +3 -0
  87. data/lib/grapethor/templates/swagger/swagger-ui/swagger-ui.css.map +1 -0
  88. data/lib/grapethor/templates/swagger/swagger-ui/swagger-ui.js +9 -0
  89. data/lib/grapethor/templates/swagger/swagger-ui/swagger-ui.js.map +1 -0
  90. data/lib/grapethor/utils/utils.rb +116 -0
  91. data/lib/grapethor/version.rb +3 -0
  92. metadata +235 -0
data/lib/grapethor.rb ADDED
@@ -0,0 +1,10 @@
1
+ require "grapethor/version"
2
+ require "grapethor/utils/utils"
3
+ require "grapethor/generators/new"
4
+ require "grapethor/generators/api"
5
+ require "grapethor/generators/endpoint"
6
+ require "grapethor/generators/resource"
7
+ require "grapethor/generators/cli"
8
+
9
+ module Grapethor
10
+ end
@@ -0,0 +1,78 @@
1
+ require 'thor/group'
2
+ require 'yaml'
3
+
4
+ module Grapethor
5
+ class Api < Thor::Group
6
+ include Thor::Actions
7
+ include Grapethor::Utils
8
+
9
+ attr_reader :api_version,
10
+ :app_path
11
+
12
+ namespace :api
13
+
14
+ def self.exit_on_failure?
15
+ true
16
+ end
17
+
18
+ def self.source_root
19
+ File.join(__dir__, '..')
20
+ end
21
+
22
+
23
+ argument :version, type: :string,
24
+ desc: 'API version'
25
+
26
+ class_option :path, aliases: '-p',
27
+ type: :string,
28
+ default: '.',
29
+ desc: 'Relative path to application directory'
30
+
31
+
32
+ def parse_args_and_opts
33
+ @api_version = version.downcase
34
+ @app_path = options[:path]
35
+ end
36
+
37
+
38
+ def validate_target_app
39
+ unless app_dir_exists?
40
+ alert <<~MSG
41
+ Directory '#{app_path}' does not seem to be generated by Grapethor or root application directory.\n
42
+ Please 'cd' into application root diretory or use '--path' option.
43
+ MSG
44
+ exit
45
+ end
46
+ end
47
+
48
+
49
+ def create_api
50
+ report("Creating new API...") do
51
+ directory 'templates/api', app_path
52
+ directory "templates/api_#{app_test_framework}", app_path
53
+ insert_into_file "#{app_path}/api/base.rb",
54
+ "\s\s\s\smount API#{api_version}::Base\n",
55
+ :before => "\s\s\s\s# mount API<VERSION>::Base\n"
56
+ end
57
+ end
58
+
59
+
60
+ private
61
+
62
+ def app_dir_exists?
63
+ File.exist?("#{app_path}/api/base.rb")
64
+ end
65
+
66
+ def app_name
67
+ @app_name ||= YAML.load(File.read(CONFIG_FILENAME))['app_name']
68
+ end
69
+
70
+ def app_prefix
71
+ @app_prefix ||= YAML.load(File.read(CONFIG_FILENAME))['app_prefix']
72
+ end
73
+
74
+ def app_swagger?
75
+ @app_swagger||= YAML.load(File.read(CONFIG_FILENAME))['app_swagger']
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,35 @@
1
+ require 'thor'
2
+
3
+ module Grapethor
4
+ class CLI < Thor
5
+ include Thor::Actions
6
+ include Grapethor::Utils
7
+
8
+ check_unknown_options!
9
+
10
+ def self.exit_on_failure?
11
+ true
12
+ end
13
+
14
+
15
+ desc 'version', 'Displays Grapethor version'
16
+ map %w[-v --version] => :version
17
+ def version
18
+ say "Grapethor #{VERSION}"
19
+ end
20
+
21
+
22
+ # register(class_name, subcommand_alias, usage_list_string, description_string, options={})
23
+ register(Grapethor::New, 'new', 'new NAME', 'Creates new Grape application', options)
24
+ commands['new'].options = Grapethor::New.class_options
25
+
26
+ register(Grapethor::Api, 'api', 'api VERSION', 'Creates new API within application', options)
27
+ commands['api'].options = Grapethor::Api.class_options
28
+
29
+ register(Grapethor::Endpoint, 'endpoint', 'endpoint RESOURCE [NAME]', 'Creates new Endpoint within API', options)
30
+ commands['endpoint'].options = Grapethor::Endpoint.class_options
31
+
32
+ register(Grapethor::Resource, 'resource', 'resource NAME', 'Creates new Resource within API', options)
33
+ commands['resource'].options = Grapethor::Resource.class_options
34
+ end
35
+ end
@@ -0,0 +1,168 @@
1
+ require 'thor/group'
2
+ require 'active_support/inflector'
3
+
4
+ module Grapethor
5
+ class Endpoint < Thor::Group
6
+ include Thor::Actions
7
+ include Grapethor::Utils
8
+
9
+ attr_reader :api_version,
10
+ :app_path,
11
+ :end_resource,
12
+ :end_name,
13
+ :end_method,
14
+ :end_desc,
15
+ :end_params,
16
+ :end_query,
17
+ :end_query_with_params,
18
+ :request_path,
19
+ :end_query_sample,
20
+ :request_path_sample
21
+
22
+ namespace :endpoint
23
+
24
+ def self.exit_on_failure?
25
+ true
26
+ end
27
+
28
+ def self.source_root
29
+ File.join(__dir__, '..')
30
+ end
31
+
32
+
33
+ argument :resource, type: :string,
34
+ desc: "Resource name"
35
+
36
+ argument :name, type: :string,
37
+ desc: 'Endpoint name',
38
+ default: ""
39
+
40
+
41
+ class_option :path, aliases: '-p',
42
+ type: :string,
43
+ default: '.',
44
+ desc: 'Relative path to application directory'
45
+
46
+ class_option :version, aliases: '-v',
47
+ type: :string,
48
+ default: 'v1',
49
+ desc: 'API version tag'
50
+
51
+ class_option :method, aliases: '-m',
52
+ type: :string,
53
+ default: 'GET',
54
+ enum: %w[GET POST PUT DELETE],
55
+ desc: 'HTTP request method'
56
+
57
+ class_option :desc, aliases: '-d',
58
+ type: :string,
59
+ default: "",
60
+ desc: 'Endpoint description'
61
+
62
+ class_option :params, aliases: '-a',
63
+ type: :hash,
64
+ default: {},
65
+ desc: 'Request resource (path) param'
66
+
67
+ class_option :query, aliases: '-q',
68
+ type: :hash,
69
+ default: {},
70
+ desc: 'Request query params'
71
+
72
+
73
+ def parse_args_and_opts
74
+ @end_resource = resource.downcase.singularize
75
+ @end_name = name.downcase.singularize
76
+ @end_method = options[:method].upcase
77
+ @end_params = options[:params]
78
+ @end_query = options[:query].map { |k, v| [k, v.downcase] }.to_h
79
+ @end_query_with_params = options[:params].merge(options[:query]).map { |k, v| [k, v.downcase] }.to_h
80
+ @api_version = options[:version].downcase
81
+ @app_path = options[:path]
82
+ end
83
+
84
+
85
+ def prepare_endpoint
86
+ prepare_request_path
87
+
88
+ prepare_request_path_sample
89
+
90
+ @end_desc = options[:desc].empty? ? "#{end_method} #{request_path}" : options[:desc]
91
+ end
92
+
93
+
94
+ def validate_target_api
95
+ unless api_version_exists?
96
+ alert "API version '#{api_version}' does not exist!"
97
+ exit
98
+ end
99
+ end
100
+
101
+
102
+ def create_endpoint
103
+ report("Creating new endpoint...") do
104
+ unless File.exist?("#{app_path}/api/#{api_version}/#{end_resource_plural}.rb")
105
+ directory "templates/endpoint/api/\%api_version\%", "#{app_path}/api/#{api_version}"
106
+ end
107
+
108
+ insert_into_file "#{app_path}/api/#{api_version}/#{end_resource_plural}.rb",
109
+ end_content,
110
+ after: "resource :#{end_resource.pluralize} do\n"
111
+
112
+ insert_into_file "#{app_path}/api/#{api_version}/base.rb",
113
+ "\s\s\s\smount API#{api_version}::#{end_resource.classify.pluralize}\n",
114
+ before: "\s\s\s\s# mount API#{api_version}::<ResourceOrEndpointClass>\n"
115
+
116
+ unless File.exist?("#{app_path}/#{test_dirname}/api/#{api_version}/#{end_resource_plural}_#{test_dirname}.rb")
117
+ directory "templates/endpoint_#{app_test_framework}", app_path
118
+ end
119
+
120
+ insert_into_file "#{app_path}/#{test_dirname}/api/#{api_version}/#{end_resource_plural}_#{test_dirname}.rb",
121
+ end_test_content,
122
+ after: "\s\s### grapethor works here ###\n"
123
+ end
124
+ end
125
+
126
+
127
+ private
128
+
129
+ def prepare_request_path
130
+ req_path = []
131
+ end_params.each { |k, v| req_path << ":#{k}" } unless end_params.empty?
132
+ req_path << "#{end_name}" unless end_name.empty?
133
+ @request_path = req_path.join('/')
134
+ end
135
+
136
+
137
+ def prepare_request_path_sample
138
+ req_path_sample = []
139
+ end_params.each { |k,v| req_path_sample << sample_value(v, true) } unless end_params.empty?
140
+ req_path_sample << "#{end_name}" unless end_name.empty?
141
+ @request_path_sample = req_path_sample.join('/')
142
+ end
143
+
144
+
145
+ def api_version_exists?
146
+ Dir.exist?("#{app_path}/api/#{api_version}")
147
+ end
148
+
149
+
150
+ def end_content
151
+ erb_file = File.join(__dir__, "../templates/endpoint.rb.erb")
152
+ erb_templates = File.read(erb_file)
153
+ ERB.new(erb_templates, nil, '-').result(binding)
154
+ end
155
+
156
+
157
+ def end_test_content
158
+ erb_file = File.join(__dir__, "../templates/endpoint_#{app_test_framework}.rb.erb")
159
+ erb_templates = File.read(erb_file)
160
+ ERB.new(erb_templates, nil, '-').result(binding)
161
+ end
162
+
163
+
164
+ def end_resource_plural
165
+ end_resource.pluralize
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,161 @@
1
+ require 'thor/group'
2
+
3
+ module Grapethor
4
+ class New < Thor::Group
5
+ include Thor::Actions
6
+ include Grapethor::Utils
7
+
8
+ attr_reader :app_name,
9
+ :app_path,
10
+ :app_prefix,
11
+ :app_server,
12
+ :app_test_framework,
13
+ :app_db,
14
+ :app_orm,
15
+ :app_license,
16
+ :app_copyright,
17
+ :app_ruby
18
+
19
+
20
+ namespace :new
21
+
22
+ def self.exit_on_failure?
23
+ true
24
+ end
25
+
26
+
27
+ def self.source_root
28
+ File.join(__dir__, '..')
29
+ end
30
+
31
+
32
+ argument :name, type: :string,
33
+ desc: 'Application name'
34
+
35
+
36
+ class_option :path, aliases: '-p',
37
+ type: :string,
38
+ default: '.',
39
+ desc: 'Relative path to place application directory'
40
+
41
+ class_option :prefix, aliases: '-x',
42
+ type: :string,
43
+ default: 'api',
44
+ desc: 'Add Application URL prefix'
45
+
46
+ class_option :db, aliases: '-d',
47
+ type: :string,
48
+ default: 'sqlite',
49
+ enum: %w[sqlite postgresql mysql],
50
+ desc: 'Use specific database'
51
+
52
+ class_option :orm, aliases: '-o',
53
+ type: :string,
54
+ default: 'activerecord',
55
+ enum: %w[activerecord],
56
+ desc: 'Use specific ORM'
57
+
58
+ class_option :server, aliases: '-s',
59
+ type: :string,
60
+ default: 'thin',
61
+ enum: %w[thin],
62
+ desc: 'Preconfigure web server'
63
+
64
+ class_option :test, aliases: '-t',
65
+ type: :string,
66
+ default: 'minitest',
67
+ enum: %w[minitest rspec],
68
+ desc: 'Use specific test framework'
69
+
70
+ class_option :docker, type: :boolean,
71
+ default: true,
72
+ desc: 'Use docker'
73
+
74
+ class_option :license, aliases: '-l',
75
+ type: :string,
76
+ default: 'mit',
77
+ enum: %w[mit apache2 freebsd newbsd gpl2 gpl3 mpl2 cddl1 epl1],
78
+ desc: 'Add software license information'
79
+
80
+ class_option :copyright, aliases: '-c',
81
+ type: :string,
82
+ desc: 'Add copyright information within license file'
83
+
84
+ class_option :ruby, aliases: '-r',
85
+ type: :string,
86
+ default: "#{RUBY_VERSION}",
87
+ desc: 'Ruby version for application'
88
+
89
+ class_option :swagger, type: :boolean,
90
+ default: true,
91
+ desc: 'Generate swagger documentation and install swagger-ui'
92
+
93
+
94
+ def parse_args_and_opts
95
+ @app_name = name
96
+ @app_path = options[:path]
97
+ @app_prefix = options[:prefix]
98
+ @app_server = options[:server]
99
+ @app_test_framework = options[:test]
100
+ @app_db = options[:db]
101
+ @app_orm = options[:orm]
102
+ @app_docker = options[:docker]
103
+ @app_license = options[:license]
104
+ @app_copyright = options[:copyright] || "Author of #{app_name}"
105
+ @app_ruby = options[:ruby]
106
+ @app_swagger = options[:swagger]
107
+ end
108
+
109
+
110
+ def create_new
111
+ report("Creating new application...") do
112
+ directory 'templates/new', File.join(app_path, app_name)
113
+ chmod File.join(app_path, app_name, 'bin', 'console'), 0755
114
+ chmod File.join(app_path, app_name, 'bin', 'setup'), 0755
115
+ chmod File.join(app_path, app_name, 'bin', 'server'), 0755
116
+
117
+ directory "templates/#{app_db}", "#{app_path}/#{app_name}"
118
+
119
+ directory "templates/#{app_test_framework}", "#{app_path}/#{app_name}"
120
+
121
+ directory "templates/docker", "#{app_path}/#{app_name}" if app_docker?
122
+
123
+ directory "templates/license/#{app_license}", "#{app_path}/#{app_name}"
124
+
125
+ directory "templates/swagger", "#{app_path}/#{app_name}" if app_swagger?
126
+ end
127
+ end
128
+
129
+
130
+ private
131
+
132
+ def app_docker?
133
+ @app_docker
134
+ end
135
+
136
+
137
+ def app_swagger?
138
+ @app_swagger
139
+ end
140
+
141
+
142
+ def rspec?
143
+ @app_test_framework == 'rspec'
144
+ end
145
+
146
+
147
+ def app_license_link
148
+ {
149
+ mit: '[MIT License](http://opensource.org/licenses/MIT)',
150
+ apache2: '[Apache-2.0 License](https://opensource.org/licenses/Apache-2.0)',
151
+ freebsd: '[FreeBSD License](https://opensource.org/licenses/BSD-2-Clause)',
152
+ newbsd: '[New BSD License](https://opensource.org/licenses/BSD-3-Clause)',
153
+ gpl2: '[GPL-3.0 License](https://opensource.org/licenses/GPL-2.0)',
154
+ gpl3: '[GPL-2.0 License](https://opensource.org/licenses/GPL-3.0)',
155
+ mpl2: '[MPL-2.0 License](https://opensource.org/licenses/MPL-2.0)',
156
+ cddl1: '[CDDL-1.0 License](https://opensource.org/licenses/CDDL-1.0)',
157
+ epl1: '[EPL-1.0 License](https://opensource.org/licenses/EPL-1.0)'
158
+ }[app_license.to_sym]
159
+ end
160
+ end
161
+ end