tzispa 0.6.1 → 0.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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/lib/tzispa/api/handler.rb +54 -23
  4. data/lib/tzispa/app.rb +60 -68
  5. data/lib/tzispa/cli.rb +42 -3
  6. data/lib/tzispa/commands/api.rb +55 -0
  7. data/lib/tzispa/commands/app.rb +83 -0
  8. data/lib/tzispa/commands/cli/generate.rb +60 -0
  9. data/lib/tzispa/commands/command.rb +28 -0
  10. data/lib/tzispa/commands/console.rb +62 -0
  11. data/lib/tzispa/commands/helpers/i18n.rb +67 -0
  12. data/lib/tzispa/commands/helpers/project.rb +69 -0
  13. data/lib/tzispa/commands/helpers/repository.rb +46 -0
  14. data/lib/tzispa/commands/project.rb +104 -0
  15. data/lib/tzispa/commands/repository.rb +66 -0
  16. data/lib/tzispa/commands/rig.rb +28 -0
  17. data/lib/tzispa/commands/server.rb +26 -0
  18. data/lib/tzispa/config/{appconfig.rb → app_config.rb} +12 -32
  19. data/lib/tzispa/config/base.rb +7 -5
  20. data/lib/tzispa/config/db_config.rb +67 -0
  21. data/lib/tzispa/config/yaml.rb +9 -10
  22. data/lib/tzispa/context.rb +3 -2
  23. data/lib/tzispa/controller/api.rb +66 -60
  24. data/lib/tzispa/controller/auth_layout.rb +4 -28
  25. data/lib/tzispa/controller/base.rb +61 -24
  26. data/lib/tzispa/controller/exceptions.rb +3 -4
  27. data/lib/tzispa/controller/http_error.rb +0 -3
  28. data/lib/tzispa/controller/layout.rb +4 -4
  29. data/lib/tzispa/domain.rb +27 -23
  30. data/lib/tzispa/env.rb +34 -0
  31. data/lib/tzispa/environment.rb +231 -0
  32. data/lib/tzispa/http/context.rb +65 -80
  33. data/lib/tzispa/http/request.rb +29 -17
  34. data/lib/tzispa/http/response.rb +45 -12
  35. data/lib/tzispa/route_set.rb +100 -0
  36. data/lib/tzispa/server.rb +61 -0
  37. data/lib/tzispa/tzisparc.rb +80 -0
  38. data/lib/tzispa/version.rb +1 -1
  39. data/lib/tzispa.rb +3 -1
  40. data/tzispa.gemspec +12 -6
  41. metadata +68 -17
  42. data/lib/tzispa/command/api.rb +0 -24
  43. data/lib/tzispa/command/app.rb +0 -95
  44. data/lib/tzispa/command/cli/generate.rb +0 -51
  45. data/lib/tzispa/command/project.rb +0 -258
  46. data/lib/tzispa/command/rig.rb +0 -26
  47. data/lib/tzispa/controller/signed_api.rb +0 -13
  48. data/lib/tzispa/http/session_flash_bag.rb +0 -62
  49. data/lib/tzispa/middleware.rb +0 -48
  50. data/lib/tzispa/routes.rb +0 -69
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1e7d9bdf85429d1bbe0fd303daff3853049aa4f6
4
- data.tar.gz: 61aecb036fb1501b56572e8f5504ed9911e51242
3
+ metadata.gz: 494da0d1c9e0718fe00cf30c6ca12ff79656a152
4
+ data.tar.gz: b076698a91484ffee3f0561f4293034f5eea6115
5
5
  SHA512:
