Module: EnvBash
- Defined in:
- lib/envbash/load.rb,
lib/envbash/read.rb
Defined Under Namespace
Classes: ScriptExitedEarly
Constant Summary collapse
- FIXUPS =
%w{_ OLDPWD PWD SHLVL}
Class Method Summary collapse
- .load(envbash, into: ENV, override: false, remove: false, **kwargs) ⇒ Object
- .read(envbash, bash: 'bash', env: ENV, missing_ok: false, fixups: FIXUPS) ⇒ Object
Class Method Details
.load(envbash, into: ENV, override: false, remove: false, **kwargs) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 |
# 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) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# 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 |