-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathutils.jl
193 lines (179 loc) · 7.36 KB
/
utils.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# Note: This file is also included by LocalPackageServer tests.
using LocalRegistry: gitcmd
using RegistryTools: Compress
using RegistryInstances: RegistryInstance
import Pkg
import TOML
# Read `project_file` and create or update a corresponding bare bones
# package directory under `package_dir`. Commit the changes to git.
#
# Strictly speaking it is only the "Project.toml" file and the src
# file that matter. Additional files are added to make the set up
# somewhat more normal looking.
function prepare_package(packages_dir, project_file, subdir = "";
use_julia_project = false, module_file=true)
project_file = joinpath(@__DIR__, "project_files", project_file)
project_data = TOML.parsefile(project_file)
name = project_data["name"]
version = get(project_data, "version", nothing)
# Fake repository URL.
repo = "git@example.com:Julia/$(name).jl.git"
top_dir = joinpath(packages_dir, name)
package_dir = joinpath(top_dir, subdir)
mkpath(package_dir)
mkpath(joinpath(package_dir, "src"))
mkpath(joinpath(package_dir, "test"))
if !isempty(subdir)
write(joinpath(top_dir, "README.md"), "# Top Level README")
end
git = gitcmd(top_dir, TEST_GITCONFIG)
if !isdir(joinpath(top_dir, ".git"))
run(`$(git) init -q`)
run(`$git remote add origin $repo`)
end
if use_julia_project
project = read(project_file, String)
write(joinpath(package_dir, "JuliaProject.toml"), project)
# Write a corrupted Project.toml as well to test that the
# right file is chosen. (This makes an assumption of the
# package name used for this case.)
write(joinpath(package_dir, "Project.toml"),
replace(project, "JuliaProjectTest" => "ProjectTest"))
else
write(joinpath(package_dir, "Project.toml"), read(project_file, String))
end
write(joinpath(package_dir, "README.md"), "# $(name)\n")
write(joinpath(package_dir, "LICENSE"), "$(name) is in the public domain\n")
if module_file
write(joinpath(package_dir, "src", "$(name).jl"), "module $(name)\nend\n")
end
write(joinpath(package_dir, "test", "runtests.jl"),
"using Test\n@test true\n")
run(`$git add --all`)
vers = if isnothing(version)
"No version"
else
"Version $(version)"
end
@show vers
if !occursin("nothing to commit, working tree clean",
read(`$git status`, String))
@info("nothing to commit")
run(`$git commit -qm $(vers)`)
end
return
end
function readdir_excluding_git(dir)
return filter(!isequal(".git"), readdir(dir))
end
function check_result(actual_result_dir, expected_result_dir)
check1 = compare_file_trees(actual_result_dir,
joinpath(@__DIR__, "expected_results",
expected_result_dir))
check2 = sanity_check_registry(actual_result_dir)
return check1 && check2
end
function compare_file_trees(path1, path2)
if isdir(path1) && isdir(path2)
dir1 = readdir_excluding_git(path1)
if sort(dir1) != sort(readdir_excluding_git(path2))
println("Directories $(path1) and $(path2) differ.")
return false
end
for path in dir1
if !compare_file_trees(joinpath(path1, path), joinpath(path2, path))
return false
end
end
elseif isfile(path1) && isfile(path2)
if !compare_files(path1, path2)
println("Files $(path1) and $(path2) differ.")
return false
end
else
println("Mismatch between paths $(path1) and $(path2)")
return false
end
return true
end
# Compress.save writes files differently on e.g. Julia 1.1 and
# 1.3. Compare the Deps.toml and Compat.toml files after reading them
# with Compress.load.
function compare_files(path1, path2)
if endswith(path1, "Deps.toml") || endswith(path1, "Compat.toml")
file1 = Compress.load(path1)
file2 = Compress.load(path2)
if endswith(path1, "Compat.toml")
# For unknown reasons, Julia 1.11 has started adding
# spaces in the Compat files, e.g. "1.1.0 - 1"
# instead of "1.1.0-1". Let's just wipe those spaces
# before comparing to the expected results.
for v in values(file1)
for (key, value) in v
v[key] = replace(value, " " => "")
end
end
end
return file1 == file2
end
return read_normalize_line_end(path1) == read_normalize_line_end(path2)
end
function read_normalize_line_end(path)
return replace(read(path, String), "\r\n" => "\n")
end
# Check that the deps and compat files can be read at all by a
# function used in the internals of Pkg. Return true whenever there is
# no error.
function sanity_check_registry(path)
registry = TOML.parsefile(joinpath(path, "Registry.toml"))
if VERSION >= v"1.7-"
registry = RegistryInstance(path)
return true
end
for (uuid, package) in registry["packages"]
package_path = joinpath(path, package["path"])
deps_file = joinpath(package_path, "Deps.toml")
compat_file = joinpath(package_path, "Compat.toml")
if isdefined(Pkg.Operations, :load_package_data_raw)
deps_data = Pkg.Operations.load_package_data_raw(Pkg.Types.UUID,
deps_file)
compat_data = Pkg.Operations.load_package_data_raw(Pkg.Types.VersionSpec,
compat_file)
else
ctx = Pkg.Types.Context()
version_info = Pkg.Operations.load_versions(ctx, package_path;
include_yanked = false)
versions = sort!(collect(keys(version_info)))
if applicable(Pkg.Operations.load_package_data,
Pkg.Types.UUID, deps_file, versions)
deps_data = Pkg.Operations.load_package_data(Pkg.Types.UUID,
deps_file, versions)
compat_data = Pkg.Operations.load_package_data(Pkg.Types.VersionSpec,
compat_file, versions)
else
deps_data = Pkg.Operations.load_package_data(ctx, Pkg.Types.UUID,
deps_file, versions)
compat_data = Pkg.Operations.load_package_data(ctx, Pkg.Types.VersionSpec,
compat_file, versions)
end
end
end
return true
end
function with_testdir(f::Function)
testdir = mktempdir(prefix = "LocalRegistryTests")
f(testdir)
rm(testdir, recursive = true)
end
function with_empty_registry(f::Function)
with_testdir() do testdir
registry_dir = joinpath(testdir, "TestRegistry")
packages_dir = joinpath(testdir, "packages")
# Create a new registry.
create_registry(registry_dir, "git@example.com:Julia/TestRegistry.git",
description = "For testing purposes only.",
uuid = "ed6ca2f6-392d-11ea-3224-d3daf7fee369",
gitconfig = TEST_GITCONFIG, push = false)
f(registry_dir, packages_dir)
end
end