private void AnalyzeMarkdownHelp( IEnumerable <string> scopes, string directory, ReportLogger <HelpIssue> helpLogger, List <string> processedHelpFiles, string savedDirectory) { var helpFolder = Directory.EnumerateDirectories(directory, "help").FirstOrDefault(); var service = Path.GetFileName(directory); if (helpFolder == null) { helpLogger.LogRecord(new HelpIssue() { Assembly = service, Description = string.Format("{0} has no matching help folder", service), Severity = 0, Remediation = string.Format("Make sure a help folder for {0} exists and it is " + "being copied to the output directory.", service), Target = service, HelpFile = service + "/folder", ProblemId = MissingHelpFile }); return; } var helpFiles = Directory.EnumerateFiles(helpFolder, "*.md").Select(Path.GetFileNameWithoutExtension).ToList(); // Assume all cmdlets markdown file following format of VERB-AzResource. Dash is required. helpFiles = helpFiles.Where(c => c.Contains("-")).ToList(); if (!helpFiles.Any()) { return; } Directory.SetCurrentDirectory(directory); var manifestFiles = Directory.EnumerateFiles(directory, "*.psd1").ToList(); if (manifestFiles.Count > 1) { manifestFiles = manifestFiles.Where(f => Path.GetFileName(f).IndexOf(service) >= 0).ToList(); } if (manifestFiles.Count == 0) { return; } var psd1 = manifestFiles.FirstOrDefault(); var parentDirectory = Directory.GetParent(psd1).FullName; var psd1FileName = Path.GetFileName(psd1); var powershell = PowerShell.Create(); var script = $"Import-LocalizedData -BaseDirectory {parentDirectory} -FileName {psd1FileName} -BindingVariable ModuleMetadata; $ModuleMetadata.NestedModules"; powershell.AddScript(script); var cmdletResult = powershell.Invoke(); var nestedModules = new List <string>(); foreach (var module in cmdletResult) { if (module != null && module.ToString().StartsWith(".")) { nestedModules.Add(module.ToString().Substring(2)); } else if (module != null) { nestedModules.Add(module.ToString()); } } script = $"Import-LocalizedData -BaseDirectory {parentDirectory} -FileName {psd1FileName}" + " -BindingVariable ModuleMetadata; $ModuleMetadata.RequiredModules | % { $_[\"ModuleName\"] };"; cmdletResult = PowerShell.Create().AddScript(script).Invoke(); var requiredModules = cmdletResult.Where(c => c != null && !c.ToString().StartsWith(".")).Select(c => c.ToString()).ToList(); var allCmdlets = new List <CmdletMetadata>(); if (nestedModules.Any()) { Directory.SetCurrentDirectory(directory); requiredModules = requiredModules.Join(scopes, module => 1, dir => 1, (module, dir) => Path.Combine(dir, module)) .Where(Directory.Exists) .ToList(); requiredModules.Add(directory); foreach (var nestedModule in nestedModules) { var assemblyFile = Directory.GetFiles(parentDirectory, nestedModule, SearchOption.AllDirectories).FirstOrDefault(); if (!File.Exists(assemblyFile)) { continue; } var assemblyFileName = Path.GetFileName(assemblyFile); helpLogger.Decorator.AddDecorator(h => { h.HelpFile = assemblyFileName; h.Assembly = assemblyFileName; }, "Cmdlet"); processedHelpFiles.Add(assemblyFileName); // TODO: Remove IfDef #if NETSTANDARD var proxy = new CmdletLoader(); #else var proxy = EnvironmentHelpers.CreateProxy <CmdletLoader>(directory, out _appDomain); #endif var module = proxy.GetModuleMetadata(assemblyFile, requiredModules); var cmdlets = module.Cmdlets; allCmdlets.AddRange(cmdlets); helpLogger.Decorator.Remove("Cmdlet"); // TODO: Remove IfDef code #if !NETSTANDARD AppDomain.Unload(_appDomain); #endif } } script = $"Import-LocalizedData -BaseDirectory {parentDirectory} -FileName {psd1FileName} -BindingVariable ModuleMetadata; $ModuleMetadata.FunctionsToExport;"; cmdletResult = PowerShell.Create().AddScript(script).Invoke(); var functionCmdlets = cmdletResult.Select(c => c.ToString()).ToList(); foreach (var cmdlet in functionCmdlets) { var metadata = new CmdletMetadata(); metadata.VerbName = cmdlet.Split("-")[0]; metadata.NounName = cmdlet.Split("-")[1]; allCmdlets.Add(metadata); } ValidateHelpRecords(allCmdlets, helpFiles, helpLogger); ValidateHelpMarkdown(helpFolder, helpFiles, helpLogger); Directory.SetCurrentDirectory(savedDirectory); }
private void AnalyzeMamlHelp( IEnumerable <string> scopes, string directory, ReportLogger <HelpIssue> helpLogger, List <string> processedHelpFiles, string savedDirectory) { var commandAssemblies = Directory.EnumerateFiles(directory, "*.Commands.*.dll") .Where(f => IsAssemblyFile(f) && !File.Exists(f + "-Help.xml")); foreach (var orphanedAssembly in commandAssemblies) { helpLogger.LogRecord(new HelpIssue() { Assembly = orphanedAssembly, Description = string.Format("{0} has no matching help file", orphanedAssembly), Severity = 0, Remediation = string.Format("Make sure a dll Help file for {0} exists and it is " + "being copied to the output directory.", orphanedAssembly), Target = orphanedAssembly, HelpFile = orphanedAssembly + "-Help.xml", ProblemId = MissingHelpFile }); } var helpFiles = Directory.EnumerateFiles(directory, "*.dll-Help.xml") .Where(f => !processedHelpFiles.Contains(Path.GetFileName(f), StringComparer.OrdinalIgnoreCase)).ToList(); if (!helpFiles.Any()) { return; } Directory.SetCurrentDirectory(directory); foreach (var helpFile in helpFiles) { var cmdletFile = helpFile.Substring(0, helpFile.Length - "-Help.xml".Length); var helpFileName = Path.GetFileName(helpFile); var cmdletFileName = Path.GetFileName(cmdletFile); if (!File.Exists(cmdletFile)) { continue; } processedHelpFiles.Add(helpFileName); helpLogger.Decorator.AddDecorator(h => { h.HelpFile = helpFileName; h.Assembly = cmdletFileName; }, "Cmdlet"); // TODO: Remove IfDef #if NETSTANDARD var proxy = new CmdletLoader(); #else var proxy = EnvironmentHelpers.CreateProxy <CmdletLoader>(directory, out _appDomain); #endif var module = proxy.GetModuleMetadata(cmdletFile); var cmdlets = module.Cmdlets; var helpRecords = CmdletHelpParser.GetHelpTopics(helpFile, helpLogger); ValidateHelpRecords(cmdlets, helpRecords, helpLogger); helpLogger.Decorator.Remove("Cmdlet"); // TODO: Remove IfDef code #if !NETSTANDARD AppDomain.Unload(_appDomain); #endif } Directory.SetCurrentDirectory(savedDirectory); }