Class: FastlaneCore::ConfigItem

Inherits:
Object
  • Object
show all
Defined in:
fastlane_core/lib/fastlane_core/configuration/config_item.rb

Direct Known Subclasses

Precheck::Rule

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key: nil, env_name: nil, env_names: nil, description: nil, short_option: nil, default_value: nil, default_value_dynamic: false, verify_block: nil, is_string: true, type: nil, skip_type_validation: false, optional: nil, conflicting_options: nil, conflict_block: nil, deprecated: nil, sensitive: nil, code_gen_sensitive: false, code_gen_default_value: nil, display_in_shell: true) ⇒ ConfigItem

Creates a new option rubocop:disable Metrics/ParameterLists rubocop:disable Metrics/PerceivedComplexity

Parameters:

  • key (Symbol) (defaults to: nil)

    the key which is used as command parameters or key in the fastlane tools

  • env_name (String) (defaults to: nil)

    the name of the environment variable, which is only used if no other values were found

  • env_names (Array) (defaults to: nil)

    the names of the environment variables, which is only used if no other values were found

  • description (String) (defaults to: nil)

    A description shown to the user

  • short_option (String) (defaults to: nil)

    A string of length 1 which is used for the command parameters (e.g. -f)

  • default_value (defaults to: nil)

    the value which is used if there was no given values and no environment values

  • default_value_dynamic (Boolean) (defaults to: false)

    Set if the default value is generated dynamically

  • verify_block (defaults to: nil)

    an optional block which is called when a new value is set. Check value is valid. This could be type checks or if a folder/file exists You have to raise a specific exception if something goes wrong. Append .red after the string

  • is_string (defaults to: true)

    *DEPRECATED: Use ‘type` instead* (Boolean) is that parameter a string? Defaults to true. If it’s true, the type string will be verified.

  • type (Class) (defaults to: nil)

    the data type of this config item. Takes precedence over ‘is_string`. Use `:shell_string` to allow types `String`, `Hash` and `Array` that will be converted to shell-escaped strings

  • skip_type_validation (Boolean) (defaults to: false)

    is false by default. If set to true, type of the parameter will not be validated.

  • optional (Boolean) (defaults to: nil)

    is false by default. If set to true, also string values will not be asked to the user

  • conflicting_options ([]) (defaults to: nil)

    array of conflicting option keys(@param key). This allows to resolve conflicts intelligently

  • conflict_block (defaults to: nil)

    an optional block which is called when options conflict happens

  • deprecated (Boolean|String) (defaults to: nil)

    Set if the option is deprecated. A deprecated option should be optional and is made optional if the parameter isn’t set, and fails otherwise

  • sensitive (Boolean) (defaults to: nil)

    Set if the variable is sensitive, such as a password or API token, to prevent echoing when prompted for the parameter

  • display_in_shell (Boolean) (defaults to: true)

    Set if the variable can be used from shell



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 96

