MinManifestInfo.cs (6190B)
1 // ----------------------------------------------------------------------------- 2 // <copyright file="MinManifestInfo.cs" company="Microsoft Corporation"> 3 // Copyright (c) Microsoft Corporation. Licensed under the MIT License. 4 // </copyright> 5 // ----------------------------------------------------------------------------- 6 7 namespace Microsoft.WinGetUtil.Models.V1 8 { 9 using System.IO; 10 using YamlDotNet.Serialization; 11 using YamlDotNet.Serialization.NamingConventions; 12 13 /// <summary> 14 /// Class that contains minimum manifest info for each single manifest in a multi file manifest. 15 /// Used in validation pipeline to check multi file manifest consistency. 16 /// </summary> 17 public class MinManifestInfo 18 { 19 private const string ManifestTypeSingleton = "singleton"; 20 private const string ManifestTypeLocale = "locale"; 21 private const string ManifestTypeDefaultLocale = "defaultLocale"; 22 23 private const string ValidationErrorMissingField = "Manifest file missing required field: "; 24 private const string ValidationErrorFailedManifestCreation = "Failed to create Manifest object from manifest file."; 25 26 /// <summary> 27 /// Gets or sets the Id of the package. 28 /// </summary> 29 [YamlMember(Alias = "PackageIdentifier")] 30 public string Id { get; set; } 31 32 /// <summary> 33 /// Gets or sets the version of the package. 34 /// </summary> 35 [YamlMember(Alias = "PackageVersion")] 36 public string Version { get; set; } 37 38 /// <summary> 39 /// Gets or sets the manifest type. 40 /// </summary> 41 public string ManifestType { get; set; } 42 43 /// <summary> 44 /// Gets or sets the manifest version. 45 /// </summary> 46 public string ManifestVersion { get; set; } 47 48 /// <summary> 49 /// Gets or sets the package locale. Used in locale manifest in a multi file manifest. 50 /// </summary> 51 public string PackageLocale { get; set; } 52 53 /// <summary> 54 /// Deserialize a stream reader into a Manifest object. 55 /// </summary> 56 /// <param name="filePath">file path.</param> 57 /// <returns>Manifest object populated and validated.</returns> 58 public static MinManifestInfo CreateManifestInfoFromPath(string filePath) 59 { 60 using (StreamReader streamReader = new StreamReader(filePath)) 61 { 62 return MinManifestInfo.CreateManifestInfoFromStreamReader(streamReader); 63 } 64 } 65 66 /// <summary> 67 /// Deserialize a stream into a Manifest object. 68 /// </summary> 69 /// <param name="stream">Manifest stream.</param> 70 /// <returns>Manifest object populated and validated.</returns> 71 public static MinManifestInfo CreateManifestInfoFromStream(Stream stream) 72 { 73 using (StreamReader streamReader = new StreamReader(stream)) 74 { 75 return MinManifestInfo.CreateManifestInfoFromStreamReader(streamReader); 76 } 77 } 78 79 /// <summary> 80 /// Deserialize a stream reader into a Manifest object. 81 /// </summary> 82 /// <param name="streamReader">stream reader.</param> 83 /// <returns>Manifest object populated and validated.</returns> 84 public static MinManifestInfo CreateManifestInfoFromStreamReader(StreamReader streamReader) 85 { 86 streamReader.BaseStream.Seek(0, SeekOrigin.Begin); 87 var deserializer = CreateDeserializer(); 88 var result = deserializer.Deserialize<MinManifestInfo>(streamReader); 89 ValidateManifestInfo(result); 90 return result; 91 } 92 93 /// <summary> 94 /// Deserialize a string into a Manifest object. 95 /// </summary> 96 /// <param name="value">Manifest in string value.</param> 97 /// <returns>Manifest object populated and validated.</returns> 98 public static MinManifestInfo CreateManifestInfoFromString(string value) 99 { 100 var deserializer = CreateDeserializer(); 101 var result = deserializer.Deserialize<MinManifestInfo>(value); 102 ValidateManifestInfo(result); 103 return result; 104 } 105 106 /// <summary> 107 /// Helper to deserialize the manifest. 108 /// </summary> 109 /// <returns>IDeserializer object.</returns> 110 private static IDeserializer CreateDeserializer() 111 { 112 var deserializer = new DeserializerBuilder(). 113 WithNamingConvention(PascalCaseNamingConvention.Instance). 114 IgnoreUnmatchedProperties(); 115 return deserializer.Build(); 116 } 117 118 /// <summary> 119 /// Validate manifest info integrity. 120 /// </summary> 121 private static void ValidateManifestInfo(MinManifestInfo manifestInfo) 122 { 123 if (manifestInfo == null) 124 { 125 throw new InvalidDataException(ValidationErrorFailedManifestCreation); 126 } 127 128 if (string.IsNullOrEmpty(manifestInfo.Id)) 129 { 130 throw new InvalidDataException(ValidationErrorMissingField + "PackageIdentifier"); 131 } 132 133 if (string.IsNullOrEmpty(manifestInfo.Version)) 134 { 135 throw new InvalidDataException(ValidationErrorMissingField + "PackageVersion"); 136 } 137 138 if (string.IsNullOrEmpty(manifestInfo.ManifestType)) 139 { 140 throw new InvalidDataException(ValidationErrorMissingField + "ManifestType"); 141 } 142 143 if (string.IsNullOrEmpty(manifestInfo.ManifestVersion)) 144 { 145 throw new InvalidDataException(ValidationErrorMissingField + "ManifestVersion"); 146 } 147 148 if (string.IsNullOrEmpty(manifestInfo.PackageLocale) && 149 (manifestInfo.ManifestType == ManifestTypeDefaultLocale || 150 manifestInfo.ManifestType == ManifestTypeLocale || 151 manifestInfo.ManifestType == ManifestTypeSingleton)) 152 { 153 throw new InvalidDataException(ValidationErrorMissingField + "PackageLocale"); 154 } 155 } 156 } 157 }