Class: Autoproj::Configuration

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

Overview

Class that does the handling of configuration options as well as loading/saving on disk

Constant Summary collapse

DEFAULT_UTILITY_SETUP =

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path = nil) ⇒ Configuration

Returns a new instance of Configuration.



29
30
31
32
33
34
35
36
# File 'lib/autoproj/configuration.rb', line 29

def initialize(path = nil)
    @config = Hash.new
    @overrides = Hash.new
    @declared_options = Hash.new
    @displayed_options = Hash.new
    @path = path
    @modified = false
end

Instance Attribute Details

#configObject (readonly)

Set of currently known options

These are the values that are going to be saved on disk. Use #override to change a value without changing the saved configuration file.



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

def config
  @config
end

#declared_optionsObject (readonly)

Set of options that have been declared with #declare



20
21
22
# File 'lib/autoproj/configuration.rb', line 20

def declared_options
  @declared_options
end

#displayed_optionsObject (readonly)

The options that have already been shown to the user



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

def displayed_options
  @displayed_options
end

#interactiveObject

Whether the configuration should be performed interactively or not



27
28
29
# File 'lib/autoproj/configuration.rb', line 27

def interactive
  @interactive
end

#overridesObject (readonly)

Set of overriden option values that won’t get written to file



18
19
20
# File 'lib/autoproj/configuration.rb', line 18

def overrides
  @overrides
end

#pathObject (readonly)

The path to the underlying configuration file



24
25
26
# File 'lib/autoproj/configuration.rb', line 24

def path
  @path
end

Class Method Details

.dot_gem_dirObject

The user-wide place where RubyGems installs gems



272
273
274
# File 'lib/autoproj/configuration.rb', line 272

def self.dot_gem_dir
    Ops::Install.dot_gem_dir
end

.gems_path_suffixObject

The Ruby platform and version-specific subdirectory used by bundler and rubygem



277
278
279
# File 'lib/autoproj/configuration.rb', line 277

def self.gems_path_suffix
    Ops::Install.gems_path_suffix
end

Instance Method Details

#apply_autobuild_configurationObject



352
353
354
355
356
357
358
359
360
361
# File 'lib/autoproj/configuration.rb', line 352

def apply_autobuild_configuration
    if has_value_for?("autobuild")
        params = get("autobuild")
        if params.kind_of?(Hash)
            params.each do |k, v|
                Autobuild.send("#{k}=", v)
            end
        end
    end
end

#build_dirString

Defines the temporary area in which packages should put their build files

If absolute, it is handled as #prefix_dir: the package name will be appended to it. If relative, it is relative to the package’s source directory

The default is “build”

Returns:

  • (String)


412
413
414
# File 'lib/autoproj/configuration.rb', line 412

def build_dir
    get("build", "build")
end

#bundler_versionObject



348
349
350
# File 'lib/autoproj/configuration.rb', line 348

def bundler_version
    get "bundler_version", nil
end

#configure(option_name) ⇒ Object

Configures a given option by asking the user about its desired value

Returns:

  • (Object)

    the new option value

Raises:

  • ConfigError if the option is not declared



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/autoproj/configuration.rb', line 179

def configure(option_name)
    if (opt = declared_options[option_name])
        if (current_value = config[option_name])
            current_value = current_value.first
        end
        is_default = false
        if interactive?
            value = opt.ask(current_value, nil)
        else
            value, is_default = opt.ensure_value(current_value)
            Autoproj.info "       using: #{value} (noninteractive mode)"
        end
        @modified = true
        if is_default
            value = opt.validate(value)
        else
            config[option_name] = [value, true]
            displayed_options[option_name] = value
        end
        value
    else
        raise ConfigError.new, "undeclared option '#{option_name}'"
    end
end

#declare(name, type, **options, &validator) ⇒ Object

Declare an option

This declares a given option, thus allowing to ask the user about it

Parameters:

  • name (String)

    the option name

  • type (String)

    the option type (can be ‘boolean’ or ‘string’)

  • options (Hash)

    a customizable set of options

Options Hash (**options):

  • :short_doc (String)

    the one-line documentation string that is displayed when the user does not have to be queried. It defaults to the first line of :doc if not given

  • :doc (String)

    the full option documentation. It is displayed to the user when he is explicitly asked about the option’s value

  • :default (Object)

    the default value this option should take

  • :possible_values (Array)

    list of possible values (only if the option type is ‘string’)

  • :lowercase (Boolean) — default: false

    whether the user’s input should be converted to lowercase before it gets validated / saved.

  • :uppercase (Boolean) — default: false

    whether the user’s input should be converted to uppercase before it gets validated / saved.



