philiprehberger-task_runner 0.6.0 → 0.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 +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +22 -0
- data/lib/philiprehberger/task_runner/result.rb +27 -0
- data/lib/philiprehberger/task_runner/version.rb +1 -1
- data/lib/philiprehberger/task_runner.rb +3 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dddebb2a9f61387b45cc9650f3d695c07be69388f6d2b988f551326b5cfba973
|
|
4
|
+
data.tar.gz: 2d53404bcb1eb3fbbb941091d8c7b4a4e68515fe224c6891b0473c9a609d0773
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b8d1d3691823020fdd69b5d7642fe61d26415c654f6d26d3069755aa4ee95e09a8fa3f7bd34ffc9fb004d67366c7806a297aa4a7890251a7cce421c9e70ae3f4
|
|
7
|
+
data.tar.gz: 5a0123b5b514d3d07b1d9ade8e02137a92773564253f2fc7331531de844190ff3f921e732c794fd0b5d8c86c1d393baed9281d0d4fe8342c7716d8c00333fd71
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.7.0] - 2026-05-20
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `Result#parse_json` — parse stdout as JSON, raising `Philiprehberger::TaskRunner::ParseError` (new) when stdout is empty or not valid JSON
|
|
14
|
+
- `Result#json?` — predicate for safely probing whether stdout is parseable JSON
|
|
15
|
+
- Card image reference in the README for registry-side rendering
|
|
16
|
+
|
|
10
17
|
## [0.6.0] - 2026-04-28
|
|
11
18
|
|
|
12
19
|
### Added
|
data/README.md
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
[](https://rubygems.org/gems/philiprehberger-task_runner)
|
|
5
5
|
[](https://github.com/philiprehberger/rb-task-runner/commits/main)
|
|
6
6
|
|
|
7
|
+

|
|
8
|
+
|
|
7
9
|
Shell command runner with output capture, timeout, streaming, signal handling, and stdin piping
|
|
8
10
|
|
|
9
11
|
## Requirements
|
|
@@ -134,6 +136,24 @@ Philiprehberger::TaskRunner.run('make', 'build') do |line, stream|
|
|
|
134
136
|
end
|
|
135
137
|
```
|
|
136
138
|
|
|
139
|
+
### Parsing JSON Output
|
|
140
|
+
|
|
141
|
+
```ruby
|
|
142
|
+
result = Philiprehberger::TaskRunner.run('kubectl', 'get', 'pod', 'web', '-o', 'json')
|
|
143
|
+
|
|
144
|
+
if result.json?
|
|
145
|
+
doc = result.parse_json
|
|
146
|
+
doc['status']['phase'] # => "Running"
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# parse_json raises ParseError when stdout isn't valid JSON
|
|
150
|
+
begin
|
|
151
|
+
result.parse_json
|
|
152
|
+
rescue Philiprehberger::TaskRunner::ParseError => e
|
|
153
|
+
warn "command did not return JSON: #{e.message}"
|
|
154
|
+
end
|
|
155
|
+
```
|
|
156
|
+
|
|
137
157
|
## API
|
|
138
158
|
|
|
139
159
|
| Method / Class | Description |
|
|
@@ -153,6 +173,8 @@ end
|
|
|
153
173
|
| `Result#duration` | Execution time in seconds |
|
|
154
174
|
| `Result#signal` | Signal that killed the process (:TERM, :KILL, or nil) |
|
|
155
175
|
| `Result#timed_out?` | Whether the process was killed for exceeding its timeout |
|
|
176
|
+
| `Result#json?` | Whether stdout contains a parseable JSON document |
|
|
177
|
+
| `Result#parse_json` | Parse stdout as JSON; raises `ParseError` on invalid or empty stdout |
|
|
156
178
|
| `Result#to_h` | Hash representation of the result (includes `:success` and `:timed_out`) |
|
|
157
179
|
|
|
158
180
|
## Development
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
3
5
|
module Philiprehberger
|
|
4
6
|
module TaskRunner
|
|
5
7
|
# Represents the result of a shell command execution.
|
|
@@ -55,6 +57,31 @@ module Philiprehberger
|
|
|
55
57
|
%i[TERM KILL].include?(@signal)
|
|
56
58
|
end
|
|
57
59
|
|
|
60
|
+
# Whether stdout contains a parseable JSON document.
|
|
61
|
+
# Empty stdout is treated as non-JSON.
|
|
62
|
+
#
|
|
63
|
+
# @return [Boolean]
|
|
64
|
+
def json?
|
|
65
|
+
return false if @stdout.nil? || @stdout.strip.empty?
|
|
66
|
+
|
|
67
|
+
JSON.parse(@stdout)
|
|
68
|
+
true
|
|
69
|
+
rescue JSON::ParserError
|
|
70
|
+
false
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Parse stdout as JSON.
|
|
74
|
+
#
|
|
75
|
+
# @return [Object] the parsed JSON document (Hash, Array, String, Numeric, true, false, or nil)
|
|
76
|
+
# @raise [ParseError] if stdout is empty or not valid JSON
|
|
77
|
+
def parse_json
|
|
78
|
+
raise ParseError, 'stdout is empty' if @stdout.nil? || @stdout.strip.empty?
|
|
79
|
+
|
|
80
|
+
JSON.parse(@stdout)
|
|
81
|
+
rescue JSON::ParserError => e
|
|
82
|
+
raise ParseError, "stdout is not valid JSON: #{e.message}"
|
|
83
|
+
end
|
|
84
|
+
|
|
58
85
|
# Hash representation of the result.
|
|
59
86
|
#
|
|
60
87
|
# @return [Hash]
|
|
@@ -11,6 +11,9 @@ module Philiprehberger
|
|
|
11
11
|
class Error < StandardError; end
|
|
12
12
|
class TimeoutError < Error; end
|
|
13
13
|
|
|
14
|
+
# Raised by Result#parse_json when the stdout cannot be parsed as JSON.
|
|
15
|
+
class ParseError < Error; end
|
|
16
|
+
|
|
14
17
|
# Raised by run! when the command exits with a non-zero status.
|
|
15
18
|
class CommandError < Error
|
|
16
19
|
# @return [Result] the failed command result
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: philiprehberger-task_runner
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Philip Rehberger
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-05-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Run shell commands with captured stdout/stderr, exit code, duration measurement,
|
|
14
14
|
configurable timeout, environment variables, line-by-line streaming, graceful signal
|