6
- metadata.gz: 79493c3072124348bc1e9458615da7a75665c4a9ee6f29ef138ede3df6bdae48648402c7ecfb3058fc93357905717ed034f6e17b4f0929d18993603927981560
7
- data.tar.gz: f38fabe97d6d006bfde4e0e2d9f2349d96a428c68f7fa818e38e33cb836b8f8a04257b7cd4137d06f69206e48c03f1d20610eba913411a61f2d45edf6081a435
6
+ metadata.gz: 98dd03475d556c2a0990b4f7979a4eba9ecc1ba94c8943874abf67a568c136f07fceb4c89de9672399bff13f7322d2f1a069a2d6693942be520b5d6816d00d4b
7
+ data.tar.gz: df7eb2126ea1cf8fc7bd2ddeefc8f975cf99c03d97ab90f31dd4cf5a3ba4d8e843e88ef56beac5bb66ed1d10252074b51ffff0e25a9ea4036e77d0d95a75aedb
data/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@ Tzispa
2
2
 
3
3
  General purpose web framework
4
4
 
5
+ ## v0.7.0
6
+ - distinct error and http status in api handlers
7
+ - better api responses by content type
8
+ - controller base: better error handling in invoke
9
+ - api handlers: added support for api http verbs using request_method
10
+ - independent db/repository configuration file
11
+ - app environment implementation
12
+ - automatic code reloading in development env (Shotgun)
13
+ - added before hook in controllers and api-handlers
14
+ - new routes specification file per app
15
+ - code refactoring and bug fixes
16
+
5
17
  ## v0.6.1
6
18
  - sessions security improvements
7
19
  - added "x-frame-option: sameorigin" header to security improvement
@@ -19,69 +19,100 @@ module Tzispa
19
19
  class InvalidSign < ApiException; end
20
20
 
21
21
  class Handler
22
+ extend Forwardable
23
+
22
24
  include Tzispa::Helpers::Provider
23
25
  include Tzispa::Helpers::SignRequirer
24
- extend Forwardable
25
26
 
26
- using Tzispa::Utils
27
+ using Tzispa::Utils::TzString
27
28
 
28
- attr_reader :context, :response_verb, :data, :status
29
- def_delegators :@context, :request, :response, :app, :repository, :config, :logger
29
+ attr_reader :context, :type, :data, :error, :status
30
+ def_delegators :@context, :request, :response, :app, :repository,
31
+ :config, :logger, :unauthorized_but_logged, :login_redirect
30
32
 
31
- HANDLER_STATUS_UNDEFINED = nil
32
- HANDLER_STATUS_OK = :ok
33
- HANDLER_MISSING_PARAMETER = :missing_parameter
33
+ attr_writer :error
34
34
 
35
+ HANDLER_OK = :ok
36
+ HANDLER_MISSING_PARAMETER = :missing_parameter
35
37
 
36
38
  def initialize(context)
37
39
  @context = context
40
+ @error = nil
41
+ @status = nil
38
42
  end
39
43
 
40
- def result(response_verb:, data: nil, status: HANDLER_STATUS_UNDEFINED)
41
- @response_verb = response_verb
42
- @status = status if status
44
+ def result(type:, data: nil, error: nil)
45
+ @type = type
43
46
  @data = data
47
+ @error = error
48
+ end
49
+
50
+ class << self
51
+ def before(*args)
52
+ (@before_chain ||= []).tap do |bef|
53
+ args.each do |s|
54
+ s = s.to_sym
55
+ bef << s unless bef.include?(s)
56
+ end
57
+ end
58
+ end
44
59
  end
45
60
 
46
61
  def error?
47
- status && status != HANDLER_STATUS_OK
62
+ error && error != HANDLER_OK
63
+ end
64
+
65
+ def error_status(error, status = nil)
66
+ @error = error
67
+ @status = status
48
68
  end
49
69
 
50
- def result_json(data, status: nil)
51
- result response_verb: :json, data: data, status: status
70
+ def result_json(data, error: nil)
71
+ result type: :json, data: data, error: error
52
72
  end
53
73
 
54
- def result_download(data, status: nil)
55
- result response_verb: :download, data: data, status: status
74
+ def result_download(data, error: nil)
75
+ result type: :download, data: data, error: error
56
76
  end
