test-cmd.rb 2.5.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a0790a7e8e68709204aeb42611543db79e3575615d6ed77ee0b166fff7827825
4
- data.tar.gz: 7965cd9baf53560ff8648f0652876b3d31a969528b1419b5b975406ec37c13fc
3
+ metadata.gz: c42ecb86960f6c733054ea3cd7ed041c23accec019f7addb7a2a595020b507bf
4
+ data.tar.gz: 05fd256aa2c70bb23e8e9ef3e3f8e91eb9bcff9fa2680f48a059960333e74b06
5
5
  SHA512:
6
- metadata.gz: f0f7c63d381cbbd8c603c8fc7a1c22e7c73509b0a51965107c2fe2c23adf3c2b8cf5f243712b4f297f90aeb0535c01477ddd4518c10be6afd6a29b248c30af18
7
- data.tar.gz: aee5d21c5948e17b29f0df43636bb18d396d6919efdc3a0fe6c03628ba85d5f3ae0e04cd03e61e51c33ad30aa88a2e7a840051cc704d3ac384957ea75d6f1cd1
6
+ metadata.gz: e2c4e2b3858f7b090359a46756a54408d28c729603f0f47ccda5a68c35e2c11dd807dade25cf79d88af938861a112b582d9ecea0198d4b2023ab6fba504ba63d
7
+ data.tar.gz: 7efb00552507bbbb2b1d66e599ccdd165e7acb3628f5a5e97daa2ec0bdafca5e63ebce274d937a737224836db806a171d4f8bbd07b2195bc092aa529ddacc2d8
@@ -12,7 +12,7 @@ jobs:
12
12
  fail-fast: false
13
13
  matrix:
14
14
  os: [ubuntu-latest, macos-latest]
15
- ruby: [3.1, 3.2, 3.3]
15
+ ruby: [3.1, 3.2, 3.3, 4.0]
16
16
  runs-on: ${{ matrix.os }}
17
17
  steps:
18
18
  - uses: actions/checkout@v2
data/README.md CHANGED
@@ -34,7 +34,6 @@ test-cmd.rb can be installed via rubygems.org:
34
34
 
35
35
  ### Commands
36
36
 
37
-
38
37
  ```ruby
39
38
  require "test-cmd"
40
39
 
@@ -42,7 +41,7 @@ require "test-cmd"
42
41
  # Call the 'ls' command
43
42
  p Test::Command
44
43
  .new("ls")
45
- .argv("-l")
44
+ .arguments("-l")
46
45
  .stdout
47
46
 
48
47
  ##
@@ -63,11 +62,11 @@ p Test::Command
63
62
 
64
63
  ##
65
64
  # Limit how much data is read from stdout and
66
- # stderr. At most 20k chars is read from both:
65
+ # stderr. At most 20k bytes is read from both:
67
66
  p Test::Command
68
67
  .new("git")
68
+ .arguments("diff", "--cached")
69
69
  .limit(stdout: 20_000, stderr: 20_000)
70
- .argv("diff", "--cached")
71
70
  .stdout
72
71
  ```
73
72
 
@@ -75,13 +74,35 @@ p Test::Command
75
74
  <summary>Environment</summary>
76
75
  <br>
77
76
 
77
+ A command that is not given an environment inherits the parent's
78
+ environment. When `env` is called, only the variables that are
79
+ given to `env` are set on the spawned process, alongside `$PATH`
80
+ which is always inherited. `$PATH` is inherited so that the
81
+ command can still be found via path lookup.
82
+
78
83
  ```ruby
79
- require "test-cmd"
84
+ ##
85
+ # Inherit the parent's environment. All variables
86
+ # from the parent process are available.
87
+ p Test::Command
88
+ .new("env")
89
+ .stdout
80
90
 
91
+ ##
92
+ # Only $FOO and $BAR are set, plus the inherited
93
+ # $PATH. Everything else is left behind.
94
+ p Test::Command
95
+ .new("env")
96
+ .env("FOO" => "42", "BAR" => "7")
97
+ .stdout
98
+
99
+ ##
100
+ # An empty hash yields only $PATH and the rest of
101
+ # environment is left empty.
81
102
  p Test::Command
82
- .new("ruby", "-e", "puts ENV['FOO']")
83
- .env("FOO" => "42")
84
- .stdout # => "42\n"
103
+ .new("env")
104
+ .env({})
105
+ .stdout
85
106
  ```
