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.



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/autobuild/environment.rb', line 107

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)



97
98
99
# File 'lib/autobuild/environment.rb', line 97

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


91
92
93
# File 'lib/autobuild/environment.rb', line 91

def inherited_environment
  @inherited_environment
end

#inherited_variablesObject (readonly)

Returns the value of attribute inherited_variables.



99
100
101
# File 'lib/autobuild/environment.rb', line 99

def inherited_variables
  @inherited_variables
end

#original_envObject (readonly)

Returns the value of attribute original_env.



99
100
101
# File 'lib/autobuild/environment.rb', line 99

def original_env
  @original_env
end

#path_variablesObject (readonly)

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



105
106
107
# File 'lib/autobuild/environment.rb', line 105

def path_variables
  @path_variables
end

#system_envObject (readonly)

Returns the value of attribute system_env.



99
100
101
# File 'lib/autobuild/environment.rb', line 99

def system_env
  @system_env
end

#target_archObject

Returns the value of attribute target_arch.



99
100
101
# File 'lib/autobuild/environment.rb', line 99

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



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
565
566
567
# File 'lib/autobuild/environment.rb', line 540

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



788
789
790
791
792
793
794
795
796
797
798
# File 'lib/autobuild/environment.rb', line 788

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



804
805
806
807
808
809
810
# File 'lib/autobuild/environment.rb', line 804

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



570
571
572
573
574
575
576
# File 'lib/autobuild/environment.rb', line 570

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



157
158
159
# File 'lib/autobuild/environment.rb', line 157

def [](name)
    resolved_env[name]
end

#add(name, *values) ⇒ Object

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



301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/autobuild/environment.rb', line 301

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:



399
400
401
402
403
404
405
406
407
408
409
410
411
412
# File 'lib/autobuild/environment.rb', line 399

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



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
780
781
782
# File 'lib/autobuild/environment.rb', line 730

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



631
632
633
634
635
636
637
638
639
640
641
642
643
644
# File 'lib/autobuild/environment.rb', line 631

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



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

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


183
184
185
186
187
188
189
190
191
192
193
# File 'lib/autobuild/environment.rb', line 183

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)


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

def declare_path_variable(name)
    path_variables << name
end

#default_cmake_search_globs(prefix, *file_globs) ⇒ Object



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
692
693
694
# File 'lib/autobuild/environment.rb', line 650

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



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

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



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

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



825
826
827
# File 'lib/autobuild/environment.rb', line 825

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



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

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



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

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



277
278
279
# File 'lib/autobuild/environment.rb', line 277

def filter_original_env(_name, parent_env)
    parent_env.dup
end

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



784
785
786
# File 'lib/autobuild/environment.rb', line 784

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



800
801
802
# File 'lib/autobuild/environment.rb', line 800

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)


696
697
698
699
700
701
# File 'lib/autobuild/environment.rb', line 696

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)


369
370
371
# File 'lib/autobuild/environment.rb', line 369

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:



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

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|
            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:



236
237
238
239
240
241
242
243
# File 'lib/autobuild/environment.rb', line 236

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:



217
218
219
220
221
222
223
224
225
# File 'lib/autobuild/environment.rb', line 217

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

#init_from_env(name) ⇒ Object



281
282
283
284
285
286
287
288
# File 'lib/autobuild/environment.rb', line 281

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



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/autobuild/environment.rb', line 141

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



812
813
814
815
# File 'lib/autobuild/environment.rb', line 812

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)


137
138
139
# File 'lib/autobuild/environment.rb', line 137

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

#pkgconfig_tool_pathObject



705
706
707
708
709
# File 'lib/autobuild/environment.rb', line 705

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

#prepareObject



817
818
819
820
821
# File 'lib/autobuild/environment.rb', line 817

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



290
291
292
293
294
295
296
297
298
# File 'lib/autobuild/environment.rb', line 290

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:



428
429
430
431
432
433
434
435
436
437
# File 'lib/autobuild/environment.rb', line 428

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



414
415
416
417
418
419
# File 'lib/autobuild/environment.rb', line 414

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



163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/autobuild/environment.rb', line 163

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



373
374
375
376
377
378
379
380
381
382
383
384
# File 'lib/autobuild/environment.rb', line 373

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



196
197
198
199
# File 'lib/autobuild/environment.rb', line 196

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

#set_path(name, *paths) ⇒ Object



386
387
388
389
390
# File 'lib/autobuild/environment.rb', line 386

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



467
468
469
470
471
472
473
474
475
# File 'lib/autobuild/environment.rb', line 467

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



448
449
450
451
452
453
454
455
456
# File 'lib/autobuild/environment.rb', line 448

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



206
207
208
# File 'lib/autobuild/environment.rb', line 206

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

#update_environment(newprefix, includes = nil) ⇒ Object



646
647
648
# File 'lib/autobuild/environment.rb', line 646

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



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
364
365
366
# File 'lib/autobuild/environment.rb', line 330

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