def initialize(key: nil,
               env_name: nil,
               env_names: nil,
               description: nil,
               short_option: nil,
               default_value: nil,
               default_value_dynamic: false,
               verify_block: nil,
               is_string: true,
               type: nil,
               skip_type_validation: false,
               optional: nil,
               conflicting_options: nil,
               conflict_block: nil,
               deprecated: nil,
               sensitive: nil,
               code_gen_sensitive: false,
               code_gen_default_value: nil,
               display_in_shell: true)
  UI.user_error!("key must be a symbol") unless key.kind_of?(Symbol)
  UI.user_error!("env_name must be a String") unless (env_name || '').kind_of?(String)

  UI.user_error!("env_names must be an Array") unless (env_names || []).kind_of?(Array)
  (env_names || []).each do |name|
    UI.user_error!("env_names must only contain String") unless (name || '').kind_of?(String)
  end

  if short_option
    UI.user_error!("short_option for key :#{key} must of type String") unless short_option.kind_of?(String)
    UI.user_error!("short_option for key :#{key} must be a string of length 1") unless short_option.delete('-').length == 1
  end

  if description
    UI.user_error!("Do not let descriptions end with a '.', since it's used for user inputs as well for key :#{key}") if description[-1] == '.'
  end

  if conflicting_options
    conflicting_options.each do |conflicting_option_key|
      UI.user_error!("Conflicting option key must be a symbol") unless conflicting_option_key.kind_of?(Symbol)
    end
  end

  if deprecated
    # deprecated options are automatically optional
    optional = true if optional.nil?
    UI.crash!("Deprecated option must be optional") unless optional

    # deprecated options are marked deprecated in their description
    description = deprecated_description(description, deprecated)
  end

  optional = false if optional.nil?
  sensitive = false if sensitive.nil?

  @key = key
  @env_name = env_name
  @env_names = [env_name].compact + (env_names || [])
  @description = description
  @short_option = short_option
  @default_value = default_value
  @default_value_dynamic = default_value_dynamic
  @verify_block = verify_block
  @is_string = is_string
  @data_type = type
  @data_type = String if type == :shell_string
  @optional = optional
  @conflicting_options = conflicting_options
  @conflict_block = conflict_block
  @deprecated = deprecated
  @sensitive = sensitive
  @code_gen_sensitive = code_gen_sensitive || sensitive
  @allow_shell_conversion = (type == :shell_string)
  @display_in_shell = display_in_shell
  @skip_type_validation = skip_type_validation # sometimes we allow multiple types which causes type validation failures, e.g.: export_options in gym

  @code_gen_default_value = code_gen_default_value

  update_code_gen_default_value_if_able!
end

Instance Attribute Details

#allow_shell_conversionObject

Boolean

Set if the variable is to be converted to a shell-escaped String when provided as a Hash or Array

Allows items expected to be strings used in shell arguments to be alternatively provided as a Hash or Array for better readability and auto-escaped for us.



69
70
71
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 69

def allow_shell_conversion
  @allow_shell_conversion
end

#code_gen_default_valueObject

the value which is used during Swift code generation

if the default_value reads from ENV or a file, or from local credentials, we need
to provide a different default or it might be included in our autogenerated Swift
as a built-in default for the fastlane gem. This is because when we generate the
Swift API at deployment time, it fetches the default_value from the config_items


35
36
37
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 35

def code_gen_default_value
  @code_gen_default_value
end

#code_gen_sensitiveObject

Boolean

Set if the default value should never be used during code generation for Swift

We generate the Swift API at deployment time, and if there is a value that should never be
included in the Fastlane.swift or other autogenerated classes, we need to strip it out.
This includes things like API keys that could be read from ENV[]


65
66
67
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 65

def code_gen_sensitive
  @code_gen_sensitive
end

#conflict_blockObject

An optional block which is called when options conflict happens



52
53
54
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 52

def conflict_block
  @conflict_block
end

#conflicting_optionsObject

Array

array of conflicting option keys(@param key). This allows to resolve conflicts intelligently



49
50
51
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 49

def conflicting_options
  @conflicting_options
end

#default_valueObject

the value which is used if there was no given values and no environment values



25
26
27
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 25

def default_value
  @default_value
end

#default_value_dynamicObject

Boolean

Set if the default value is generated dynamically



28
29
30
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 28

def default_value_dynamic
  @default_value_dynamic
end

#deprecatedObject

String

Set if the option is deprecated. A deprecated option should be optional and is made optional if the parameter isn’t set, and fails otherwise



55
56
57
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 55

def deprecated
  @deprecated
end

#descriptionObject

String

A description shown to the user



19
20
21
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 19

def description
  @description
end

#display_in_shellObject

Boolean

Set if the variable can be used from shell



72
73
74
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 72

def display_in_shell
  @display_in_shell
end

#env_nameObject

String

