/// <summary> /// Download one Cocoapods package and extract it to the target directory. /// </summary> /// <param name="purl"> Package URL of the package to download. </param> /// <returns> n/a </returns> public override async Task <IEnumerable <string> > DownloadVersionAsync(PackageURL purl, bool doExtract, bool cached = false) { Logger.Trace("DownloadVersion {0}", purl?.ToString()); string? packageName = purl?.Name; string? packageVersion = purl?.Version; string? fileName = purl?.ToStringFilename(); List <string> downloadedPaths = new(); if (string.IsNullOrWhiteSpace(packageName) || string.IsNullOrWhiteSpace(packageVersion) || string.IsNullOrWhiteSpace(fileName)) { Logger.Debug("Error with 'purl' argument. Unable to download [{0} {1}] @ {2}. Both must be defined.", packageName, packageVersion, fileName); return(downloadedPaths); } HttpClient httpClient = CreateHttpClient(); string prefix = GetCocoapodsPrefix(packageName); System.Text.Json.JsonDocument podspec = await GetJsonCache(httpClient, $"{ENV_COCOAPODS_SPECS_RAW_ENDPOINT}/Specs/{prefix}/{packageName}/{packageVersion}/{packageName}.podspec.json"); if (podspec.RootElement.TryGetProperty("source", out System.Text.Json.JsonElement source)) { string?url = null; if (source.TryGetProperty("git", out System.Text.Json.JsonElement sourceGit) && source.TryGetProperty("tag", out System.Text.Json.JsonElement sourceTag)) { string?sourceGitString = sourceGit.GetString(); string?sourceTagString = sourceTag.GetString(); if (!string.IsNullOrWhiteSpace(sourceGitString) && sourceGitString.EndsWith(".git")) { sourceGitString = sourceGitString[0..^ 4];
/// <summary> /// Download one Cargo package and extract it to the target directory. /// </summary> /// <param name="purl"> Package URL of the package to download. </param> /// <returns> Path to the downloaded package </returns> public override async Task <IEnumerable <string> > DownloadVersionAsync(PackageURL purl, bool doExtract, bool cached = false) { Logger.Trace("DownloadVersion {0}", purl?.ToString()); string? packageName = purl?.Name; string? packageVersion = purl?.Version; string? fileName = purl?.ToStringFilename(); List <string> downloadedPaths = new(); if (string.IsNullOrWhiteSpace(packageName) || string.IsNullOrWhiteSpace(packageVersion) || string.IsNullOrWhiteSpace(fileName)) { Logger.Debug("Error with 'purl' argument. Unable to download [{0} {1}] @ {2}. Both must be defined.", packageName, packageVersion, fileName); return(downloadedPaths); } string url = $"{ENV_CARGO_ENDPOINT}/api/v1/crates/{packageName}/{packageVersion}/download"; try { string targetName = $"cargo-{fileName}"; string extractionPath = Path.Combine(TopLevelExtractionDirectory, targetName); // if the cache is already present, no need to extract if (doExtract && cached && Directory.Exists(extractionPath)) { downloadedPaths.Add(extractionPath); return(downloadedPaths); } Logger.Debug("Downloading {0}", url); HttpClient httpClient = CreateHttpClient(); System.Net.Http.HttpResponseMessage result = await httpClient.GetAsync(url); result.EnsureSuccessStatusCode(); if (doExtract) { downloadedPaths.Add(await ArchiveHelper.ExtractArchiveAsync(TopLevelExtractionDirectory, targetName, await result.Content.ReadAsStreamAsync(), cached)); } else { extractionPath += Path.GetExtension(url) ?? ""; await File.WriteAllBytesAsync(extractionPath, await result.Content.ReadAsByteArrayAsync()); downloadedPaths.Add(extractionPath); } } catch (Exception ex) { Logger.Debug(ex, "Error downloading Cargo package: {0}", ex.Message); } return(downloadedPaths); }
/// <summary> /// Downloads metadata if only metadata is requested; downloads and extracts the package if /// doExtract is requested /// </summary> /// <param name="_downloader"> </param> /// <param name="purl"> </param> /// <param name="metadataOnly"> </param> /// <param name="doExtract"> </param> /// <param name="cached"> </param> /// <returns> /// A list with /// 1) the name of the file if metadata requested /// 2) The name of the file if package download and no extraction is requested /// 3) The directory of the downloaded and extracted package, if extraction is requested /// </returns> public async Task <List <string> > Download( PackageURL purl, bool metadataOnly, bool doExtract) { List <string> downloadPaths = new List <string>(); if (packageManager != null) { if (metadataOnly) { var metadata = await packageManager.GetMetadata(purl); if (metadata != null) { var outputFilename = Path.Combine(packageManager.TopLevelExtractionDirectory, $"metadata-{purl.ToStringFilename()}"); // this will be effectively the same as above, if the cache doesnt exist if (!this.actualCaching) { while (File.Exists(outputFilename)) { outputFilename = Path.Combine(packageManager.TopLevelExtractionDirectory, $"metadata-{purl.ToStringFilename()}-{DateTime.Now.Ticks}"); } } File.WriteAllText(outputFilename, metadata); downloadPaths.Add(outputFilename); } } else { // only version download requests reach here downloadPaths.AddRange(await packageManager.DownloadVersion(purl, doExtract, this.actualCaching)); } } // Add the return values to our internal storage to be cleaned up later by CleanPackageLocalCopy this.downloadPaths.AddRange(downloadPaths); return(downloadPaths); }
public async Task <List <string> > Download(PackageURL purl, string destinationDirectory = null) { Logger.Trace("Download({0})", purl?.ToString()); var downloadPaths = new List <string>(); destinationDirectory ??= (string)Options["download-directory"] ?? "."; if (!Directory.Exists(destinationDirectory)) { Logger.Warn("Invalid directory, {0} does not exist.", destinationDirectory); return(new List <string>()); } // Use reflection to find the correct package management class var downloaderClass = typeof(BaseProjectManager).Assembly.GetTypes() .Where(type => type.IsSubclassOf(typeof(BaseProjectManager))) .Where(type => type.Name.Equals($"{purl.Type}ProjectManager", StringComparison.InvariantCultureIgnoreCase)) .FirstOrDefault(); if (downloaderClass != null) { var ctor = downloaderClass.GetConstructor(Array.Empty <Type>()); var _downloader = (BaseProjectManager)(ctor.Invoke(Array.Empty <object>())); _downloader.TopLevelExtractionDirectory = destinationDirectory; if ((bool)Options["download-metadata-only"]) { var metadata = await _downloader.GetMetadata(purl); if (metadata != default) { var outputFilename = Path.Combine(destinationDirectory, $"metadata-{purl.ToStringFilename()}"); while (File.Exists(outputFilename)) { outputFilename = Path.Combine(destinationDirectory, $"metadata-{purl.ToStringFilename()}-{DateTime.Now.Ticks}"); } File.WriteAllText(outputFilename, metadata); downloadPaths.Add(outputFilename); } } else { if (!bool.TryParse(Options["extract"]?.ToString(), out bool doExtract)) { doExtract = true; } downloadPaths = await _downloader.Download(purl, doExtract); } } else { throw new ArgumentException(string.Format("Invalid Package URL type: {0}", purl?.Type)); } return(downloadPaths); }