yobi 0.3.0 → 0.3.1

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: 47dd32402940fcd7c2699d932ca4a4e0db0f6e1ca4e8342ac5d41abc1cbe6114
4
- data.tar.gz: 888feb226907437769093ffbad5245f159e5879acb9a6a12de77e908ef14ed51
3
+ metadata.gz: 56739c72c75a1d5c856bbd619b781dd3986cf1b3c1447d4864edd19b9543d8d9
4
+ data.tar.gz: a5321fe628cab2f74011ce257a4eee380ed1fcb804456f8afa5482ac84c96b6f
5
5
  SHA512:
6
- metadata.gz: d9d683046fe0d910622731b5e527f2fda6a93ddf753bc849d9066ae2432667fe4feb2a3c404c48f7e0a54c7cacb5442bf7b1ab36cefd17d24e21388932342893
7
- data.tar.gz: 46c31f00651a04b6fd67ec3ccba73ff1bca4b6f2f8deccd3f18233f274d0c8c1394f19d4472dd96013ac340adb225d20f4fc87e8a41d49eeeef9f34dd256b8d4
6
+ metadata.gz: 9b2253d54dd64aa88658c7ddd53734a2edbcaf2623bb98258bc14d71d0d4a82bb3bcb447e6434bfb28505d2bfcd329988841d8f491ce7c3d1b13865b4a50b0f7
7
+ data.tar.gz: 7cd169b509d216a99b258180381c9caa9cd92837b822467781b01c3788cc37af4252d825b4de50a511b71a521a4e8d9bff8317a7f9c0da11b82847c6b65c2b8c
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [0.3.1] - 2026-08-10
2
+
3
+ ### Fixed
4
+
5
+ - `#forget`/`#init`/`#stats`/`#find`/`#snapshots`/`#key_list`/the `#cat_*` methods no longer raise a bare, uninformative `JSON::ParserError` when Restic exits with code 3 ("succeeded with warnings" - e.g. `#forget` failing to remove one or more snapshots) and mixes a plain-text diagnostic line into otherwise-JSON output. Raises `Yobi::ResticCommandFailed` instead, with the diagnostic still available in the error message.
6
+
1
7
  ## [0.3.0] - 2026-08-03
2
8
 
3
9
  ### Changed
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "json"
4
-
5
3
  module Yobi
6
4
  class Repository
7
5
  # `restic cat config`: the repository's own config document.
@@ -10,7 +8,7 @@ module Yobi
10
8
  # @raise [Yobi::RepositoryNotFound, Yobi::AuthenticationFailed]
11
9
  def cat_config
12
10
  execution = run_restic(build_argv("cat", "config"))
13
- JSON.parse(execution[:output].to_s)
11
+ parse_json_output(execution)
14
12
  end
15
13
  alias_method :config, :cat_config
16
14
 
@@ -21,7 +19,7 @@ module Yobi
21
19
  def cat_snapshot(id)
22
20
  id = id.id if id.is_a?(Yobi::Snapshot)
23
21
  execution = run_restic(build_argv("cat", "snapshot", id))
24
- JSON.parse(execution[:output].to_s)
22
+ parse_json_output(execution)
25
23
  end
26
24
 
27
25
  # `restic cat index ID`: one index file's own raw contents. IDs come
@@ -31,7 +29,7 @@ module Yobi
31
29
  # @return [Hash]
32
30
  def cat_index(id)
33
31
  execution = run_restic(build_argv("cat", "index", id))
34
- JSON.parse(execution[:output].to_s)
32
+ parse_json_output(execution)
35
33
  end
36
34
 
37
35
  # `restic cat key ID`: one key's own raw stored record.
@@ -41,7 +39,7 @@ module Yobi
41
39
  def cat_key(id)
42
40
  id = id.id if id.is_a?(Yobi::Key)
43
41
  execution = run_restic(build_argv("cat", "key", id))
44
- JSON.parse(execution[:output].to_s)
42
+ parse_json_output(execution)
45
43
  end
46
44
 
47
45
  # `restic cat tree snapshot:subfolder`: the raw tree object at a
@@ -58,7 +56,7 @@ module Yobi
58
56
  "#{snapshot_id}:#{subfolder}"
59
57
  end
60
58
  execution = run_restic(build_argv("cat", "tree", target))
61
- JSON.parse(execution[:output].to_s)
59
+ parse_json_output(execution)
62
60
  end
63
61
 
64
62
  # `restic cat pack ID`: one pack file's raw, still-encrypted bytes.
@@ -91,7 +89,7 @@ module Yobi
91
89
  # @return [Hash]
92
90
  def cat_masterkey_and_game_over_if_this_leaks
93
91
  execution = run_restic(build_argv("cat", "masterkey"))
94
- JSON.parse(execution[:output].to_s)
92
+ parse_json_output(execution)
95
93
  end
96
94
  end
97
95
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "json"
4
3
  require "time"
5
4
 
6
5
  module Yobi