86
107
  </details>
87
108
 
@@ -4,5 +4,5 @@ end unless defined?(Test)
4
4
  class Test::Command
5
5
  ##
6
6
  # @string [String]
7
- VERSION = "2.5.0"
7
+ VERSION = "2.7.0"
8
8
  end
data/lib/test/command.rb CHANGED
@@ -28,7 +28,7 @@ class Test::Command
28
28
  def initialize(cmd, *argv)
29
29
  @cmd = cmd
30
30
  @argv = argv.dup
31
- @env = {}
31
+ @env = nil
32
32
  @status = nil
33
33
  @spawned = false
34
34
  @stdout = ""
@@ -38,19 +38,20 @@ class Test::Command
38
38
  end
39
39
 
40
40
  ##
41
- # @param [Array<String, #to_s>] argv
41
+ # @param [Array<String, #to_s>] arguments
42
42
  # Command-line arguments
43
43
  # @return [Test::Command]
44
- def argv(*argv)
45
- tap { @argv.concat(argv) }
44
+ def arguments(*arguments)
45
+ tap { @argv.concat(arguments) }
46
46
  end
47
+ alias_method :argv, :arguments
47
48
 
48
49
  ##
49
50
  # @param [Hash{String => String}] env
50
51
  # Environment variables to set for the spawned command
51
52
  # @return [Test::Command]
52
53
  def env(env)
53
- tap { @env.merge!(env) }
54
+ tap { (@env ||= {}).merge!(env) }
54
55
  end
55
56
 
56
57
  ##
@@ -91,7 +92,7 @@ class Test::Command
91
92
  @spawned = true
92
93
  @out, @err = Pipe.pair, Pipe.pair
93
94
  @pid = Process.spawn(
94
- @env,
95
+ envp,
95
96
  @cmd, *@argv.map(&:to_s),
96
97
  {in: @in_r, out: @out.w, err: @err.w}
97
98
  )
@@ -246,6 +247,29 @@ class Test::Command
246
247
 
247
248
  private
248
249
 
250
+ ##
251
+ # Builds the environment passed to Process.spawn.
252
+ # The spawned process receives only the variables
253
+ # set with #env: every inherited variable is
254
+ # cleared, so an empty @env spawns with an empty
255
+ # environment.
256
+ # @return [Hash{String => String}]
257
+ def envp
258
+ if @env.nil?
259
+ ##
260
+ # Inherit the parent's environment
261
+ ENV.to_h
262
+ else
263
+ ##
264
+ # Clear all environment variables except those
265
+ # that are set by `@env`. Always inherit ${PATH}.
266
+ envp = ENV.except("PATH")
267
+ .each_key
268
+ .to_h { |key| [key, nil] }
269
+ envp.merge!(@env)
270
+ end
271
+ end
272
+
249
273
  ##
250
274
  # Reads up to +max+ bytes from a stream, then drains
251
275
  # the remainder so a child writing more than the limit
data/test/cmd_test.rb CHANGED
@@ -7,24 +7,41 @@ class Test::Command
7
7
  def ruby(str)
8
8
  ::Test::Command.new "ruby", "-e", str
9
9
  end
10
+
11
+ ##
12
+ # macos-specific env vars that are always set
13
+ # @return [String]
14
+ def macos
15
+ if ENV["__CF_USER_TEXT_ENCODING"]
16
+ "__CF_USER_TEXT_ENCODING\n"
17
+ else
18
+ ""
19
+ end
20
+ end
10
21
  end
11
22
  end
12
23
 
13
24
  class Test::Command
14
25
  ##
