decko 0.11.1 → 0.11.6
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 +4 -4
- data/bin/decko +2 -2
- data/lib/card_controller.rb +25 -0
- data/{rails/controllers → lib}/card_controller/errors.rb +1 -0
- data/lib/card_controller/mark.rb +66 -0
- data/lib/{decko → card_controller}/response.rb +5 -61
- data/lib/card_controller/rest.rb +105 -0
- data/lib/decko.rb +1 -2
- data/lib/decko/application.rb +4 -1
- data/lib/decko/cli.rb +1 -1
- data/lib/decko/commands.rb +9 -9
- data/lib/decko/commands/application.rb +1 -1
- data/lib/decko/commands/cucumber_command.rb +2 -2
- data/lib/decko/commands/cucumber_command/parser.rb +28 -24
- data/lib/decko/commands/rake_command.rb +3 -2
- data/lib/decko/commands/rake_command/parser.rb +2 -1
- data/lib/decko/commands/rspec_command.rb +2 -2
- data/lib/decko/commands/rspec_command/parser.rb +1 -0
- data/lib/decko/config/environments/cucumber.rb +1 -0
- data/lib/decko/config/environments/development.rb +1 -1
- data/lib/decko/config/environments/production.rb +3 -1
- data/lib/decko/config/environments/profile.rb +1 -0
- data/lib/decko/config/environments/test.rb +1 -0
- data/lib/decko/config/initializers/secret_token.rb +1 -0
- data/lib/decko/config/initializers/sedate_parser.rb +3 -2
- data/lib/decko/engine.rb +0 -2
- data/lib/decko/generators/deck/deck_generator.rb +2 -1
- data/lib/decko/generators/deck/deck_generator/deck_helper.rb +1 -1
- data/lib/decko/generators/deck/deck_generator/interactive.rb +4 -4
- data/lib/decko/generators/deck/templates/Rakefile.erb +1 -2
- data/lib/decko/generators/deck/templates/config.ru.erb +3 -3
- data/lib/decko/generators/deck/templates/config/application.rb.erb +13 -13
- data/lib/decko/generators/deck/templates/config/boot.rb.erb +4 -4
- data/lib/decko/generators/deck/templates/config/environment.rb.erb +1 -1
- data/lib/decko/generators/deck/templates/script/decko +3 -3
- data/lib/decko/script_decko_loader.rb +32 -17
- data/lib/decko/tasks/alias.rb +4 -5
- data/lib/decko/tasks/cucumber.rake +52 -44
- data/lib/decko/tasks/db.rake +9 -2
- data/lib/decko/tasks/decko.rake +6 -4
- data/lib/decko/tasks/decko/docs.rake +1 -1
- data/lib/decko/tasks/decko/seed.rake +4 -1
- data/rails/engine-routes.rb +1 -1
- data/script/decko +2 -2
- data/script/rails +4 -4
- metadata +19 -14
- data/rails/controllers/application_controller.rb +0 -2
- data/rails/controllers/card_controller.rb +0 -122
- data/script/test_filter +0 -25
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 99728f79ff5c295eb94e5978c8cde7d817d8d77529aab5ef2de84eb374f163a0
|
|
4
|
+
data.tar.gz: 233aaa6f69d3af91f4a802166a6153f1a8cb651641450e743e7c672c2bc01f4e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 251382ac224b1579d147c495472ca0ff289fe85f167ce928dd65bb66bfe29b4e2b9ead2b7927ebb0c011bbe17b5dd35c49478d7c761baf38aff8e188f3727feb
|
|
7
|
+
data.tar.gz: 88459337becaf40c3a5fd17ea4e6db21d32d76c2b05e9debfba7567fb37a569cd988ffacaf2e4acd90a719b807665b22a9bf99f4048394f82effaf922fe65c4b
|
data/bin/decko
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
-
git_path = File.expand_path("
|
|
3
|
+
git_path = File.expand_path("../../.git", __dir__)
|
|
4
4
|
|
|
5
5
|
if File.exist?(git_path)
|
|
6
|
-
railties_path = File.expand_path("
|
|
6
|
+
railties_path = File.expand_path("../lib", __dir__)
|
|
7
7
|
$LOAD_PATH.unshift(railties_path)
|
|
8
8
|
end
|
|
9
9
|
require "decko/cli"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
|
2
|
+
|
|
3
|
+
# Decko's only controller.
|
|
4
|
+
class CardController < ActionController::Base
|
|
5
|
+
include Mark
|
|
6
|
+
include Rest
|
|
7
|
+
include Response
|
|
8
|
+
include Errors
|
|
9
|
+
|
|
10
|
+
# NOTE: including Card::Env::Location triggers card loading, which triggers mod loading,
|
|
11
|
+
# which can include initializers that add to the CardController class.
|
|
12
|
+
# It's important that it come *after* the modules above, so that mod modules
|
|
13
|
+
# can override them.
|
|
14
|
+
include ::Card::Env::Location
|
|
15
|
+
|
|
16
|
+
layout nil
|
|
17
|
+
attr_reader :card
|
|
18
|
+
|
|
19
|
+
before_action :setup, except: [:asset]
|
|
20
|
+
before_action :authenticate, except: [:asset]
|
|
21
|
+
before_action :load_mark, only: [:read]
|
|
22
|
+
before_action :load_card, except: [:asset]
|
|
23
|
+
before_action :load_action, only: [:read]
|
|
24
|
+
before_action :refresh_card, only: %i[create update delete]
|
|
25
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
class CardController
|
|
2
|
+
# methods for interpretation of card marks requested
|
|
3
|
+
module Mark
|
|
4
|
+
private
|
|
5
|
+
|
|
6
|
+
def load_mark
|
|
7
|
+
params[:mark] = interpret_mark params[:mark]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def interpret_mark mark
|
|
11
|
+
case mark
|
|
12
|
+
when "*previous"
|
|
13
|
+
# Why support this? It's only needed in Success, right? Deprecate?
|
|
14
|
+
hard_redirect Card::Env.previous_location
|
|
15
|
+
when nil
|
|
16
|
+
implicit_mark
|
|
17
|
+
else
|
|
18
|
+
explicit_mark mark
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def explicit_mark mark
|
|
23
|
+
# we should find the place where we produce these bad urls
|
|
24
|
+
mark.valid_encoding? ? mark : mark.force_encoding("ISO-8859-1").encode("UTF-8")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def implicit_mark
|
|
28
|
+
case
|
|
29
|
+
when initial_setup
|
|
30
|
+
""
|
|
31
|
+
when (name = mark_from_card_hash)
|
|
32
|
+
name
|
|
33
|
+
when view_does_not_require_name?
|
|
34
|
+
""
|
|
35
|
+
else
|
|
36
|
+
home_mark
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def home_mark
|
|
41
|
+
Card::Rule.global_setting(:home) || "Home"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def view_does_not_require_name?
|
|
45
|
+
return false unless (view = params[:view]&.to_sym)
|
|
46
|
+
|
|
47
|
+
Card::Set::Format::AbstractFormat::ViewOpts.unknown_ok[view]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def mark_from_card_hash
|
|
51
|
+
params.dig :card, :name
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# alters params
|
|
55
|
+
def initial_setup
|
|
56
|
+
return unless Card::Auth.needs_setup? && Card::Env.html?
|
|
57
|
+
|
|
58
|
+
prepare_setup_card!
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def prepare_setup_card!
|
|
62
|
+
params[:card] = { type_id: Card.default_accounted_type_id }
|
|
63
|
+
params[:view] = "setup"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
class CardController
|
|
2
2
|
# methods for managing decko responses
|
|
3
3
|
module Response
|
|
4
4
|
def response_format
|
|
@@ -72,13 +72,8 @@ module Decko
|
|
|
72
72
|
|
|
73
73
|
def require_card_for_soft_redirect!
|
|
74
74
|
return if card.is_a? Card
|
|
75
|
-
raise Card::Error, "tried to do soft redirect without a card"
|
|
76
|
-
end
|
|
77
75
|
|
|
78
|
-
|
|
79
|
-
def send_deprecated_asset
|
|
80
|
-
filename = [params[:mark], params[:format]].compact.join(".")
|
|
81
|
-
send_file asset_file_path(filename), x_sendfile: true
|
|
76
|
+
raise Card::Error, "tried to do soft redirect without a card"
|
|
82
77
|
end
|
|
83
78
|
|
|
84
79
|
def asset_file_path filename
|
|
@@ -107,64 +102,13 @@ module Decko
|
|
|
107
102
|
end
|
|
108
103
|
|
|
109
104
|
def format_name_from_params
|
|
110
|
-
if explicit_file_format?
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
end
|
|
105
|
+
return :file if explicit_file_format?
|
|
106
|
+
|
|
107
|
+
(params[:format].present? ? params[:format] : request.format).to_sym
|
|
114
108
|
end
|
|
115
109
|
|
|
116
110
|
def explicit_file_format?
|
|
117
111
|
params[:explicit_file] || !Card::Format.registered.member?(request.format)
|
|
118
112
|
end
|
|
119
|
-
|
|
120
|
-
def interpret_mark mark
|
|
121
|
-
case mark
|
|
122
|
-
when "*previous"
|
|
123
|
-
# Why support this? It's only needed in Success, right? Deprecate?
|
|
124
|
-
return hard_redirect(Card::Env.previous_location)
|
|
125
|
-
when nil
|
|
126
|
-
implicit_mark
|
|
127
|
-
else
|
|
128
|
-
explicit_mark mark
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
def explicit_mark mark
|
|
133
|
-
# we should find the place where we produce these bad urls
|
|
134
|
-
mark.valid_encoding? ? mark : mark.force_encoding("ISO-8859-1").encode("UTF-8")
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def implicit_mark
|
|
138
|
-
case
|
|
139
|
-
when initial_setup then ""
|
|
140
|
-
when (name = params.dig :card, :name) then name
|
|
141
|
-
when view_does_not_require_name? then ""
|
|
142
|
-
else home_mark
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
def home_mark
|
|
147
|
-
Card::Rule.global_setting(:home) || "Home"
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
def view_does_not_require_name?
|
|
151
|
-
return false unless (view = params[:view]&.to_sym)
|
|
152
|
-
Card::Set::Format::AbstractFormat::ViewOpts.unknown_ok[view]
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
# alters params
|
|
156
|
-
def initial_setup
|
|
157
|
-
return unless initial_setup?
|
|
158
|
-
prepare_setup_card!
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
def initial_setup?
|
|
162
|
-
Card::Auth.needs_setup? && Card::Env.html?
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
def prepare_setup_card!
|
|
166
|
-
params[:card] = { type_id: Card.default_accounted_type_id }
|
|
167
|
-
params[:view] = "setup"
|
|
168
|
-
end
|
|
169
113
|
end
|
|
170
114
|
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
class CardController
|
|
2
|
+
# RESTful action methods for card
|
|
3
|
+
module Rest
|
|
4
|
+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
5
|
+
# PUBLIC METHODS
|
|
6
|
+
|
|
7
|
+
def create
|
|
8
|
+
handle { card.save! }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def read
|
|
12
|
+
show
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def update
|
|
16
|
+
card.new_card? ? create : handle { card.update! params[:card]&.to_unsafe_h }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def delete
|
|
20
|
+
handle { card.delete! }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @deprecated
|
|
24
|
+
def asset
|
|
25
|
+
body = "Decko installation error: missing asset symlinks"
|
|
26
|
+
Rails.logger.info "#{body}.\n >>> Try `rake decko:update_assets_symlink`"
|
|
27
|
+
render body: body, status: 404
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
31
|
+
# PRIVATE METHODS
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def setup
|
|
36
|
+
Card::Machine.refresh_script_and_style unless params[:explicit_file]
|
|
37
|
+
Card::Cache.renew
|
|
38
|
+
Card::Env.reset controller: self
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def authenticate
|
|
42
|
+
Card::Auth.signin_with params
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def load_card
|
|
46
|
+
@card = Card.uri_fetch params
|
|
47
|
+
raise Card::Error::NotFound unless card
|
|
48
|
+
|
|
49
|
+
record_as_main
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def load_action
|
|
53
|
+
card.select_action_by_params params
|
|
54
|
+
return unless params[:edit_draft] && card.drafts.present?
|
|
55
|
+
|
|
56
|
+
card.content = card.last_draft_content
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# TODO: refactor this away this when new layout handling is ready
|
|
60
|
+
def record_as_main
|
|
61
|
+
Card::Env[:main_name] = params[:main] || card&.name || ""
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def refresh_card
|
|
65
|
+
@card = card.refresh
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# ----------( HELPER METHODS ) -------------
|
|
69
|
+
|
|
70
|
+
def handle
|
|
71
|
+
Card::Env.success card.name
|
|
72
|
+
yield ? cud_success : raise(Card::Error::UserError)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# successful create, update, or delete act
|
|
76
|
+
def cud_success
|
|
77
|
+
success = Card::Env.success.in_context card.name
|
|
78
|
+
if success.reload?
|
|
79
|
+
reload # instruct JSON to reload
|
|
80
|
+
else
|
|
81
|
+
redirect_cud_success success
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def show view=nil, status=200
|
|
86
|
+
card.action = :read
|
|
87
|
+
format = load_format status
|
|
88
|
+
result = render_page format, view
|
|
89
|
+
status = format.error_status || status
|
|
90
|
+
respond format, result, status
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def render_page format, view
|
|
94
|
+
view ||= view_from_params
|
|
95
|
+
card.act do
|
|
96
|
+
format.page self, view, Card::Env.slot_opts
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def view_from_params
|
|
101
|
+
%i[view v].each { |k| return params[k] if params[k].present? }
|
|
102
|
+
nil
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
data/lib/decko.rb
CHANGED
data/lib/decko/application.rb
CHANGED
|
@@ -63,7 +63,9 @@ module Decko
|
|
|
63
63
|
config.filter_parameters += [:password]
|
|
64
64
|
|
|
65
65
|
# Rails.autoloaders.log!
|
|
66
|
-
Rails.autoloaders.main.ignore(
|
|
66
|
+
Rails.autoloaders.main.ignore(
|
|
67
|
+
File.join(Cardio.gem_root, "lib/card/seed_consts.rb")
|
|
68
|
+
)
|
|
67
69
|
config
|
|
68
70
|
end
|
|
69
71
|
end
|
|
@@ -77,6 +79,7 @@ module Decko
|
|
|
77
79
|
|
|
78
80
|
paths["app/models"] = []
|
|
79
81
|
paths["app/mailers"] = []
|
|
82
|
+
paths["app/controllers"] = []
|
|
80
83
|
|
|
81
84
|
unless paths["config/routes.rb"].existent.present?
|
|
82
85
|
add_path paths, "config/routes.rb",
|
data/lib/decko/cli.rb
CHANGED
|
@@ -3,7 +3,7 @@ require "decko/script_decko_loader"
|
|
|
3
3
|
|
|
4
4
|
# If we are inside a Decko application this method performs an exec and thus
|
|
5
5
|
# the rest of this script is not run.
|
|
6
|
-
Decko::ScriptDeckoLoader.
|
|
6
|
+
Decko::ScriptDeckoLoader.exec!
|
|
7
7
|
|
|
8
8
|
require "rails/ruby_version_check"
|
|
9
9
|
Signal.trap("INT") { puts; exit(1) }
|
data/lib/decko/commands.rb
CHANGED
|
@@ -7,21 +7,21 @@ def load_rake_tasks
|
|
|
7
7
|
Decko::Application.load_tasks
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
RAILS_COMMANDS = %w
|
|
11
|
-
server dbconsole application runner
|
|
12
|
-
DECKO_COMMANDS = %w
|
|
13
|
-
DECKO_DB_COMMANDS = %w
|
|
10
|
+
RAILS_COMMANDS = %w[ generate destroy plugin benchmarker profiler console
|
|
11
|
+
server dbconsole application runner ].freeze
|
|
12
|
+
DECKO_COMMANDS = %w[new cucumber rspec jasmine].freeze
|
|
13
|
+
DECKO_DB_COMMANDS = %w[seed reseed load update].freeze
|
|
14
14
|
|
|
15
15
|
ALIAS = {
|
|
16
16
|
"rs" => "rspec",
|
|
17
17
|
"cc" => "cucumber",
|
|
18
18
|
"jm" => "jasmine",
|
|
19
|
-
"g"
|
|
20
|
-
"d"
|
|
21
|
-
"c"
|
|
22
|
-
"s"
|
|
19
|
+
"g" => "generate",
|
|
20
|
+
"d" => "destroy",
|
|
21
|
+
"c" => "console",
|
|
22
|
+
"s" => "server",
|
|
23
23
|
"db" => "dbconsole",
|
|
24
|
-
"r"
|
|
24
|
+
"r" => "runner"
|
|
25
25
|
}.freeze
|
|
26
26
|
|
|
27
27
|
def supported_rails_command? arg
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require File.expand_path("
|
|
1
|
+
require File.expand_path("command", __dir__)
|
|
2
2
|
|
|
3
3
|
module Decko
|
|
4
4
|
module Commands
|
|
@@ -45,4 +45,4 @@ module Decko
|
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
require File.expand_path("
|
|
48
|
+
require File.expand_path("cucumber_command/parser", __dir__)
|
|
@@ -1,38 +1,42 @@
|
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
|
2
|
+
|
|
2
3
|
require "optparse"
|
|
3
4
|
|
|
4
5
|
module Decko
|
|
5
6
|
module Commands
|
|
6
7
|
class CucumberCommand
|
|
7
8
|
class Parser < OptionParser
|
|
9
|
+
class Flagger
|
|
10
|
+
def initialize parser, opts
|
|
11
|
+
@parser = parser
|
|
12
|
+
@opts = opts
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def add_flags
|
|
16
|
+
add_flag "DEBUG", "-d", "--debug", "Drop into debugger on failure"
|
|
17
|
+
add_flag "FAST", "-f", "--fast", "Stop on first failure"
|
|
18
|
+
add_flag "LAUNCH", "-l", "--launchy", "Open page on failure"
|
|
19
|
+
add_flag "STEP", "-s", "--step", "Pause after each step"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def add_flag flag, *args
|
|
23
|
+
@parser.on(*args) { |a| @opts[:env] << "#{flag}=1" if a }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def parse_spring parser, opts
|
|
28
|
+
parser.on("--[no-]spring", "Run with spring") do |spring|
|
|
29
|
+
opts[:executer] = spring ? "spring" : "bundle exec"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
8
33
|
def initialize opts
|
|
9
34
|
super() do |parser|
|
|
10
35
|
parser.banner = "Usage: decko cucumber [DECKO ARGS] -- [CUCUMBER ARGS]\n\n"
|
|
11
|
-
parser.separator
|
|
12
|
-
|
|
13
|
-
DECKO ARGS
|
|
14
|
-
EOT
|
|
36
|
+
parser.separator "\nDECKO ARGS"
|
|
15
37
|
opts[:env] = ["RAILS_ROOT=."]
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
end
|
|
19
|
-
parser.on("-f", "--fast", "Stop on first failure") do |a|
|
|
20
|
-
opts[:env] << "FAST=1" if a
|
|
21
|
-
end
|
|
22
|
-
parser.on("-l", "--launchy", "Open page on failure") do |a|
|
|
23
|
-
opts[:env] << "LAUNCHY=1" if a
|
|
24
|
-
end
|
|
25
|
-
parser.on("-s", "--step", "Pause after each step") do |a|
|
|
26
|
-
opts[:env] << "STEP=1" if a
|
|
27
|
-
end
|
|
28
|
-
parser.on("--[no-]spring", "Run with spring") do |spring|
|
|
29
|
-
opts[:executer] =
|
|
30
|
-
if spring
|
|
31
|
-
"spring"
|
|
32
|
-
else
|
|
33
|
-
"bundle exec"
|
|
34
|
-
end
|
|
35
|
-
end
|
|
38
|
+
Flagger.new(parser, opts).add_flags
|
|
39
|
+
parse_spring parser, opts
|
|
36
40
|
end
|
|
37
41
|
end
|
|
38
42
|
end
|