57
77
 
58
78
  def not_found
59
- result response_verb: :not_found
79
+ result type: :not_found
60
80
  end
61
81
 
62
82
  def message
63
- I18n.t("#{self.class.name.dottize}.#{status}", default: "#{status}") if status
83
+ I18n.t("#{self.class.name.dottize}.#{error}", default: error.to_s) if error
64
84
  end
65
85
 
66
- def run!(verb, predicate=nil)
86
+ def run!(verb, predicate = nil)
67
87
  raise UnknownHandlerVerb.new(verb, self.class.name) unless provides? verb
68
- raise InvalidSign.new if sign_required? && !sign_valid?
88
+ raise InvalidSign if sign_required? && !sign_valid?
89
+ do_before
69
90
  # process compound predicates
70
91
  args = predicate ? predicate.split(',') : nil
71
92
  send verb, *args
72
93
  end
73
94
 
74
- def set_status(value)
75
- @status = value
95
+ def redirect_url(url)
96
+ if url && !url.strip.empty?
97
+ url.start_with?('#') ? "#{request.referer}#{url}" : url
98
+ else
99
+ request.referer
100
+ end
76
101
  end
77
102
 
78
103
  protected
79
104
 
80
105
  def static_path_sign?
81
- context.path_sign? context.router_params[:sign], context.router_params[:handler], context.router_params[:verb], context.router_params[:predicate]
106
+ context.path_sign? context.router_params[:sign],
107
+ context.router_params[:handler],
108
+ context.router_params[:verb],
109
+ context.router_params[:predicate]
82
110
  end
83
111
 
84
-
112
+ def do_before
113
+ self.class.before.each { |hbef| send hbef }
114
+ end
85
115
  end
116
+
86
117
  end
87
118
  end
data/lib/tzispa/app.rb CHANGED
@@ -4,49 +4,37 @@ require 'forwardable'
4
4
  require 'logger'
5
5
  require 'i18n'
6
6
  require 'tzispa/domain'
7
- require 'tzispa/routes'
8
- require 'tzispa/config/appconfig'
9
- require 'tzispa/middleware'
7
+ require 'tzispa/route_set'
8
+ require 'tzispa/config/app_config'
9
+ require 'tzispa/config/db_config'
10
10
  require 'tzispa_data'
11
11
 
12
-
13
12
  module Tzispa
14
13
 
15
- ENV_TZISPA_APP = :tzispa__app
16
- ENV_TZISPA_CONTEXT = :tzispa__context
17
-
18
-
19
14
  class Application
20
15
  extend Forwardable
21
16
 
22
- attr_reader :domain, :config, :middleware, :repository, :engine,
23
- :logger, :mount_path, :routes
24
-
25
- def_delegator :@middleware, :use
26
- def_delegator :@domain, :name
27
- def_delegators :@routes, :routing, :route_rig_index, :route_rig_api, :route_rig_signed_api, :route_rig_layout
17
+ attr_reader :domain, :logger, :map_path
28
18
 
19
+ def_delegators :@domain, :name, :path
20
+ def_delegators :@routes, :routing, :index, :api, :signed_api, :layout
29
21
 
30
22
  class << self
31
-
32
- alias :__new__ :new
23
+ alias __new__ :new
33
24
 
34
25
  def new(*args, &block)
35
- __new__(*args, &block).tap { |app|
36
- add app
37
- }
26
+ __new__(*args, &block).tap { |app| add app }
38
27
  end
39
28
 
29
+ # rubocop:disable Style/ClassVars
40
30
  def applications
41
31
  synchronize do
42
- @@applications ||= Hash.new{ |hash, key| raise UnknownApplication.new("#{key}") }
32
+ @@applications ||= Hash.new { |_, key| raise UnknownApplication(key.to_s) }
43
33
  end