15
- # Test::Command#argv
16
- class ARGVTest < Test
17
- def test_ruby_argv
26
+ # Test::Command#arguments
27
+ class ArgumentsTest < Test
28
+ def test_ruby_arguments
18
29
  assert_equal "42\n", ::Test::Command.new("ruby")
19
- .argv("-e", "warn 42")
30
+ .arguments("-e", "warn 42")
20
31
  .stderr
21
32
  end
22
33
 
23
- def test_ruby_argv_to_s
34
+ def test_ruby_arguments_to_s
24
35
  arg = Object.new
25
36
  def arg.to_s = "-e"
26
37
  assert_equal "42\n", ::Test::Command.new("ruby")
27
- .argv(arg, "warn 42")
38
+ .arguments(arg, "warn 42")
39
+ .stderr
40
+ end
41
+
42
+ def test_ruby_arguments_argv_alias
43
+ assert_equal "42\n", ::Test::Command.new("ruby")
44
+ .argv("-e", "warn 42")
28
45
  .stderr
29
46
  end
30
47
  end
@@ -38,6 +55,41 @@ class Test::Command
38
55
  .env("FOO" => "42")
39
56
  .stdout
40
57
  end
58
+
59
+ def test_ruby_env_only_given_keys
60
+ assert_equal "BAR\nFOO\nPATH\n#{macos}",
61
+ ::Test::Command.new("ruby", "-e", "puts ENV.keys.sort")
62
+ .env("FOO" => "42", "BAR" => "7")
63
+ .stdout
64
+ end
65
+
66
+ def test_ruby_env_empty_is_empty_env
67
+ assert_equal "PATH\n#{macos}",
68
+ ::Test::Command.new("ruby", "-e", "puts ENV.keys.sort")
69
+ .env({})
70
+ .stdout
71
+ end
72
+
73
+ def test_ruby_env_does_not_leak_inherited
74
+ assert_equal "true",
75
+ ::Test::Command.new("ruby", "-e", "print ENV.key?('PATH')")
76
+ .stdout
77
+ end
78
+
79
+ def test_ruby_env_path_carries_over_inherited
80
+ parent_path = ENV["PATH"]
81
+ assert_equal parent_path,
82
+ ::Test::Command.new("ruby", "-e", "print ENV['PATH']")
83
+ .stdout
84
+ end
85
+
86
+ def test_ruby_env_path_carries_over_empty
87
+ parent_path = ENV["PATH"]
88
+ assert_equal parent_path,
89
+ ::Test::Command.new("ruby", "-e", "print ENV['PATH']")
90
+ .env({})
91
+ .stdout
92
+ end
41
93
  end
42
94
 
43
95
  ##
data/test-cmd.rb.gemspec CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |gem|
6
6
  gem.name = "test-cmd.rb"
7
7
  gem.authors = ["Robert Gleeson"]
8
8
  gem.email = ["robert@r.uby.dev"]
9
- gem.homepage = "https://github.com/0x1eef/test-cmd.rb#readme"
9
+ gem.homepage = "https://github.com/r-uby-dev/test-cmd.rb#readme"
10
10
  gem.version = Test::Command::VERSION
11
11
  gem.required_ruby_version = ">= 3.0"
12
12
  gem.licenses = ["MIT"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: test-cmd.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Gleeson
@@ -106,7 +106,7 @@ files:
106
106
  - test-cmd.rb.gemspec
107
107
  - test/cmd_test.rb
108
108
  - test/setup.rb
109
- homepage: https://github.com/0x1eef/test-cmd.rb#readme
109
+ homepage: https://github.com/r-uby-dev/test-cmd.rb#readme
110
110
  licenses:
111
111
  - MIT
112
112
  metadata: {}
@@ -124,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
126
  requirements: []
127
- rubygems_version: 4.0.16
127
+ rubygems_version: 4.0.20
128
128
  specification_version: 4
129
129
  summary: test-cmd.rb is a Go-inspired, object-oriented interface for running commands
130
130
  on UNIX-like systems, in the spirit of Go's `os/exec`. A command can be built by