165
166
167
# File 'lib/autoproj/configuration.rb', line 165

def declare(name, type, **options, &validator)
    declared_options[name] = BuildOption.new(name, type, options, validator)
end

#declared?(name) ⇒ Boolean

Checks if an option exists

Returns:

  • (Boolean)


171
172
173
# File 'lib/autoproj/configuration.rb', line 171

def declared?(name)
    declared_options.has_key?(name)
end

#each_reused_autoproj_installation(&block) ⇒ Object



238
239
240
241
242
243
244
# File 'lib/autoproj/configuration.rb', line 238

def each_reused_autoproj_installation(&block)
    if has_value_for?("reused_autoproj_installations")
        get("reused_autoproj_installations").each(&block)
    else
        [].each(&block)
    end
end

#gems_gem_homeString

The GEM_HOME into which the workspace gems are installed

Parameters:

  • ws (Workspace)

    the workspace whose gems are being considered

Returns:

  • (String)


301
302
303
# File 'lib/autoproj/configuration.rb', line 301

def gems_gem_home
    File.join(gems_install_path, self.class.gems_path_suffix)
end

#gems_install_pathString

The gem install root into which the workspace gems are installed

Note that while this setting is separated from the other gems path, the only way to reliably isolate the gems of an autoproj workspace is to separate both the autoproj gems and the workspace gems. This is why there are only –public and –private settings in autoproj_install