the name of the environment variable, which is only used if no other values were found



13
14
15
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 13

def env_name
  @env_name
end

#env_namesObject

Array

the names of the environment variables, which is only used if no other values were found



16
17
18
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 16

def env_names
  @env_names
end

#keyObject

Symbol

the key which is used as command parameters or key in the fastlane tools



10
11
12
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 10

def key
  @key
end

#optionalObject

Boolean

is false by default. If set to true, also string values will not be asked to the user



43
44
45
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 43

def optional
  @optional
end

#sensitiveObject

Boolean

Set if the variable is sensitive, such as a password or API token, to prevent echoing when prompted for the parameter

If a default value exists, it won’t be used during code generation as default values can read from environment variables.



59
60
61
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 59

def sensitive
  @sensitive
end

#short_optionObject

String

A string of length 1 which is used for the command parameters (e.g. -f)



22
23
24
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 22

def short_option
  @short_option
end

#skip_type_validationObject

Boolean

is false by default. If set to true, type of the parameter will not be validated.



46
47
48
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 46

def skip_type_validation
  @skip_type_validation
end

#verify_blockObject

An optional block which is called when a new value is set.

Check value is valid. This could be type checks or if a folder/file exists
You have to raise a specific exception if something goes wrong. Use `user_error!` for the message: UI.user_error!("your message")


40
41
42
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 40

def verify_block
  @verify_block
end

Instance Method Details

#auto_convert_value(value) ⇒ Object

rubocop:disable Metrics/PerceivedComplexity Returns an updated value type (if necessary)



269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 269

def auto_convert_value(value)
  return nil if value.nil?

  if data_type == Array
    return value.split(',') if value.kind_of?(String)
  elsif data_type == Integer
    return value.to_i if value.to_i.to_s == value.to_s
  elsif data_type == Float
    return value.to_f if value.to_f.to_s == value.to_s
  elsif data_type == Symbol
    return value.to_sym if value.to_sym.to_s == value.to_s
  elsif allow_shell_conversion
    return value.shelljoin if value.kind_of?(Array)
    return value.map { |k, v| "#{k.to_s.shellescape}=#{v.shellescape}" }.join(' ') if value.kind_of?(Hash)
  elsif data_type == Hash && value.kind_of?(String)
    begin
      parsed = JSON.parse(value)
      return parsed if parsed.kind_of?(Hash)
    rescue JSON::ParserError
    end
  elsif data_type != String
    # Special treatment if the user specified true, false, on, off or YES, NO
    # There is no boolean type, so we just do it here
    if %w(yes YES true TRUE on ON).include?(value)
      return true
    elsif %w(no NO false FALSE off OFF).include?(value)
      return false
    end
  end
  # rubocop:enable Metrics/PerceivedComplexity

  return value # fallback to not doing anything
end

#data_typeObject

Determines the defined data type of this ConfigItem



304
305
306
307
308
309
310
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 304

def data_type
  if @data_type
    @data_type
  else
    (@is_string ? String : nil)
  end
end

#deprecated_description(initial_description, deprecated) ⇒ Object



326
327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 326

def deprecated_description(initial_description, deprecated)
  has_description = !initial_description.to_s.empty?

  description = "**DEPRECATED!**"

  if deprecated.kind_of?(String)
    description << " #{deprecated}"
    description << " -" if has_description
  end

  description << " #{initial_description}" if has_description

  description
end

#doc_default_valueObject



341
342
343
344
345
346
347
348
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 341

def doc_default_value
  return "[*](#parameters-legend-dynamic)" if self.default_value_dynamic
  return "" if self.default_value.nil?
  return "`''`" if self.default_value.instance_of?(String) && self.default_value.empty?
  return "`:#{self.default_value}`" if self.default_value.instance_of?(Symbol)

  "`#{self.default_value}`"
end

#ensure_array_type_passes_validation(value) ⇒ Object



