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 }