The gems are actually installed under a platform and version-specific subdirectory (returned by #gems_path_suffix)

Parameters:

  • ws (Workspace)

    the workspace whose gems are being considered

Returns:

  • (String)


293
294
295
# File 'lib/autoproj/configuration.rb', line 293

def gems_install_path
    get("gems_install_path")
end

#get(key, *default_value) ⇒ Object

Get the value for a given option



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/autoproj/configuration.rb', line 109

def get(key, *default_value)
    return overrides[key].dup if overrides.has_key?(key)

    has_value = config.has_key?(key)
    value, validated = config[key]

    if !declared?(key)
        if has_value
            value.dup
        elsif default_value.empty?
            raise ConfigError, "undeclared option '#{key}'"
        else
            default_value.first.dup
        end
    elsif validated
        doc = declared_options[key].short_doc
        doc = "#{doc}:" if doc[-1, 1] != "?"
        displayed_options[key] = value
        value.dup
    else
        configure(key).dup
    end
end

#has_value_for?(name) ⇒ Boolean

Tests whether a value is set for the given option name

Returns:

  • (Boolean)


104
105
106
# File 'lib/autoproj/configuration.rb', line 104

def has_value_for?(name)
    config.has_key?(name) || overrides.has_key?(name)
end

#import_log_enabled=(value) ⇒ Object



250
251
252
# File 'lib/autoproj/configuration.rb', line 250

def import_log_enabled=(value)
    set("import_log_enabled", !!value)
end

#import_log_enabled?Boolean

Returns:

  • (Boolean)


246
247
248
# File 'lib/autoproj/configuration.rb', line 246

def import_log_enabled?
    get("import_log_enabled", true)
end

#importer_cache_dirObject

A cache directory for autobuild’s importers



364
365
366
# File 'lib/autoproj/configuration.rb', line 364

def importer_cache_dir
    get("importer_cache_dir", nil)
end

#importer_cache_dir=(path) ⇒ Object

Set import and gem cache directory



369
370
371
# File 'lib/autoproj/configuration.rb', line 369

def importer_cache_dir=(path)
    set("importer_cache_dir", path, true)
end

#interactive?Boolean

Returns true if the configuration should be performed interactively

Returns:

  • (Boolean)

See Also:



467
468
469
470
471
472
473
474
475
476
477
# File 'lib/autoproj/configuration.rb', line 467

def interactive?
    if !interactive.nil?
        return interactive
    elsif ENV["AUTOPROJ_NONINTERACTIVE"] == "1"
        return false
    elsif has_value_for?("interactive")
        return get("interactive")
    end

    true
end

#load(path: self.path, reconfigure: false) ⇒ Object



204
205
206
207
208
209
210
211
212
213
# File 'lib/autoproj/configuration.rb', line 204

def load(path: self.path, reconfigure: false)
    current_keys = @config.keys
    return unless (h = YAML.load(File.read(path)))

    h.each do |key, value|
        current_keys.delete(key)
        set(key, value, !reconfigure)
    end
    @modified = false if current_keys.empty?
end

#merge(conf) ⇒ Object



580
581
582
# File 'lib/autoproj/configuration.rb', line 580

def merge(conf)
    config.merge!(conf.config)
end

#modified?Boolean

Whether the configuration was changed since the last call to #load or #save

Returns:

  • (Boolean)


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

def modified?
    @modified
end

#override(option_name, value) ⇒ Object

Override a known option value

The new value will not be saved to disk, unlike with #set



88
89
90
# File 'lib/autoproj/configuration.rb', line 88

def override(option_name, value)
    overrides[option_name] = value
end

#parallel_build_levelObject



254
255
256
# File 'lib/autoproj/configuration.rb', line 254

def parallel_build_level
    get("parallel_build_level", nil) || Autobuild.parallel_build_level
end

#parallel_build_level=(level) ⇒ Object



258
259
260
261
# File 'lib/autoproj/configuration.rb', line 258

def parallel_build_level=(level)
    set("parallel_build_level", level)
    Autobuild.parallel_build_level = level
end

#parallel_import_levelObject



263
264
265
# File 'lib/autoproj/configuration.rb', line 263

def parallel_import_level
    get("parallel_import_level", 10)
end

#parallel_import_level=(level) ⇒ Object



267
268
269
# File 'lib/autoproj/configuration.rb', line 267

def parallel_import_level=(level)
    set("parallel_import_level", level)
end

#prefer_indep_over_os_packages?Boolean

Whether the OS package handler should prefer installing OS-independent packages (as e.g. RubyGems) as opposed to the binary packages equivalent (e.g. thor as a gem vs. thor as the ruby-thor Ubuntu package)

This is false by default

Returns:

  • (Boolean)


590
591
592
# File 'lib/autoproj/configuration.rb', line 590

def prefer_indep_over_os_packages?
    get("prefer_indep_over_os_packages", false)
end

#prefix_dirString

The directory in which packages will be installed.

If it is a relative path, it is relative to the root dir of the installation.

The default is “install”

Returns:

  • (String)


386
387
388
# File 'lib/autoproj/configuration.rb', line 386

def prefix_dir
    get("prefix", "install")
end

#prefix_dir=(path) ⇒ Object

Sets the directory in which packages will be installed



374
375
376
# File 'lib/autoproj/configuration.rb', line 374

def prefix_dir=(path)
    set("prefix", path, true)
end

#randomize_layout=(value) ⇒ Boolean

Sets whether the layout should be randomized

Returns:

  • (Boolean)

See Also:



459
460
461
# File 'lib/autoproj/configuration.rb', line 459

def randomize_layout=(value)
    set("randomize_layout", value, true)
end

#randomize_layout?Boolean

Returns true if packages and prefixes should be auto-generated, based on the SHA of the package names. This is meant to be used for build services that want to check that dependencies are properly set

The default is false (disabled)

Returns:

  • (Boolean)


451
452
453
# File 'lib/autoproj/configuration.rb', line 451

def randomize_layout?
    get("randomize_layout", false)
end

#reconfigure!Object



215
216
217
218
219
220
221
222
# File 'lib/autoproj/configuration.rb', line 215

def reconfigure!
    new_config = Hash.new
    config.each do |key, (value, _user_validated)|
        new_config[key] = [value, false]
    end
    @modified = true
    @config = new_config
end

#reset(name = nil) ⇒ Object

Deletes the current configuration for all options or the one specified

The user will be asked for a new value next time one of the reset options is needed

Parameters:

  • name (String) (defaults to: nil)

    the option name (or by default nil to reset all options)

Returns:

  • the deleted value



57
58
59
60
61
62
63
64
65
66
67
# File 'lib/autoproj/configuration.rb', line 57

def reset(name = nil)
    if name
        @modified ||= config.has_key?(name)
        config.delete(name)
        overrides.delete(name)
    else
        @config.clear
        @overrides.clear
        @modified = true
    end
end

#reset_modifiedObject

Resets the modified? flag to false



45
46
47
# File 'lib/autoproj/configuration.rb', line 45

def reset_modified
    @modified = false
end

#reset_overrides(*names) ⇒ Object

Remove all overrides



93
94
95
96
97
98
99
# File 'lib/autoproj/configuration.rb', line 93

def reset_overrides(*names)
    if names.empty?
        @overrides.clear
    else
        names.each { |n| @overrides.delete(n) }
    end
end

#ruby_executableObject

The full path to the expected ruby executable



306
307
308
309
310
311
312
313
# File 'lib/autoproj/configuration.rb', line 306

def ruby_executable
    unless (path = get("ruby_executable", nil))
        path = OSPackageResolver.autodetect_ruby_program
        set("ruby_executable", path, true)
    end

    path
end

#save(path = self.path, force: false) ⇒ Object



224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/autoproj/configuration.rb', line 224

def save(path = self.path, force: false)
    return if !modified? && !force

    Ops.atomic_write(path) do |io|
        h = Hash.new
        config.each do |key, value|
            h[key] = value.first
        end

        io.write YAML.dump(h)
    end
    @modified = false
end

#separate_prefixes=(flag) ⇒ Object

Controls whether there should be one prefix per package



440
441
442
# File 'lib/autoproj/configuration.rb', line 440

def separate_prefixes=(flag)
    set("separate_prefixes", flag, true)
end

#separate_prefixes?Boolean

Returns true if there should be one prefix per package

The default is false (disabled)

Returns:

  • (Boolean)


433
434
435
# File 'lib/autoproj/configuration.rb', line 433

def separate_prefixes?
    get("separate_prefixes", false)
end

#set(key, value, user_validated = false) ⇒ Object

Sets a configuration option

Parameters:

  • key (String)

    the option name

  • value (Object)

    the option value

  • user_validated (Boolean) (defaults to: false)

    if true, autoproj will not ask the user about this value next time it is needed. Otherwise, it will be asked about it, the new value being used as default



76
77
78
79
80
81
82
83
# File 'lib/autoproj/configuration.rb', line 76

def set(key, value, user_validated = false)
    if config.has_key?(key)
        @modified ||= (config[key][0] != value)
    else
        @modified = true
    end
    config[key] = [value.dup, user_validated]
end

#shell_helpers=(flag) ⇒ Object



344
345
346
# File 'lib/autoproj/configuration.rb', line 344

def shell_helpers=(flag)
    set "shell_helpers", flag, true
end

#shell_helpers?Boolean

Returns:

  • (Boolean)


340
341
342
# File 'lib/autoproj/configuration.rb', line 340

def shell_helpers?
    get "shell_helpers", true
end

#source_dirString?

Defines a folder to which source packages will be layed out relative to

If nil, packages will be layed out relative to root_dir Only relative paths are allowed

The default is nil

Returns:

  • (String, nil)


424
425
426
# File 'lib/autoproj/configuration.rb', line 424

def source_dir
    get("source", nil)
end

#to_hashObject

The configuration as a key => value map



595
596
597
598
599
600
601
602
603
604
605
606
607
608
# File 'lib/autoproj/configuration.rb', line 595

def to_hash
    result = Hash.new
    @config.each do |key, (value, _)|
        if declared_options.include?(key)
            result[key] = declared_options[key].ensure_value(value)
        else
            result[key] = value
        end
    end
    overrides.each do |key, value|
        result[key] = value
    end
    result
end

#use_prerelease?Boolean

Returns:

  • (Boolean)


329
330
331
332
333
334
335
336
337
338
# File 'lib/autoproj/configuration.rb', line 329

def use_prerelease?
    use_prerelease =
        if (env_flag = ENV["AUTOPROJ_USE_PRERELEASE"])
            env_flag == "1"
        elsif has_value_for?("autoproj_use_prerelease")
            get("autoproj_use_prerelease")
        end
    set "autoproj_use_prerelease", (use_prerelease ? true : false), true
    use_prerelease
end

#user_shellsArray<String>

The shells used in this workspace.

Returns:

  • (Array<String>)


398
399
400
# File 'lib/autoproj/configuration.rb', line 398

def user_shells
    get("user_shells", [])
end

#user_shells=(shells) ⇒ Object

Sets the shells used in this workspace.



391
392
393
# File 'lib/autoproj/configuration.rb', line 391

def user_shells=(shells)
    set("user_shells", shells, true)
end

#utility_default(utility, enabled) ⇒ void

This method returns an undefined value.

Set the given utility to enabled by default

Unlike #utility_enable_all and #utility_disable_all, it does not touch existing exclusions

Parameters:

  • utility (String)

    the utility name (e.g. ‘doc’ or ‘test’)

  • enabled (Boolean)

    whether the utility will be enabled (true) or disabled (false)



521
522
523
# File 'lib/autoproj/configuration.rb', line 521

def utility_default(utility, enabled)
    set("#{utility_key(utility)}_default", enabled ? true : false)
end

#utility_disable(utility, *packages) ⇒ void

This method returns an undefined value.

Disables a utility for a specific package

Note that if the default for this utility is to be disabled, this is essentially a no-op.

Parameters:

  • utility (String)

    the utility name (e.g. ‘doc’ or ‘test’)

  • packages (String)

    the package names



572
573
574
575
576
577
578
# File 'lib/autoproj/configuration.rb', line 572

def utility_disable(utility, *packages)
    utility_config = get(utility_key(utility), Hash.new)
    packages.each do |pkg_name|
        utility_config[pkg_name] = false
    end
    set(utility_key(utility), utility_config)
end

#utility_disable_all(utility) ⇒ void

This method returns an undefined value.

Disables a utility for all packages

This both sets the default value for all packages and resets all package-specific values set with utility_enable_for and utility_disable_for

Parameters:

  • utility (String)

    the utility name (e.g. ‘doc’ or ‘test’)



559
560
561
562
# File 'lib/autoproj/configuration.rb', line 559

def utility_disable_all(utility)
    reset(utility_key(utility))
    set("#{utility_key(utility)}_default", false)
end

#utility_enable(utility, *packages) ⇒ void

This method returns an undefined value.

Enables a utility for a set of packages

Parameters:

  • utility (String)

    the utility name (e.g. ‘doc’ or ‘test’)

  • packages (String)

    the package names



543
544
545
546
547
548
549
# File 'lib/autoproj/configuration.rb', line 543

def utility_enable(utility, *packages)
    utility_config = get(utility_key(utility), Hash.new)
    packages.each do |pkg_name|
        utility_config[pkg_name] = true
    end
    set(utility_key(utility), utility_config)
end

#utility_enable_all(utility) ⇒ void

This method returns an undefined value.

Enables a utility for all packages

This both sets the default value for all packages and resets all package-specific values set with utility_enable_for and utility_disable_for

Parameters:

  • utility (String)

    the utility name (e.g. ‘doc’ or ‘test’)



533
534
535
536
# File 'lib/autoproj/configuration.rb', line 533

def utility_enable_all(utility)
    reset(utility_key(utility))
    set("#{utility_key(utility)}_default", true)
end

#utility_enabled_for?(utility, package) ⇒ Boolean

Returns whether a given utility is enabled for the package

If there is no specific configuration for the package, uses the global default set with utility_enable_all or utility_disable_all. If none of these methods has been called, uses the default in DEFAULT_UTILITY_SETUP

Parameters:

  • utility (String)

    the utility name (e.g. ‘doc’ or ‘test’)

  • package (String)

    the package name

Returns:

  • (Boolean)

    true if the utility should be enabled for the requested package and false otherwise



503
504
505
506
507
508
509
510
# File 'lib/autoproj/configuration.rb', line 503

def utility_enabled_for?(utility, package)
    utility_config = get(utility_key(utility), Hash.new)
    if utility_config.has_key?(package)
        utility_config[package]
    else
        get("#{utility_key(utility)}_default", DEFAULT_UTILITY_SETUP[utility])
    end
end

#utility_key(utility) ⇒ String

The configuration key that should be used to store the utility enable/disable information

Parameters:

  • the (String)

    utility name

Returns:

  • (String)

    the config key



488
489
490
# File 'lib/autoproj/configuration.rb', line 488

def utility_key(utility)
    "autoproj_#{utility}_utility"
end

#validate_ruby_executableObject

Verify that the Ruby executable that is being used to run autoproj matches the one expected in the configuration



317
318
319
320
321
322
323
324
325
326
327
# File 'lib/autoproj/configuration.rb', line 317

def validate_ruby_executable
    actual = OSPackageResolver.autodetect_ruby_program
    if has_value_for?("ruby_executable")
        expected = get("ruby_executable")
        if expected != actual
            raise ConfigError.new, "this autoproj installation was bootstrapped using #{expected}, but you are currently running under #{actual}. Changing the Ruby executable for in an existing autoproj workspace is unsupported"
        end
    else
        set("ruby_executable", actual, true)
    end
end

#validated_valuesObject

Returns the option’s name-value pairs for the options that do not require user input



135
136
137
138
139
140
141
142
143
# File 'lib/autoproj/configuration.rb', line 135

def validated_values
    config.inject(Hash.new) do |h, (k, v)|
        h[k] =
            if overrides.has_key?(k) then overrides[k]
            elsif v.last || !declared?(k) then v.first
            end
        h
    end
end