@@ -45,7 +44,7 @@ module Yobi
45
44
  a.end_of_options.append(patterns)
46
45
  end
47
46
  execution = run_restic(argv)
48
- JSON.parse(execution[:output].to_s).map { |raw| MatchesPerSnapshot.new(raw) }
47
+ parse_json_output(execution).map { |raw| MatchesPerSnapshot.new(raw) }
49
48
  end
50
49
  end
51
50
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "json"
4
-
5
3
  module Yobi
6
4
  class Repository
7
5
  # `restic forget`: applies a retention policy, removing snapshots
@@ -69,7 +67,7 @@ module Yobi
69
67
  a.flag(:repack_smaller_than, repack_smaller_than) unless repack_smaller_than.nil?
70
68
  end
71
69
  execution = run_restic(argv)
72
- JSON.parse(execution[:output].to_s).map { |raw| ForgetGroup.new(raw) }
70
+ parse_json_output(execution).map { |raw| ForgetGroup.new(raw) }
73
71
  end
74
72
  end
75
73
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "json"
4
-
5
3
  module Yobi
6
4
  class Repository
7
5
  # `restic init`: creates the repository at {#url}.
@@ -33,7 +31,7 @@ module Yobi
33
31
  end
34
32
 
35
33
  execution = run_restic(argv, extra_env: password_env(from_password, "RESTIC_FROM_PASSWORD"))
36
- Initialized.new(JSON.parse(execution[:output].to_s))
34
+ Initialized.new(parse_json_output(execution))
37
35
  end
38
36
 
39
37
  # Constructs a new {Yobi::Repository} at `url`, already initialized with
@@ -37,7 +37,7 @@ module Yobi
37
37
  # @return [Array<Yobi::Key>]
38
38
  def key_list
39
39
  execution = run_restic(build_argv("key", "list"))
40
- JSON.parse(execution[:output].to_s).map { |raw| Key.new(raw) }
40
+ parse_json_output(execution).map { |raw| Key.new(raw) }
41
41
  end
42
42
  alias_method :keys, :key_list
43
43
 
@@ -23,7 +23,7 @@ module Yobi
23
23
  a.flag(:latest, latest) unless latest.nil?
24
24
  end
25
25
  execution = run_restic(argv)
26
- JSON.parse(execution[:output].to_s).map { |raw| Snapshot.new(raw) }
26
+ parse_json_output(execution).map { |raw| Snapshot.new(raw) }
27
27
  end
28
28
  end
29
29
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "json"
4
-
5
3
  module Yobi
6
4
  class Repository
7
5
  # @private
@@ -29,7 +27,7 @@ module Yobi
29
27
  a.repeat_flag(:tag, tags)
30
28
  end
31
29
  execution = run_restic(argv)
32
- RepositoryStats.new(JSON.parse(execution[:output].to_s))
30
+ RepositoryStats.new(parse_json_output(execution))
33
31
  end
34
32
  end
35
33
 
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "json"
3
4
  require "uri"
4
5
 
5
6
  module Yobi
@@ -62,6 +63,21 @@ module Yobi
62
63
  builder.to_a
63
64
  end
64
65
 
66
+ # Parses a command's captured output as JSON. If parsing fails, raises
67
+ # {Yobi::ResticCommandFailed} when `execution[:exit_code]` is `3`
68
+ # (Restic reported a problem alongside otherwise-JSON output), or
69
+ # re-raises the original +JSON::ParserError+ when it's `0`.
70
+ #
71
+ # @param execution [Hash] `{exit_code:, output:, argv:}`
72
+ # @return [Object] the parsed JSON
73
+ # @raise [Yobi::ResticCommandFailed] if parsing fails and `exit_code` is `3`
74
+ def parse_json_output(execution)
75
+ JSON.parse(execution[:output].to_s)
76
+ rescue JSON::ParserError
77
+ raise if execution[:exit_code].zero?
78
+ raise Yobi::ResticCommandFailed, execution
79
+ end
80
+
65
81
  def resolved_password
66
82
  password_env(password)
67
83
  end
data/lib/yobi/version.rb CHANGED
@@ -4,5 +4,5 @@
4
4
  # plain Ruby objects instead of shelling out to flags and raw JSON by hand.
5
5
  module Yobi
6
6
  # @return [String]
7
- VERSION = "0.3.0"
7
+ VERSION = "0.3.1"
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yobi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zia Perdana
@@ -61,7 +61,7 @@ metadata:
61
61
  homepage_uri: https://codeberg.org/ukazap/yobi
62
62
  source_code_uri: https://codeberg.org/ukazap/yobi
63
63
  changelog_uri: https://codeberg.org/ukazap/yobi/src/branch/main/CHANGELOG.md
64
- documentation_uri: https://rubydoc.info/gems/yobi/0.3.0
64
+ documentation_uri: https://rubydoc.info/gems/yobi/0.3.1
65
65
  rdoc_options: []
66
66
  require_paths:
67
67
  - lib