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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 81a304bf73bc20e70f8bb340125ed6cbc3add80df788e746909341cdbcac85a4
4
- data.tar.gz: 46e8d6a93c2f3501142a9a4c330a8686e0d91edfd2c3bcd2674508075d563c34
3
+ metadata.gz: dddebb2a9f61387b45cc9650f3d695c07be69388f6d2b988f551326b5cfba973
4
+ data.tar.gz: 2d53404bcb1eb3fbbb941091d8c7b4a4e68515fe224c6891b0473c9a609d0773
5
5
  SHA512:
6
- metadata.gz: 83345dc31740a6618be9d21078c0b0640ba04bb54b08d457e67fc0df37786e2c8f86b316355ffd558bf1470967e71aa54575a4f98a2b75acaf8731059b8fbf52
7
- data.tar.gz: 304a3c5de5afd3a41e61dd9e127dc8fabecf546743a22900df0486ad95a768f7112f3713f8f4de9747080a31a0e0563a2c3d67b547a3cd6eefbc9f32b0e9ea83
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
  [![Gem Version](https://badge.fury.io/rb/philiprehberger-task_runner.svg)](https://rubygems.org/gems/philiprehberger-task_runner)
5
5
  [![Last updated](https://img.shields.io/github/last-commit/philiprehberger/rb-task-runner)](https://github.com/philiprehberger/rb-task-runner/commits/main)
6
6
 
7
+ ![philiprehberger-task_runner](https://raw.githubusercontent.com/philiprehberger/rb-task-runner/main/package-card.webp)
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]
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  module TaskRunner
5
- VERSION = '0.6.0'
5
+ VERSION = '0.7.0'
6
6
  end
7
7
  end
@@ -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.6.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-04-29 00:00:00.000000000 Z
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