219
220
221
222
223
224
225
226
227
228
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 219

def ensure_array_type_passes_validation(value)
  if @skip_type_validation
    return
  end

  # Arrays can be an either be an array or string that gets split by comma in auto_convert_type
  if !value.kind_of?(Array) && !value.kind_of?(String)
    UI.user_error!("'#{self.key}' value must be either `Array` or `comma-separated String`! Found #{value.class} instead.")
  end
end

#ensure_boolean_type_passes_validation(value) ⇒ Object



208
209
210
211
212
213
214
215
216
217
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 208

def ensure_boolean_type_passes_validation(value)
  if @skip_type_validation
    return
  end

  # We need to explicitly test against Fastlane::Boolean, TrueClass/FalseClass
  if value.class != FalseClass && value.class != TrueClass
    UI.user_error!("'#{self.key}' value must be either `true` or `false`! Found #{value.class} instead.")
  end
end

#ensure_generic_type_passes_validation(value) ⇒ Object



198
199
200
201
202
203
204
205
206
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 198

def ensure_generic_type_passes_validation(value)
  if @skip_type_validation
    return
  end

  if data_type != :string_callback && data_type && !value.kind_of?(data_type)
    UI.user_error!("'#{self.key}' value must be a #{data_type}! Found #{value.class} instead.")
  end
end

#fetch_env_valueObject



257
258
259
260
261
262
263
264
265
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 257

def fetch_env_value
  env_names.each do |name|
    next if ENV[name].nil?
    # verify! before using (see https://github.com/fastlane/fastlane/issues/14449)
    return ENV[name].dup if verify!(auto_convert_value(ENV[name]))
  end

  return nil
end

#help_default_valueObject



350
351
352
353
354
355
356
357
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 350

def help_default_value
  return "#{self.default_value} *".strip if self.default_value_dynamic
  return "" if self.default_value.nil?
  return "''" if self.default_value.instance_of?(String) && self.default_value.empty?
  return ":#{self.default_value}" if self.default_value.instance_of?(Symbol)

  self.default_value
end

#is_stringObject

it’s preferred to use self.string? In most cases, except in commander_generator.rb, cause… reasons



318
319
320
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 318

def is_string
  return @is_string
end

#string?Boolean

Replaces the attr_accessor, but maintains the same interface

Returns:



313
314
315
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 313

def string?
  data_type == String
end

#to_sObject



322
323
324
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 322

def to_s
  [@key, @description].join(": ")
end

#update_code_gen_default_value_if_able!Object

if code_gen_default_value is nil, use the default value if it isn’t a ‘code_gen_sensitive` value



179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 179

def update_code_gen_default_value_if_able!
  # we don't support default values for procs
  if @data_type == :string_callback
    @code_gen_default_value = nil
    return
  end

  if @code_gen_default_value.nil?
    unless @code_gen_sensitive

      @code_gen_default_value = @default_value
    end
  end
end

#valid?(value) ⇒ Boolean

Make sure, the value is valid (based on the verify block) Raises an exception if the value is invalid

Returns:



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 232

def valid?(value)
  # we also allow nil values, which do not have to be verified.
  return true if value.nil?

  # Verify that value is the type that we're expecting, if we are expecting a type
  if data_type == Fastlane::Boolean
    ensure_boolean_type_passes_validation(value)
  elsif data_type == Array
    ensure_array_type_passes_validation(value)
  else
    ensure_generic_type_passes_validation(value)
  end

  if @verify_block
    begin
      @verify_block.call(value)
    rescue => ex
      UI.error("Error setting value '#{value}' for option '#{@key}'")
      raise Interface::FastlaneError.new, ex.to_s
    end
  end

  true
end

#verify!(value) ⇒ Object



194
195
196
# File 'fastlane_core/lib/fastlane_core/configuration/config_item.rb', line 194

def verify!(value)
  valid?(value)
end