winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

Manifest.cs (9594B)


      1 // -----------------------------------------------------------------------------
      2 // <copyright file="Manifest.cs" company="Microsoft Corporation">
      3 //     Copyright (c) Microsoft Corporation. Licensed under the MIT License.
      4 // </copyright>
      5 // -----------------------------------------------------------------------------
      6 
      7 namespace Microsoft.WinGetUtil.Models.Preview
      8 {
      9     using System;
     10     using System.Collections.Generic;
     11     using System.IO;
     12     using System.Linq;
     13     using YamlDotNet.Serialization;
     14     using YamlDotNet.Serialization.NamingConventions;
     15 
     16     /// <summary>
     17     /// Class that defines the structure of the manifest. Uses YamlDotNet
     18     /// to deserialize a string or a stream and produce a manifest object.
     19     /// </summary>
     20     public class Manifest
     21     {
     22         /// <summary>
     23         /// Gets or sets the Id of the manifest.
     24         /// </summary>
     25         public string Id { get; set; }
     26 
     27         /// <summary>
     28         /// Gets or sets the name of the package.
     29         /// </summary>
     30         public string Name { get; set; }
     31 
     32         /// <summary>
     33         /// Gets or sets the version of the package.
     34         /// </summary>
     35         public string Version { get; set; }
     36 
     37         /// <summary>
     38         /// Gets or sets the publisher.
     39         /// </summary>
     40         public string Publisher { get; set; }
     41 
     42         /// <summary>
     43         /// Gets or sets the AppMoniker.
     44         /// </summary>
     45         public string AppMoniker { get; set; }
     46 
     47         /// <summary>
     48         /// Gets or sets the Channel.
     49         /// </summary>
     50         public string Channel { get; set; }
     51 
     52         /// <summary>
     53         /// Gets or sets the Author of package.
     54         /// </summary>
     55         public string Author { get; set; }
     56 
     57         /// <summary>
     58         /// Gets or sets the License.
     59         /// </summary>
     60         public string License { get; set; }
     61 
     62         /// <summary>
     63         /// Gets or sets the MinOSVersion.
     64         /// </summary>
     65         public string MinOSVersion { get; set; }
     66 
     67         /// <summary>
     68         /// Gets or sets the Tags. Comma separated values.
     69         /// </summary>
     70         public string Tags { get; set; }
     71 
     72         /// <summary>
     73         /// Gets or sets the Commands. Comma separated values.
     74         /// </summary>
     75         public string Commands { get; set; }
     76 
     77         /// <summary>
     78         /// Gets or sets the Protocols. Comma separated values.
     79         /// </summary>
     80         public string Protocols { get; set; }
     81 
     82         /// <summary>
     83         /// Gets or sets the FileExtensions. Comma separated values.
     84         /// </summary>
     85         public string FileExtensions { get; set; }
     86 
     87         /// <summary>
     88         /// Gets or sets the InstallerType of the package. Must be one
     89         /// of the values of ValidInstallerTypes. IManifestInstallerDefaults.
     90         /// An InstallerType in the root of the manifest is required if
     91         /// InstallerType is not defined in an ManifestInstaller entry.
     92         /// </summary>
     93         public string InstallerType { get; set; }
     94 
     95         /// <summary>
     96         /// Gets or sets Description. IManifestLocalization.
     97         /// </summary>
     98         public string Description { get; set; }
     99 
    100         /// <summary>
    101         /// Gets or sets Homepage. IManifestLocalization.
    102         /// </summary>
    103         public string Homepage { get; set; }
    104 
    105         /// <summary>
    106         /// Gets or sets LicenseUrl. IManifestLocalization.
    107         /// </summary>
    108         public string LicenseUrl { get; set; }
    109 
    110         /// <summary>
    111         /// Gets or sets InstallerSwitches. IManifestInstallerDefaults.
    112         /// </summary>
    113         public InstallerSwitches Switches { get; set; }
    114 
    115         /// <summary>
    116         /// Gets or sets collection of ManifestInstaller. At least one is required.
    117         /// </summary>
    118         public List<ManifestInstaller> Installers { get; set; }
    119 
    120         /// <summary>
    121         /// Gets or sets collection of ManifestLocalization.
    122         /// </summary>
    123         public List<ManifestLocalization> Localization { get; set; }
    124 
    125         /// <summary>
    126         /// Gets or sets the manifest version.
    127         /// </summary>
    128         public string ManifestVersion { get; set; }
    129 
    130         /// <summary>
    131         /// Deserialize a stream into a Manifest object.
    132         /// </summary>
    133         /// <param name="stream">Manifest stream.</param>
    134         /// <returns>Manifest object populated and validated.</returns>
    135         public static Manifest CreateManifestFromStream(Stream stream)
    136         {
    137             using (StreamReader streamReader = new StreamReader(stream))
    138             {
    139                 return Manifest.CreateManifestFromStreamReader(streamReader);
    140             }
    141         }
    142 
    143         /// <summary>
    144         /// Deserialize a stream reader into a Manifest object.
    145         /// </summary>
    146         /// <param name="streamReader">stream reader.</param>
    147         /// <returns>Manifest object populated and validated.</returns>
    148         public static Manifest CreateManifestFromStreamReader(StreamReader streamReader)
    149         {
    150             streamReader.BaseStream.Seek(0, SeekOrigin.Begin);
    151             var deserializer = CreateDeserializer();
    152             return deserializer.Deserialize<Manifest>(streamReader);
    153         }
    154 
    155         /// <summary>
    156         /// Deserialize a stream reader into a Manifest object.
    157         /// </summary>
    158         /// <param name="filePath">file path.</param>
    159         /// <returns>Manifest object populated and validated.</returns>
    160         public static Manifest CreateManifestFromPath(string filePath)
    161         {
    162             using (StreamReader streamReader = new StreamReader(filePath))
    163             {
    164                 return Manifest.CreateManifestFromStreamReader(streamReader);
    165             }
    166         }
    167 
    168         /// <summary>
    169         /// Deserialize a string into a Manifest object.
    170         /// </summary>
    171         /// <param name="value">Manifest in string value.</param>
    172         /// <returns>Manifest object populated and validated.</returns>
    173         public static Manifest CreateManifestFromString(string value)
    174         {
    175             var deserializer = CreateDeserializer();
    176             return deserializer.Deserialize<Manifest>(value);
    177         }
    178 
    179         /// <summary>
    180         /// Returns a List of strings containing the URIs contained within this manifest.
    181         /// </summary>
    182         /// <returns>List of strings.</returns>
    183         public List<string> GetURIs()
    184         {
    185             List<string> uris = new List<string>();
    186             if (!string.IsNullOrEmpty(this.Homepage))
    187             {
    188                 uris.Add(this.Homepage);
    189             }
    190 
    191             if (!string.IsNullOrEmpty(this.LicenseUrl))
    192             {
    193                 uris.Add(this.LicenseUrl);
    194             }
    195 
    196             foreach (ManifestInstaller installer in this.Installers)
    197             {
    198                 if (!string.IsNullOrEmpty(installer.Url))
    199                 {
    200                     uris.Add(installer.Url);
    201                 }
    202             }
    203 
    204             if (this.Localization != null)
    205             {
    206                 foreach (ManifestLocalization localization in this.Localization)
    207                 {
    208                     if (!string.IsNullOrEmpty(localization.LicenseUrl))
    209                     {
    210                         uris.Add(localization.LicenseUrl);
    211                     }
    212 
    213                     if (!string.IsNullOrEmpty(localization.Homepage))
    214                     {
    215                         uris.Add(localization.Homepage);
    216                     }
    217                 }
    218             }
    219 
    220             return uris;
    221         }
    222 
    223         /// <summary>
    224         /// Checks if two manifests are equivalent.
    225         /// </summary>
    226         /// <param name="other">other object.</param>
    227         /// <returns>boolean indicating if the objects are equals.</returns>
    228         public bool IsManifestEquivalent(Manifest other)
    229         {
    230             // If parameter is null, return false.
    231             if (ReferenceEquals(other, null))
    232             {
    233                 return false;
    234             }
    235 
    236             // Optimization for a common success case.
    237             if (ReferenceEquals(this, other))
    238             {
    239                 return true;
    240             }
    241 
    242             // If run-time types are not exactly the same, return false.
    243             if (this.GetType() != other.GetType())
    244             {
    245                 return false;
    246             }
    247 
    248             // Equality of Manifest consist on only these properties.
    249             return (this.Id == other.Id) &&
    250                    (this.Version == other.Version) &&
    251                    (this.Publisher == other.Publisher) &&
    252                    (this.InstallerType == other.InstallerType) &&
    253                    (this.Switches == other.Switches) &&
    254                    this.CompareInstallers(other.Installers);
    255         }
    256 
    257         /// <summary>
    258         /// Helper to deserialize the manifest.
    259         /// </summary>
    260         /// <returns>IDeserializer object.</returns>
    261         private static IDeserializer CreateDeserializer()
    262         {
    263             var deserializer = new DeserializerBuilder().
    264                 WithNamingConvention(PascalCaseNamingConvention.Instance).
    265                 IgnoreUnmatchedProperties();
    266             return deserializer.Build();
    267         }
    268 
    269         private bool CompareInstallers(List<ManifestInstaller> installers)
    270         {
    271             ISet<ManifestInstaller> first =
    272                 new HashSet<ManifestInstaller>(
    273                     this.Installers != null ?
    274                     this.Installers :
    275                     new List<ManifestInstaller>());
    276 
    277             return first.SetEquals(installers != null
    278                 ? installers : new List<ManifestInstaller>());
    279         }
    280     }
    281 }