Skip to content

Commit 54d8e04

Browse files
Add tarball git-tree-sha1 metadata
Record the artifact-compatible git-tree-sha1 for tar.gz downloads in versions.json, keep the schema change optional, and add local test coverage for the new tarball hashing behavior. Co-authored-by: OpenAI Codex GPT-5 <codex@openai.com>
1 parent f369eb9 commit 54d8e04

4 files changed

Lines changed: 68 additions & 17 deletions

File tree

Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
1010
Lazy = "50d2b5c4-7a5e-59d5-8109-a42b560f39c0"
1111
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
1212
SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce"
13+
Tar = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"
1314
TimeZones = "f269a46b-ccf7-5d73-abea-4c690281aa53"
1415
WebCacheUtilities = "0c1c26de-fc5f-47ff-87a8-a157289a9bac"
1516

schema.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
"sha256": {
4242
"type": "string"
4343
},
44+
"git-tree-sha1": {
45+
"type": "string"
46+
},
4447
"size": {
4548
"type": "integer"
4649
},

src/VersionsJSONUtil.jl

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
module VersionsJSONUtil
22

3-
using HTTP, JSON, Pkg.BinaryPlatforms, WebCacheUtilities, SHA, Lazy
3+
using HTTP, JSON, Pkg.BinaryPlatforms, WebCacheUtilities, SHA, Lazy, Tar
44
import Pkg.BinaryPlatforms: triplet, arch
5+
import Pkg.PlatformEngines: exe7z
56

67
"Wrapper types to define three jlext methods for portable, tarball and installer Windows"
78
struct WindowsPortable
@@ -122,6 +123,10 @@ function is_stable(v::VersionNumber)
122123
return v.prerelease == () && v.build == ()
123124
end
124125

126+
function tarball_git_tree_sha1(tarball_path::AbstractString)
127+
return open(Tar.tree_hash, `$(exe7z()) x $tarball_path -so`)
128+
end
129+
125130
# Get list of tags from the Julia repo
126131
function get_tags()
127132
@info("Probing for tag list...")
@@ -160,6 +165,22 @@ function main(out_path)
160165
number_urls_success += 1
161166
println(stdout, "")
162167

168+
if endswith(filename, ".dmg")
169+
kind = "archive"
170+
extension = "dmg"
171+
elseif endswith(filename, ".exe")
172+
kind = "installer"
173+
extension = "exe"
174+
elseif endswith(filename, ".tar.gz")
175+
kind = "archive"
176+
extension = "tar.gz"
177+
elseif endswith(filename, ".zip")
178+
kind = "archive"
179+
extension = "zip"
180+
else
181+
error("Unsupported file extension in filename: $(filename)")
182+
end
183+
163184
tarball_hash_path = hit_file_cache("$(filename).sha256") do tarball_hash_path
164185
open(filepath, "r") do io
165186
open(tarball_hash_path, "w") do hash_io
@@ -169,6 +190,17 @@ function main(out_path)
169190
end
170191
tarball_hash = String(read(tarball_hash_path))
171192

193+
tarball_git_tree_hash = if extension == "tar.gz"
194+
tarball_git_tree_hash_path = hit_file_cache("$(filename).git-tree-sha1") do tree_hash_path
195+
open(tree_hash_path, "w") do hash_io
196+
write(hash_io, tarball_git_tree_sha1(filepath))
197+
end
198+
end
199+
String(read(tarball_git_tree_hash_path))
200+
else
201+
nothing
202+
end
203+
172204
# Initialize overall version key, if needed
173205
if !haskey(meta, version)
174206
meta[version] = Dict(
@@ -196,21 +228,6 @@ function main(out_path)
196228
end
197229

198230
# Build up metadata about this file
199-
if endswith(filename, ".dmg")
200-
kind = "archive"
201-
extension = "dmg"
202-
elseif endswith(filename, ".exe")
203-
kind = "installer"
204-
extension = "exe"
205-
elseif endswith(filename, ".tar.gz")
206-
kind = "archive"
207-
extension = "tar.gz"
208-
elseif endswith(filename, ".zip")
209-
kind = "archive"
210-
extension = "zip"
211-
else
212-
error("Unsupported file extension in filename: $(filename)")
213-
end
214231
file_dict = Dict(
215232
"triplet" => triplet(platform),
216233
"os" => meta_os(platform),
@@ -222,6 +239,9 @@ function main(out_path)
222239
"extension" => extension,
223240
"url" => url,
224241
)
242+
if tarball_git_tree_hash !== nothing
243+
file_dict["git-tree-sha1"] = tarball_git_tree_hash
244+
end
225245
# Add in `.asc` signature content, if applicable
226246
if asc_signature !== nothing
227247
file_dict["asc"] = asc_signature

test/runtests.jl

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
using Pkg.BinaryPlatforms, JSON
1+
using Pkg.BinaryPlatforms, JSON, Tar
22
using VersionsJSONUtil
33
import VersionsJSONUtil: WindowsPortable, WindowsTarball, MacOSTarball
4+
import VersionsJSONUtil: tarball_git_tree_sha1
5+
import Pkg.PlatformEngines: exe7z
46
using Test
57

68
const download_urls = Dict(
@@ -32,4 +34,29 @@ const download_urls = Dict(
3234
@test VersionsJSONUtil.download_url(v, p) == url
3335
end
3436
end
37+
38+
@testset "Tarball git-tree-sha1" begin
39+
mktempdir() do tempdir
40+
srcdir = joinpath(tempdir, "src")
41+
mkpath(joinpath(srcdir, "bin"))
42+
write(joinpath(srcdir, "README.txt"), "VersionsJSONUtil test fixture\n")
43+
write(joinpath(srcdir, "bin", "julia"), "#!/bin/sh\n")
44+
45+
tar_path = joinpath(tempdir, "fixture.tar")
46+
tar_gz_path = joinpath(tempdir, "fixture.tar.gz")
47+
Tar.create(srcdir, tar_path)
48+
run(`$(exe7z()) a -tgzip $tar_gz_path $tar_path`)
49+
50+
@test tarball_git_tree_sha1(tar_gz_path) == Tar.tree_hash(tar_path)
51+
end
52+
end
53+
54+
@testset "Schema tarball requirements" begin
55+
schema = JSON.parsefile(joinpath(dirname(@__DIR__), "schema.json"))
56+
file_properties = schema["definitions"]["File"]["properties"]
57+
file_required = Set(schema["definitions"]["File"]["required"])
58+
59+
@test haskey(file_properties, "git-tree-sha1")
60+
@test !("git-tree-sha1" in file_required)
61+
end
3562
end

0 commit comments

Comments
 (0)