public void MissingServiceFoundShouldThrowException() { var modelCollection = new ConfigModelCollection(); modelCollection.ConfigModels.Add("serviceA", new ConfigModel { AssemblyName = "ServiceA" }); modelCollection.ConfigModels.Add("serviceB", new ConfigModel { AssemblyName = "ServiceB" }); var foundServiceList = new string[] { "ServiceA", "ServiceB", "ServiceC" }; try { CmdletGenerator.VerifyAllAssembliesHaveConfiguration(_sdkVersionsJson, modelCollection, foundServiceList); } catch (Exception ex) { Assert.AreEqual("Missing XML configuration for: SkippedService, ServiceC", ex.Message); throw; } }
public void AllAssembliesConfiguredShouldNotThrowException() { var modelCollection = new ConfigModelCollection(); modelCollection.ConfigModels.Add("serviceA", new ConfigModel { AssemblyName = "ServiceA" }); modelCollection.ConfigModels.Add("serviceB", new ConfigModel { AssemblyName = "ServiceB" }); modelCollection.IncludeLibrariesList.Add(new Library("AWSSDK.SkippedService", false)); CmdletGenerator.VerifyAllAssembliesHaveConfiguration(_sdkVersionsJson, modelCollection, null); }
/// <summary> /// Verifies that all services included in the SDK's _sdk-version.json either have a /// PowerShell configuration or were intentionally omitted. Also ensures there is a /// configuration for not yet released services. /// </summary> /// <param name="sdkAssembliesFolder">location of the SDK assemblies to generate against</param> /// <param name="modelCollection">PowerShell configuration, assumes ConfigModels and IncludeLibrariesList have been fully instantiated</param> /// <param name="allSdkAssemblyFilenames">A list of all the SDK assembly filenames in the net45 and netstandard2.0 folders</param> public static void VerifyAllAssembliesHaveConfiguration(JObject sdkVersionsJson, ConfigModelCollection modelCollection, IEnumerable <string> allSdkAssemblyFilenames) { var intentionallySkippedModules = new HashSet <string>(); var configuredAssemblies = new HashSet <string>(); foreach (var module in modelCollection.IncludeLibrariesList) { intentionallySkippedModules.Add(module.Name); } foreach (var configuredService in modelCollection.ConfigModels.Values) { configuredAssemblies.Add(configuredService.AssemblyName); } var sdkAssembliesNoConfig = new List <string>(); //Check to ensure we have an configuration for each SDK service in _sdk-version.json. foreach (var service in sdkVersionsJson["ServiceVersions"]) { var assemblyName = ((JProperty)service).Name; if (!configuredAssemblies.Contains(assemblyName) && !intentionallySkippedModules.Contains("AWSSDK." + assemblyName)) { sdkAssembliesNoConfig.Add(assemblyName); } } //Check to ensure we have a configuration for any SDK service sitting in the assemblies //folder. New services are not in the _sdk-version.json until release. if (allSdkAssemblyFilenames != null) { sdkAssembliesNoConfig.AddRange( allSdkAssemblyFilenames.Where(name => !configuredAssemblies.Contains(name) && !intentionallySkippedModules.Contains("AWSSDK." + name)) ); } //Return all assemblies missing a XML configuration. if (sdkAssembliesNoConfig.Any()) { throw new Exception($"Missing XML configuration for: {string.Join(", ", sdkAssembliesNoConfig)}"); } }
public void MissingServiceShouldThrowException() { var modelCollection = new ConfigModelCollection(); modelCollection.ConfigModels.Add("serviceA", new ConfigModel { AssemblyName = "ServiceA" }); modelCollection.IncludeLibrariesList.Add(new Library("AWSSDK.SkippedService", false)); try { CmdletGenerator.VerifyAllAssembliesHaveConfiguration(_sdkVersionsJson, modelCollection, null); } catch (Exception ex) { Assert.AreEqual("Missing XML configuration for: ServiceB", ex.Message); throw; } }
public static void ApplyOverrides(string folderPath, ConfigModelCollection modelCollection, string configurationsFolder) { var serviceOverrides = DeserializeModelCollection(folderPath); foreach (var serviceOverride in serviceOverrides) { ConfigModel configModel; if (modelCollection.ConfigModels.TryGetValue(serviceOverride.C2jFilename, out configModel)) { configModel = Merge(configModel, serviceOverride); modelCollection.ConfigModels[configModel.C2jFilename] = configModel; } else { configModel = serviceOverride; configModel.ModelFilename = configModel.C2jFilename + ".xml"; modelCollection.ConfigModels.Add(serviceOverride.C2jFilename, serviceOverride); } configModel.ServiceOperationsList = configModel.ServiceOperationsList.OrderBy(so => so.MethodName).ToList(); configModel.Serialize(configurationsFolder); } }
protected override void GenerateHelper() { CmdletsOutputPath = Path.Combine(OutputFolder, CmdletsOutputSubFoldername); var configurationsFolder = Path.Combine(Options.RootPath, ConfigurationFolderName); var serviceConfigurationsFolder = Path.Combine(configurationsFolder, ServiceConfigFoldername); ModelCollection = ConfigModelCollection.LoadAllConfigs(configurationsFolder, Options.Verbose); XmlOverridesMerger.ApplyOverrides(Options.RootPath, ModelCollection, serviceConfigurationsFolder); SourceArtifacts = new GenerationSources(OutputFolder, SdkNugetFolder, Options.VersionNumber); LoadCoreSDKRuntimeMaterials(); LoadSpecialServiceAssemblies(); CheckForServicePrefixDuplication(); if (!Options.SkipCmdletGeneration) { //We clean and setup service folders, some services share a folder, project and module, so we use distinct foreach (var project in ModelCollection.ConfigModels.Values .Where(service => !service.SkipCmdletGeneration) .GroupBy(folder => folder.AssemblyName)) { var modelsWithGuid = project.Where(model => !string.IsNullOrWhiteSpace(model.ServiceModuleGuid)); if (modelsWithGuid.Count() > 1) { AnalysisError.DuplicatedAssemblyName(modelsWithGuid); } SetupOutputDir(project.Key); } } foreach (var configModel in ModelCollection.ConfigModels.Values) { // hold some state to model under work so we can make use of // static helpers CurrentModel = configModel; try { Logger.Log("======================================================="); Logger.Log("Processing service: {0}", CurrentModel.ServiceName); LoadCurrentService(CurrentModel); if (!Options.SkipCmdletGeneration) { GenerateClientAndCmdlets(); // if the service contains any hand-maintained cmdlets, scan them to update the // argument completers for any use of ConstantClass-derived types ScanAdvancedCmdletsForServices(); GenerateArgumentCompleters(); ProcessLegacyAliasesForCustomCmdlets(); CheckForCmdletNameDuplication(); } } catch (Exception e) { AnalysisError.ExceptionWhileGeneratingForService(CurrentModel, e); } } if (!Options.SkipCmdletGeneration) { ScanAdvancedCmdletsForCommonModule(); SourceArtifacts.WriteLegacyAliasesFile(LegacyAliases, ModelCollection.CommonModuleAliases); SourceArtifacts.WriteMonolithicCompletionScriptsFile(GetArgumentCompletionScriptContent()); SourceArtifacts.WriteMonolithicProjectFile(); SourceArtifacts.WriteMonolithicModuleFiles(); SourceArtifacts.WriteAdditionalAliasesFiles(Aliases); SourceArtifacts.WriteModularSolution(ModelCollection.ConfigModels.Values); SourceArtifacts.WriteCopyModularArtifactsScript(ModelCollection.ConfigModels.Values); SourceArtifacts.WriteCmdletsList(ModelCollection.ConfigModels.Values); SourceArtifacts.WriteCommonModule(CommonAdvancedCmdlets.Keys, ModelCollection.CommonModuleAliases); SourceArtifacts.WriteCommonProjectFile(); SourceArtifacts.WriteLegacyAliasesFileForCommonModule(ModelCollection.CommonModuleAliases); SourceArtifacts.WriteCommonCompletionScriptsFile(); SourceArtifacts.WriteCommonModuleCmdletsList(ModelCollection.ConfigModels.Values); SourceArtifacts.WriteModularProjectFiles(ModelCollection.ConfigModels.Values); SourceArtifacts.WriteLegacyAliasesModularFiles(LegacyAliases, ModelCollection.ConfigModels.Values); SourceArtifacts.WriteCompletersModularFiles(ModelCollection.ConfigModels.Values); SourceArtifacts.WriteModularManifestFiles(ModelCollection.ConfigModels.Values, LegacyAliases); SourceArtifacts.WriteVersionFile(); WriteConfigurationChanges(); } foreach (var configModel in ModelCollection.ConfigModels.Values) { foreach (var error in configModel.AnalysisErrors.Concat( configModel.ServiceOperationsList .OrderBy(so => so.MethodName) .SelectMany(operation => operation.AnalysisErrors))) { Logger.LogError(error.ToString()); } } }
protected override void GenerateHelper() { var configurationsFolder = Path.Combine(Options.RootPath, FormatGeneratorConfigurationsFoldername); ConfigCollection = ConfigModelCollection.LoadAllConfigs(configurationsFolder, Options.Verbose); LoadCustomFormatDocuments(configurationsFolder); var types = new List <Type>(); foreach (var assembly in TargetAssemblies) { var assemblyTypes = GetTypes(assembly); types.AddRange(assemblyTypes); var includeTypes = GetTypes(assembly, ConfigCollection.TypesToInclude.ToArray()); types.AddRange(includeTypes); } var cmdletType = typeof(Cmdlet); types.RemoveAll(t => { var isPrivate = !t.IsPublic || t.IsNestedPrivate; var shouldExclude = ConfigCollection.TypeExclusionSet.Contains(t.FullName); var isCmdlet = t.IsSubclassOf(cmdletType); var exclude = (isPrivate || shouldExclude || isCmdlet); if (exclude) { Logger.Log("Excluding type {0} from formats file", t.FullName); } return(exclude); }); if (!Directory.Exists(OutputFolder)) { Directory.CreateDirectory(OutputFolder); } var outputFile = Path.Combine(OutputFolder, Name + ".Format.ps1xml"); if (File.Exists(outputFile)) { File.Delete(outputFile); } using (var stream = File.OpenWrite(outputFile)) { var writerSettings = new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true }; using (var writer = XmlWriter.Create(stream, writerSettings)) { writer.WriteStartDocument(); writer.WriteStartElement("Configuration"); writer.WriteStartElement("ViewDefinitions"); foreach (var type in types) { var config = GetConfig(type); Logger.Log(); Logger.Log(new string('>', 20)); Logger.Log("Generating config: {0}", config); GenerateView(config, writer, type); Logger.Log(new string('<', 20)); Logger.Log(); } foreach (var cfd in ConfigCollection.CustomFormatDocuments) { var viewDefinitions = cfd.SelectSingleNode("descendant::ViewDefinitions"); if (viewDefinitions == null) { continue; } foreach (var viewNode in viewDefinitions.ChildNodes) { var viewNodeXml = viewNode as XmlNode; using (var reader = XmlReader.Create(new StringReader(viewNodeXml.OuterXml))) { writer.WriteNode(reader, false); } } } writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteEndDocument(); } } }