test-cmd.rb 2.2.0 → 2.4.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: e57955db2ea9f64997167878e30449b920c1746751e493b54c1ff549b852d55d
4
- data.tar.gz: 3e2527cb8deedc6205726ff8900aa2e23c15b69c9662debfb9322ebbc38e7ee3
3
+ metadata.gz: b091ee25f1e890969728e516747d3104c20076d2a71973e02ccc346a9eb1cc8e
4
+ data.tar.gz: 4dbb449b245f30e89285b7cae84de42564e352a4f0790fcc3a8a048e21b3ede2
5
5
  SHA512:
6
- metadata.gz: 782b41654883c063415e13191a28fdaf719123db4c4980a1f69102d23ad2026a61e8ce0b2c927cde4e12b321426cdcf1ecd25fce528fca5d586fe627160c8373
7
- data.tar.gz: 442fb73c9759f458c448729a2893b507ab0c8e6db2d5d8bea4d465b2b117c01794f9b501bb910460dbbc9a56f627c8147dea53a7e0814c1ae503133b4cc2774a
6
+ metadata.gz: 43fb7bb3700e9f384c253c8ab36ec3a1ebb2ec5e807b3af1d57883a64bddb132838086fc15b242ce3a65b85092941d23a040b866b3e173bed4bf5254e2829690
7
+ data.tar.gz: c314163ab04470596296e8644414bec98414955b7423a1cc5affe202184befedffaff5f1f63427b18dd192b356fe491d3ec85e1b1c5140857c185b3a7ea37402
data/LICENSE CHANGED
@@ -1,15 +1,21 @@
1
- Copyright (C) 2023 by 0x1eef <0x1eef@protonmail.com>
2
-
3
- Permission to use, copy, modify, and/or distribute this
4
- software for any purpose with or without fee is hereby
5
- granted.
6
-
7
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS
8
- ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
9
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
10
- EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
12
- RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
14
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
15
- OF THIS SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Robert Gleeson <robert@r.uby.dev>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -10,16 +10,19 @@
10
10
  </a>
11
11
  </p>
12
12
 
