-
-
Notifications
You must be signed in to change notification settings - Fork 227
/
packagesupplier.d
127 lines (107 loc) · 4.32 KB
/
packagesupplier.d
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
module dub.packagesuppliers.packagesupplier;
public import dub.dependency : PackageName, Dependency, Version, VersionRange;
import dub.dependency : visit;
public import dub.internal.vibecompat.core.file : NativePath;
public import dub.internal.vibecompat.data.json : Json;
/**
Base interface for remote package suppliers.
Provides functionality necessary to query package versions, recipes and
contents.
*/
interface PackageSupplier {
/// Represents a single package search result.
static struct SearchResult { string name, description, version_; }
/// Returns a human-readable representation of the package supplier.
@property string description();
/** Retrieves a list of all available versions(/branches) of a package.
Throws: Throws an exception if the package name is not known, or if
an error occurred while retrieving the version list.
*/
deprecated("Use `getVersions(PackageName)` instead")
final Version[] getVersions(string name)
{
return this.getVersions(PackageName(name));
}
Version[] getVersions(in PackageName name);
/** Downloads a package and returns its binary content
Params:
name = Name of the package to retrieve
dep = Version constraint to match against
pre_release = If true, matches the latest pre-release version.
Otherwise prefers stable versions.
*/
ubyte[] fetchPackage(in PackageName name, in VersionRange dep,
bool pre_release);
deprecated("Use `writeFile(path, fetchPackage(PackageName, VersionRange, bool))` instead")
final void fetchPackage(in NativePath path, in PackageName name,
in VersionRange dep, bool pre_release)
{
import dub.internal.vibecompat.core.file : writeFile;
if (auto res = this.fetchPackage(name, dep, pre_release))
writeFile(path, res);
}
deprecated("Use `fetchPackage(NativePath, PackageName, VersionRange, bool)` instead")
final void fetchPackage(NativePath path, string name, Dependency dep, bool pre_release)
{
return dep.visit!(
(const VersionRange rng) {
return this.fetchPackage(path, PackageName(name), rng, pre_release);
}, (any) {
assert(0, "Trying to fetch a package with a non-version dependency: " ~ any.toString());
},
);
}
/** Retrieves only the recipe of a particular package.
Params:
package_id = Name of the package of which to retrieve the recipe
dep = Version constraint to match against
pre_release = If true, matches the latest pre-release version.
Otherwise prefers stable versions.
*/
Json fetchPackageRecipe(in PackageName name, in VersionRange dep, bool pre_release);
deprecated("Use `fetchPackageRecipe(PackageName, VersionRange, bool)` instead")
final Json fetchPackageRecipe(string name, Dependency dep, bool pre_release)
{
return dep.visit!(
(const VersionRange rng) {
return this.fetchPackageRecipe(PackageName(name), rng, pre_release);
}, (any) {
return Json.init;
},
);
}
/** Searches for packages matching the given search query term.
Search queries are currently a simple list of words separated by
white space. Results will get ordered from best match to worst.
*/
SearchResult[] searchPackages(string query);
}
// TODO: Could drop the "best package" behavior and let retrievePackage/
// getPackageDescription take a Version instead of Dependency. But note
// this means that two requests to the registry are necessary to retrieve
// a package recipe instead of one (first get version list, then the
// package recipe)
package Json getBestPackage(Json metadata, in PackageName name,
in VersionRange dep, bool pre_release)
{
import std.exception : enforce;
import std.format : format;
if (metadata.type == Json.Type.null_)
return metadata;
Json best = null;
Version bestver;
foreach (json; metadata["versions"]) {
auto cur = Version(json["version"].get!string);
if (!dep.matches(cur)) continue;
if (best == null) best = json;
else if (pre_release) {
if (cur > bestver) best = json;
} else if (bestver.isPreRelease) {
if (!cur.isPreRelease || cur > bestver) best = json;
} else if (!cur.isPreRelease && cur > bestver) best = json;
bestver = Version(cast(string)best["version"]);
}
enforce(best != null,
"No package candidate found for %s@%s".format(name.main, dep));
return best;
}