public IPackageMetadata ResolveSource(string workingDirectory, PackageRequestRef request) { return(new FolderPackageMetadata( request.Uri.Substring("local-template://".Length), PackageManager.PACKAGE_TYPE_TEMPLATE, (workingDirectoryAlt, metadata, folder, name, upgrade, source) => _sourcePackageResolve.Resolve(workingDirectoryAlt, metadata, folder, name, upgrade))); }
public IPackageMetadata ResolveSource(PackageRequestRef request) { return new FolderPackageMetadata( request.Uri.Substring("local-template://".Length), PackageManager.PACKAGE_TYPE_TEMPLATE, (metadata, folder, name, upgrade, source) => _sourcePackageResolve.Resolve(metadata, folder, name, upgrade)); }
public IPackageMetadata ResolveSource(PackageRequestRef request) { return(new GitPackageMetadata( NormalizeScheme(request.Uri), request.GitRef, PackageManager.PACKAGE_TYPE_LIBRARY, (metadata, folder, name, upgrade, source) => _sourcePackageResolve.Resolve(metadata, folder, name, upgrade))); }
public IPackageMetadata ResolveSource(PackageRequestRef request) { return(new GitPackageMetadata( request.Uri.Substring("local-template-git://".Length), request.GitRef, PackageManager.PACKAGE_TYPE_TEMPLATE, (metadata, folder, name, upgrade, source) => _sourcePackageResolve.Resolve(metadata, folder, name, upgrade))); }
public IPackageMetadata ResolveSource(PackageRequestRef request) { return new GitPackageMetadata( NormalizeScheme(request.Uri), request.GitRef, PackageManager.PACKAGE_TYPE_LIBRARY, (metadata, folder, name, upgrade, source) => _sourcePackageResolve.Resolve(metadata, folder, name, upgrade)); }
public IPackageMetadata ResolveSource(PackageRequestRef request) { string prefix, archiveType, packageType; if (request.Uri.StartsWith("local-lzma://")) { prefix = "local-lzma://"; archiveType = PackageManager.ARCHIVE_FORMAT_TAR_LZMA; packageType = PackageManager.PACKAGE_TYPE_LIBRARY; } else if (request.Uri.StartsWith("local-gzip://")) { prefix = "local-gzip://"; archiveType = PackageManager.ARCHIVE_FORMAT_TAR_GZIP; packageType = PackageManager.PACKAGE_TYPE_LIBRARY; } else if (request.Uri.StartsWith("local-tool-lzma://")) { prefix = "local-tool-lzma://"; archiveType = PackageManager.ARCHIVE_FORMAT_TAR_LZMA; packageType = PackageManager.PACKAGE_TYPE_GLOBAL_TOOL; } else if (request.Uri.StartsWith("local-tool-gzip://")) { prefix = "local-tool-gzip://"; archiveType = PackageManager.ARCHIVE_FORMAT_TAR_GZIP; packageType = PackageManager.PACKAGE_TYPE_GLOBAL_TOOL; } else { throw new InvalidOperationException("Unexpected prefix for local package URL " + request.Uri); } var localPackagePath = request.Uri.Substring(prefix.Length); if (!File.Exists(localPackagePath)) { throw new InvalidOperationException("Unable to find local package file " + localPackagePath + " on disk."); } return(new ProtobuildPackageMetadata( null, packageType, null, request.Platform, request.GitRef, archiveType, localPackagePath, (metadata, folder, name, upgrade, source) => { _binaryPackageResolve.Resolve(metadata, folder, name, upgrade); }, _binaryPackageResolve.GetProtobuildPackageBinary)); }
public IPackageMetadata ResolveSource(PackageRequestRef request) { string prefix, archiveType, packageType; if (request.Uri.StartsWith("local-lzma://")) { prefix = "local-lzma://"; archiveType = PackageManager.ARCHIVE_FORMAT_TAR_LZMA; packageType = PackageManager.PACKAGE_TYPE_LIBRARY; } else if (request.Uri.StartsWith("local-gzip://")) { prefix = "local-gzip://"; archiveType = PackageManager.ARCHIVE_FORMAT_TAR_GZIP; packageType = PackageManager.PACKAGE_TYPE_LIBRARY; } else if (request.Uri.StartsWith("local-tool-lzma://")) { prefix = "local-tool-lzma://"; archiveType = PackageManager.ARCHIVE_FORMAT_TAR_LZMA; packageType = PackageManager.PACKAGE_TYPE_GLOBAL_TOOL; } else if (request.Uri.StartsWith("local-tool-gzip://")) { prefix = "local-tool-gzip://"; archiveType = PackageManager.ARCHIVE_FORMAT_TAR_GZIP; packageType = PackageManager.PACKAGE_TYPE_GLOBAL_TOOL; } else { throw new InvalidOperationException("Unexpected prefix for local package URL " + request.Uri); } var localPackagePath = request.Uri.Substring(prefix.Length); if (!File.Exists(localPackagePath)) { throw new InvalidOperationException("Unable to find local package file " + localPackagePath + " on disk."); } return new ProtobuildPackageMetadata( null, packageType, null, request.Platform, request.GitRef, archiveType, localPackagePath, (metadata, folder, name, upgrade, source) => { _binaryPackageResolve.Resolve(metadata, folder, name, upgrade); }, _binaryPackageResolve.GetProtobuildPackageBinary); }
public IPackageMetadata ResolveSource(string workingDirectory, PackageRequestRef request) { return(new TransformedPackageMetadata( NormalizeScheme(request.Uri), PackageManager.PACKAGE_TYPE_LIBRARY, request.Platform, request.GitRef, _transformer, (workingDirectoryAlt, metadata, folder, name, upgrade, preferSource) => { _binaryPackageResolve.Resolve(workingDirectoryAlt, metadata, folder, name, upgrade); }, _binaryPackageResolve.GetProtobuildPackageBinary)); }
public IPackageMetadata ResolveSource(PackageRequestRef request) { return new TransformedPackageMetadata( NormalizeScheme(request.Uri), PackageManager.PACKAGE_TYPE_LIBRARY, request.Platform, request.GitRef, _transformer, (metadata, folder, name, upgrade, preferSource) => { _binaryPackageResolve.Resolve(metadata, folder, name, upgrade); }, _binaryPackageResolve.GetProtobuildPackageBinary); }
public IPackageMetadata ResolveSource(string workingDirectory, PackageRequestRef request) { var path = request.Uri.Substring("local-nuget-v3://".Length); string packageName; string packageType; string sourceCodeUrl; string version; string binaryFormat; string binaryUri; string commitHashForSourceResolve; // Figure out the package type by looking at the tags inside // the package's .nuspec file. using (var storer = ZipStorer.Open(path, FileAccess.Read)) { var entries = storer.ReadCentralDir(); var nuspecEntries = entries.Where( x => x.FilenameInZip.EndsWith(".nuspec") && !x.FilenameInZip.Contains("/") && !x.FilenameInZip.Contains("\\")).ToList(); if (nuspecEntries.Count != 0) { using (var stream = new MemoryStream()) { storer.ExtractFile(nuspecEntries[0], stream); stream.Seek(0, SeekOrigin.Begin); var document = new XmlDocument(); document.Load(stream); var ns = new XmlNamespaceManager(document.NameTable); ns.AddNamespace("x", "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"); packageName = document.SelectSingleNode("//x:id", ns)?.InnerText; version = document.SelectSingleNode("//x:version", ns)?.InnerText; var tags = document.SelectSingleNode("//x:tags", ns)?.InnerText?.Split(new[] { ' ' }) ?? new string[0]; packageType = PackageManager.PACKAGE_TYPE_LIBRARY; commitHashForSourceResolve = null; sourceCodeUrl = null; foreach (var tag in tags) { if (!string.IsNullOrWhiteSpace(tag)) { if (tag == "type=global-tool") { packageType = PackageManager.PACKAGE_TYPE_GLOBAL_TOOL; } else if (tag == "type=template") { packageType = PackageManager.PACKAGE_TYPE_TEMPLATE; } if (tag.StartsWith("commit=")) { commitHashForSourceResolve = tag.Substring("commit=".Length); } if (tag.StartsWith("git=")) { sourceCodeUrl = tag.Substring("git=".Length); } } } binaryUri = path; binaryFormat = PackageManager.ARCHIVE_FORMAT_NUGET_ZIP; } } else { throw new InvalidOperationException("NuGet package is missing nuspec file!"); } } return(new NuGet3PackageMetadata( null, packageName, packageType, sourceCodeUrl, request.Platform, version, binaryFormat, binaryUri, commitHashForSourceResolve, (workingDirectoryAlt, metadata, folder, name, upgrade, source) => { if (source == true) { _sourcePackageResolve.Resolve(workingDirectoryAlt, metadata, folder, name, upgrade); } else { _binaryPackageResolve.Resolve(workingDirectoryAlt, metadata, folder, name, upgrade); } })); }
public IPackageMetadata ResolveSource(string workingDirectory, PackageRequestRef request) { var baseUri = new Uri(request.Uri); var apiUri = new Uri(baseUri.ToString().TrimEnd('/') + "/api"); dynamic apiData = null; var performOnlineLookup = true; if (!request.ForceUpgrade && request.IsStaticReference) { performOnlineLookup = false; if (_packageRequestCache.IsCached(request.Uri)) { try { apiData = _packageRequestCache.GetCachedJsonObject(request.Uri); } catch (ExecEnvironment.SelfInvokeExitException) { throw; } catch { performOnlineLookup = true; } } else { performOnlineLookup = true; } } if (performOnlineLookup) { try { string jsonString; apiData = this.GetJSON(apiUri, out jsonString); if (apiData.has_error) { throw new InvalidOperationException((string)apiData.error); } try { _packageRequestCache.StoreCachedData(request.Uri, jsonString); } catch (IOException) { RedirectableConsole.WriteLine("WARNING: Unable to save cached result of request."); } } catch (Exception) { // Attempt to retrieve it from the lookup cache. if (_packageRequestCache.IsCached(request.Uri)) { var shouldThrow = false; try { apiData = _packageRequestCache.GetCachedJsonObject(request.Uri); } catch (ExecEnvironment.SelfInvokeExitException) { throw; } catch { shouldThrow = true; } if (shouldThrow) { throw; } } else { throw; } } } if (apiData == null) { throw new InvalidOperationException("apiData is null"); } var sourceUri = (string)apiData.result.package.gitUrl; var type = (string)apiData.result.package.type; if (!string.IsNullOrWhiteSpace(sourceUri)) { try { new Uri(sourceUri); } catch (ExecEnvironment.SelfInvokeExitException) { throw; } catch { throw new InvalidOperationException( "Received invalid Git URL when loading package from " + apiUri); } } else { RedirectableConsole.WriteLine("WARNING: This package does not have a source repository set."); } var downloadMap = new Dictionary <string, string>(); var archiveTypeMap = new Dictionary <string, string>(); var resolvedHash = new Dictionary <string, string>(); foreach (var ver in apiData.result.versions) { if (ver.platformName != request.Platform) { continue; } if (!downloadMap.ContainsKey(ver.versionName)) { downloadMap.Add(ver.versionName, ver.downloadUrl); archiveTypeMap.Add(ver.versionName, ver.archiveType); resolvedHash.Add(ver.versionName, ver.versionName); } } foreach (var branch in apiData.result.branches) { if (!downloadMap.ContainsKey(branch.versionName)) { continue; } if (!downloadMap.ContainsKey(branch.branchName)) { downloadMap.Add(branch.branchName, downloadMap[branch.versionName]); archiveTypeMap.Add(branch.branchName, archiveTypeMap[branch.versionName]); resolvedHash.Add(branch.branchName, branch.versionName); } } // Resolve Git reference to Git commit hash. var gitCommit = resolvedHash.ContainsKey(request.GitRef) ? resolvedHash[request.GitRef] : request.GitRef; if (string.IsNullOrWhiteSpace(sourceUri)) { // Normalize source URI value. sourceUri = null; } string fileUri, archiveType; if (!downloadMap.ContainsKey(gitCommit)) { if (string.IsNullOrWhiteSpace(sourceUri)) { throw new InvalidOperationException("Unable to resolve binary package for version \"" + request.GitRef + "\" and platform \"" + request.Platform + "\" and this package does not have a source repository"); } else { RedirectableConsole.WriteLine("Unable to resolve binary package for version \"" + request.GitRef + "\" and platform \"" + request.Platform + "\", falling back to source version"); fileUri = null; archiveType = null; } } else { fileUri = downloadMap[gitCommit]; archiveType = archiveTypeMap[gitCommit]; } return(new ProtobuildPackageMetadata( request.Uri, type, sourceUri, request.Platform, gitCommit, archiveType, fileUri, (workingDirectoryAlt, metadata, folder, name, upgrade, source) => { if (source == true) { _sourcePackageResolve.Resolve(workingDirectoryAlt, metadata, folder, name, upgrade); } else { _binaryPackageResolve.Resolve(workingDirectoryAlt, metadata, folder, name, upgrade); } }, _binaryPackageResolve.GetProtobuildPackageBinary)); }
public IPackageMetadata ResolveSource(string workingDirectory, PackageRequestRef request) { var components = request.Uri.Split(new[] { '|' }, 2); var repository = NormalizeScheme(components[0]); var packageName = components[1]; var version = request.GitRef; var semVerRegex = new Regex("^[0-9]\\.[0-9]\\.[0-9](\\-.*)?$"); var gitHashRegex = new Regex("^[0-9a-fA-F]{40}$"); var shouldQuerySourceRepository = false; if (semVerRegex.IsMatch(version)) { // This is a semantic version; leave as-is. } else if (gitHashRegex.IsMatch(version)) { // This is a Git hash, convert it to NuGet's semantic version. version = NuGetVersionHelper.CreateNuGetPackageVersion(version, request.Platform); } else { // This is a branch, or other kind of source reference. We need // to query the source repository to resolve it to a Git hash. shouldQuerySourceRepository = true; } string serviceJson; var serviceIndex = _packageRequestCache.TryGetOptionallyCachedJsonObject( repository, !request.ForceUpgrade, out serviceJson, id => GetData(new Uri(id))); string registrationsBaseUrl = null; foreach (var entry in serviceIndex.resources) { var entryType = (string)entry["@type"]; if (entryType == "RegistrationsBaseUrl") { registrationsBaseUrl = (string)entry["@id"]; } } if (registrationsBaseUrl == null) { throw new InvalidOperationException("Unable to locate RegistrationsBaseUrl service."); } var packageMetadataUrl = $"{registrationsBaseUrl.TrimEnd(new[] {'/'})}/{packageName.ToLowerInvariant()}/index.json"; string packageMetadataJson; var packageMetadata = _packageRequestCache.TryGetOptionallyCachedJsonObject( packageMetadataUrl, !request.ForceUpgrade && request.IsStaticReference, out packageMetadataJson, id => GetData(new Uri(id))); string latestPackageVersion = null; foreach (var item in packageMetadata.items) { if (latestPackageVersion == null || string.CompareOrdinal((string)item.upper, latestPackageVersion) > 0) { latestPackageVersion = item.upper; } } var packagesByVersionLock = new object(); var packagesByVersion = new Dictionary <string, dynamic>(); if (_hostPlatformDetector.DetectPlatform() == "Windows") { // Do this in parallel as we may need to make multiple HTTPS requests. Parallel.ForEach((IEnumerable <object>)packageMetadata.items, item => PopulatePackagesByVersion(packagesByVersionLock, packagesByVersion, (dynamic)item, request)); } else { // Parallelisation is not safe on this platform, do it sequentually. foreach (var item in packageMetadata.items) { PopulatePackagesByVersion(packagesByVersionLock, packagesByVersion, item, request); } } string packageType = PackageManager.PACKAGE_TYPE_LIBRARY; string sourceCodeUrl = null; string commitHashForSourceResolve = null; if (shouldQuerySourceRepository) { var lookupVersion = latestPackageVersion; if (!packagesByVersion.ContainsKey(lookupVersion) && packagesByVersion.ContainsKey(lookupVersion + "+git.unspecified")) { lookupVersion += "+git.unspecified"; } sourceCodeUrl = ExtractSourceRepository(packagesByVersion[lookupVersion]); packageType = ExtractPackageType(packagesByVersion[lookupVersion]); if (!string.IsNullOrWhiteSpace(sourceCodeUrl)) { if (sourceCodeUrl.StartsWith("git=")) { sourceCodeUrl = sourceCodeUrl.Substring("git=".Length); var performGitLsRemote = true; if (sourceCodeUrl.StartsWith("https://github.com/")) { try { // This is a GitHub repository. During the installation of Protobuild Manager (hosted on GitHub), we need // to resolve the latest version on NuGet, but we can't do this because Git may not be in the PATH or may // not be available. We still want developers to be able to install Protobuild Manager without Git on // their PATH (as they may have dedicated shells to use it), so we attempt to use the GitHub API to resolve // the commit hash first. string gitHubJsonInfo; var gitHubComponents = sourceCodeUrl.Substring("https://github.com/".Length).Split('/'); var gitHubOwner = gitHubComponents[0]; var gitHubRepo = gitHubComponents[1]; var gitHubApiUrl = "https://api.github.com/repos/" + gitHubOwner + "/" + gitHubRepo + "/branches/" + version; var gitHubJson = _packageRequestCache.TryGetOptionallyCachedJsonObject( gitHubApiUrl, !request.ForceUpgrade && request.IsStaticReference, out packageMetadataJson, id => { using (var client = new RetryableWebClient()) { client.SilentOnError = true; client.SetHeader("User-Agent", "Protobuild NuGet Lookup/v1.0"); client.SetHeader("Accept", "application/vnd.github.v3+json"); return(client.DownloadString(gitHubApiUrl)); } }); var commitHash = gitHubJson.commit.sha; if (!string.IsNullOrWhiteSpace(commitHash)) { // This is a match and we've found our Git hash to use. version = NuGetVersionHelper.CreateNuGetPackageVersion(commitHash.Trim(), request.Platform); commitHashForSourceResolve = commitHash.Trim(); performGitLsRemote = false; } } catch (Exception) { Console.WriteLine("NOTICE: Unable to lookup version information via GitHub API; falling back to 'git ls-remote'"); } } if (performGitLsRemote) { var heads = _packageRequestCache.TryGetOptionallyCachedData( "git:" + sourceCodeUrl, !request.ForceUpgrade && request.IsStaticReference, id => GitUtils.RunGitAndCapture( workingDirectory, null, "ls-remote --heads " + new Uri(sourceCodeUrl))); var lines = heads.Split(new string[] { "\r\n", "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { var sourceEntryComponents = line.Split('\t'); if (sourceEntryComponents.Length >= 2) { var branchName = sourceEntryComponents[1].Trim(); if (branchName.StartsWith("refs/heads/")) { branchName = branchName.Substring("refs/heads/".Length); } else { continue; } if (string.Equals(version, branchName, StringComparison.InvariantCulture)) { // This is a match and we've found our Git hash to use. version = NuGetVersionHelper.CreateNuGetPackageVersion( sourceEntryComponents[0].Trim(), request.Platform); commitHashForSourceResolve = sourceEntryComponents[0].Trim(); break; } } } } } else { throw new InvalidOperationException("Unknown source code repository type '" + sourceCodeUrl + "'"); } // If we fall out of this loop, we'll hit the next if statement and most likely fail. } } string binaryUri = null; string binaryFormat = null; if (!packagesByVersion.ContainsKey(version)) { if (string.IsNullOrWhiteSpace(sourceCodeUrl)) { throw new InvalidOperationException( "Unable to resolve binary package for version \"" + version + "\" and platform \"" + request.Platform + "\" and this package does not have a source repository"); } else { RedirectableConsole.WriteLine("Unable to resolve binary package for version \"" + version + "\" and platform \"" + request.Platform + "\", falling back to source version"); } } else { sourceCodeUrl = ExtractSourceRepository(packagesByVersion[version]); packageType = ExtractPackageType(packagesByVersion[version]); if (!string.IsNullOrWhiteSpace(sourceCodeUrl)) { if (sourceCodeUrl.StartsWith("git=")) { sourceCodeUrl = sourceCodeUrl.Substring("git=".Length); } else { throw new InvalidOperationException("Unknown source code repository type '" + sourceCodeUrl + "'"); } } if (commitHashForSourceResolve == null) { commitHashForSourceResolve = ExtractCommitHash(packagesByVersion[version]); } // packageContent may not be under catalogEntry; our best guess is that NuGet // moved it from the root to catalogEntry at some point in the past, but not // all of the registrations are updated with it under catalogEntry, e.g. RestSharp try { binaryUri = packagesByVersion[version].catalogEntry.packageContent; } catch { binaryUri = packagesByVersion[version].packageContent; } binaryFormat = PackageManager.ARCHIVE_FORMAT_NUGET_ZIP; } return(new NuGet3PackageMetadata( repository, packageName, packageType, sourceCodeUrl, request.Platform, version, binaryFormat, binaryUri, commitHashForSourceResolve, (workingDirectoryAlt, metadata, folder, name, upgrade, source) => { if (source == true) { _sourcePackageResolve.Resolve(workingDirectoryAlt, metadata, folder, name, upgrade); } else { _binaryPackageResolve.Resolve(workingDirectoryAlt, metadata, folder, name, upgrade); } })); }
private void PopulatePackagesByVersion(object packagesByVersionLock, Dictionary <string, object> packagesByVersion, dynamic item, PackageRequestRef request) { try { var subitems = item.items; lock (packagesByVersionLock) { foreach (var subitem in subitems) { packagesByVersion[(string)subitem.catalogEntry.version] = subitem; } } } catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException) { string subdocumentJson; dynamic subdocument; // We can cache this request even when we have non-static references if the cached // document has 64 items in it. This is because individual documents can only at // maximum have 64 items in them, so adding a version between two points will cause // new URLs to be generated (that won't have previously been cached). var idUrl = (string)item["@id"]; if (!request.ForceUpgrade && _packageRequestCache.IsCached(idUrl)) { try { subdocument = _packageRequestCache.GetCachedJsonObject(idUrl); if ((int)subdocument.count == 64) { // Use the persisted version in the cache since it will never change. lock (packagesByVersionLock) { foreach (var subitem in subdocument.items) { packagesByVersion[(string)subitem.catalogEntry.version] = subitem; } } return; } } catch { // Unable to parse or read cached data. Fallback to making the request again. } } // When NuGet packages have a lot of versions, the items list is in a seperate document. // Download the document for each group of versions. Ideally we would only download // the document we need, but for branches it's a little more complicated (we first need // to get the document for the latest version and then get the document for the resolved // version). For now, we just download each document as we need it. subdocument = _packageRequestCache.TryGetOptionallyCachedJsonObject( idUrl, !request.ForceUpgrade && request.IsStaticReference, out subdocumentJson, id => GetData(new Uri(id))); lock (packagesByVersionLock) { foreach (var subitem in subdocument.items) { packagesByVersion[(string)subitem.catalogEntry.version] = subitem; } } } }
public IPackageMetadata ResolveSource(PackageRequestRef request) { var baseUri = new Uri(request.Uri); var apiUri = new Uri(baseUri.ToString().TrimEnd('/') + "/api"); dynamic apiData = null; var performOnlineLookup = true; if (request.PreferCacheLookup) { performOnlineLookup = false; if (File.Exists(this.GetLookupCacheFilename(request.Uri))) { try { using (var reader = new StreamReader(this.GetLookupCacheFilename(request.Uri))) { apiData = JSON.ToDynamic(reader.ReadToEnd()); } } catch (ExecEnvironment.SelfInvokeExitException) { throw; } catch { performOnlineLookup = true; } } else { performOnlineLookup = true; } } if (performOnlineLookup) { try { string jsonString; apiData = this.GetJSON(apiUri, out jsonString); if (apiData.has_error) { throw new InvalidOperationException((string)apiData.error); } try { using (var writer = new StreamWriter(this.GetLookupCacheFilename(request.Uri))) { writer.Write(jsonString); } } catch (IOException ex) { Console.WriteLine("WARNING: Unable to save cached result of request."); } } catch (WebException) { // Attempt to retrieve it from the lookup cache. if (File.Exists(this.GetLookupCacheFilename(request.Uri))) { var shouldThrow = false; try { using (var reader = new StreamReader(this.GetLookupCacheFilename(request.Uri))) { apiData = JSON.ToDynamic(reader.ReadToEnd()); } } catch (ExecEnvironment.SelfInvokeExitException) { throw; } catch { shouldThrow = true; } if (shouldThrow) { throw; } } else { throw; } } catch (InvalidOperationException) { // Attempt to retrieve it from the lookup cache. if (File.Exists(this.GetLookupCacheFilename(request.Uri))) { var shouldThrow = false; try { using (var reader = new StreamReader(this.GetLookupCacheFilename(request.Uri))) { apiData = JSON.ToDynamic(reader.ReadToEnd()); } } catch (ExecEnvironment.SelfInvokeExitException) { throw; } catch { shouldThrow = true; } if (shouldThrow) { throw; } } else { throw; } } } if (apiData == null) { throw new InvalidOperationException("apiData is null"); } var sourceUri = (string)apiData.result.package.gitUrl; var type = (string)apiData.result.package.type; if (!string.IsNullOrWhiteSpace(sourceUri)) { try { new Uri(sourceUri); } catch (ExecEnvironment.SelfInvokeExitException) { throw; } catch { throw new InvalidOperationException( "Received invalid Git URL when loading package from " + apiUri); } } else { Console.WriteLine("WARNING: This package does not have a source repository set."); } var downloadMap = new Dictionary<string, string>(); var archiveTypeMap = new Dictionary<string, string>(); var resolvedHash = new Dictionary<string, string>(); foreach (var ver in apiData.result.versions) { if (ver.platformName != request.Platform) { continue; } if (!downloadMap.ContainsKey(ver.versionName)) { downloadMap.Add(ver.versionName, ver.downloadUrl); archiveTypeMap.Add(ver.versionName, ver.archiveType); resolvedHash.Add(ver.versionName, ver.versionName); } } foreach (var branch in apiData.result.branches) { if (!downloadMap.ContainsKey(branch.versionName)) { continue; } if (!downloadMap.ContainsKey(branch.branchName)) { downloadMap.Add(branch.branchName, downloadMap[branch.versionName]); archiveTypeMap.Add(branch.branchName, archiveTypeMap[branch.versionName]); resolvedHash.Add(branch.branchName, branch.versionName); } } // Resolve Git reference to Git commit hash. var gitCommit = resolvedHash.ContainsKey(request.GitRef) ? resolvedHash[request.GitRef] : request.GitRef; string fileUri, archiveType; if (!downloadMap.ContainsKey(gitCommit)) { if (string.IsNullOrWhiteSpace(sourceUri)) { throw new InvalidOperationException("Unable to resolve binary package for version \"" + request.GitRef + "\" and platform \"" + request.Platform + "\" and this package does not have a source repository"); } else { Console.WriteLine("Unable to resolve binary package for version \"" + request.GitRef + "\" and platform \"" + request.Platform + "\", falling back to source version"); fileUri = null; archiveType = null; } } else { fileUri = downloadMap[gitCommit]; archiveType = archiveTypeMap[gitCommit]; } return new ProtobuildPackageMetadata( request.Uri, type, sourceUri, request.Platform, gitCommit, archiveType, fileUri, (metadata, folder, name, upgrade, source) => { if (source == true) { _sourcePackageResolve.Resolve(metadata, folder, name, upgrade); } else { _binaryPackageResolve.Resolve(metadata, folder, name, upgrade); } }, _binaryPackageResolve.GetProtobuildPackageBinary); }