44
34
  end
45
35
 
46
36
  def synchronize
47
- Mutex.new.synchronize {
48
- yield
49
- }
37
+ Mutex.new.synchronize { yield }
50
38
  end
51
39
 
52
40
  def [](name)
@@ -55,78 +43,82 @@ module Tzispa
55
43
 
56
44
  def add(app)
57
45
  synchronize do
58
- raise DuplicateDomain.new("You have try to add an app with a duplicate domain name #{app.name}") if applications.has_key? app.name
46
+ raise DuplicateDomain.new(app.name) if applications.key?(app.name)
59
47
  applications[app.name] = app
60
48
  end
61
49
  end
62
-
63
- def run(appid, builder: nil, on: nil, &block)
64
- theapp = self.new appid, on: on, &block
65
- theapp.run builder
66
- end
67
-
68
50
  end
69
51
 
70
52
  def initialize(appid, on: nil, &block)
71
53
  @domain = Domain.new(appid)
72
- @config = Config::AppConfig.new(@domain).load!
73
- @middleware = Middleware.new self
74
- @routes ||= Routes.new(self, on)
54
+ @map_path = on
75
55
  instance_eval(&block) if block
76
56
  end
77
57
 
78
- def run(builder=nil)
79
- builder ||= ::Rack::Builder.new
80
- if routes.map_path
81
- this_app = self
82
- builder.map routes.map_path do
83
- run this_app.middleware.builder
84
- end
85
- else
86
- builder.run middleware.builder
87
- end
58
+ def call(env)
59
+ routes.call env
88
60
  end
89
61
 
90
62
  def load!
91
- self.class.synchronize {
92
- load_locales
93
- @logger = Logger.new("logs/#{domain.name}.log", config.logging.shift_age).tap { |log|
94
- log.level = config.developing ? Logger::DEBUG : Logger::INFO
95
- } if config.logging&.enabled
96
- domain_setup
97
- @repository = Data::Repository.new(config.repository.to_h).load!(domain) if config.respond_to? :repository
98
- @loaded = true
99
- }
100
- self
63
+ tap do |app|
64
+ app.class.synchronize do
65
+ logging
66
+ load_locales
67
+ domain.setup
68
+ routes.setup
69
+ repository&.load!(domain)
70
+ end
71
+ end
101
72
  end
102
73
 
103
74
  def [](domain)
104
75
  self.class[domain]
105
76
  end
106
77
 
107
- private
78
+ def default_layout?(layout)
79
+ config.default_layout.to_sym == layout
80
+ end
108
81
 
109
- def domain_setup
110
- domain.require_dir
111
- domain.require_dir 'helpers'
112
- domain.require_dir 'services'
113
- domain.require_dir 'api'
114
- domain.require_dir 'middleware'
82
+ def env
83
+ Tzispa::Environment.instance
115
84
  end
116
85
 
117
- def load_locales
118
- if config.respond_to?(:locales)
119
- I18n.enforce_available_locales = false
120
- I18n.load_path += Dir["config/locales/*.yml", "#{domain.path}/locales/*.yml"]
86
+ def routes
87
+ @routes ||= RouteSet.new(self, map_path)
88
+ end
89
+
90
+ def config
91
+ @config ||= Config::AppConfig.new(@domain).load!
92
+ end
93
+
94
+ def repository
95
+ @repository ||= begin
96
+ dbcfg = Config::DbConfig.new(env.environment)&.to_h
97
+ Data::Repository.new(dbcfg) if dbcfg&.count&.positive?
121
98
  end
122
99
  end
123
100
 
124
- public
101
+ private
125
102
 
126
- class ApplicationError < StandardError; end
127
- class UnknownApplication < ApplicationError; end
128
- class DuplicateDomain < ApplicationError; end
103
+ def logging
104
+ return unless config&.logging&.enabled
105
+ @logger = Logger.new("logs/#{domain.name}.log", config.logging&.shift_age)
106
+ @logger.level = Tzispa::Environment.development? ? Logger::DEBUG : Logger::INFO
107
+ end
129
108
 
