[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 3/4] implement environment variable expansion
From: |
Eric Wong |
Subject: |
[PATCH 3/4] implement environment variable expansion |
Date: |
Sun, 8 Sep 2013 02:12:47 +0000 |
This will allow users to more-easily edit configs and feel
like a real shell. We no longer mistakenly expand nil env
variables to "" anymore, either.
---
lib/dtas/process.rb | 28 ++++++++++++++++++++---
lib/dtas/source/sox.rb | 2 +-
test/test_env.rb | 55 +++++++++++++++++++++++++++++++++++++++++++++
test/test_rg_integration.rb | 3 +--
4 files changed, 82 insertions(+), 6 deletions(-)
create mode 100644 test/test_env.rb
diff --git a/lib/dtas/process.rb b/lib/dtas/process.rb
index b90b318..a3c1c04 100644
--- a/lib/dtas/process.rb
+++ b/lib/dtas/process.rb
@@ -19,12 +19,33 @@ module DTAS::Process # :nodoc:
end while true
end
+ # expand common shell constructs based on environment variables
+ # this is order-dependent, but Ruby 1.9+ hashes are already order-dependent
+ def env_expand(env, opts)
+ env = env.dup
+ if false == opts.delete(:expand)
+ env.each do |key, val|
+ Numeric === val and env[key] = val.to_s
+ end
+ else
+ env.each do |key, val|
+ case val
+ when Numeric # stringify numeric values to simplify users' lives
+ env[key] = val.to_s
+ when /[\`\$]/ # perform variable/command expansion
+ tmp = env.dup
+ tmp.delete(key)
+ val = qx(tmp, "echo #{val}", expand: false)
+ env[key] = val.chomp
+ end
+ end
+ end
+ end
+
# for long-running processes (sox/play/ecasound filters)
def dtas_spawn(env, cmd, opts)
opts = { close_others: true, pgroup: true }.merge!(opts)
-
- # stringify env, integer values are easier to type unquoted as strings
- env.each { |k,v| env[k] = v.to_s }
+ env = env_expand(env, opts)
pid = begin
Process.spawn(env, cmd, opts)
@@ -53,6 +74,7 @@ module DTAS::Process # :nodoc:
re.binmode
opts[:err] = we
end
+ env = env_expand(env, opts)
pid = begin
Process.spawn(env, *cmd, opts)
rescue Errno::EINTR # Ruby bug?
diff --git a/lib/dtas/source/sox.rb b/lib/dtas/source/sox.rb
index e26f54b..484a0ec 100644
--- a/lib/dtas/source/sox.rb
+++ b/lib/dtas/source/sox.rb
@@ -41,7 +41,7 @@ class DTAS::Source::Sox # :nodoc:
def try(infile, offset = nil)
err = ""
cmd = %W(soxi -s #{infile})
- s = qx(@env, cmd, err_str: err, no_raise: true)
+ s = qx(@env.dup, cmd, err_str: err, no_raise: true)
return if err =~ /soxi FAIL formats:/
self.class.try_to_fail_harder(infile, s, cmd) or return
source_file_dup(infile, offset)
diff --git a/test/test_env.rb b/test/test_env.rb
new file mode 100644
index 0000000..92fc53c
--- /dev/null
+++ b/test/test_env.rb
@@ -0,0 +1,55 @@
+# Copyright (C) 2013, Eric Wong <address@hidden> and all contributors
+# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt)
+require_relative 'helper'
+require 'dtas/process'
+class TestEnv < Testcase
+ include DTAS::Process
+ def setup
+ @orig = ENV.to_hash
+ end
+
+ def teardown
+ ENV.clear
+ ENV.update(@orig)
+ end
+
+ def test_expand
+ ENV["HELLO"] = 'HIHI'
+ expect = { "BLAH" => "HIHI/WORLD" }
+ opts = {}
+
+ env = { "BLAH" => "$HELLO/WORLD" }
+ assert_equal(expect, env_expand(env, opts))
+
+ env = { "BLAH" => "${HELLO}/WORLD" }
+ assert_equal(expect, env_expand(env, opts))
+
+ env = { "BLAH" => "$(echo $HELLO)/WORLD" }
+ assert_equal(expect, env_expand(env, opts))
+
+ env = { "BLAH" => "`echo $HELLO/WORLD`" }
+ assert_equal(expect, env_expand(env, opts))
+
+ env = { "BLAH" => "HIHI/WORLD" }
+ assert_equal(expect, env_expand(env, opts))
+
+ # disable expansion
+ env = expect = { "BLAH" => "`echo $HELLO/WORLD`" }
+ assert_equal(expect, env_expand(env, expand: false))
+
+ # numeric expansion always happens
+ env = { "BLAH" => 1 }
+ assert_equal({"BLAH"=>"1"}, env_expand(env, expand: false))
+ env = { "BLAH" => 1 }
+ assert_equal({"BLAH"=>"1"}, env_expand(env, {}))
+
+ expect = { "BLAH" => nil }
+ env = expect.dup
+ assert_equal expect, env_expand(env, expand:false)
+ assert_equal expect, env_expand(env, expand:true)
+
+ # recursive expansion
+ res = env_expand({"PATH"=>"$PATH"}, expand: true)
+ assert_equal ENV["PATH"], res["PATH"]
+ end
+end
diff --git a/test/test_rg_integration.rb b/test/test_rg_integration.rb
index d6a90b0..2779f86 100644
--- a/test/test_rg_integration.rb
+++ b/test/test_rg_integration.rb
@@ -40,7 +40,7 @@ class TestRgIntegration < Testcase
end while cur["current_offset"] == 0 && sleep(0.01)
end
- assert_empty cur["current"]["env"]["RGFX"]
+ assert_nil cur["current"]["env"]["RGFX"]
assert_equal DTAS::Format.new.rate * len, cur["current_expect"]
@@ -119,7 +119,6 @@ class TestRgIntegration < Testcase
"REPLAYGAIN_ALBUM_GAIN" => "-3.0",
"REPLAYGAIN_TRACK_PEAK" => "0.666",
"REPLAYGAIN_ALBUM_PEAK" => "0.999",
- "REPLAYGAIN_REFERENCE_LOUDNESS" => nil
}
assert_equal expect, rg
end
--
1.8.4