module EnvBash
Constants
- FIXUPS
Public Class Methods
load(envbash, into: ENV, override: false, remove: false, **kwargs)
click to toggle source
# File lib/envbash/load.rb, line 5 def EnvBash.load(envbash, into: ENV, override: false, remove: false, **kwargs) loaded = read(envbash, **kwargs) is_env = into.equal? ENV into = into.to_h if is_env if loaded into.select! {|k| loaded.include? k} if remove loaded.reject! {|k| into.include? k} unless override into.merge! loaded end ENV.replace into if is_env end
read(envbash, bash: 'bash', env: ENV, missing_ok: false, fixups: FIXUPS)
click to toggle source
# File lib/envbash/read.rb, line 12 def EnvBash.read(envbash, bash: 'bash', env: ENV, missing_ok: false, fixups: FIXUPS) # make sure the file exists and is readable. # alternatively we could test File.readable?(envbash) but this approach # raises Errno::ENOENT or Errno::EACCES which is what we want. begin File.open(envbash).close rescue Errno::ENOENT return if missing_ok raise end # construct an inline script which sources env.bash then prints the # resulting environment so it can be eval'd back into this process. inline = <<-EOT set -a source #{envbash.shellescape} >/dev/null #{Gem.ruby.shellescape} -e 'p ENV' EOT # Process.spawn treats env as overriding ENV, and anything that should be # omitted needs to have a nil value. If env == ENV then this is a noop. env = Hash[ENV.keys.map {|k| [k, nil]}].merge(env) # run the inline script with bash -c, capturing stdout. if there is any # error output from env.bash, it will pass through to stderr. # exit status is ignored. output, _ = Open3.capture2(env, 'bash', '-c', inline, :in=>"/dev/null") # the only stdout from the inline script should be # `p ENV` so there should be no syntax errors eval'ing this. however there # will be no output to eval if the sourced env.bash exited early, and that # indicates script failure. raise ScriptExitedEarly if output.empty? # the eval'd output should return a hash. nenv = eval(output) # there are a few environment variables that vary between this process and # running the inline script with bash -c, but are certainly not part of the # intentional settings in env.bash. for f in fixups if env[f] # not .include? because env might have nil values nenv[f] = env[f] else nenv.delete(f) end end nenv end