|
1 | 1 | export supported_platforms, expand_gfortran_versions, expand_cxxstring_abis, expand_microarchitectures
|
2 | 2 |
|
3 |
| -using Pkg.Artifacts: load_artifacts_toml, ensure_all_artifacts_installed |
| 3 | +using Pkg.Artifacts: load_artifacts_toml, ensure_all_artifacts_installed, artifact_path |
4 | 4 | using Base.BinaryPlatforms: set_compare_strategy!, compare_version_cap
|
| 5 | +using REPL.TerminalMenus |
| 6 | +using Printf: @sprintf |
5 | 7 |
|
6 | 8 | # This is a type that encompasses a shard; it makes it easy to pass it around,
|
7 | 9 | # get its download url, extraction url, mounting url, etc...
|
@@ -1100,3 +1102,88 @@ function installed_shards()
|
1100 | 1102 |
|
1101 | 1103 | return all_compiler_shards()[idx]
|
1102 | 1104 | end
|
| 1105 | + |
| 1106 | +""" |
| 1107 | + manage_shards(; sort_by=:name, rev=false) |
| 1108 | +
|
| 1109 | +Open a prompt allowing a user to selectively remove downloaded compiler shards. |
| 1110 | +By default, the shards are sorted by name, alternatively you can sort them by |
| 1111 | +file size on disk by specifying `sort_by=:size`. With `rev=true` you can |
| 1112 | +reverse the sort order. |
| 1113 | +""" |
| 1114 | +function manage_shards(; sort_by=:name, rev=false) |
| 1115 | + # Get all installed shards |
| 1116 | + shards = installed_shards() |
| 1117 | + |
| 1118 | + # Obtain directory sizes for the artifacts |
| 1119 | + totalsizes = totalsize.(Artifacts.artifact_path.(shard_source_artifact_hash.(shards))) |
| 1120 | + |
| 1121 | + # Sort shards and totalsizes |
| 1122 | + if sort_by === :name |
| 1123 | + function isless_shards(a::CompilerShard, b::CompilerShard) |
| 1124 | + return isless((a.name, a.version, string(a.target), a.host, a.archive_type), |
| 1125 | + (b.name, b.version, string(b.target), b.host, b.archive_type)) |
| 1126 | + end |
| 1127 | + |
| 1128 | + perm = sortperm(shards; rev, lt=isless_shards) |
| 1129 | + elseif sort_by == :size |
| 1130 | + perm = sortperm(totalsizes; rev) |
| 1131 | + else |
| 1132 | + error("unsupported sort value: :$sort_by (allowed: :name, :size)") |
| 1133 | + end |
| 1134 | + shards .= shards[perm] |
| 1135 | + totalsizes .= totalsizes[perm] |
| 1136 | + |
| 1137 | + # Build menu items |
| 1138 | + menuitems = similar(shards, String) |
| 1139 | + for i in eachindex(shards, totalsizes) |
| 1140 | + menuitems[i] = @sprintf("(%5.3f GiB) %s", totalsizes[i] / 2^30, shards[i]) |
| 1141 | + end |
| 1142 | + |
| 1143 | + # Prompt user |
| 1144 | + ts = @sprintf("%5.3f", sum(totalsizes) / 2^30) |
| 1145 | + manage_shards_menu = TerminalMenus.request( |
| 1146 | + "Which compiler shards should be removed (total size on disk: $ts GiB)?", |
| 1147 | + TerminalMenus.MultiSelectMenu(menuitems; pagesize = 10, charset=:ascii) |
| 1148 | + ) |
| 1149 | + |
| 1150 | + # Handle no selection |
| 1151 | + if isempty(manage_shards_menu) |
| 1152 | + println("Removed 0 compiler shards.") |
| 1153 | + return nothing |
| 1154 | + end |
| 1155 | + |
| 1156 | + # Otherwise prompt for confirmation |
| 1157 | + println("\nThe following shards have been marked for removal:\n") |
| 1158 | + for item in menuitems[sort(Int.(manage_shards_menu))] |
| 1159 | + println(" ", item) |
| 1160 | + end |
| 1161 | + print("\nAre you sure that these should be removed? [Y/n]: ") |
| 1162 | + answer = lowercase(strip(readline())) |
| 1163 | + |
| 1164 | + # If removal is confirmed, deleting the relevant artifacts |
| 1165 | + if isempty(answer) || answer == "yes" || answer == "y" |
| 1166 | + Pkg.remove_artifact.(shard_source_artifact_hash.(shards[Int.(manage_shards_menu)])) |
| 1167 | + println("Removed ", length(manage_shards_menu), " compiler shards.") |
| 1168 | + else |
| 1169 | + println("Removed 0 compiler shards.") |
| 1170 | + end |
| 1171 | +end |
| 1172 | + |
| 1173 | +# Return total size on a disk of a file or directory |
| 1174 | +function totalsize(path) |
| 1175 | + if !isdir(path) |
| 1176 | + return filesize(path) |
| 1177 | + end |
| 1178 | + |
| 1179 | + total = 0 |
| 1180 | + for (root, dirs, files) in walkdir(path) |
| 1181 | + total += filesize(root) |
| 1182 | + |
| 1183 | + for file in files |
| 1184 | + total += filesize(joinpath(root, file)) |
| 1185 | + end |
| 1186 | + end |
| 1187 | + |
| 1188 | + return total |
| 1189 | +end |
0 commit comments