nugrant 1.4.2 → 2.0.0.dev1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +1 -2
- data/.travis.yml +0 -6
- data/CHANGELOG.md +3 -79
- data/Gemfile +8 -8
- data/README.md +10 -146
- data/lib/nugrant.rb +4 -19
- data/lib/nugrant/bag.rb +8 -12
- data/lib/nugrant/config.rb +55 -24
- data/lib/nugrant/helper/bag.rb +19 -17
- data/lib/nugrant/parameters.rb +37 -9
- data/lib/nugrant/vagrant/v1/command/parameters.rb +13 -13
- data/lib/nugrant/vagrant/v1/command/root.rb +2 -7
- data/lib/nugrant/vagrant/v1/config/user.rb +1 -10
- data/lib/nugrant/vagrant/v2/command/parameters.rb +1 -1
- data/lib/nugrant/vagrant/v2/command/root.rb +2 -7
- data/lib/nugrant/vagrant/v2/config/user.rb +1 -10
- data/lib/nugrant/version.rb +1 -1
- data/nugrant.gemspec +1 -4
- data/test/lib/nugrant/test_bag.rb +19 -33
- data/test/lib/nugrant/test_config.rb +92 -100
- data/test/lib/nugrant/test_parameters.rb +186 -203
- data/test/resources/README.md +11 -11
- data/test/resources/{vagrantfiles/v1.empty → Vagrantfile.v1.empty} +0 -0
- data/test/resources/{vagrantfiles/v1.fake → Vagrantfile.v1.fake} +0 -0
- data/test/resources/{vagrantfiles/v1.real → Vagrantfile.v1.real} +0 -0
- data/test/resources/{vagrantfiles/v2.empty → Vagrantfile.v2.empty} +0 -0
- data/test/resources/{vagrantfiles/v2.fake → Vagrantfile.v2.fake} +1 -4
- data/test/resources/{vagrantfiles/v2.real → Vagrantfile.v2.real} +0 -0
- data/test/resources/json/params_current_1.json +6 -0
- data/test/resources/json/params_current_2.json +29 -0
- data/test/resources/{yml → yaml}/params_array.yml +0 -0
- data/test/resources/{yml → yaml}/params_boolean.yml +0 -0
- data/test/resources/{yml → yaml}/params_combinations.yml +0 -0
- data/test/resources/yaml/params_current_1.yml +4 -0
- data/test/resources/yaml/params_current_2.yml +23 -0
- data/test/resources/{yml → yaml}/params_defaults_at_root.yml +0 -0
- data/test/resources/{yml → yaml}/params_defaults_not_at_root.yml +0 -0
- data/test/resources/{yml → yaml}/params_empty.yml +0 -0
- data/test/resources/{yml → yaml}/params_list.yml +0 -0
- data/test/resources/{yml → yaml}/params_simple.yml +0 -0
- data/test/resources/{yml → yaml}/params_system_1.yml +0 -0
- data/test/resources/{yml → yaml}/params_system_2.yml +0 -0
- data/test/resources/{yml → yaml}/params_unix_eol.yml +0 -0
- data/test/resources/{yml → yaml}/params_user_1.yml +0 -0
- data/test/resources/{yml → yaml}/params_user_2.yml +0 -0
- data/test/resources/{yml → yaml}/params_windows_eol.yml +0 -0
- metadata +71 -95
- data/lib/nugrant/helper/env/exporter.rb +0 -208
- data/lib/nugrant/helper/env/namer.rb +0 -47
- data/lib/nugrant/helper/stack.rb +0 -86
- data/lib/nugrant/vagrant/errors.rb +0 -27
- data/lib/nugrant/vagrant/v1/command/env.rb +0 -107
- data/lib/nugrant/vagrant/v2/command/env.rb +0 -107
- data/locales/en.yml +0 -13
- data/test/lib/nugrant/helper/env/test_exporter.rb +0 -238
- data/test/lib/nugrant/helper/test_stack.rb +0 -149
- data/test/resources/json/params_project_1.json +0 -6
- data/test/resources/json/params_project_2.json +0 -29
- data/test/resources/json/params_user_nil_values.json +0 -9
- data/test/resources/vagrantfiles/v1.defaults_mixed_string_symbols +0 -18
- data/test/resources/vagrantfiles/v1.defaults_using_string +0 -18
- data/test/resources/vagrantfiles/v1.defaults_using_symbol +0 -18
- data/test/resources/vagrantfiles/v1.missing_parameter +0 -3
- data/test/resources/vagrantfiles/v2.defaults_mixed_string_symbols +0 -20
- data/test/resources/vagrantfiles/v2.defaults_null_values_in_vagrantuser +0 -25
- data/test/resources/vagrantfiles/v2.defaults_using_string +0 -20
- data/test/resources/vagrantfiles/v2.defaults_using_symbol +0 -20
- data/test/resources/vagrantfiles/v2.missing_parameter +0 -5
- data/test/resources/yml/params_project_1.yml +0 -4
- data/test/resources/yml/params_project_2.yml +0 -23
- data/test/resources/yml/params_user_nil_values.yml +0 -5
data/lib/nugrant/bag.rb
CHANGED
@@ -15,11 +15,11 @@ module Nugrant
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def method_missing(method, *args, &block)
|
18
|
-
return __fetch(method)
|
18
|
+
return __fetch(method.to_s)
|
19
19
|
end
|
20
20
|
|
21
21
|
def has?(key)
|
22
|
-
return @__elements.has_key?(key
|
22
|
+
return @__elements.has_key?(key)
|
23
23
|
end
|
24
24
|
|
25
25
|
def empty?()
|
@@ -42,7 +42,7 @@ module Nugrant
|
|
42
42
|
current.__merge!(value)
|
43
43
|
elsif current.kind_of?(Array) and value.kind_of?(Array)
|
44
44
|
@__elements[key] = current | value
|
45
|
-
|
45
|
+
else
|
46
46
|
@__elements[key] = value
|
47
47
|
end
|
48
48
|
|
@@ -59,16 +59,12 @@ module Nugrant
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
def __to_hash(
|
62
|
+
def __to_hash()
|
63
63
|
return {} if empty?()
|
64
64
|
|
65
|
-
string_key = options[:string_key]
|
66
|
-
|
67
65
|
hash = {}
|
68
66
|
each do |key, value|
|
69
|
-
key =
|
70
|
-
|
71
|
-
hash[key] = value.kind_of?(Bag) ? value.__to_hash(:string_key => string_key) : value
|
67
|
+
hash[key] = value.kind_of?(Bag) ? value.__to_hash() : value
|
72
68
|
end
|
73
69
|
|
74
70
|
return hash
|
@@ -80,12 +76,12 @@ module Nugrant
|
|
80
76
|
|
81
77
|
hash.each do |key, value|
|
82
78
|
if not value.kind_of?(Hash)
|
83
|
-
@__elements[key
|
79
|
+
@__elements[key] = value
|
84
80
|
next
|
85
81
|
end
|
86
82
|
|
87
83
|
# It is a hash, transform it into a bag
|
88
|
-
@__elements[key
|
84
|
+
@__elements[key] = Bag.new(value)
|
89
85
|
end
|
90
86
|
end
|
91
87
|
|
@@ -94,7 +90,7 @@ module Nugrant
|
|
94
90
|
raise KeyError, "Undefined parameter '#{key}'"
|
95
91
|
end
|
96
92
|
|
97
|
-
return @__elements[key
|
93
|
+
return @__elements[key]
|
98
94
|
end
|
99
95
|
end
|
100
96
|
end
|
data/lib/nugrant/config.rb
CHANGED
@@ -2,17 +2,24 @@ require 'rbconfig'
|
|
2
2
|
|
3
3
|
module Nugrant
|
4
4
|
class Config
|
5
|
-
DEFAULT_PARAMS_FILENAME = ".
|
6
|
-
|
5
|
+
DEFAULT_PARAMS_FILENAME = ".nuparams"
|
6
|
+
DEFAULT_PARAMS_FORMAT = :yaml
|
7
7
|
|
8
|
-
|
9
|
-
attr :params_filetype, true
|
8
|
+
attr_reader :params_filename, :params_format, :current_path, :user_path, :system_path
|
10
9
|
|
11
|
-
|
10
|
+
##
|
11
|
+
# Return the fully expanded path of the user parameters
|
12
|
+
# default location that is used in the constructor.
|
13
|
+
#
|
14
|
+
def self.default_user_path()
|
12
15
|
File.expand_path("~")
|
13
16
|
end
|
14
17
|
|
15
|
-
|
18
|
+
##
|
19
|
+
# Return the fully expanded path of the system parameters
|
20
|
+
# default location that is used in the constructor.
|
21
|
+
#
|
22
|
+
def self.default_system_path()
|
16
23
|
if Config.on_windows?
|
17
24
|
return File.expand_path(ENV['PROGRAMDATA'] || ENV['ALLUSERSPROFILE'])
|
18
25
|
end
|
@@ -20,31 +27,55 @@ module Nugrant
|
|
20
27
|
"/etc"
|
21
28
|
end
|
22
29
|
|
30
|
+
##
|
31
|
+
# Return true if we are currently on a Windows platform.
|
32
|
+
#
|
23
33
|
def self.on_windows?()
|
24
34
|
(RbConfig::CONFIG['host_os'].downcase =~ /mswin|mingw|cygwin/) != nil
|
25
35
|
end
|
26
36
|
|
37
|
+
##
|
38
|
+
# Creates a new config object that is used to configure an instance
|
39
|
+
# of Nugrant::Parameters. See the list of options and how they interact
|
40
|
+
# with Nugrant::Parameters.
|
41
|
+
#
|
42
|
+
# =| Options
|
43
|
+
# * +:params_filename+ - The filename used to fetch parameters from. This
|
44
|
+
# will be appended to various default locations.
|
45
|
+
# Location are system, project and current that
|
46
|
+
# can be tweaked individually by using the options
|
47
|
+
# below.
|
48
|
+
# Defaults => ".nuparams"
|
49
|
+
# * +:params_format+ - The format in which parameters are to be parsed.
|
50
|
+
# Presently supporting :yaml and :json.
|
51
|
+
# Defaults => :yaml
|
52
|
+
# * +:current_path+ - The current path has the highest precedence over
|
53
|
+
# any other location. It can be be used for many purposes
|
54
|
+
# depending on your usage.
|
55
|
+
# * A path from where to read project parameters
|
56
|
+
# * A path from where to read overriding parameters for a cli tool
|
57
|
+
# * A path from where to read user specific settings not to be committed in a VCS
|
58
|
+
# Defaults => "./#{@params_filename}"
|
59
|
+
# * +:user_path+ - The user path is the location where the user
|
60
|
+
# parameters should resides. The parameters loaded from this
|
61
|
+
# location have the second highest precedence.
|
62
|
+
# Defaults => "~/#{@params_filename}"
|
63
|
+
# * +:user_path+ - The system path is the location where system wide
|
64
|
+
# parameters should resides. The parameters loaded from this
|
65
|
+
# location have the third highest precedence.
|
66
|
+
# Defaults => Default system path depending on OS + @params_filename
|
67
|
+
#
|
27
68
|
def initialize(options = {})
|
28
|
-
|
69
|
+
@params_filename = options[:params_filename] || DEFAULT_PARAMS_FILENAME
|
70
|
+
@params_format = options[:params_format] || DEFAULT_PARAMS_FORMAT
|
29
71
|
|
30
|
-
|
31
|
-
|
72
|
+
raise ArgumentError,
|
73
|
+
"Invalid value for :params_format. \
|
74
|
+
The format [#{@params_format}] is currently not supported." if not [:json, :yaml].include?(@params_format)
|
32
75
|
|
33
|
-
@
|
34
|
-
@
|
35
|
-
@
|
36
|
-
end
|
37
|
-
|
38
|
-
def project_params_path()
|
39
|
-
File.expand_path(@project_params_path || "./#{@params_filename}")
|
40
|
-
end
|
41
|
-
|
42
|
-
def user_params_path()
|
43
|
-
File.expand_path(@user_params_path || "#{Config.user_base_path()}/#{@params_filename}")
|
44
|
-
end
|
45
|
-
|
46
|
-
def system_params_path()
|
47
|
-
File.expand_path(@system_params_path || "#{Config.system_base_path()}/#{@params_filename}")
|
76
|
+
@current_path = File.expand_path(options[:current_path] || "./#{@params_filename}")
|
77
|
+
@user_path = File.expand_path(options[:user_path] || "#{Config.default_user_path()}/#{@params_filename}")
|
78
|
+
@system_path = File.expand_path(options[:system_path] || "#{Config.default_system_path()}/#{@params_filename}")
|
48
79
|
end
|
49
80
|
end
|
50
81
|
end
|
data/lib/nugrant/helper/bag.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'json'
|
2
2
|
require 'yaml'
|
3
3
|
|
4
4
|
require 'nugrant/bag'
|
@@ -6,34 +6,36 @@ require 'nugrant/bag'
|
|
6
6
|
module Nugrant
|
7
7
|
module Helper
|
8
8
|
module Bag
|
9
|
-
def self.read(filepath,
|
10
|
-
data = parse_data(filepath,
|
9
|
+
def self.read(filepath, format, error_handler = nil)
|
10
|
+
data = parse_data(filepath, format, error_handler)
|
11
11
|
|
12
12
|
return Nugrant::Bag.new(data)
|
13
13
|
end
|
14
14
|
|
15
|
-
def self.parse_data(filepath,
|
15
|
+
def self.parse_data(filepath, format, error_handler = nil)
|
16
16
|
return if not File.exists?(filepath)
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
18
|
+
begin
|
19
|
+
File.open(filepath, "rb") do |file|
|
20
|
+
parsing_method = "parse_#{format.to_s}"
|
21
|
+
return send(parsing_method, file.read())
|
22
|
+
end
|
23
|
+
rescue => error
|
24
|
+
if error_handler
|
25
|
+
# TODO: Implements error handler logic
|
26
|
+
error_handler.handle("Could not parse the user #{format.to_s} parameters file '#{filepath}': #{error}")
|
27
|
+
end
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
29
|
-
def self.parse_json(
|
30
|
-
|
31
|
+
def self.parse_json(input)
|
32
|
+
JSON.parse(input)
|
31
33
|
end
|
32
34
|
|
33
|
-
def self.
|
34
|
-
YAML::ENGINE.yamler
|
35
|
+
def self.parse_yaml(input)
|
36
|
+
YAML::ENGINE.yamler= 'syck' if defined?(YAML::ENGINE)
|
35
37
|
|
36
|
-
YAML.load(
|
38
|
+
YAML.load(input)
|
37
39
|
end
|
38
40
|
end
|
39
41
|
end
|
data/lib/nugrant/parameters.rb
CHANGED
@@ -3,15 +3,29 @@ require 'nugrant/helper/bag'
|
|
3
3
|
|
4
4
|
module Nugrant
|
5
5
|
class Parameters
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :__current, :__user, :__system, :__defaults, :__all
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
##
|
9
|
+
# Create a new parameters object which holds completed
|
10
|
+
# merged values. The following precedence is used to decide
|
11
|
+
# which location has precedence over which location:
|
12
|
+
#
|
13
|
+
# (Highest) ------------------ (Lowest)
|
14
|
+
# current < user < system < defaults
|
15
|
+
#
|
16
|
+
# =| Options
|
17
|
+
# * +:config+ - A hash that will be passed to Nugrant::Config.new().
|
18
|
+
# See Nugrant::Config constructor for options that you can use.
|
19
|
+
# * +:defaults+ - The default values for the various parameters that will be read. This
|
20
|
+
# must be a Hash object.
|
21
|
+
#
|
22
|
+
def initialize(options = {})
|
23
|
+
@__config = Config.new(options[:config])
|
10
24
|
|
11
|
-
@
|
12
|
-
@
|
13
|
-
@
|
14
|
-
@
|
25
|
+
@__current = Helper::Bag.read(@__config.current_path, @__config.params_format)
|
26
|
+
@__user = Helper::Bag.read(@__config.user_path, @__config.params_format)
|
27
|
+
@__system = Helper::Bag.read(@__config.system_path, @__config.params_format)
|
28
|
+
@__defaults = Bag.new(options[:defaults] || {})
|
15
29
|
|
16
30
|
__compute_all()
|
17
31
|
end
|
@@ -21,7 +35,7 @@ module Nugrant
|
|
21
35
|
end
|
22
36
|
|
23
37
|
def method_missing(method, *args, &block)
|
24
|
-
return
|
38
|
+
return @__all[method.to_s]
|
25
39
|
end
|
26
40
|
|
27
41
|
def empty?()
|
@@ -36,6 +50,15 @@ module Nugrant
|
|
36
50
|
@__all.each(&block)
|
37
51
|
end
|
38
52
|
|
53
|
+
##
|
54
|
+
# Set the new default values for the
|
55
|
+
# various parameters contain by this instance.
|
56
|
+
# This will call __compute_all() to recompute
|
57
|
+
# correct precedences.
|
58
|
+
#
|
59
|
+
# =| Attributes
|
60
|
+
# * +elements+ - The new default elements
|
61
|
+
#
|
39
62
|
def defaults=(elements)
|
40
63
|
@__defaults = Bag.new(elements)
|
41
64
|
|
@@ -43,12 +66,17 @@ module Nugrant
|
|
43
66
|
__compute_all()
|
44
67
|
end
|
45
68
|
|
69
|
+
##
|
70
|
+
# Recompute the correct precedences by merging the various
|
71
|
+
# bag in the right order and return the result as a Nugrant::Bag
|
72
|
+
# object.
|
73
|
+
#
|
46
74
|
def __compute_all()
|
47
75
|
@__all = Bag.new()
|
48
76
|
@__all.__merge!(@__defaults)
|
49
77
|
@__all.__merge!(@__system)
|
50
78
|
@__all.__merge!(@__user)
|
51
|
-
@__all.__merge!(@
|
79
|
+
@__all.__merge!(@__current)
|
52
80
|
end
|
53
81
|
end
|
54
82
|
end
|
@@ -37,18 +37,18 @@ module Nugrant
|
|
37
37
|
end
|
38
38
|
|
39
39
|
parser.on("-u", "--user", "Show only user parameters") do
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
40
|
+
@show_user = true
|
41
|
+
end
|
42
|
+
|
43
|
+
parser.on("-p", "--project", "Show only project parameters") do
|
44
|
+
@show_project = true
|
45
|
+
end
|
46
|
+
|
47
|
+
parser.separator ""
|
48
|
+
parser.separator "When no options is provided, the command prints the names and values \n" +
|
49
|
+
"of all parameters that would be available for usage in the Vagrantfile.\n" +
|
50
|
+
"The hierarchy of the parameters is respected, so the final values are\n" +
|
51
|
+
"displayed."
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -110,7 +110,7 @@ module Nugrant
|
|
110
110
|
|
111
111
|
print_parameters(kind, {
|
112
112
|
'config' => {
|
113
|
-
'user' => bag.__to_hash(
|
113
|
+
'user' => bag.__to_hash()
|
114
114
|
}
|
115
115
|
})
|
116
116
|
end
|
@@ -1,6 +1,4 @@
|
|
1
1
|
require 'nugrant'
|
2
|
-
require 'nugrant/vagrant/v1/command/env'
|
3
|
-
require 'nugrant/vagrant/v1/command/parameters'
|
4
2
|
require 'nugrant/version'
|
5
3
|
|
6
4
|
module Nugrant
|
@@ -17,12 +15,9 @@ module Nugrant
|
|
17
15
|
@argv = @arguments
|
18
16
|
|
19
17
|
@subcommands = ::Vagrant::Registry.new()
|
20
|
-
@subcommands.register(:env) do
|
21
|
-
Command::Env
|
22
|
-
end
|
23
|
-
|
24
18
|
@subcommands.register(:parameters) do
|
25
|
-
|
19
|
+
require File.expand_path("../parameters", __FILE__)
|
20
|
+
Parameters
|
26
21
|
end
|
27
22
|
|
28
23
|
@show_help = false
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'nugrant'
|
2
|
-
require 'nugrant/vagrant/errors'
|
3
2
|
|
4
3
|
module Nugrant
|
5
4
|
module Vagrant
|
@@ -9,29 +8,21 @@ module Nugrant
|
|
9
8
|
attr_reader :parameters
|
10
9
|
|
11
10
|
def initialize()
|
12
|
-
@parameters = Nugrant::Parameters.new()
|
11
|
+
@parameters = Nugrant::Parameters.new({:config => {:params_filename => ".vagrantuser"}})
|
13
12
|
end
|
14
13
|
|
15
14
|
def [](param_name)
|
16
15
|
return @parameters[param_name]
|
17
|
-
rescue KeyError
|
18
|
-
raise Errors::ParameterNotFoundError, :key => param_name
|
19
16
|
end
|
20
17
|
|
21
18
|
def method_missing(method, *args, &block)
|
22
19
|
return @parameters.method_missing(method, *args, &block)
|
23
|
-
rescue KeyError
|
24
|
-
raise Errors::ParameterNotFoundError, :key => method
|
25
20
|
end
|
26
21
|
|
27
22
|
def each(&block)
|
28
23
|
@parameters.each(&block)
|
29
24
|
end
|
30
25
|
|
31
|
-
def has?(key)
|
32
|
-
@parameters.has?(key)
|
33
|
-
end
|
34
|
-
|
35
26
|
def defaults(parameters)
|
36
27
|
@parameters.defaults(parameters)
|
37
28
|
end
|
@@ -1,6 +1,4 @@
|
|
1
1
|
require 'nugrant'
|
2
|
-
require 'nugrant/vagrant/v2/command/env'
|
3
|
-
require 'nugrant/vagrant/v2/command/parameters'
|
4
2
|
require 'nugrant/version'
|
5
3
|
|
6
4
|
module Nugrant
|
@@ -17,12 +15,9 @@ module Nugrant
|
|
17
15
|
@argv = @arguments
|
18
16
|
|
19
17
|
@subcommands = ::Vagrant::Registry.new()
|
20
|
-
@subcommands.register(:env) do
|
21
|
-
Command::Env
|
22
|
-
end
|
23
|
-
|
24
18
|
@subcommands.register(:parameters) do
|
25
|
-
|
19
|
+
require File.expand_path("../parameters", __FILE__)
|
20
|
+
Parameters
|
26
21
|
end
|
27
22
|
|
28
23
|
@show_help = false
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'nugrant'
|
2
|
-
require 'nugrant/vagrant/errors'
|
3
2
|
|
4
3
|
module Nugrant
|
5
4
|
module Vagrant
|
@@ -9,29 +8,21 @@ module Nugrant
|
|
9
8
|
attr_reader :parameters
|
10
9
|
|
11
10
|
def initialize()
|
12
|
-
@parameters = Nugrant::Parameters.new()
|
11
|
+
@parameters = Nugrant::Parameters.new({:config => {:params_filename => ".vagrantuser"}})
|
13
12
|
end
|
14
13
|
|
15
14
|
def [](param_name)
|
16
15
|
return @parameters[param_name]
|
17
|
-
rescue KeyError
|
18
|
-
raise Errors::ParameterNotFoundError, :key => param_name
|
19
16
|
end
|
20
17
|
|
21
18
|
def method_missing(method, *args, &block)
|
22
19
|
return @parameters.method_missing(method, *args, &block)
|
23
|
-
rescue KeyError
|
24
|
-
raise Errors::ParameterNotFoundError, :key => method
|
25
20
|
end
|
26
21
|
|
27
22
|
def each(&block)
|
28
23
|
@parameters.each(&block)
|
29
24
|
end
|
30
25
|
|
31
|
-
def has?(key)
|
32
|
-
@parameters.has?(key)
|
33
|
-
end
|
34
|
-
|
35
26
|
def defaults(parameters)
|
36
27
|
@parameters.defaults(parameters)
|
37
28
|
end
|