Class: Autobuild::Environment

Inherits:
Object
  • Object
show all
Defined in:
lib/autobuild/environment.rb

Overview

Manager class for environment variables

Defined Under Namespace

Classes: ExportedEnvironment

Constant Summary collapse

PKGCONFIG_PATH_RX =
%r{.*/((?:lib|lib64|share)/.*)}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeEnvironment

Returns a new instance of Environment.



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/autobuild/environment.rb', line 103

def initialize
    @inherited_environment = Hash.new
    @environment = Hash.new
    @source_before = Set.new
    @source_after = Set.new
    @inherit = true
    @inherited_variables = Set.new
    @path_variables = Set.new

    @system_env = Hash.new
    @original_env = ORIGINAL_ENV.dup

    @default_pkgconfig_search_suffixes = nil
    @arch_names = nil
    @target_arch = nil
    @arch_size = nil
end

Instance Attribute Details

#environmentObject (readonly)

List of the environment that should be set before calling a subcommand

It is a map from environment variable name to the corresponding value. If the value is an array, it is joined using the operating system’s path separator (File::PATH_SEPARATOR)



93
94
95
# File 'lib/autobuild/environment.rb', line 93

def environment
  @environment
end

#inherited_environmentObject (readonly)

In generated environment update shell files, indicates whether an environment variable should be overriden by the shell script, or simply updated

If inherited_environment is true, the generated shell script will contain

export VARNAME=new_value:new_value:$VARNAME

otherwise

export VARNAME=new_value:new_value


87
88
89
# File 'lib/autobuild/environment.rb', line 87

def inherited_environment
  @inherited_environment
end

#inherited_variablesObject (readonly)

Returns the value of attribute inherited_variables.



95
96
97
# File 'lib/autobuild/environment.rb', line 95

def inherited_variables
  @inherited_variables
end

#original_envObject (readonly)

Returns the value of attribute original_env.



95
96
97
# File 'lib/autobuild/environment.rb', line 95

def original_env
  @original_env
end

#path_variablesObject (readonly)

The set of environment variables that are known to hold paths on the filesystem



101
102
103
# File 'lib/autobuild/environment.rb', line 101

def path_variables
  @path_variables
end

#system_envObject (readonly)

Returns the value of attribute system_env.



95
96
97
# File 'lib/autobuild/environment.rb', line 95

def system_env
  @system_env
end

#target_archObject

Returns the value of attribute target_arch.



95
96
97
# File 'lib/autobuild/environment.rb', line 95

def target_arch
  @target_arch
end

Class Method Details

.environment_from_export(export, base_env = ENV) ⇒ Object

Build an environment hash from an environment export and some initial state

This is basically the programmatic version of what #export_env_sh instructs the shell to do



537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
# File 'lib/autobuild/environment.rb', line 537

def self.environment_from_export(export, base_env = ENV)
    result = Hash.new
    export.set.each do |name, value|
        result[name] = value.join(File::PATH_SEPARATOR)
    end
    base_env.each do |name, value|
        result[name] ||= value
    end
    export.unset.each do |name|
        result.delete(name)
    end
    export.update.each do |name, (with_inheritance, without_inheritance)|
        if result[name]
            variable_expansion = "$#{name}"
            with_inheritance = with_inheritance.map do |value|
                if value == variable_expansion
                    base_env[name]
                else
                    value
                end
            end
            result[name] = with_inheritance.join(File::PATH_SEPARATOR)
        else
            result[name] = without_inheritance.join(File::PATH_SEPARATOR)
        end
    end
    result
end

.find_executable_in_path(file, entries) ⇒ Object



785
786
787
788
789
790
791
792
793
794
795
# File 'lib/autobuild/environment.rb', line 785

def self.find_executable_in_path(file, entries)
    entries.each do |dir|
        full = File.join(dir, file)
        begin
            stat = File.stat(full)
            return full if stat.file? && stat.executable?
        rescue ::Exception # rubocop:disable Lint/SuppressedException
        end
    end
    nil
end

.find_in_path(file, entries) ⇒ Object



