public Stream GetPackageFileStream(UniversalPackageId id, UniversalPackageVersion version, string filePath) { Stream packageStream = null; ZipArchive zip = null; try { packageStream = this.GetPackageStream(id, version); if (packageStream == null) { return(null); } zip = new ZipArchive(packageStream, ZipArchiveMode.Read); var entry = zip.GetEntry(filePath); if (entry == null) { return(null); } return(new ZipEntryStream(entry.Open(), zip)); } catch { zip?.Dispose(); packageStream?.Dispose(); throw; } }
internal RemoteUniversalPackage(JObject obj) { var group = (string)obj["group"]; var name = (string)obj["name"]; if (string.IsNullOrEmpty(name)) { throw new FormatException("Missing \"name\" property."); } this.FullName = new UniversalPackageId(group, name); var latestVersion = (string)obj["latestVersion"]; if (string.IsNullOrEmpty(latestVersion)) { throw new FormatException("Missing \"latestVersion\" property."); } this.LatestVersion = UniversalPackageVersion.Parse(latestVersion); this.Title = (string)obj["title"]; this.Icon = (string)obj["icon"]; this.Description = (string)obj["description"]; this.Downloads = (int?)obj["downloads"] ?? 0; this.AllVersions = Array.AsReadOnly(((JArray)obj["versions"]).Select(t => UniversalPackageVersion.Parse((string)t)).ToArray()); this.AllProperties = new ReadOnlyDictionary <string, object>((IDictionary <string, object>)obj.ToObject(typeof(Dictionary <string, object>))); }
public static async Task RunAsync(UniversalPackage package, string script, bool simulate) { PackageId = new UniversalPackageId(package.Group, package.Name); PackageVersion = package.Version; await ExtensionsManager.WaitForInitializationAsync().ConfigureAwait(false); var tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); try { Directory.CreateDirectory(tempPath); Console.WriteLine("Extracting package..."); await package.ExtractAllItemsAsync(tempPath, default); var installScriptFileName = Path.Combine(tempPath, script); var installScript = Compile(installScriptFileName); if (installScript == null) { throw new RompException($"Unable to compile {script}."); } PackageRootPath = tempPath; await RunPlanAsync(installScript, simulate); } finally { Console.WriteLine("Cleaning up..."); try { Directory.Delete(tempPath, true); } catch { } } }
/// <summary> /// Copies data from a stream to a cached package file in the registry. /// </summary> /// <param name="packageId">The ID of the package to cache.</param> /// <param name="packageVersion">The version of the package to cache.</param> /// <param name="packageStream">Stream backed by the package to cache.</param> /// <param name="cancellationToken">Token used to cancel the operation.</param> /// <exception cref="ArgumentNullException"><paramref name="packageId"/> is null or <paramref name="packageVersion"/> is null.</exception> public async Task WriteToCacheAsync(UniversalPackageId packageId, UniversalPackageVersion packageVersion, Stream packageStream, CancellationToken cancellationToken) { if (packageId == null) { throw new ArgumentNullException(nameof(packageId)); } if (packageVersion == null) { throw new ArgumentNullException(nameof(packageVersion)); } if (packageStream == null) { throw new ArgumentNullException(nameof(packageStream)); } var fileName = this.GetCachedPackagePath(packageId, packageVersion, true); try { using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None, 4096, FileOptions.Asynchronous | FileOptions.SequentialScan)) { await packageStream.CopyToAsync(fileStream, 81920, cancellationToken); } } catch (OperationCanceledException) { File.Delete(fileName); throw; } }
internal RemoteUniversalPackageVersion(JObject obj) { var group = (string)obj["group"]; var name = (string)obj["name"]; if (string.IsNullOrEmpty(name)) { throw new FormatException("Missing \"name\" property."); } this.FullName = new UniversalPackageId(group, name); var version = (string)obj["version"]; if (string.IsNullOrEmpty(version)) { throw new FormatException("Missing \"version\" property."); } this.Version = UniversalPackageVersion.Parse(version); this.Title = (string)obj["title"]; this.Icon = (string)obj["icon"]; this.Description = (string)obj["description"]; this.Size = (long?)obj["size"] ?? 0; this.PublishedDate = (DateTimeOffset)obj["published"]; this.Downloads = (int?)obj["downloads"] ?? 0; var sha1String = (string)obj["sha1"]; if (!string.IsNullOrEmpty(sha1String)) { this.SHA1 = HexString.Parse(sha1String); } this.AllProperties = new ReadOnlyDictionary <string, object>((IDictionary <string, object>)obj.ToObject(typeof(Dictionary <string, object>))); }
private async Task <UniversalPackageMetadata> GetMetadataToMergeAsync() { if (string.IsNullOrWhiteSpace(this.Manifest)) { return(new UniversalPackageMetadata { Group = this.Group, Name = this.Name, Version = UniversalPackageVersion.TryParse(this.NewVersion), Title = this.Title, Description = this.PackageDescription, Icon = this.IconUrl }); } else { try { using (var metadataStream = File.OpenRead(this.Manifest)) { return(await ReadManifestAsync(metadataStream)); } } catch (Exception ex) { throw new UpackException($"The manifest file '{this.Manifest}' does not exist or could not be opened.", ex); } } }
internal static async Task <UniversalPackageVersion> GetVersionAsync(UniversalFeedClient client, UniversalPackageId id, string version, bool prerelease, CancellationToken cancellationToken) { if (!string.IsNullOrEmpty(version) && !string.Equals(version, "latest", StringComparison.OrdinalIgnoreCase) && !prerelease) { var parsed = UniversalPackageVersion.TryParse(version); if (parsed != null) { return(parsed); } throw new UpackException($"Invalid UPack version number: {version}"); } IReadOnlyList <RemoteUniversalPackageVersion> versions; try { versions = await client.ListPackageVersionsAsync(id, false, null, cancellationToken); } catch (WebException ex) { throw ConvertWebException(ex); } if (!versions.Any()) { throw new UpackException($"No versions of package {id} found."); } return(versions.Max(v => v.Version)); }
/// <summary> /// Returns a stream backed by the specified cached package if possible; returns <c>null</c> if /// the package was not found in the cache. /// </summary> /// <param name="packageId">The ID of the package to open.</param> /// <param name="packageVersion">The version of the package to open.</param> /// <param name="cancellationToken">Token used to cancel the operation.</param> /// <returns>Stream backed by the specified cached package, or null if the package was not found.</returns> /// <exception cref="ArgumentNullException"><paramref name="packageId"/> is null or <paramref name="packageVersion"/> is null.</exception> public Task <Stream> TryOpenFromCacheAsync(UniversalPackageId packageId, UniversalPackageVersion packageVersion, CancellationToken cancellationToken) { if (packageId == null) { throw new ArgumentNullException(nameof(packageId)); } if (packageVersion == null) { throw new ArgumentNullException(nameof(packageVersion)); } var fileName = this.GetCachedPackagePath(packageId, packageVersion); if (!File.Exists(fileName)) { return(Task.FromResult <Stream>(null)); } try { return(Task.FromResult <Stream>(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete))); } catch (IOException) { // The File.Exists check above should handle most instances of this, but there is still // the possibility of a race condition if the file gets deleted before it is opened. return(Task.FromResult <Stream>(null)); } }
private bool ParseOption(ArgOption o) { if (string.Equals("source", o.Key, StringComparison.OrdinalIgnoreCase)) { if (string.IsNullOrWhiteSpace(o.Value)) { throw new RompException("Expected source name or URL after --source="); } if (o.Value.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || o.Value.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) { this.Source = new UniversalFeedEndpoint(o.Value, true); } else { var source = RompDb.GetPackageSources() .FirstOrDefault(s => string.Equals(s.Name, o.Value, StringComparison.OrdinalIgnoreCase)); if (source == null) { throw new RompException($"Package source \"{o.Value}\" not found."); } if (string.IsNullOrEmpty(source.UserName) || source.Password == null) { this.Source = new UniversalFeedEndpoint(source.FeedUrl, true); } else { this.Source = new UniversalFeedEndpoint(new Uri(source.FeedUrl), source.UserName, source.Password); } } return(true); } else if (string.Equals("version", o.Key, StringComparison.OrdinalIgnoreCase)) { if (string.IsNullOrWhiteSpace(o.Value)) { throw new RompException("Expected package version after --version="); } try { this.PackageVersion = UniversalPackageVersion.Parse(o.Value); } catch (Exception ex) { throw new RompException("Invalid version: " + o.Value, ex); } return(true); } return(false); }
/// <summary> /// Deletes the specified package from the package cache. /// </summary> /// <param name="packageId">The ID of the package to delete.</param> /// <param name="packageVersion">The version of the package to delete.</param> /// <param name="cancellationToken">Token used to cancel the operation.</param> /// <exception cref="ArgumentNullException"><paramref name="packageId"/> is null or <paramref name="packageVersion"/> is null.</exception> /// <remarks> /// No exception is raised if the package was not in the cache to begin with. /// </remarks> public Task DeleteFromCacheAsync(UniversalPackageId packageId, UniversalPackageVersion packageVersion, CancellationToken cancellationToken) { if (packageId == null) { throw new ArgumentNullException(nameof(packageId)); } if (packageVersion == null) { throw new ArgumentNullException(nameof(packageVersion)); } File.Delete(this.GetCachedPackagePath(packageId, packageVersion)); return(AH.CompletedTask); }
private static JObject GetMungedPackage(IEnumerable <PackageFile> packageVersions) { var sorted = (from p in packageVersions let v = UniversalPackageVersion.Parse((string)p.JObject["version"]) orderby v descending select p).ToList(); var latest = (JObject)sorted.First().JObject.DeepClone(); latest["latestVersion"] = latest["version"]; latest.Remove("version"); latest["versions"] = new JArray(sorted.Select(v => (string)v.JObject["version"])); return(latest); }
private string GetCachedPackagePath(UniversalPackageId id, UniversalPackageVersion version, bool ensureDirectory = false) { var directoryName = id.Group?.Replace('/', '$')?.Trim('$') + "$" + id.Name; var fullPath = Path.Combine(this.RegistryRoot, "packageCache", directoryName); if (ensureDirectory) { Directory.CreateDirectory(fullPath); } var fileName = Path.Combine(fullPath, $"{id.Name}-{version}.upack"); return(Path.Combine(fullPath, fileName)); }
public override async Task <int> RunAsync(CancellationToken cancellationToken) { var client = CreateClient(this.SourceUrl, this.Authentication); UniversalPackageId packageId; try { packageId = UniversalPackageId.Parse(this.PackageName); } catch (ArgumentException ex) { throw new UpackException("Invalid package ID: " + ex.Message, ex); } UniversalPackageVersion version = null; if (!string.IsNullOrEmpty(this.Version)) { version = UniversalPackageVersion.TryParse(this.Version); if (version == null) { throw new UpackException($"Invalid UPack version number: {this.Version}"); } } JObject data; using (var stream = await client.GetPackageFileStreamAsync(packageId, version, string.IsNullOrEmpty(this.FilePath) ? "upack.json" : this.FilePath, cancellationToken)) using (var reader = new StreamReader(stream, Encoding.UTF8, true, 4096, true)) using (var jsonReader = new JsonTextReader(reader) { CloseInput = false }) { data = await JObject.LoadAsync(jsonReader, cancellationToken); } foreach (var p in data.Properties()) { Console.WriteLine($"{p.Name} = {p.Value}"); } return(0); }
/// <summary> /// Returns a stream containing the file at the specified path in the specified package if it is available; otherwise null. /// </summary> /// <param name="id">Full name of the package.</param> /// <param name="version">Version of the package. Specify null for the latest version.</param> /// <param name="cancellationToken">Cancellation token for asynchronous operations.</param> /// <param name="filePath">Path of the file inside the package.</param> /// <returns>Stream containing the specified package if it is available; otherwise null.</returns> /// <exception cref="ArgumentNullException"><paramref name="id"/> is null.</exception> /// <remarks> /// The stream returned by this method is not buffered at all. If random access is required, the caller must /// first copy it to another stream. /// </remarks> public async Task <Stream> GetPackageFileStreamAsync(UniversalPackageId id, UniversalPackageVersion version, string filePath, CancellationToken cancellationToken) { if (id == null) { throw new ArgumentNullException(nameof(id)); } if (string.IsNullOrEmpty(filePath)) { throw new ArgumentNullException(nameof(filePath)); } if (this.Endpoint.IsLocalDirectory) { return(this.localRepository.Value.GetPackageFileStream(id, version, filePath)); } var url = "download-file/" + Uri.EscapeUriString(id.ToString()); if (version != null) { url += "/" + Uri.EscapeUriString(version.ToString()) + "?path=" + Uri.EscapeDataString(filePath); } else { url += "?latest&path=" + Uri.EscapeDataString(filePath); } var request = new ApiRequest(this.Endpoint, url); var response = await this.transport.GetResponseAsync(request, cancellationToken).ConfigureAwait(false); try { return(response.GetResponseStream()); } catch { response?.Dispose(); throw; } }
public Stream GetPackageStream(UniversalPackageId id, UniversalPackageVersion version) { var packageVersions = this.allPackages.Value[new PackageKey(id.Group, id.Name)]; var match = default(PackageFile); if (version == null) { match = packageVersions.OrderByDescending(p => UniversalPackageVersion.Parse((string)p.JObject["version"])).FirstOrDefault(); } else { var s = version.ToString(); match = packageVersions.FirstOrDefault(p => string.Equals((string)p.JObject["version"], s, StringComparison.OrdinalIgnoreCase)); } if (match.IsNull) { return(null); } return(new FileStream(match.FileName, FileMode.Open, FileAccess.Read, FileShare.Read)); }
/// <summary> /// Deletes the specified package from the remote feed. /// </summary> /// <param name="id">Full name of the package.</param> /// <param name="version">Version of the package.</param> /// <param name="cancellationToken">Cancellation token for asynchronous operations.</param> /// <exception cref="ArgumentNullException"><paramref name="id"/> is null or <paramref name="version"/> is null.</exception> public async Task DeletePackageAsync(UniversalPackageId id, UniversalPackageVersion version, CancellationToken cancellationToken) { if (id == null) { throw new ArgumentNullException(nameof(id)); } if (version == null) { throw new ArgumentNullException(nameof(version)); } if (this.Endpoint.IsLocalDirectory) { throw new NotSupportedException(); } var url = "delete/" + Uri.EscapeUriString(id.ToString()) + "/" + Uri.EscapeUriString(version.ToString()); var request = new ApiRequest(this.Endpoint, url, method: "DELETE"); using (var response = await this.transport.GetResponseAsync(request, cancellationToken).ConfigureAwait(false)) { } }
private void VerifyAndPopulate(Stream stream) { using (var package = open()) { var id = new UniversalPackageId(package.Group, package.Name); if (this.PackageId == null) { this.PackageId = id; } else if (this.PackageId != id) { throw new RompException("Package has an unexpected ID."); } if (this.PackageVersion == null) { this.PackageVersion = package.Version; } else if (this.PackageVersion != package.Version) { throw new RompException("Package has an unexpected version."); } } UniversalPackage open() { try { return(new UniversalPackage(stream, true)); } catch (Exception ex) { throw new RompException("Invalid package: " + ex.Message, ex); } } }
/// <summary> /// Returns a stream containing the file at the specified path in the specified package if it is available; otherwise null. /// </summary> /// <param name="id">Full name of the package.</param> /// <param name="version">Version of the package. Specify null for the latest version.</param> /// <param name="filePath">Path of the file inside the package.</param> /// <returns>Stream containing the specified package if it is available; otherwise null.</returns> /// <exception cref="ArgumentNullException"><paramref name="id"/> is null.</exception> /// <remarks> /// The stream returned by this method is not buffered at all. If random access is required, the caller must /// first copy it to another stream. /// </remarks> public Task <Stream> GetPackageFileStreamAsync(UniversalPackageId id, UniversalPackageVersion version, string filePath) => this.GetPackageFileStreamAsync(id, version, filePath, default);
/// <summary> /// Returns a stream containing the specified package if it is available; otherwise null. /// </summary> /// <param name="id">Full name of the package.</param> /// <param name="version">Version of the package. Specify null for the latest version.</param> /// <returns>Stream containing the specified package if it is available; otherwise null.</returns> /// <exception cref="ArgumentNullException"><paramref name="id"/> is null.</exception> /// <remarks> /// The stream returned by this method is not buffered at all. If random access is required, the caller must /// first copy it to another stream. /// </remarks> public Task <Stream> GetPackageStreamAsync(UniversalPackageId id, UniversalPackageVersion version) => this.GetPackageStreamAsync(id, version, default);
/// <summary> /// Returns metadata for a specific version of a package, or null if the package was not found. /// </summary> /// <param name="id">Full name of the package.</param> /// <param name="version">Version of the package.</param> /// <param name="includeFileList">Value indicating whether a list of files inside the package should be included. This will incur additional overhead.</param> /// <param name="cancellationToken">Cancellation token for asynchronous operations.</param> /// <exception cref="ArgumentNullException"><paramref name="id"/> is null or <paramref name="version"/> is null.</exception> /// <returns>Package vesion metadata if it was found; otherwise null.</returns> public async Task <RemoteUniversalPackageVersion> GetPackageVersionAsync(UniversalPackageId id, UniversalPackageVersion version, bool includeFileList, CancellationToken cancellationToken) { if (id == null) { throw new ArgumentNullException(nameof(id)); } if (version == null) { throw new ArgumentNullException(nameof(version)); } var results = await this.ListVersionsInternalAsync(id, version, includeFileList, null, cancellationToken).ConfigureAwait(false); return(results.FirstOrDefault()); }
/// <summary> /// Returns metadata for a specific version of a package, or null if the package was not found. /// </summary> /// <param name="id">Full name of the package.</param> /// <param name="version">Version of the package.</param> /// <param name="includeFileList">Value indicating whether a list of files inside the package should be included. This will incur additional overhead.</param> /// <exception cref="ArgumentNullException"><paramref name="id"/> is null or <paramref name="version"/> is null.</exception> /// <returns>Package vesion metadata if it was found; otherwise null.</returns> public Task <RemoteUniversalPackageVersion> GetPackageVersionAsync(UniversalPackageId id, UniversalPackageVersion version, bool includeFileList) => this.GetPackageVersionAsync(id, version, includeFileList, default);
/// <summary> /// Returns metadata for a specific version of a package, or null if the package was not found. /// </summary> /// <param name="id">Full name of the package.</param> /// <param name="version">Version of the package.</param> /// <exception cref="ArgumentNullException"><paramref name="id"/> is null or <paramref name="version"/> is null.</exception> /// <returns>Package vesion metadata if it was found; otherwise null.</returns> public Task <RemoteUniversalPackageVersion> GetPackageVersionAsync(UniversalPackageId id, UniversalPackageVersion version) => this.GetPackageVersionAsync(id, version, false, default);
/// <summary> /// Deletes the specified package from the package cache. /// </summary> /// <param name="packageId">The ID of the package to delete.</param> /// <param name="packageVersion">The version of the package to delete.</param> /// <exception cref="ArgumentNullException"><paramref name="packageId"/> is null or <paramref name="packageVersion"/> is null.</exception> /// <remarks> /// No exception is raised if the package was not in the cache to begin with. /// </remarks> public Task DeleteFromCacheAsync(UniversalPackageId packageId, UniversalPackageVersion packageVersion) => this.DeleteFromCacheAsync(packageId, packageVersion, default);
private async Task <IReadOnlyList <RemoteUniversalPackageVersion> > ListVersionsInternalAsync(UniversalPackageId id, UniversalPackageVersion version, bool includeFileList, int?maxCount, CancellationToken cancellationToken) { if (this.Endpoint.IsLocalDirectory) { if (version == null) { return(this.localRepository.Value.ListPackageVersions(id).ToList()); } else { var v = this.localRepository.Value.GetPackageVersion(id, version); return(v != null ? new[] { v } : new RemoteUniversalPackageVersion[0]); } } var url = FormatUrl("versions", ("group", id?.Group), ("name", id?.Name), ("version", version?.ToString()), ("includeFileList", includeFileList), ("count", maxCount)); var request = new ApiRequest(this.Endpoint, url); using (var response = await this.transport.GetResponseAsync(request, cancellationToken).ConfigureAwait(false)) { if (response.ContentType?.StartsWith("application/json", StringComparison.OrdinalIgnoreCase) != true) { throw new InvalidDataException($"Server returned {response.ContentType} content type; expected application/json."); } using (var responseStream = response.GetResponseStream()) using (var reader = new StreamReader(responseStream, AH.UTF8)) using (var jsonReader = new JsonTextReader(reader)) { if (version == null) { var arr = await JArray.LoadAsync(jsonReader, cancellationToken).ConfigureAwait(false); var results = new List <RemoteUniversalPackageVersion>(arr.Count); foreach (var token in arr) { if (!(token is JObject obj)) { throw new InvalidDataException("Unexpected token in JSON array."); } results.Add(new RemoteUniversalPackageVersion(obj)); } return(results.AsReadOnly()); } else { var obj = await JObject.LoadAsync(jsonReader, cancellationToken).ConfigureAwait(false); return(new[] { new RemoteUniversalPackageVersion(obj) }); } } } }
public override async Task <int> RunAsync(CancellationToken cancellationToken) { if (this.NoAudit && !string.IsNullOrEmpty(this.Note)) { Console.Error.WriteLine("--no-audit cannot be used with --note."); return(2); } UniversalPackageMetadata info; if (string.IsNullOrWhiteSpace(this.Manifest)) { info = new UniversalPackageMetadata { Group = this.Group, Name = this.Name, Version = UniversalPackageVersion.TryParse(this.Version), Title = this.Title, Description = this.PackageDescription, Icon = this.IconUrl }; } else { if (!File.Exists(this.Manifest)) { Console.Error.WriteLine($"The manifest file '{this.Manifest}' does not exist."); return(2); } using (var metadataStream = File.OpenRead(this.Manifest)) { info = await ReadManifestAsync(metadataStream); } } var error = ValidateManifest(info); if (error != null) { Console.Error.WriteLine("Invalid {0}: {1}", string.IsNullOrWhiteSpace(this.Manifest) ? "parameters" : "upack.json", error); return(2); } PrintManifest(info); if (!this.NoAudit) { info["createdDate"] = DateTime.UtcNow.ToString("u"); if (!string.IsNullOrEmpty(this.Note)) { info["createdReason"] = this.Note; } info["createdUsing"] = "upack/" + typeof(Pack).Assembly.GetName().Version.ToString(3); info["createdBy"] = Environment.UserName; } if (!Directory.Exists(this.SourcePath) && !File.Exists(this.SourcePath)) { Console.Error.WriteLine($"The source directory '{this.SourcePath}' does not exist."); return(2); } string relativePackageFileName = $"{info.Name}-{info.Version.Major}.{info.Version.Minor}.{info.Version.Patch}.upack"; string targetFileName = Path.Combine(this.TargetDirectory ?? Environment.CurrentDirectory, relativePackageFileName); if (File.Exists(Path.Combine(this.SourcePath, relativePackageFileName))) { Console.Error.WriteLine("Warning: output file already exists in source directory and may be included inadvertently in the package contents."); } string tmpPath = Path.GetTempFileName(); using (var builder = new UniversalPackageBuilder(tmpPath, info)) { if (Directory.Exists(this.SourcePath)) { await builder.AddContentsAsync( this.SourcePath, "/", true, s => string.IsNullOrWhiteSpace(this.Manifest) || !string.Equals(s, "upack.json", StringComparison.OrdinalIgnoreCase), cancellationToken ); } else { using (var file = File.Open(this.SourcePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { await builder.AddFileAsync(file, Path.GetFileName(this.SourcePath), File.GetLastWriteTimeUtc(this.SourcePath), cancellationToken); } } } Directory.CreateDirectory(Path.GetDirectoryName(targetFileName)); File.Delete(targetFileName); File.Move(tmpPath, targetFileName); return(0); }
/// <summary> /// Deletes the specified package from the remote feed. /// </summary> /// <param name="id">Full name of the package.</param> /// <param name="version">Version of the package.</param> /// <exception cref="ArgumentNullException"><paramref name="id"/> is null or <paramref name="version"/> is null.</exception> public Task DeletePackageAsync(UniversalPackageId id, UniversalPackageVersion version) => this.DeletePackageAsync(id, version, default);
/// <summary> /// Copies data from a stream to a cached package file in the registry. /// </summary> /// <param name="packageId">The ID of the package to cache.</param> /// <param name="packageVersion">The version of the package to cache.</param> /// <param name="packageStream">Stream backed by the package to cache.</param> /// <exception cref="ArgumentNullException"><paramref name="packageId"/> is null or <paramref name="packageVersion"/> is null.</exception> public Task WriteToCacheAsync(UniversalPackageId packageId, UniversalPackageVersion packageVersion, Stream packageStream) => this.WriteToCacheAsync(packageId, packageVersion, packageStream, default);
/// <summary> /// Returns a stream backed by the specified cached package if possible; returns <c>null</c> if /// the package was not found in the cache. /// </summary> /// <param name="packageId">The ID of the package to open.</param> /// <param name="packageVersion">The version of the package to open.</param> /// <returns>Stream backed by the specified cached package, or null if the package was not found.</returns> public Task <Stream> TryOpenFromCacheAsync(UniversalPackageId packageId, UniversalPackageVersion packageVersion) => this.TryOpenFromCacheAsync(packageId, packageVersion, default);
public override async Task <int> RunAsync(CancellationToken cancellationToken) { var client = CreateClient(this.SourceUrl, this.Authentication); UniversalPackageId packageId; try { packageId = UniversalPackageId.Parse(this.PackageName); } catch (ArgumentException ex) { throw new UpackException("Invalid package ID: " + ex.Message, ex); } UniversalPackageVersion version = null; if (!string.IsNullOrEmpty(this.Version)) { version = UniversalPackageVersion.TryParse(this.Version); if (version == null) { throw new UpackException($"Invalid UPack version number: {this.Version}"); } } JObject data; try { using (var stream = await client.GetPackageFileStreamAsync(packageId, version, string.IsNullOrEmpty(this.FilePath) ? "upack.json" : this.FilePath, cancellationToken)) using (var reader = new StreamReader(stream, Encoding.UTF8, true, 4096, true)) using (var jsonReader = new JsonTextReader(reader) { CloseInput = false }) { data = await JObject.LoadAsync(jsonReader, cancellationToken); } } catch (WebException ex) when(ex.Response is HttpWebResponse r) { var error = $"Server returned {(int)r.StatusCode}: "; if (string.Equals(r.ContentType, "text/plain", StringComparison.OrdinalIgnoreCase)) { using (var reader = new StreamReader(r.GetResponseStream(), Encoding.UTF8)) { var buffer = new char[1000]; reader.Read(buffer, 0, buffer.Length); error += new string(buffer); } } else { error += r.StatusDescription; } throw new UpackException(error, ex); } foreach (var p in data.Properties()) { Console.WriteLine($"{p.Name} = {p.Value}"); } return(0); }
public RemoteUniversalPackageVersion GetPackageVersion(UniversalPackageId id, UniversalPackageVersion version) { return(this.ListPackageVersions(id) .FirstOrDefault(p => p.Version == version)); }