13
- > A [r.uby.dev](https://r.uby.dev) project.
13
+ > [r.uby.dev](https://r.uby.dev) project.
14
14
 
15
15
  Welcome to the canonical test-cmd.rb repository.
16
16
 
17
17
  test-cmd.rb is a Go-inspired, object-oriented interface for running
18
18
  commands on UNIX-like systems, in the spirit of Go's `os/exec`. A
19
- command is built up and then spawned so its standard output and
20
- error streams, process ID, and exit status are captured in the
21
- background. Predicates, callbacks, and process control cover the
22
- common cases with a small and dependency-free API.
19
+ command can be built by chaining multiple method calls that impact
20
+ different command attributes. The environment the command executes
21
+ with can be set, its standard input stream can be written to, and
22
+ the standard output and standard error streams are captured so the
23
+ parent process can read them.
24
+
25
+ It has zero runtime dependencies (stdlib-only).
23
26
 
24
27
  ## Install
25
28
 
@@ -31,37 +34,42 @@ test-cmd.rb can be installed via rubygems.org:
31
34
 
32
35
  ### Commands
33
36
 
34
- A command is created with
35
- [`Test::Command#initialize`](https://r.uby.dev/api-docs/test-cmd.rb/Test/Command.html#initialize-instance_method)
36
- which takes the name or path of a command, and given additional
37
- arguments with
38
- [`Test::Command#argv`](https://r.uby.dev/api-docs/test-cmd.rb/Test/Command.html#argv-instance_method).
39
- Environment variables can be set for the spawned process with
40
- [`Test::Command#env`](https://r.uby.dev/api-docs/test-cmd.rb/Test/Command.html#env-instance_method),
41
- and standard input with
42
- [`Test::Command#stdin`](https://r.uby.dev/api-docs/test-cmd.rb/Test/Command.html#stdin-instance_method).
43
- The instance has access to the command's process ID, exit status,
44
- standard output stream, and standard error stream.
45
37
 
46
38
  ```ruby
47
39
  require "test-cmd"
48
- puts Test::Command.new("ls").argv("-l").stdout
49
- puts Test::Command.new("env").env("FOO" => "bar").stdout
50
- test_cmd = Test::Command.new("tr", "a-z", "A-Z").stdin("hello").stdout # => "HELLO"
40
+
41
+ ##
42
+ # Call the 'ls' command
43
+ p Test::Command
44
+ .new("ls")
45
+ .argv("-l")
46
+ .stdout
47
+
48
+ ##
49
+ # Call the env command with the given environment
50
+ # variables set.
51
+ p Test::Command
52
+ .new("env")
53
+ .env("FOO" => "bar")
54
+ .stdout
55
+
56
+ ##
57
+ # Write to the stdin stream of the command that
58
+ # is executed.
59
+ p Test::Command
60
+ .new("tr", "a-z", "A-Z")
61
+ .stdin("hello")
62
+ .stdout # => "HELLO"
51
63
  ```
52
64
 
53
65
  <details>
54
66
  <summary>Environment</summary>
55
67
  <br>
56
68
 
57
- Environment variables for the spawned process are set with
58
- [`Test::Command#env`](https://r.uby.dev/api-docs/test-cmd.rb/Test/Command.html#env-instance_method),
59
- which merges the given variables into the child's environment and
60
- returns the command for chaining.
61
-
62
69
  ```ruby
63
70
  require "test-cmd"
64
- puts Test::Command
71
+
72
+ p Test::Command
65
73
  .new("ruby", "-e", "puts ENV['FOO']")
66
74
  .env("FOO" => "42")
67
75
  .stdout # => "42\n"
@@ -72,18 +80,16 @@ puts Test::Command
72
80
  <summary>Standard input</summary>
73
81
  <br>
74
82
 
75
- Standard input for the spawned process is set with
76
- [`Test::Command#stdin`](https://r.uby.dev/api-docs/test-cmd.rb/Test/Command.html#stdin-instance_method).
77
- Pass a String to write it to the child's standard input, or another
78
- [Test::Command](https://r.uby.dev/api-docs/test-cmd.rb/Test/Command.html)
79
- whose standard output will be used as the standard input.
80
-
81
83
  ```ruby
82
84
  require "test-cmd"
83
- puts Test::Command.new("cat").stdin("hello world").stdout # => "hello world"
84
85
 
85
- # Pipe one command's standard output into another's standard input
86
- puts Test::Command.new("tr", "a-z", "A-Z")
86
+ p Test::Command
87
+ .new("cat")
88
+ .stdin("hello world")
89
+ .stdout # => "hello world"
90
+
91
+ p Test::Command
92
+ .new("tr", "a-z", "A-Z")
87
93
  .stdin(Test::Command.new("echo", "hello"))
88
94
  .stdout # => "HELLO\n"
89
95
  ```
@@ -93,13 +99,6 @@ puts Test::Command.new("tr", "a-z", "A-Z")
93
99
  <summary>Callbacks</summary>
94
100
  <br>
95
101
 
96
- The success and failure callbacks provide hooks for when
97
- a command exits successfully or unsuccessfully. The callbacks
98
- are passed an instance of
99
- [Test::Command](https://r.uby.dev/api-docs/test-cmd.rb/Test/Command.html)
100
- that has access to the command's process ID, exit status,
101
- standard output stream, and standard error stream.
102
-
103
102
  ```ruby
104
103
  require "test-cmd"
105
104
  Test::Command.new("ruby", "-e", "exit 0")
@@ -121,7 +120,7 @@ stream of the spawned ruby process:
121
120
 
122
121
  ```ruby
123
122
  require "test/unit"
124
- require "test/cmd"
123
+ require "test-cmd"
125
124
 
126
125
  class CmdTest < Test::Unit::TestCase
127
126
  def test_ruby_stdout
@@ -149,12 +148,7 @@ end
149
148
  ```
150
149
  </details>
151
150
 
152
- ## Documentation
153
-
154
- A complete API reference is available at
155
- [r.uby.dev/api-docs/test-cmd.rb](https://r.uby.dev/api-docs/test-cmd.rb)
156
-
157
151
  ## License
158
152
 
159
- This software is released under the terms of the BSD Zero Clause license. <br>
160
- See [LICENSE](./LICENSE) for details.
153
+ This software is released under the MIT license. <br>
154
+ See [LICENSE](LICENSE) for details.
@@ -0,0 +1,8 @@
1
+ module Test
2
+ end unless defined?(Test)
3
+
4
+ class Test::Command
5
+ ##
6
+ # @string [String]
7
+ VERSION = "2.4.0"
8
+ end
@@ -5,6 +5,8 @@ end unless defined?(Test)
5
5
  # test-cmd.rb provides an object oriented interface
6
6
  # for spawning a command
7
7
  class Test::Command
8
+ require_relative "command/version"
9
+
8
10
  ##
9
11
  # @api private
10
12
  class Pipe < Struct.new(:r, :w)
@@ -76,7 +78,7 @@ class Test::Command
76
78
  @out, @err = Pipe.pair, Pipe.pair
77
79
  @pid = Process.spawn(
78
80
  @env,
79
- @cmd, *@argv,
81
+ @cmd, *@argv.map(&:to_s),
80
82
  {in: @in_r, out: @out.w, err: @err.w}
81
83
  )
82
84
  @in_r.close unless @in_r.equal?(IO::NULL)
@@ -256,4 +258,4 @@ class Test::Command
256
258
  return unless @producer&.alive?
257
259
  @producer.join
258
260
  end
259
- end
261
+ end
data/lib/test-cmd.rb CHANGED
@@ -1 +1 @@
1
- require_relative "test/cmd"
1
+ require_relative "test/command"
data/rubydev.svg CHANGED
@@ -1,30 +1,78 @@
1
1
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 560 220" role="img" aria-labelledby="title desc">
2
2
  <title id="title">r.uby.dev</title>
3
- <desc id="desc">A wide r.uby.dev wordmark with three small ruby gemstones moving around the text.</desc>
3
+ <desc id="desc">A wide r.uby.dev wordmark with ruby, sapphire, and emerald gemstones moving around the text.</desc>
4
4
  <defs>
5
5
  <linearGradient id="body" x1="45" y1="35" x2="211" y2="224" gradientUnits="userSpaceOnUse">
6
- <stop offset="0" stop-color="#ff7468"/>
7
- <stop offset="0.42" stop-color="#cc342d"/>
6
+ <stop offset="0" stop-color="#e0796f"/>
7
+ <stop offset="0.42" stop-color="#a7312b"/>
8
8
  <stop offset="1" stop-color="#5b090d"/>
9
9
  </linearGradient>
10
10
  <linearGradient id="table" x1="75" y1="31" x2="166" y2="104" gradientUnits="userSpaceOnUse">
11
11
  <stop offset="0" stop-color="#fff3ec"/>
12
- <stop offset="0.26" stop-color="#ff8f84"/>
13
- <stop offset="1" stop-color="#d62f2c"/>
12
+ <stop offset="0.26" stop-color="#d9867d"/>
13
+ <stop offset="1" stop-color="#a32d2a"/>
14
14
  </linearGradient>
15
15
  <linearGradient id="right" x1="150" y1="59" x2="219" y2="195" gradientUnits="userSpaceOnUse">
16
- <stop offset="0" stop-color="#bb2026"/>
16
+ <stop offset="0" stop-color="#911b20"/>
17
17
  <stop offset="1" stop-color="#3c0407"/>
18
18
  </linearGradient>
19
19
  <linearGradient id="center" x1="99" y1="104" x2="146" y2="226" gradientUnits="userSpaceOnUse">
20
- <stop offset="0" stop-color="#ff6c61"/>
21
- <stop offset="0.48" stop-color="#c82d2a"/>
22
- <stop offset="1" stop-color="#8d1618"/>
20
+ <stop offset="0" stop-color="#c8554f"/>
21
+ <stop offset="0.48" stop-color="#992522"/>
22
+ <stop offset="1" stop-color="#6d1315"/>
23
23
  </linearGradient>
24
24
  <radialGradient id="glow" cx="38%" cy="22%" r="66%">
25
25
  <stop offset="0" stop-color="#fff8ed" stop-opacity="0.68"/>
26
- <stop offset="0.42" stop-color="#ffb0a7" stop-opacity="0.18"/>
27
- <stop offset="1" stop-color="#ffb0a7" stop-opacity="0"/>
26
+ <stop offset="0.42" stop-color="#d89a92" stop-opacity="0.18"/>
27
+ <stop offset="1" stop-color="#d89a92" stop-opacity="0"/>
28
+ </radialGradient>
29
+ <linearGradient id="body-blue" x1="45" y1="35" x2="211" y2="224" gradientUnits="userSpaceOnUse">
30
+ <stop offset="0" stop-color="#7aa5d9"/>
31
+ <stop offset="0.42" stop-color="#35669e"/>
32
+ <stop offset="1" stop-color="#162f4a"/>
33
+ </linearGradient>
34
+ <linearGradient id="table-blue" x1="75" y1="31" x2="166" y2="104" gradientUnits="userSpaceOnUse">
35
+ <stop offset="0" stop-color="#edf4ff"/>
36
+ <stop offset="0.26" stop-color="#7d9ed9"/>
37
+ <stop offset="1" stop-color="#2a5ca3"/>
38
+ </linearGradient>
39
+ <linearGradient id="right-blue" x1="150" y1="59" x2="219" y2="195" gradientUnits="userSpaceOnUse">
40
+ <stop offset="0" stop-color="#1f4a91"/>
41
+ <stop offset="1" stop-color="#071b3c"/>
42
+ </linearGradient>
43
+ <linearGradient id="center-blue" x1="99" y1="104" x2="146" y2="226" gradientUnits="userSpaceOnUse">
44
+ <stop offset="0" stop-color="#4f78c8"/>
45
+ <stop offset="0.48" stop-color="#254a99"/>
46
+ <stop offset="1" stop-color="#132a6d"/>
47
+ </linearGradient>
48
+ <radialGradient id="glow-blue" cx="38%" cy="22%" r="66%">
49
+ <stop offset="0" stop-color="#edf6ff" stop-opacity="0.68"/>
50
+ <stop offset="0.42" stop-color="#92aed9" stop-opacity="0.18"/>
51
+ <stop offset="1" stop-color="#92aed9" stop-opacity="0"/>
52
+ </radialGradient>
53
+ <linearGradient id="body-green" x1="45" y1="35" x2="211" y2="224" gradientUnits="userSpaceOnUse">
54
+ <stop offset="0" stop-color="#79d9a0"/>
55
+ <stop offset="0.42" stop-color="#359e66"/>
56
+ <stop offset="1" stop-color="#164a2f"/>
57
+ </linearGradient>
58
+ <linearGradient id="table-green" x1="75" y1="31" x2="166" y2="104" gradientUnits="userSpaceOnUse">
59
+ <stop offset="0" stop-color="#edfff4"/>
60
+ <stop offset="0.26" stop-color="#7dd9a5"/>
61
+ <stop offset="1" stop-color="#2aa360"/>
62
+ </linearGradient>
63
+ <linearGradient id="right-green" x1="150" y1="59" x2="219" y2="195" gradientUnits="userSpaceOnUse">
64
+ <stop offset="0" stop-color="#1b9147"/>
65
+ <stop offset="1" stop-color="#043c1c"/>
66
+ </linearGradient>
67
+ <linearGradient id="center-green" x1="99" y1="104" x2="146" y2="226" gradientUnits="userSpaceOnUse">
68
+ <stop offset="0" stop-color="#4fc87d"/>
69
+ <stop offset="0.48" stop-color="#259950"/>
70
+ <stop offset="1" stop-color="#136d30"/>
71
+ </linearGradient>
72
+ <radialGradient id="glow-green" cx="38%" cy="22%" r="66%">
73
+ <stop offset="0" stop-color="#edfff4" stop-opacity="0.68"/>
74
+ <stop offset="0.42" stop-color="#92d9b0" stop-opacity="0.18"/>
75
+ <stop offset="1" stop-color="#92d9b0" stop-opacity="0"/>
28
76
  </radialGradient>
29
77
  <linearGradient id="wordmark" x1="0" y1="76" x2="0" y2="138" gradientUnits="userSpaceOnUse">
30
78
  <stop offset="0" stop-color="#ffffff"/>
@@ -33,7 +81,7 @@
33
81
  </linearGradient>
34
82
  <linearGradient id="accentLine" x1="90" y1="0" x2="470" y2="0" gradientUnits="userSpaceOnUse">
35
83
  <stop offset="0" stop-color="#30363d"/>
36
- <stop offset="0.5" stop-color="#cc342d"/>
84
+ <stop offset="0.5" stop-color="#a7312b"/>
37
85
  <stop offset="1" stop-color="#30363d"/>
38
86
  </linearGradient>
39
87
  <filter id="shadow" x="-18%" y="-18%" width="136%" height="146%">
@@ -45,17 +93,47 @@
45
93
  <symbol id="gemstone" viewBox="0 0 256 256">
46
94
  <path d="M33 91 78 30h100l45 61-95 134Z" fill="url(#body)" stroke="#250507" stroke-width="7" stroke-linejoin="round"/>
47
95
  <path d="M78 30h100l-50 61Z" fill="url(#table)" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
48
- <path d="M33 91h95l-52 44Z" fill="#e93c35" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
96
+ <path d="M33 91h95l-52 44Z" fill="#b03a33" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
49
97
  <path d="M223 91h-95l52 44Z" fill="url(#right)" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
50
- <path d="M76 135 128 225 33 91Z" fill="#9f1b1d" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
98
+ <path d="M76 135 128 225 33 91Z" fill="#7a1a1b" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
51
99
  <path d="M180 135 128 225 223 91Z" fill="#62080d" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
52
100
  <path d="M76 135h104l-52 90Z" fill="url(#center)" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
53
- <path d="M78 30 128 91 76 135 33 91Z" fill="#d9322d" opacity="0.72"/>
54
- <path d="M178 30 128 91 180 135 223 91Z" fill="#8f1519" opacity="0.72"/>
55
- <path d="M128 91 76 135h104Z" fill="#ff6257" opacity="0.5"/>
101
+ <path d="M78 30 128 91 76 135 33 91Z" fill="#a32d29" opacity="0.72"/>
102
+ <path d="M178 30 128 91 180 135 223 91Z" fill="#6f1416" opacity="0.72"/>
103
+ <path d="M128 91 76 135h104Z" fill="#c44f47" opacity="0.5"/>
56
104
  <path d="M49 91 84 43h43L86 96Z" fill="url(#glow)"/>
57
105
  <path d="M85 62 101 43h35L93 87Z" fill="#fff6eb" opacity="0.52"/>
58
- <path d="M97 153h62" fill="none" stroke="#ffaba2" stroke-width="4" stroke-linecap="round" opacity="0.25"/>
106
+ <path d="M97 153h62" fill="none" stroke="#cf8d85" stroke-width="4" stroke-linecap="round" opacity="0.25"/>
107
+ </symbol>
108
+ <symbol id="gemstone-blue" viewBox="0 0 256 256">
109
+ <path d="M33 91 78 30h100l45 61-95 134Z" fill="url(#body-blue)" stroke="#250507" stroke-width="7" stroke-linejoin="round"/>
110
+ <path d="M78 30h100l-50 61Z" fill="url(#table-blue)" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
111
+ <path d="M33 91h95l-52 44Z" fill="#336fb0" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
112
+ <path d="M223 91h-95l52 44Z" fill="url(#right-blue)" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
113
+ <path d="M76 135 128 225 33 91Z" fill="#1a3a7a" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
114
+ <path d="M180 135 128 225 223 91Z" fill="#081a62" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
115
+ <path d="M76 135h104l-52 90Z" fill="url(#center-blue)" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
116
+ <path d="M78 30 128 91 76 135 33 91Z" fill="#2d5ba3" opacity="0.72"/>
117
+ <path d="M178 30 128 91 180 135 223 91Z" fill="#142d6f" opacity="0.72"/>
118
+ <path d="M128 91 76 135h104Z" fill="#4774c4" opacity="0.5"/>
119
+ <path d="M49 91 84 43h43L86 96Z" fill="url(#glow-blue)"/>
120
+ <path d="M85 62 101 43h35L93 87Z" fill="#edf4ff" opacity="0.52"/>
121
+ <path d="M97 153h62" fill="none" stroke="#85a5cf" stroke-width="4" stroke-linecap="round" opacity="0.25"/>
122
+ </symbol>
123
+ <symbol id="gemstone-green" viewBox="0 0 256 256">
124
+ <path d="M33 91 78 30h100l45 61-95 134Z" fill="url(#body-green)" stroke="#250507" stroke-width="7" stroke-linejoin="round"/>
125
+ <path d="M78 30h100l-50 61Z" fill="url(#table-green)" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
126
+ <path d="M33 91h95l-52 44Z" fill="#33b070" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
127
+ <path d="M223 91h-95l52 44Z" fill="url(#right-green)" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
128
+ <path d="M76 135 128 225 33 91Z" fill="#1a7a4b" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
129
+ <path d="M180 135 128 225 223 91Z" fill="#086220" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
130
+ <path d="M76 135h104l-52 90Z" fill="url(#center-green)" stroke="#250507" stroke-width="4" stroke-linejoin="round"/>
131
+ <path d="M78 30 128 91 76 135 33 91Z" fill="#2da36a" opacity="0.72"/>
132
+ <path d="M178 30 128 91 180 135 223 91Z" fill="#146f3d" opacity="0.72"/>
133
+ <path d="M128 91 76 135h104Z" fill="#47c478" opacity="0.5"/>
134
+ <path d="M49 91 84 43h43L86 96Z" fill="url(#glow-green)"/>
135
+ <path d="M85 62 101 43h35L93 87Z" fill="#edfff4" opacity="0.52"/>
136
+ <path d="M97 153h62" fill="none" stroke="#85cf9f" stroke-width="4" stroke-linecap="round" opacity="0.25"/>
59
137
  </symbol>
60
138
  </defs>
61
139
  <style>
@@ -99,22 +177,22 @@
99
177
  stroke: var(--accent-shadow);
100
178
  }
101
179
  .gem {
102
- animation-duration: 8.5s;
180
+ animation-duration: 6.5s;
103
181
  animation-iteration-count: infinite;
104
182
  animation-timing-function: ease-in-out;
105
183
  }
106
184
  .gem-a { animation-name: gem-a; }
107
- .gem-b { animation-name: gem-b; animation-duration: 9.5s; }
108
- .gem-c { animation-name: gem-c; animation-duration: 10s; }
185
+ .gem-b { animation-name: gem-b; animation-duration: 7.5s; }
186
+ .gem-c { animation-name: gem-c; animation-duration: 8s; }
109
187
  .gem-front {
110
188
  opacity: 0;
111
- animation-duration: 18s;
189
+ animation-duration: 12s;
112
190
  animation-iteration-count: infinite;
113
191
  animation-timing-function: ease-in-out;
114
192
  }
115
193
  .gem-front-a { animation-name: gem-front-a; }
116
- .gem-front-b { animation-name: gem-front-b; animation-delay: -6s; }
117
- .gem-front-c { animation-name: gem-front-c; animation-delay: -12s; }
194
+ .gem-front-b { animation-name: gem-front-b; animation-delay: -4s; }
195
+ .gem-front-c { animation-name: gem-front-c; animation-delay: -8s; }
118
196
  @keyframes gem-a {
119
197
  0%, 100% { transform: translate(42px, 82px) rotate(-10deg); }
120
198
  35% { transform: translate(66px, 45px) rotate(5deg); }
@@ -151,13 +229,10 @@
151
229
  }
152
230
  </style>
153
231
 
154
- <path class="rule" d="M32 38h496M32 182h496" stroke-width="1" opacity="0.62"/>
155
- <path class="rule-strong" d="M90 32h380" stroke-width="2" stroke-linecap="round" opacity="0.72"/>
156
-
157
- <g filter="url(#shadow)" opacity="0.92">
232
+ <g opacity="0.92">
158
233
  <g class="gem gem-a"><use href="#gemstone" width="78" height="78"/></g>
159
- <g class="gem gem-b"><use href="#gemstone" width="84" height="84"/></g>
160
- <g class="gem gem-c"><use href="#gemstone" width="78" height="78"/></g>
234
+ <g class="gem gem-b"><use href="#gemstone-blue" width="84" height="84"/></g>
235
+ <g class="gem gem-c"><use href="#gemstone-green" width="78" height="78"/></g>
161
236
  </g>
162
237
 
163
238
  <g font-family="system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif" text-anchor="middle">
@@ -170,15 +245,12 @@
170
245
  font-size="72" font-weight="800">r.uby.dev</text>
171
246
  </g>
172
247
 
173
- <g filter="url(#shadow)">
248
+ <g>
174
249
  <g class="gem gem-a"><use class="gem-front gem-front-a" href="#gemstone" width="78" height="78"/></g>
175
- <g class="gem gem-b"><use class="gem-front gem-front-b" href="#gemstone" width="84" height="84"/></g>
176
- <g class="gem gem-c"><use class="gem-front gem-front-c" href="#gemstone" width="78" height="78"/></g>
250
+ <g class="gem gem-b"><use class="gem-front gem-front-b" href="#gemstone-blue" width="84" height="84"/></g>
251
+ <g class="gem gem-c"><use class="gem-front gem-front-c" href="#gemstone-green" width="78" height="78"/></g>
177
252
  </g>
178
253
 
179
- <path class="accent-shadow" d="M90 176h380" stroke-width="8" stroke-linecap="round"/>
180
- <path d="M90 176h380" stroke="url(#accentLine)" stroke-width="4" stroke-linecap="round"/>
181
- <circle cx="280" cy="176" r="5" fill="#cc342d"/>
182
254
  <text class="tagline" x="280" y="204"
183
255
  font-family="system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
184
256
  text-anchor="middle" font-size="18" font-weight="650">Building cool stuff with Ruby</text>
data/test/cmd_test.rb CHANGED
@@ -19,6 +19,14 @@ class Test::Command
19
19
  .argv("-e", "warn 42")
20
20
  .stderr
21
21
  end
22
+
23
+ def test_ruby_argv_to_s
24
+ arg = Object.new
25
+ def arg.to_s = "-e"
26
+ assert_equal "42\n", ::Test::Command.new("ruby")
27
+ .argv(arg, "warn 42")
28
+ .stderr
29
+ end
22
30
  end
23
31
 
24
32
  ##
data/test/setup.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  require "bundler/setup"
2
2
  require "test/unit"
3
- require "test/cmd"
3
+ require "test-cmd"
data/test-cmd.rb.gemspec CHANGED
@@ -1,16 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require File.join(__dir__, "lib", "test", "command", "version.rb")
4
+
3
5
  Gem::Specification.new do |gem|
4
6
  gem.name = "test-cmd.rb"
5
- gem.authors = ["robert"]
7
+ gem.authors = ["Robert Gleeson"]
6
8
  gem.email = ["robert@r.uby.dev"]
7
9
  gem.homepage = "https://github.com/0x1eef/test-cmd.rb#readme"
8
- gem.version = "2.2.0"
10
+ gem.version = Test::Command::VERSION
9
11
  gem.required_ruby_version = ">= 3.0"
10
- gem.licenses = ["0BSD"]
12
+ gem.licenses = ["MIT"]
11
13
  gem.files = `git ls-files`.split($/)
12
14
  gem.require_paths = ["lib"]
13
- gem.summary = "test-cmd.rb provides an object-oriented interface for spawning a command"
15
+ gem.summary = <<~SUMMARY
16
+ test-cmd.rb is a Go-inspired, object-oriented interface for running
17
+ commands on UNIX-like systems, in the spirit of Go's `os/exec`. A
18
+ command can be built by chaining multiple method calls that impact
19
+ different command attributes. The environment the command executes
20
+ with can be set, its standard input stream can be written to, and
21
+ the standard output and standard error streams are captured so the
22
+ parent process can read them.
23
+ SUMMARY
14
24
  gem.description = gem.summary
15
25
  gem.add_development_dependency "test-unit", "~> 3.5.7"
16
26
  gem.add_development_dependency "yard", "~> 0.9"
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: test-cmd.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
- - robert
7
+ - Robert Gleeson
8
8
  bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
@@ -79,7 +79,12 @@ dependencies:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
81
  version: '13.1'
82
- description: test-cmd.rb provides an object-oriented interface for spawning a command
82
+ description: test-cmd.rb is a Go-inspired, object-oriented interface for running commands
83
+ on UNIX-like systems, in the spirit of Go's `os/exec`. A command can be built by
84
+ chaining multiple method calls that impact different command attributes. The environment
85
+ the command executes with can be set, its standard input stream can be written to,
86
+ and the standard output and standard error streams are captured so the parent process
87
+ can read them.
83
88
  email:
84
89
  - robert@r.uby.dev
85
90
  executables: []
@@ -95,14 +100,15 @@ files:
95
100
  - README.md
96
101
  - Rakefile.rb
97
102
  - lib/test-cmd.rb
98
- - lib/test/cmd.rb
103
+ - lib/test/command.rb
104
+ - lib/test/command/version.rb
99
105
  - rubydev.svg
100
106
  - test-cmd.rb.gemspec
101
107
  - test/cmd_test.rb
102
108
  - test/setup.rb
103
109
  homepage: https://github.com/0x1eef/test-cmd.rb#readme
104
110
  licenses:
105
- - 0BSD
111
+ - MIT
106
112
  metadata: {}
107
113
  rdoc_options: []
108
114
  require_paths:
@@ -120,5 +126,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
126
  requirements: []
121
127
  rubygems_version: 4.0.16
122
128
  specification_version: 4
123
- summary: test-cmd.rb provides an object-oriented interface for spawning a command
129
+ summary: test-cmd.rb is a Go-inspired, object-oriented interface for running commands
130
+ on UNIX-like systems, in the spirit of Go's `os/exec`. A command can be built by
131
+ chaining multiple method calls that impact different command attributes. The environment
132
+ the command executes with can be set, its standard input stream can be written to,
133
+ and the standard output and standard error streams are captured so the parent process
134
+ can read them.
124
135
  test_files: []