801
802
803
804
805
806
807
# File 'lib/autobuild/environment.rb', line 801

def self.find_in_path(file, entries)
    entries.each do |dir|
        full = File.join(dir, file)
        return full if File.file?(full)
    end
    nil
end

.pathvar(path, varname) ⇒ Object

DEPRECATED: use add_path instead



567
568
569
570
571
572
573
# File 'lib/autobuild/environment.rb', line 567

def self.pathvar(path, varname)
    if File.directory?(path)
        return if block_given? && !yield(path)

        add_path(varname, path)
    end
end

Instance Method Details

#[](name) ⇒ Object



153
154
155
# File 'lib/autobuild/environment.rb', line 153

def [](name)
    resolved_env[name]
end

#add(name, *values) ⇒ Object

Adds new value(s) at the end of an environment variable



298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/autobuild/environment.rb', line 298

def add(name, *values)
    values = values.map { |v| expand(v) }

    set = environment[name] if environment.key?(name)
    init_from_env(name) unless inherited_environment.key?(name)

    if !set
        set = Array.new
    elsif !set.respond_to?(:to_ary)
        set = [set]
    end

    values.concat(set)
    @environment[name] = values
end

#add_path(name, *paths) ⇒ Object

Add a path at the end of an environment variable

Unlike “normal” variables, entries of path variables that cannot be found on disk are filtered out at usage points (either #resolve_env or at the time of envirnonment export)

See Also:



396
397
398
399
400
401
402
403
404
405
406
407
408
409
# File 'lib/autobuild/environment.rb', line 396

def add_path(name, *paths)
    declare_path_variable(name)
    paths = paths.map { |p| expand(p) }

    oldpath = (environment[name] ||= Array.new)
    paths.reverse_each do |path|
        path = path.to_str
        next if oldpath.include?(path)

        add(name, path)
        oldpath << path
        $LOAD_PATH.unshift path if name == 'RUBYLIB'
    end
end

#add_prefix(newprefix, includes = nil) ⇒ Object

Updates the environment when a new prefix has been added



727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
# File 'lib/autobuild/environment.rb', line 727

def add_prefix(newprefix, includes = nil)
    if (!includes || includes.include?('PATH')) &&
       File.directory?("#{newprefix}/bin")
        add_path('PATH', "#{newprefix}/bin")
    end

    if !includes || includes.include?('PKG_CONFIG_PATH')
        each_env_search_path(newprefix,
                             default_pkgconfig_search_suffixes) do |path|
            add_path('PKG_CONFIG_PATH', path)
        end
    end

    if !includes || includes.include?(LIBRARY_PATH)
        ld_library_search = ['lib', 'lib/ARCH', 'libARCHSIZE']
        each_env_search_path(newprefix, ld_library_search) do |path|
            glob_path = File.join(path, "lib*.#{LIBRARY_SUFFIX}")
            has_sofile = Dir.enum_for(:glob, glob_path)
                .find { true }
            add_path(LIBRARY_PATH, path) if has_sofile
        end
    end

    cmake_pairs = []
    cmake_pairs << ["CMAKE_PREFIX_PATH", ["*-config.cmake", "*Config.cmake"]]
    cmake_pairs << ["CMAKE_MODULE_PATH", ["Find*.cmake"]]
    cmake_pairs.each do |cmake_var, cmake_file_globs|
        if !includes || includes.include?(cmake_var)
            has_cmake = has_cmake_files?(newprefix, *cmake_file_globs)
            add_path(cmake_var, newprefix) if has_cmake
        end
    end

    # Validate the new rubylib path
    if !includes || includes.include?('RUBYLIB')
        new_rubylib = "#{newprefix}/lib"

        standalone_ruby_package =
            File.directory?(new_rubylib) &&
            !File.directory?(File.join(new_rubylib, "ruby")) &&
            !Dir["#{new_rubylib}/**/*.rb"].empty?
        add_path('RUBYLIB', new_rubylib) if standalone_ruby_package

        %w[rubylibdir archdir sitelibdir sitearchdir vendorlibdir vendorarchdir].
            map { |key| RbConfig::CONFIG[key] }.
            map { |path| path.gsub(%r{.*lib(?:32|64)?/}, '\\1') }.
            each do |subdir|
                if File.directory?("#{newprefix}/lib/#{subdir}")
                    add_path("RUBYLIB", "#{newprefix}/lib/#{subdir}")
                end
            end
    end
end

#arch_namesObject



628
629
630
631
632
633
634
635
636
637
638
639
640
641
# File 'lib/autobuild/environment.rb', line 628

def arch_names
    return @arch_names if @arch_names

    result = Set.new
    if File.file?('/usr/bin/dpkg-architecture')
        cmdline = ['/usr/bin/dpkg-architecture']
        cmdline << "-T" << target_arch if target_arch
        out = `#{cmdline.join(" ")}`.split
        arch = out.grep(/DEB_TARGET_MULTIARCH/).first ||
               out.grep(/DEB_BUILD_MULTIARCH/).first
        result << arch.chomp.split('=').last if arch
    end
    @arch_names = result
end

#arch_sizeObject



602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
# File 'lib/autobuild/environment.rb', line 602

def arch_size
    return @arch_size if @arch_size

    if File.file?('/usr/bin/dpkg-architecture')
        cmdline = ['/usr/bin/dpkg-architecture']
        cmdline << "-T" << target_arch if target_arch
        out = `#{cmdline.join(" ")}`.split
        arch = out.grep(/DEB_TARGET_ARCH_BITS/).first ||
               out.grep(/DEB_BUILD_ARCH_BITS/).first
        @arch_size = Integer(arch.chomp.split('=').last) if arch
    end

    @arch_size ||=
        if RbConfig::CONFIG['host_cpu'] =~ /64/
            64
        else
            32
        end
    @arch_size
end

#clear(name = nil) ⇒ Object

Unsets any value on the environment variable name, including inherited value.

In a bourne shell, this would be equivalent to doing

unset name


179
180
181
182
183
184
185
186
187
188
189
# File 'lib/autobuild/environment.rb', line 179

def clear(name = nil)
    if name
        environment[name] = nil
        inherited_environment[name] = nil
    else
        keys = environment.keys # get keys first to avoid delete-while-iterating
        keys.each do |env_key|
            clear(env_key)
        end
    end
end

#declare_path_variable(name) ⇒ Object

Declares that the given environment variable holds a path

Non-existent paths in these variables are filtered out. It is called automatically if one of the ‘path’ methods are called (#set_path, #push_path, …)

Parameters:

  • name (String)


128
129
130
# File 'lib/autobuild/environment.rb', line 128

def declare_path_variable(name)
    path_variables << name
end

#default_cmake_search_globs(prefix, *file_globs) ⇒ Object



647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
# File 'lib/autobuild/environment.rb', line 647

def default_cmake_search_globs(prefix, *file_globs)
    lib_globs = %w[lib]

    case arch_size
    when 32
        lib_globs << "lib32"
        lib_globs << "libx32"
    when 64
        lib_globs << "lib64"
    end

    unless arch_names.empty?
        arch_names.each do |arch_name|
            lib_globs << File.join("lib", arch_name)
        end
    end

    lib_share_glob = "{#{lib_globs.join(',')},share}"
    file_glob = "{#{file_globs.join(',')}}"

    # Reference: https://cmake.org/cmake/help/latest/command/find_package.html
    #
    # <prefix>/                                                       (W)
    # <prefix>/(cmake|CMake)/                                         (W)
    # <prefix>/<name>*/                                               (W)
    # <prefix>/<name>*/(cmake|CMake)/                                 (W)
    # <prefix>/(lib/<arch>|lib*|share)/cmake/<name>*/                 (U)
    # <prefix>/(lib/<arch>|lib*|share)/<name>*/                       (U)
    # <prefix>/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/         (U)
    # <prefix>/<name>*/(lib/<arch>|lib*|share)/cmake/<name>*/         (W/U)
    # <prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/               (W/U)
    # <prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/ (W/U)
    [
        File.join(prefix, file_glob),
        File.join(prefix, "{cmake,CMake}", file_glob),
        File.join(prefix, "*", file_glob),
        File.join(prefix, "*", "{cmake/CMake}", file_glob),
        File.join(prefix, lib_share_glob, "cmake", "*", file_glob),
        File.join(prefix, lib_share_glob, "*", file_glob),
        File.join(prefix, lib_share_glob, "*", "{cmake,CMake}", file_glob),
        File.join(prefix, "*", lib_share_glob, "cmake", "*", file_glob),
        File.join(prefix, "*", lib_share_glob, "*", file_glob),
        File.join(prefix, "*", lib_share_glob, "*", "{cmake,CMake}", file_glob)
    ]
end

#default_pkgconfig_search_suffixesObject

Returns the system-wide search path that is embedded in pkg-config



709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
# File 'lib/autobuild/environment.rb', line 709

def default_pkgconfig_search_suffixes
    return [] unless pkgconfig_tool_path

    @default_pkgconfig_search_suffixes ||=
        `LANG=C #{pkgconfig_tool_path} --variable pc_path pkg-config`
            .strip
            .split(":")
            .grep(PKGCONFIG_PATH_RX)
            .map { |l| l.gsub(PKGCONFIG_PATH_RX, '\1') }
            .to_set
            .add("/lib/pkgconfig")
    # /lib/pkgconfig is added for packages that always install their
    # libraries in /lib/ instead of the system mandated directory
    # (/lib/x86_64-linux-gnu/ for 64bit x86 ubuntu multiarch,
    # /lib64/ for some other 64bit systems)
end

#each_env_search_path(prefix, patterns) ⇒ Object



575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
# File 'lib/autobuild/environment.rb', line 575

def each_env_search_path(prefix, patterns)
    arch_names = self.arch_names
    arch_size  = self.arch_size

    seen = Set.new
    patterns.each do |base_path|
        paths = []
        if base_path =~ /ARCHSIZE/
            base_path = base_path.gsub('ARCHSIZE', arch_size.to_s)
        end
        if base_path =~ /ARCH/
            arch_names.each do |arch|
                paths << base_path.gsub('ARCH', arch)
            end
        else
            paths << base_path
        end
        paths.each do |p|
            p = File.join(prefix, *p.split('/'))
            if !seen.include?(p) && File.directory?(p)
                yield(p)
                seen << p
            end
        end
    end
end

#expand(value) ⇒ Object

Method called to filter the environment variables before they are set, for instance to expand variables



822
823
824
# File 'lib/autobuild/environment.rb', line 822

def expand(value)
    value
end

#export_env_sh(io, shell: 'sh') ⇒ Object

Generates a shell script that sets the environment variable listed in Autobuild.environment, following the inheritance setting listed in Autobuild.inherited_environment.

It also sources the files added by source_file



510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
# File 'lib/autobuild/environment.rb', line 510

def export_env_sh(io, shell: 'sh')
    export = exported_environment
    source_before(shell: shell).each do |path|
        io.puts format(SHELL_SOURCE_SCRIPT, path)
    end
    export.unset.each do |name|
        io.puts format(SHELL_UNSET_COMMAND, name)
    end
    export.set.each do |name, value|
        io.puts format(SHELL_SET_COMMAND, name, value.join(File::PATH_SEPARATOR))
        io.puts format(SHELL_EXPORT_COMMAND, name)
    end
    export.update.each do |name, (with_inheritance, without_inheritance)|
        io.puts format(SHELL_CONDITIONAL_SET_COMMAND, name,
                       with_inheritance.join(File::PATH_SEPARATOR),
                       without_inheritance.join(File::PATH_SEPARATOR))
        io.puts format(SHELL_EXPORT_COMMAND, name)
    end
    source_after(shell: shell).each do |path|
        io.puts format(SHELL_SOURCE_SCRIPT, path)
    end
end

#exported_environmentObject

Computes the set of environment modification operations that should be applied to load this environment

This is for instance used to generate the env.sh



480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
# File 'lib/autobuild/environment.rb', line 480

def exported_environment
    export = ExportedEnvironment.new(Hash.new, Array.new, Hash.new)
    environment.each_key do |name|
        value_with_inheritance    = value(name, inheritance_mode: :keep)
        value_without_inheritance = value(name, inheritance_mode: :ignore)
        if path_variable?(name)
            [value_with_inheritance, value_without_inheritance].each do |paths|
                paths.delete_if { |p| p !~ /^\$/ && !File.exist?(p) }
            end
        end

        if !value_with_inheritance
            export.unset << name
        elsif value_with_inheritance == value_without_inheritance # no inheritance
            export.set[name] = value_with_inheritance
        else
            export.update[name] = [
                value_with_inheritance,
                value_without_inheritance
            ]
        end
    end
    export
end

#filter_original_env(_name, parent_env) ⇒ Object



274
275
276
# File 'lib/autobuild/environment.rb', line 274

def filter_original_env(_name, parent_env)
    parent_env.dup
end

#find_executable_in_path(file, path_var = 'PATH') ⇒ Object



781
782
783
# File 'lib/autobuild/environment.rb', line 781

def find_executable_in_path(file, path_var = 'PATH')
    self.class.find_executable_in_path(file, value(path_var) || Array.new)
end

#find_in_path(file, path_var = 'PATH') ⇒ Object



797
798
799
# File 'lib/autobuild/environment.rb', line 797

def find_in_path(file, path_var = 'PATH')
    self.class.find_in_path(file, value(path_var) || Array.new)
end

#has_cmake_files?(prefix, *file_globs) ⇒ Boolean

Returns:

  • (Boolean)


693
694
695
696
697
698
# File 'lib/autobuild/environment.rb', line 693

def has_cmake_files?(prefix, *file_globs)
    default_cmake_search_globs(prefix, *file_globs).each do |glob_path|
        return true unless Dir[glob_path].empty?
    end
    false
end

#include?(name) ⇒ Boolean

Whether this object manages the given environment variable

Returns:

  • (Boolean)


366
367
368
# File 'lib/autobuild/environment.rb', line 366

def include?(name)
    environment.key?(name)
end

#inherit(*names) ⇒ Boolean

Declare that the given environment variable must not be reset by the env.sh script, but that new values should simply be prepended to it.

Returns:

  • (Boolean)

    true if environment inheritance is globally enabled and false otherwise. This is controlled by Autobuild.env_inherit=

See Also:



248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/autobuild/environment.rb', line 248

def inherit(*names)
    flag =
        if !names.last.respond_to?(:to_str)
            names.pop
        else
            true
        end

    if flag
        @inherited_variables |= names
        names.each do |env_name|
            @environment[env_name] ||= []
            init_from_env(env_name)
        end
    else
        names.each do |n|
            if @inherited_variables.include?(n)
                @inherited_variables.delete(n)
                init_from_env(n)
            end
        end
    end

    @inherit
end

#inherit=(value) ⇒ Object

If true (the default), the environment variables that are marked as inherited will be inherited from the global environment (during the build as well as in the generated env.sh files)

Otherwise, only the environment that is explicitely set in autobuild will be passed on to subcommands, and saved in the environment scripts.

See Also:



232
233
234
235
236
237
238
239
# File 'lib/autobuild/environment.rb', line 232

def inherit=(value)
    @inherit = value
    # get keys first to avoid modify-while-iterating
    keys = inherited_environment.keys
    keys.each do |env_name|
        init_from_env(env_name)
    end
end

#inherit?(name = nil) ⇒ Boolean

Returns true if the given environment variable must not be reset by the env.sh script, but that new values should simply be prepended to it.

Parameters:

  • name (String, nil) (defaults to: nil)

    the environment variable that we want to check for inheritance. If nil, the global setting is returned.

Returns:

  • (Boolean)

See Also:



213
214
215
216
217
218
219
220
221
# File 'lib/autobuild/environment.rb', line 213

def inherit?(name = nil)
    if @inherit
        if name
            @inherited_variables.include?(name)
        else
            true
        end
    end
end

#init_from_env(name) ⇒ Object



278
279
280
281
282
283
284
285
# File 'lib/autobuild/environment.rb', line 278

def init_from_env(name)
    inherited_environment[name] =
        if inherit?(name) && (parent_env = original_env[name])
            filter_original_env(name, parent_env.split(File::PATH_SEPARATOR))
        else
            Array.new
        end
end

#initialize_copy(old) ⇒ Object



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/autobuild/environment.rb', line 137

def initialize_copy(old)
    super
    @inherited_environment = @inherited_environment.
        map_value { |_k, v| v&.dup }
    @environment = @environment.
        map_value { |_k, v| v&.dup }
    @source_before = Marshal.load(Marshal.dump(@source_before)) # deep copy
    @source_after = Marshal.load(Marshal.dump(@source_after)) # deep copy
    @inherited_variables = @inherited_variables.dup

    @system_env = @system_env.
        map_value { |_k, v| v&.dup }
    @original_env = @original_env.
        map_value { |_k, v| v&.dup }
end

#isolateObject



809
810
811
812
# File 'lib/autobuild/environment.rb', line 809

def isolate
    self.inherit = false
    push_path 'PATH', '/usr/local/bin', '/usr/bin', '/bin'
end

#path_variable?(name) ⇒ Boolean

Whether the given environment variable contains path(s)

Returns:

  • (Boolean)


133
134
135
# File 'lib/autobuild/environment.rb', line 133

def path_variable?(name)
    path_variables.include?(name)
end

#pkgconfig_tool_pathObject



702
703
704
705
706
# File 'lib/autobuild/environment.rb', line 702

def pkgconfig_tool_path
    @pkgconfig_tool_path ||= Autobuild.tool_in_path("pkg-config", env: self)
rescue ArgumentError
    nil
end

#prepareObject



814
815
816
817
818
# File 'lib/autobuild/environment.rb', line 814

def prepare
    # Set up some important autobuild parameters
    inherit 'PATH', 'PKG_CONFIG_PATH', 'RUBYLIB', \
            LIBRARY_PATH, 'CMAKE_PREFIX_PATH', 'PYTHONPATH'
end

#push(name, *values) ⇒ Object



287
288
289
290
291
292
293
294
295
# File 'lib/autobuild/environment.rb', line 287

def push(name, *values)
    if (current = environment[name])
        current = current.dup
        set(name, *values)
        add(name, *current)
    else
        add(name, *values)
    end
end

#push_path(name, *values) ⇒ Object

Add a path at the beginning of an environment variable

Unlike “normal” variables, entries of path variables that cannot be found on disk are filtered out at usage points (either #resolve_env or at the time of envirnonment export)

See Also:



425
426
427
428
429
430
431
432
433
434
# File 'lib/autobuild/environment.rb', line 425

def push_path(name, *values)
    declare_path_variable(name)
    if (current = environment.delete(name))
        current = current.dup
        add_path(name, *values)
        add_path(name, *current)
    else
        add_path(name, *values)
    end
end

#remove_path(name, *paths) ⇒ Object



411
412
413
414
415
416
# File 'lib/autobuild/environment.rb', line 411

def remove_path(name, *paths)
    declare_path_variable(name)
    paths.each do |p|
        environment[name].delete(p)
    end
end

#reset(name = nil) ⇒ Object

Resets the value of name to its original value. If it is inherited from the



159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/autobuild/environment.rb', line 159

def reset(name = nil)
    if name
        environment.delete(name)
        inherited_environment.delete(name)
        init_from_env(name)
    else
        keys = environment.keys # get keys first to avoid delete-while-iterating
        keys.each do |env_key|
            reset(env_key)
        end
    end
end

#resolved_envObject



370
371
372
373
374
375
376
377
378
379
380
381
# File 'lib/autobuild/environment.rb', line 370

def resolved_env
    resolved_env = Hash.new
    environment.each_key do |name|
        if (value = value(name))
            value = value.find_all { |p| File.exist?(p) } if path_variable?(name)
            resolved_env[name] = value.join(File::PATH_SEPARATOR)
        else
            resolved_env[name] = nil
        end
    end
    resolved_env
end

#set(name, *values) ⇒ Object

Set a new environment variable



192
193
194
195
# File 'lib/autobuild/environment.rb', line 192

def set(name, *values)
    environment.delete(name)
    add(name, *values)
end

#set_path(name, *paths) ⇒ Object



383
384
385
386
387
# File 'lib/autobuild/environment.rb', line 383

def set_path(name, *paths)
    declare_path_variable(name)
    clear(name)
    add_path(name, *paths)
end

#source_afterArray<String> #source_after(path) ⇒ Object

Overloads:

  • #source_afterArray<String>

    List of scripts that should be sourced at the end of env.sh

    Returns:

    • (Array<String>)

      a list of paths that should be sourced at the end of the shell script generated by #export_env_sh

  • #source_after(path) ⇒ Object

    Parameters:

    • path (String)

      a path that should be added to source_after



464
465
466
467
468
469
470
471
472
# File 'lib/autobuild/environment.rb', line 464

def source_after(file = nil, shell: 'sh')
    if file
        @source_after << { file: file, shell: shell }
        source_after(shell: shell) # for backwards compatibility
    else
        @source_after.select { |pair| pair[:shell] == shell }
                      .map { |item| item[:file] }
    end
end

#source_beforeArray<String> #source_before(path) ⇒ Object

Overloads:

  • #source_beforeArray<String>

    List of scripts that should be sourced at the top of env.sh

    Returns:

    • (Array<String>)

      a list of paths that should be sourced at the beginning of the shell script generated by #export_env_sh

  • #source_before(path) ⇒ Object

    Parameters:

    • path (String)

      a path that should be added to source_before



445
446
447
448
449
450
451
452
453
# File 'lib/autobuild/environment.rb', line 445

def source_before(file = nil, shell: 'sh')
    if file
        @source_before << { file: file, shell: shell }
        source_before(shell: shell) # for backwards compatibility
    else
        @source_before.select { |pair| pair[:shell] == shell }
                       .map { |item| item[:file] }
    end
end

#unset(name) ⇒ Object

Unset the given environment variable

It is different from #delete in that it will lead to the environment variable being actively unset, while ‘delete’ will leave it to its original value



202
203
204
# File 'lib/autobuild/environment.rb', line 202

def unset(name)
    environment[name] = nil
end

#update_environment(newprefix, includes = nil) ⇒ Object



643
644
645
# File 'lib/autobuild/environment.rb', line 643

def update_environment(newprefix, includes = nil)
    add_prefix(newprefix, includes)
end

#value(name, options = Hash.new) ⇒ nil, Array<String>

Returns an environment variable value

Parameters:

  • name (String)

    the environment variable name

  • options (Hash) (defaults to: Hash.new)

    a customizable set of options

Options Hash (options):

  • inheritance_mode (Symbol) — default: :expand

    controls how environment variable inheritance should be done. If :expand, the current envvar value is inserted in the generated value. If :keep, the name of the envvar is inserted (as e.g. $NAME). If :ignore, inheritance is disabled in the generated value. Not that this applies only for the environment variables for which inheritance has been enabled with #inherit, other variables always behave as if :ignore was selected.

Returns:

  • (nil, Array<String>)

    either nil if this environment variable is not set, or an array of values. How the values should be joined to form the actual value is OS-specific, and not handled by this method



327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
# File 'lib/autobuild/environment.rb', line 327

def value(name, options = Hash.new)
    # For backward compatibility only
    unless options.respond_to?(:to_hash)
        options =
            if options
                Hash[:inheritance_mode => :expand]
            else
                Hash[:inheritance_mode => :keep]
            end
    end
    options = Kernel.validate_options options,
                                      inheritance_mode: :expand
    inheritance_mode = options[:inheritance_mode]

    if !include?(name)
        nil
    elsif !environment[name]
        nil
    else
        inherited =
            if inheritance_mode == :expand
                inherited_environment[name] || []
            elsif inheritance_mode == :keep && inherit?(name)
                ["$#{name}"]
            else
                []
            end

        value = []
        [environment[name], inherited, system_env[name]].each do |paths|
            (paths || []).each do |p|
                value << p unless value.include?(p)
            end
        end
        value
    end
end