pray-cli 1.26.1 → 1.26.3
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 +8 -0
- data/lib/pray/hashing.rb +2 -0
- data/lib/pray/package_spec.rb +0 -21
- data/lib/pray/package_spec_tree_hash.rb +35 -0
- data/lib/pray/render_reconcile.rb +11 -3
- data/lib/pray/resolve.rb +6 -7
- data/lib/pray/resolve_deps.rb +4 -0
- data/lib/pray/version.rb +2 -2
- data/lib/pray.rb +1 -0
- data/pray-cli.gemspec +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2c518cdb4d98021a08d150ad7c0c20463d885b09c9f69b022f2fa596d9597269
|
|
4
|
+
data.tar.gz: 8e46339135b9a8cb554eb4b8d9f60510baa5eab1b1b730bbda70efdd227289f3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1b619b7f79ee252328c885ac0664270d29f00f81a720102a26f8a1af8d78c57e7f9245f6eb09e724a3ba1f19d482001c59a8153d0f2da534d64fe64cdc5cc314
|
|
7
|
+
data.tar.gz: bd6f8f108e1e8cab3e48060c09dff86b8dfc55cc5edaaed320fcb6d347f2b9ea90e208ceb5c2757136084b7da815f34b491ef7fffec3f78d7b70abfb530819d3
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 1.26.3 (2026-11-12)
|
|
6
|
+
|
|
7
|
+
- Allow `pray install` to refresh the lock when a managed span already matches the fresh render but the lock ideal is stale. Keep failing when the on-disk body matches neither, and name move-aside recovery instead of a force flag.
|
|
8
|
+
|
|
9
|
+
## 1.26.2 (2026-11-06)
|
|
10
|
+
|
|
11
|
+
- Reduce wall and CPU time for package resolve, tree hashing, and related install work without changing install results.
|
|
12
|
+
|
|
5
13
|
## 1.26.1 (2026-11-02)
|
|
6
14
|
|
|
7
15
|
- Show optional package referrals separately in `pray explain`, exclude them from dependency cycles and trees, and validate their constraints when another declaration selects the target.
|
data/lib/pray/hashing.rb
CHANGED
data/lib/pray/package_spec.rb
CHANGED
|
@@ -54,27 +54,6 @@ module Pray
|
|
|
54
54
|
copy.dependencies = dependencies.sort_by { |dependency| [dependency.name, dependency.constraint, dependency.optional] }
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
|
-
|
|
58
|
-
def tree_hash_for_root(root)
|
|
59
|
-
validate_relative_paths!
|
|
60
|
-
file_bytes = {}
|
|
61
|
-
files.each do |file|
|
|
62
|
-
path = File.join(root, file)
|
|
63
|
-
raise Error.integrity("package file missing: #{file}") unless File.exist?(path)
|
|
64
|
-
raise Error.integrity("package file is a directory: #{file}") if File.directory?(path)
|
|
65
|
-
|
|
66
|
-
file_bytes[file] = File.binread(path)
|
|
67
|
-
end
|
|
68
|
-
self.class.tree_hash_from_file_bytes(file_bytes)
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def self.tree_hash_from_file_bytes(file_bytes)
|
|
72
|
-
entries = file_bytes.map { |path, bytes| [path, Hashing.sha256_prefixed(bytes)] }.sort_by(&:first)
|
|
73
|
-
serialized = entries.map do |path, hash|
|
|
74
|
-
"file\0regular\0#{path}\0#{hash}\n"
|
|
75
|
-
end.join
|
|
76
|
-
Hashing.sha256_prefixed(serialized)
|
|
77
|
-
end
|
|
78
57
|
end
|
|
79
58
|
|
|
80
59
|
module PackageSpecParser
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "digest"
|
|
4
|
+
|
|
5
|
+
module Pray
|
|
6
|
+
class PackageSpec
|
|
7
|
+
def tree_hash_for_root(root)
|
|
8
|
+
validate_relative_paths!
|
|
9
|
+
file_bytes = {}
|
|
10
|
+
files.each do |file|
|
|
11
|
+
path = File.join(root, file)
|
|
12
|
+
raise Error.integrity("package file missing: #{file}") unless File.exist?(path)
|
|
13
|
+
raise Error.integrity("package file is a directory: #{file}") if File.directory?(path)
|
|
14
|
+
|
|
15
|
+
file_bytes[file] = File.binread(path)
|
|
16
|
+
end
|
|
17
|
+
self.class.tree_hash_from_file_bytes(file_bytes)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.tree_hash_from_file_bytes(file_bytes)
|
|
21
|
+
# Stream the same bytes the prior string builder emitted so the digest stays identical.
|
|
22
|
+
digest = Digest::SHA256.new
|
|
23
|
+
file_bytes.keys.sort.each do |path|
|
|
24
|
+
bytes = file_bytes.fetch(path)
|
|
25
|
+
digest << "file\0regular\0"
|
|
26
|
+
digest << path
|
|
27
|
+
digest << "\0"
|
|
28
|
+
digest << "sha256:"
|
|
29
|
+
digest << Digest::SHA256.hexdigest(bytes)
|
|
30
|
+
digest << "\n"
|
|
31
|
+
end
|
|
32
|
+
Hashing.prefixed_hex_digest(digest.digest)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -31,6 +31,9 @@ module Pray
|
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def reject_managed_span_conflicts!(project, rendered, previous_lockfile)
|
|
34
|
+
fresh_ideals = rendered.each_with_object({}) do |target, ideals|
|
|
35
|
+
target.managed_spans.each { |span| ideals[span.id] = span.ideal_checksum }
|
|
36
|
+
end
|
|
34
37
|
active_by_target = rendered.to_h do |target|
|
|
35
38
|
[target.path, target.managed_spans.to_h { |span| [span.id, true] }]
|
|
36
39
|
end
|
|
@@ -47,11 +50,16 @@ module Pray
|
|
|
47
50
|
bodies = RenderPatch.managed_bodies(RenderPatch.split_segments(content))
|
|
48
51
|
spans.each do |span|
|
|
49
52
|
next unless active[span.id] && bodies.key?(span.id)
|
|
50
|
-
|
|
53
|
+
|
|
54
|
+
checksum = Hashing.checksum_managed_span_content(bodies[span.id])
|
|
55
|
+
next if checksum == span.ideal_checksum
|
|
56
|
+
next if checksum == fresh_ideals[span.id]
|
|
51
57
|
|
|
52
58
|
raise Error.render(
|
|
53
|
-
"conflict: managed span `#{span.id}` in `#{target_path}`
|
|
54
|
-
"(`#{span.package}::#{span.export}`)"
|
|
59
|
+
"conflict: managed span `#{span.id}` in `#{target_path}` differs from lock and from " \
|
|
60
|
+
"fresh render (`#{span.package}::#{span.export}`).\n" \
|
|
61
|
+
"Move the destination aside and rerun `pray install`, or restore the managed block " \
|
|
62
|
+
"to the locked bytes."
|
|
55
63
|
)
|
|
56
64
|
end
|
|
57
65
|
end
|
data/lib/pray/resolve.rb
CHANGED
|
@@ -277,18 +277,17 @@ module Pray
|
|
|
277
277
|
end
|
|
278
278
|
|
|
279
279
|
def find_prayspec_file(root)
|
|
280
|
-
|
|
280
|
+
found = nil
|
|
281
281
|
Dir.each_child(root) do |entry|
|
|
282
282
|
next unless File.extname(entry) == ".prayspec"
|
|
283
283
|
|
|
284
284
|
path = File.join(root, entry)
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
when 0 then raise Error.resolution("no prayspec file found in #{root.inspect}")
|
|
290
|
-
else raise Error.resolution("multiple prayspec files found in #{root.inspect}")
|
|
285
|
+
next unless File.file?(path)
|
|
286
|
+
raise Error.resolution("multiple prayspec files found in #{root.inspect}") if found
|
|
287
|
+
|
|
288
|
+
found = path
|
|
291
289
|
end
|
|
290
|
+
found || raise(Error.resolution("no prayspec file found in #{root.inspect}"))
|
|
292
291
|
end
|
|
293
292
|
|
|
294
293
|
def source_map(sources)
|
data/lib/pray/resolve_deps.rb
CHANGED
|
@@ -5,6 +5,8 @@ module Pray
|
|
|
5
5
|
module_function
|
|
6
6
|
|
|
7
7
|
def reject_dependency_cycles(packages)
|
|
8
|
+
return if packages.all? { |package| package.spec.dependencies.all?(&:optional) }
|
|
9
|
+
|
|
8
10
|
edges = {}
|
|
9
11
|
packages.each do |package|
|
|
10
12
|
edges[package.declaration.name] = package.spec.dependencies.reject(&:optional).map(&:name)
|
|
@@ -16,6 +18,8 @@ module Pray
|
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
def validate_optional_referrals(packages)
|
|
21
|
+
return if packages.all? { |package| package.spec.dependencies.none?(&:optional) }
|
|
22
|
+
|
|
19
23
|
packages_by_name = packages.to_h { |package| [package.declaration.name, package] }
|
|
20
24
|
packages.each do |package|
|
|
21
25
|
package.spec.dependencies.select(&:optional).each do |dependency|
|
data/lib/pray/version.rb
CHANGED
data/lib/pray.rb
CHANGED
|
@@ -18,6 +18,7 @@ require_relative "pray/format_manifest"
|
|
|
18
18
|
require_relative "pray/package_relation"
|
|
19
19
|
require_relative "pray/package_spec"
|
|
20
20
|
require_relative "pray/package_spec_paths"
|
|
21
|
+
require_relative "pray/package_spec_tree_hash"
|
|
21
22
|
require_relative "pray/package_spec_version"
|
|
22
23
|
require_relative "pray/local_prayer"
|
|
23
24
|
require_relative "pray/lockfile"
|
data/pray-cli.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pray-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.26.
|
|
4
|
+
version: 1.26.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrei Makarov
|
|
@@ -77,14 +77,14 @@ dependencies:
|
|
|
77
77
|
requirements:
|
|
78
78
|
- - "~>"
|
|
79
79
|
- !ruby/object:Gem::Version
|
|
80
|
-
version: '
|
|
80
|
+
version: '4.0'
|
|
81
81
|
type: :development
|
|
82
82
|
prerelease: false
|
|
83
83
|
version_requirements: !ruby/object:Gem::Requirement
|
|
84
84
|
requirements:
|
|
85
85
|
- - "~>"
|
|
86
86
|
- !ruby/object:Gem::Version
|
|
87
|
-
version: '
|
|
87
|
+
version: '4.0'
|
|
88
88
|
description: 'Ruby Prayfile CLI and library: resolve, lock, render, verify, and publish
|
|
89
89
|
inference input packages. Consumes path, git, and registry distribution points.'
|
|
90
90
|
email:
|
|
@@ -166,6 +166,7 @@ files:
|
|
|
166
166
|
- lib/pray/package_spec.rb
|
|
167
167
|
- lib/pray/package_spec_paths.rb
|
|
168
168
|
- lib/pray/package_spec_render.rb
|
|
169
|
+
- lib/pray/package_spec_tree_hash.rb
|
|
169
170
|
- lib/pray/package_spec_version.rb
|
|
170
171
|
- lib/pray/path_safety.rb
|
|
171
172
|
- lib/pray/plan.rb
|