109
+ def load_locales
110
+ return unless config.respond_to?(:locales)
111
+ I18n.enforce_available_locales = false
112
+ I18n.load_path += Dir['config/locales/*.yml', "#{domain.path}/locales/*.yml"]
113
+ end
114
+ end
130
115
 
116
+ class ApplicationError < StandardError; end
117
+ class UnknownApplication < ApplicationError; end
118
+ class DuplicateDomain < ApplicationError
119
+ def initialize(app_name)
120
+ super "You have tried to add an app with a duplicate domain name #{app_name}"
121
+ end
131
122
  end
123
+
132
124
  end
data/lib/tzispa/cli.rb CHANGED
@@ -1,18 +1,57 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'thor'
4
+ require 'tzispa'
2
5
 
3
6
  module Tzispa
4
7
 
5
8
  class Cli < Thor
6
-
7
9
  desc 'version', 'Prints Tzispa version'
8
10
  def version
9
11
  require 'tzispa/version'
10
12
  puts "v#{VERSION}"
11
13
  end
12
14
 
13
- require 'tzispa/command/cli/generate'
14
- register Tzispa::Command::Cli::Generate, 'generate', 'generate [SUBCOMMAND]', 'Generate Tzispa components'
15
+ desc 'new', 'Generate a new Tzispa project'
16
+ def new(name)
17
+ require 'tzispa/commands/project'
18
+ Tzispa::Commands::Project.new(name).generate
19
+ puts "Project '#{name}' has been created"
20
+ end
21
+
22
+ require 'tzispa/commands/server'
23
+ desc 'server', 'Start Tzispa app server'
24
+ method_option :port, aliases: '-p', desc: 'The port to run the server on'
25
+ method_option :server, desc: 'Choose a specific Rack::Handler (webrick, thin, etc)'
26
+ method_option :rackup, desc: 'A rackup configuration file path to load (config.ru)'
27
+ method_option :host, desc: 'The host address to bind to'
28
+ method_option :debug, desc: 'Turn on debug output'
29
+ method_option :warn, desc: 'Turn on warnings'
30
+ method_option :daemonize, desc: 'If true, the server will daemonize itself'
31
+ method_option :help, desc: 'Displays the help usage'
32
+ def server
33
+ if options[:help]
34
+ invoke :help, ['server']
35
+ else
36
+ Tzispa::Commands::Server.new(options).start
37
+ end
38
+ end
39
+
40
+ require 'tzispa/commands/console'
41
+ desc 'console', 'Starts a Tzispa console'
42
+ method_option :engine, desc: "Choose: (#{Tzispa::Commands::Console::ENGINES.keys.join('/')})"
43
+ method_option :help, desc: 'Displays the usage help'
44
+ def console
45
+ if options[:help]
46
+ invoke :help, ['console']
47
+ else
48
+ Tzispa::Commands::Console.new(options).start
49
+ end
50
+ end
15
51
 
52
+ require 'tzispa/commands/cli/generate'
53
+ register Tzispa::Commands::Cli::Generate, 'generate', 'generate [SUBCOMMAND]',
54
+ 'Generate Tzispa components'
16
55
  end
17
56
 
18
57
  end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'tzispa/controller/api'
