/** A package supplier using the registry server. Copyright: © 2012 Matthias Dondorff License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file. Authors: Matthias Dondorff */ module dub.registry; import dub.dependency; import dub.packagesupplier; import dub.utils; import vibe.core.file; import vibe.core.log; import vibe.data.json; import vibe.http.client; import vibe.http.fileserver; import vibe.http.router; import vibe.inet.url; import vibe.inet.urltransfer; import std.conv; import std.exception; import std.file; private const string PackagesPath = "packages"; /// Client PackageSupplier using the registry available via registerVpmRegistry class RegistryPS : PackageSupplier { this(Url registry) { m_registryUrl = registry; } void storePackage(const Path path, const string packageId, const Dependency dep) { Json best = bestPackage(packageId, dep); logDebug("Found dllinkg: '%s'", best["url"]); download(cast(string) best["url"], to!string(path)); } Json packageJson(const string packageId, const Dependency dep) { return bestPackage(packageId, dep); } private { Url m_registryUrl; Json[string] m_allMetadata; } private Json metadata(const string packageId) { if( auto json = packageId in m_allMetadata ) return *json; logTrace("Downloading metadata for %s", packageId); logTrace("Connecting to %s", m_registryUrl.host); auto client = new HttpClient; bool ssl = m_registryUrl.schema == "https"; ushort port = m_registryUrl.port != 0? m_registryUrl.port : ssl? 443 : 80; client.connect(m_registryUrl.host, port, ssl); auto res = client.request((req) { req.url = to!string(m_registryUrl.path ~ (PackagesPath ~ "/" ~ packageId ~ ".json")); logTrace("Requested '%s'", req.url); }); if(res.statusCode == 404) { logError("Could not get metadata for %s", packageId); throw new Exception("Could not get metadata for " ~ packageId); } string jsonData = cast(string)res.bodyReader.readAll(); Json json = parseJson(jsonData); m_allMetadata[packageId] = json; return json; } private Json bestPackage(const string packageId, const Dependency dep) { Json md = metadata(packageId); Json best = null; foreach(json; md["versions"]) { auto cur = Version(cast(string)json["version"]); if(dep.matches(cur) && (best == null || Version(cast(string)best["version"]) < cur)) best = json; } enforce(best != null); return best; } }