5
+ require 'tzispa/commands/command'
6
+ require 'tzispa/utils/indenter'
7
+
8
+ module Tzispa
9
+ module Commands
10
+
11
+ class Api < Command
12
+ attr_reader :name, :domain, :verb
13
+
14
+ def initialize(name, app, verb, options = nil)
15
+ super(options)
16
+ @domain = Tzispa::Domain.new app
17
+ @name = name
18
+ @verb = verb
19
+ end
20
+
21
+ def generate
22
+ file_name = Tzispa::Controller::Api.handler_class_file(domain, name, verb)
23
+ raise "The handler '#{name}' already exist" if File.exist?(file_name)
24
+ namespace = Tzispa::Controller::Api.handler_namespace(domain, verb)
25
+ class_name = Tzispa::Controller::Api.handler_class_name(name)
26
+ create_file file_name, namespace, class_name
27
+ end
28
+
29
+ private
30
+
31
+ def create_file(file_name, ns, class_name)
32
+ dir, = Pathname.new(file_name).split
33
+ FileUtils.mkpath dir
34
+ File.open(file_name, 'w') do |f|
35
+ f.puts handler_code(ns, class_name)
36
+ end
37
+ end
38
+
39
+ def handler_code(namespace, class_name)
40
+ Tzispa::Utils::Indenter.new.tap do |code|
41
+ code << "require 'tzispa/api/handler'\n\n"
42
+ level = 0
43
+ namespace.split('::').each do |ns|
44
+ level.positive? ? code.indent << "module #{ns}\n" : code << "module #{ns}\n"
45
+ level += 1
46
+ end
47
+ code.indent << "\nclass #{class_name} < Tzispa::Api::Handler\n\n"
48
+ code << "end\n\n"
49
+ namespace.split('::').each { code.unindent << "end\n" }
50
+ end.to_s
51
+ end
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'tzispa/domain'
5
+ require 'tzispa/utils/string'
6
+ require 'tzispa/utils/indenter'
7
+ require 'tzispa/config/app_config'
8
+ require 'tzispa/commands/command'
9
+
10
+ module Tzispa
11
+ module Commands
12
+ class App < Command
13
+ using Tzispa::Utils::TzString
14
+
15
+ APP_STRUCTURE = [
16
+ 'api', 'locales', 'error', 'controller', 'helpers', 'view', 'view/_',
17
+ 'view/_/block', 'view/_/layout', 'view/_/static', 'services'
18
+ ].freeze
19
+
20
+ attr_reader :domain
21
+
22
+ def initialize(name, options = nil)
23
+ super(options)
24
+ @domain = Tzispa::Domain.new(name)
25
+ end
26
+
27
+ def generate(mount_path, index_layout, locale)
28
+ update_rackup mount_path
29
+ create_structure
30
+ create_appconfig index_layout, locale
31
+ create_home_layout
32
+ create_routes
33
+ end
34
+
35
+ private
36
+
37
+ def update_rackup(mount_path = nil)
38
+ mount_path ||= DEFAULT_MOUNT_PATH
39
+ File.open(Tzispa::Environment::DEFAULT_RACKUP, 'a') do |f|
40
+ f.puts write_app_code(mount_path)
41
+ end
42
+ end
43
+
44
+ def write_app_code(mount_path)
45
+ map_path = mount_path.start_with?('/') ? mount_path : "/#{mount_path}"
46
+ Tzispa::Utils::Indenter.new(2).tap do |code|
47
+ code << "\nmap '#{map_path}' do\n"
48
+ code.indent << "run Tzispa::Application.new(:#{domain.name},on: '#{map_path}').load!\n"
49
+ code.unindent << "end\n"
50
+ end.to_s
51
+ end
52
+
53
+ def create_structure
54
+ return unless File.exist? domain.path
55
+ Dir.mkdir domain.path.to_s
56
+ APP_STRUCTURE.each { |appdir| Dir.mkdir "#{domain.path}/#{appdir}" }
57
+ end
58
+
59
+ def create_appconfig(default_layout, locale)
60
+ appconfig = Tzispa::Config::AppConfig.new(domain)
61
+ @config = appconfig.create_default(default_layout, locale)
62
+ end
63
+
64
+ def create_home_layout
65
+ tpl = Tzispa::Rig::Template.new(name: @config.default_layout || 'index',
66
+ type: :layout,
67
+ domain: domain,
68
+ content_type: :htm)
69
+ tpl.create("<html><body><h1>Welcome: #{domain.name} is working!</h1></body></html>")
70
+ end
71
+
72
+ def create_routes
73
+ File.open("config/routes/#{domain.name}.rb", 'w') do |file|
74
+ file.puts '# app routes definitions \n'
75
+ file.puts "index '/', controller: 'layout:render!'"
76
+ file.puts "signed_api '/api_:sign/:handler/:verb(~:predicate)(/:sufix)'"
77
+ file.puts "api '/api/:handler/:verb(~:predicate)(/:sufix)'"
78
+ end
79
+ end
80
+ end
81
+
82
+ end
83
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor'
4
+
5
+ module Tzispa
6
+ module Commands
7
+ module Cli
8
+
9
+ class Generate < Thor
10
+ require 'tzispa/commands/app'
11
+ desc 'app', 'Generate new application into a project'
12
+ method_option :mount, aliases: '-m', desc: 'The mount point for this app', default: '/'
13
+ method_option :index, aliases: '-i', desc: 'Default index layout', default: 'index'
14
+ method_option :locale, aliases: '-l', desc: 'Default app locale', default: 'en'
15
+ def app(name)
16
+ tzapp = Tzispa::Commands::App.new(name)
17
+ tzapp.generate(options[:mount], options[:index], options[:locale])
18
+ puts "App '#{name}' has been created"
19
+ end
20
+
21
+ require 'tzispa/commands/rig'
22
+ desc 'rig', 'Generate new rig template'
23
+ method_option :app, aliases: '-a',
24
+ desc: 'The app where create the new template', required: true
25
+ method_option :type, aliases: '-t',
26
+ desc: 'Template type: block, static or layout', required: true
27
+ def rig(name)
28
+ tpl = Tzispa::Commands::Rig.new(name, options[:app], options[:type])
29
+ tpl.generate
30
+ puts "Rig #{options[:type]} template '#{name}' has been created in #{options[:app]}"
31
+ end
32
+
33
+ require 'tzispa/commands/repository'
34
+ desc 'repository', 'Generate new repsitory'
35
+ method_option :adapter, aliases: '-a',
36
+ desc: 'Database adapter to use in the repository', required: true
37
+ method_option :database, aliases: '-d',
38
+ desc: 'Database connection string or path', required: true
39
+ def repository(name)
40
+ repo = Tzispa::Commands::Repository.new name, options[:adapter], options[:database]
41
+ repo.generate
42
+ puts "Repository #{name} has been created into local project"
43
+ end
44
+
45
+ require 'tzispa/commands/api'
46
+ desc 'api', 'Generate new api handler'
47
+ method_option :app, aliases: '-a',
48
+ desc: 'The app where the api handler will be created', required: true
49
+ method_option :verb, aliases: '-v',
50
+ desc: 'The http verb that this api will respond to', required: true
51
+ def api(name)
52
+ hnd = Tzispa::Commands::Api.new(name, options[:app], options[:verb])
53
+ hnd.generate
54
+ puts "Api handler '#{name}' has been created in #{options[:app]}"
55
+ end
56
+ end
57
+
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tzispa/environment'
4
+
5
+ module Tzispa
6
+ module Commands
7
+
8
+ class Command
9
+
10
+ NO_PROJECT_FOLDER = 'You must be located in a Tzispa project folder to run this command'
11
+
12
+ def initialize(options)
13
+ raise NO_PROJECT_FOLDER unless project_folder?
14
+ Tzispa::Environment.opts = options
15
+ @environment = Tzispa::Environment.instance
16
+ end
17
+
18
+ protected
19
+
20
+ attr_reader :environment
21
+
22
+ def project_folder?
23
+ File.exist?(Tzispa::Environment::DEFAULT_RACKUP)
24
+ end
25
+ end
26
+
27
+ end
28
+ end