private void CheckAssemblyReference(AssemblyName reference, AssemblyRecord parent)
 {
     if (_assemblies.ContainsKey(reference.Name))
     {
         var stored = _assemblies[reference.Name];
         if (stored.Equals(reference))
         {
             stored.ReferencingAssembly.Add(parent);
         }
         else if (reference.Version.Major == 0 && reference.Version.Minor == 0)
         {
             Logger.WriteWarning("{0}.dll has reference to assembly {1} without any version specification.",
                                 parent.Name, reference.Name);
             _versionConflictLogger.LogRecord(new AssemblyVersionConflict()
             {
                 AssemblyName    = reference.Name,
                 ActualVersion   = stored.Version,
                 ExpectedVersion = reference.Version,
                 ParentAssembly  = parent.Name,
                 Severity        = 2,
                 Description     = string.Format("Assembly {0} referenced from {1}.dll does not specify any " +
                                                 "assembly version evidence.  The assembly will use version " +
                                                 "{2} from disk.", reference.Name, parent.Name, stored.Version),
                 Remediation = string.Format("Update the reference to assembly {0} from {1} so that " +
                                             "assembly version evidence is supplied", reference.Name,
                                             parent.Name)
             });
         }
         else
         {
             var minVersion = (stored.Version < reference.Version) ? stored.Version : reference.Version;
             _versionConflictLogger.LogRecord(new AssemblyVersionConflict()
             {
                 AssemblyName    = reference.Name,
                 ActualVersion   = stored.Version,
                 ExpectedVersion = reference.Version,
                 ParentAssembly  = parent.Name,
                 Severity        = 1,
                 Description     = string.Format("Assembly {0} version {1} referenced from {2}.dll does " +
                                                 "not match assembly version on disk: {3}",
                                                 reference.Name, reference.Version, parent.Name, stored.Version),
                 Remediation = string.Format("Update any references to version {0} of assembly {1}",
                                             minVersion, reference.Name)
             });
         }
     }
     else if (!IsFrameworkAssembly(reference))
     {
         _missingAssemblyLogger.LogRecord(new MissingAssembly
         {
             AssemblyName        = reference.Name,
             AssemblyVersion     = reference.Version.ToString(),
             ReferencingAssembly = parent.Name,
             Severity            = 0,
             Description         = string.Format("Missing assembly {0} referenced from {1}", reference.Name,
                                                 parent.Name),
             Remediation = "Ensure that the assembly is included in the Wix file or directory"
         });
     }
 }
        private bool AddSharedAssembly(AssemblyRecord assembly)
        {
            if (_sharedAssemblyReferences.ContainsKey(assembly.AssemblyName))
            {
                var stored = _sharedAssemblyReferences[assembly.AssemblyName];
                if (!assembly.Equals(stored) && !(IsFrameworkAssembly(assembly.AssemblyName) && assembly.Version.Major <= 4))
                {
                    _sharedConflictLogger.LogRecord(new SharedAssemblyConflict
                    {
                        AssemblyName = assembly.Name,
                        AssemblyPathsAndFileVersions = new List <Tuple <string, Version> >()
                        {
                            new Tuple <string, Version>(assembly.Location, new Version(assembly.AssemblyFileMajorVersion,
                                                                                       assembly.AssemblyFileMinorVersion)),
                            new Tuple <string, Version>(stored.Location, new Version(stored.AssemblyFileMajorVersion,
                                                                                     stored.AssemblyFileMinorVersion))
                        },
                        AssemblyVersion = assembly.Version,
                        Severity        = 0,
                        Description     = "Shared assembly conflict, shared assemblies with the same assembly " +
                                          "version have differing file versions",
                        Remediation = string.Format("Update the assembly reference for {0} in one of the " +
                                                    "referring assemblies", assembly.Name)
                    });

                    return(false);
                }
            }
            else
            {
                _sharedAssemblyReferences[assembly.AssemblyName] = assembly;
            }

            return(true);
        }
        public static IList<string> GetHelpTopics(string helpPath, ReportLogger<HelpIssue> logger)
        {
            IList<string> cmdlets = new List<string>();
            try
            {
                XDocument document = XDocument.Parse(File.ReadAllText(helpPath));
                var root = document.Root;
                foreach (var command in root.GetChildElements("command"))
                {
                    if (command.ContainsChildElement("details"))
                    {
                        var details = command.GetChildElement("details");
                        if (details.ContainsChildElement("name"))
                        {
                            cmdlets.Add(details.GetChildElement("name").Value.Trim());
                        }
                        else
                        {
                            logger.LogRecord(new HelpIssue
                          {
                              HelpFile = helpPath,
                              Severity = 0,
                              ProblemId = MissingCommandName,
                              Description = string.Format("Missing command:name element for file {0}", helpPath),
                              Remediation = "Correct the xml format of the help file"
                          });

                        }
                    }
                    else
                    {

                        logger.LogRecord(new HelpIssue
                        {
                            HelpFile = helpPath,
                            Severity = 0,
                            ProblemId = MissingCommandDetails,
                            Description = string.Format("Missing command:details element for file {0}", helpPath),
                            Remediation = "Correct the xml format of the help file"
                        });
                    }
                }
            }
            catch (Exception e)
            {
                logger.LogRecord(new HelpIssue
                {
                    HelpFile = helpPath,
                    Severity = 0,
                    ProblemId = InvalidHelpFile,
                    Description = string.Format("Parsing error for help file {0}: {1}", helpPath, e.ToString()),
                    Remediation = "Correct the xml format of the help file"
                });
            }

            return cmdlets;
        }
Beispiel #4
0
        public static IList <string> GetHelpTopics(string helpPath, ReportLogger <HelpIssue> logger)
        {
            IList <string> cmdlets = new List <string>();

            try
            {
                XDocument document = XDocument.Parse(File.ReadAllText(helpPath));
                var       root     = document.Root;
                foreach (var command in root.GetChildElements("command"))
                {
                    if (command.ContainsChildElement("details"))
                    {
                        var details = command.GetChildElement("details");
                        if (details.ContainsChildElement("name"))
                        {
                            cmdlets.Add(details.GetChildElement("name").Value.Trim());
                        }
                        else
                        {
                            logger.LogRecord(new HelpIssue
                            {
                                HelpFile    = helpPath,
                                Severity    = 0,
                                ProblemId   = MissingCommandName,
                                Description = string.Format("Missing command:name element for file {0}", helpPath),
                                Remediation = "Correct the xml format of the help file"
                            });
                        }
                    }
                    else
                    {
                        logger.LogRecord(new HelpIssue
                        {
                            HelpFile    = helpPath,
                            Severity    = 0,
                            ProblemId   = MissingCommandDetails,
                            Description = string.Format("Missing command:details element for file {0}", helpPath),
                            Remediation = "Correct the xml format of the help file"
                        });
                    }
                }
            }
            catch (Exception e)
            {
                logger.LogRecord(new HelpIssue
                {
                    HelpFile    = helpPath,
                    Severity    = 0,
                    ProblemId   = InvalidHelpFile,
                    Description = string.Format("Parsing error for help file {0}: {1}", helpPath, e.ToString()),
                    Remediation = "Correct the xml format of the help file"
                });
            }

            return(cmdlets);
        }
Beispiel #5
0
 private void CheckAlcAssemblyDependency(HashSet <string> moduleAlcAssemblySet, bool alcWrapperIsReferenced)
 {
     if (moduleAlcAssemblySet != null)
     {
         //Make sure all dependency assemblies except framework/common are available for ALC assemblies
         if (alcWrapperIsReferenced)
         {
             var alcAssemblyRecords = new Dictionary <string, AssemblyRecord>();
             foreach (var alcAssembly in moduleAlcAssemblySet)
             {
                 var assemblyRecord = CreateAssemblyRecord(alcAssembly);
                 alcAssemblyRecords[assemblyRecord.Name] = assemblyRecord;
             }
             foreach (var parent in alcAssemblyRecords.Values)
             {
                 foreach (var reference in parent.Children)
                 {
                     if (!alcAssemblyRecords.ContainsKey(reference.Name) && !IsFrameworkAssembly(reference.Name) &&
                         !IsCommonAssembly(reference.Name))
                     {
                         _missingAssemblyLogger.LogRecord(new MissingAssembly
                         {
                             AssemblyName        = reference.Name,
                             AssemblyVersion     = reference.Version.ToString(),
                             ReferencingAssembly = parent.Name,
                             Severity            = 0,
                             ProblemId           = MissingAssemblyRecord,
                             Description         = string.Format("Missing ALC assembly {0} referenced from {1}", reference.Name,
                                                                 parent.Name),
                             Remediation = "Ensure that the assembly is included in the Wix file or directory"
                         });
                     }
                 }
             }
         }
         else
         {
             //Add error record, ALC wrapper assembly is never referenced
             var alcAssemblyNames = string.Join(";", moduleAlcAssemblySet.ToArray());
             _extraAssemblyLogger.LogRecord(new ExtraAssembly
             {
                 AssemblyName = alcAssemblyNames,
                 Severity     = 1,
                 ProblemId    = ExtraAssemblyRecord,
                 Description  = string.Format("ALC Assembly {0} is not referenced from any cmdlets assembly",
                                              alcAssemblyNames),
                 Remediation = string.Format("Remove assembly {0} from the project and regenerate the Wix " +
                                             "file", alcAssemblyNames)
             });
         }
     }
 }
 private void ValidateHelpMarkdown(string helpFolder, IList <string> helpRecords, ReportLogger <HelpIssue> helpLogger)
 {
     foreach (var helpMarkdown in helpRecords)
     {
         var file    = Path.Combine(helpFolder, helpMarkdown + ".md");
         var content = File.ReadAllText(file);
         try
         {
             var parser        = new MarkdownParser();
             var transformer   = new ModelTransformerVersion2();
             var markdownModel = parser.ParseString(new[] { content });
             var model         = transformer.NodeModelToMamlModel(markdownModel).FirstOrDefault();
         }
         catch (Exception ex)
         {
             HelpIssue issue = new HelpIssue
             {
                 Target      = helpMarkdown,
                 Severity    = 1,
                 ProblemId   = PlatyPSSchemaViolation,
                 Description = "Help content doesn't conform to PlatyPS Schema definition",
                 Remediation = string.Format("No.")
             };
             helpLogger.LogRecord(issue);
             Console.Error.WriteLine($"Failed to parse {file} by PlatyPS, {ex.Message}");
         }
     }
 }
        private void FindExtraAssemblies()
        {
            if (!_assemblies.Values.Any(a =>
                                        !IsCommandAssembly(a) &&
                                        (a.ReferencingAssembly == null ||
                                         a.ReferencingAssembly.Count == 0 ||
                                         !a.GetAncestors().Any(IsCommandAssembly))))
            {
                return;
            }

            foreach (var assembly in _assemblies.Values.Where(a =>
                                                              !IsCommandAssembly(a) &&
                                                              (a.ReferencingAssembly == null ||
                                                               a.ReferencingAssembly.Count == 0 ||
                                                               !a.GetAncestors().Any(IsCommandAssembly))))
            {
                _extraAssemblyLogger.LogRecord(new ExtraAssembly
                {
                    AssemblyName = assembly.Name,
                    Severity     = 2,
                    ProblemId    = ExtraAssemblyRecord,
                    Description  = string.Format("Assembly {0} is not referenced from any cmdlets assembly",
                                                 assembly.Name),
                    Remediation = string.Format("Remove assembly {0} from the project and regenerate the Wix " +
                                                "file", assembly.Name)
                });
            }
        }
        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())
            {
                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))
                    {
                        processedHelpFiles.Add(helpFileName);
                        helpLogger.Decorator.AddDecorator((h) =>
                        {
                            h.HelpFile = helpFileName;
                            h.Assembly = cmdletFileName;
                        }, "Cmdlet");
                        var proxy       = EnvironmentHelpers.CreateProxy <CmdletLoader>(directory, out _appDomain);
                        var module      = proxy.GetModuleMetadata(cmdletFile);
                        var cmdlets     = module.Cmdlets;
                        var helpRecords = CmdletHelpParser.GetHelpTopics(helpFile, helpLogger);
                        ValidateHelpRecords(cmdlets, helpRecords, helpLogger);
                        helpLogger.Decorator.Remove("Cmdlet");
                        AppDomain.Unload(_appDomain);
                    }
                }

                Directory.SetCurrentDirectory(savedDirectory);
            }
        }
        private void ProcessDirectory(string directoryPath)
        {
            var savedDirectory = Directory.GetCurrentDirectory();

            Directory.SetCurrentDirectory(directoryPath);
            _loader =
#if !NETSTANDARD
                EnvironmentHelpers.CreateProxy <AssemblyLoader>(directoryPath, out _testDomain);
#else
                new AssemblyLoader();
#endif
            foreach (var file in Directory.GetFiles(directoryPath).Where(file => file.EndsWith(".dll")))
            {
                AssemblyRecord assembly = CreateAssemblyRecord(file);
                _assemblies[assembly.Name] = assembly;
                if (RequiresExactVersionMatch(assembly))
                {
                    AddSharedAssemblyExactVersion(assembly);
                }
                else
                {
                    AddSharedAssembly(assembly);
                }
            }

            // Now check for assembly mismatches
            foreach (var assembly in _assemblies.Values)
            {
                foreach (var reference in assembly.Children)
                {
                    CheckAssemblyReference(reference, assembly);
                }
            }

            foreach (var assembly in _assemblies.Values)
            {
                foreach (var parent in assembly.ReferencingAssembly)
                {
                    _dependencyMapLogger.LogRecord(
                        new DependencyMap
                    {
                        AssemblyName               = assembly.Name,
                        AssemblyVersion            = assembly.Version.ToString(),
                        ReferencingAssembly        = parent.Name,
                        ReferencingAssemblyVersion = parent.Version.ToString(),
                        Severity = 3
                    });
                }
            }

            FindExtraAssemblies();

#if !NETSTANDARD
            AppDomain.Unload(_testDomain);
#endif
            Directory.SetCurrentDirectory(savedDirectory);
        }
Beispiel #10
0
        private bool AddSharedAssembly(AssemblyRecord assembly)
        {
            if (_sharedAssemblyReferences.ContainsKey(assembly.AssemblyName))
            {
                var stored = _sharedAssemblyReferences[assembly.AssemblyName];
                if (assembly.Equals(stored) || IsFrameworkAssembly(assembly.AssemblyName) && assembly.Version.Major <= 4)
                {
                    return(true);
                }
                //TODO: Compare Azure.Core version
                if (string.Equals(assembly.AssemblyName.Name, "Azure.Core", StringComparison.InvariantCultureIgnoreCase))
                {
                    return(true);
                }

                _sharedConflictLogger.LogRecord(new SharedAssemblyConflict
                {
                    AssemblyName = assembly.Name,
                    AssemblyPathsAndFileVersions = new List <Tuple <string, Version> >
                    {
                        new Tuple <string, Version>(assembly.Location, new Version(assembly.AssemblyFileMajorVersion,
                                                                                   assembly.AssemblyFileMinorVersion)),
                        new Tuple <string, Version>(stored.Location, new Version(stored.AssemblyFileMajorVersion,
                                                                                 stored.AssemblyFileMinorVersion))
                    },
                    AssemblyVersion = assembly.Version,
                    Severity        = 0,
                    ProblemId       = AssemblyVersionFileVersionMismatch,
                    Description     = "Shared assembly conflict, shared assemblies with the same assembly " +
                                      "version have differing file versions",
                    Remediation = string.Format("Update the assembly reference for {0} in one of the " +
                                                "referring assemblies", assembly.Name)
                });

                return(false);
            }

            _sharedAssemblyReferences[assembly.AssemblyName] = assembly;

            return(true);
        }
 public static void LogSignatureIssue(this ReportLogger <SignatureIssue> issueLogger, CmdletMetadata cmdlet,
                                      string description, string remediation, int severity, int problemId)
 {
     issueLogger.LogRecord(new SignatureIssue
     {
         ClassName   = cmdlet.ClassName,
         Target      = cmdlet.Name,
         Description = description,
         Remediation = remediation,
         Severity    = severity,
         ProblemId   = problemId
     });
 }
Beispiel #12
0
        private void ProcessDirectory(string directoryPath)
        {
            var savedDirectory = Directory.GetCurrentDirectory();

            Directory.SetCurrentDirectory(directoryPath);
            _loader = new AssemblyLoader();
            foreach (var file in Directory.GetFiles(directoryPath).Where(file => file.EndsWith(".dll")))
            {
                var assembly = CreateAssemblyRecord(file);
                if (assembly?.Name != null && !IsFrameworkAssembly(assembly.Name))
                {
                    _assemblies[assembly.Name] = assembly;
                    AddSharedAssembly(assembly);
                }
            }

            // Now check for assembly mismatches
            foreach (var assembly in _assemblies.Values)
            {
                foreach (var reference in assembly.Children)
                {
                    CheckAssemblyReference(reference, assembly);
                }
            }

            foreach (var assembly in _assemblies.Values)
            {
                if (!assembly.Name.Contains("Microsoft.IdentityModel") && !assembly.Name.Equals("Newtonsoft.Json") && !IsFrameworkAssembly(assembly.Name))
                {
                    foreach (var parent in assembly.ReferencingAssembly)
                    {
                        _dependencyMapLogger.LogRecord(
                            new DependencyMap
                        {
                            AssemblyName               = assembly.Name,
                            AssemblyVersion            = assembly.Version.ToString(),
                            ReferencingAssembly        = parent.Name,
                            ReferencingAssemblyVersion = parent.Version.ToString(),
                            Severity = 3
                        });
                    }
                }
            }

            FindExtraAssemblies();
            Directory.SetCurrentDirectory(savedDirectory);
        }
 private void ValidateHelpRecords(IList <CmdletHelpMetadata> cmdlets, IList <string> helpRecords,
                                  ReportLogger <HelpIssue> helpLogger)
 {
     foreach (var cmdlet in cmdlets)
     {
         if (!helpRecords.Contains(cmdlet.CmdletName, StringComparer.OrdinalIgnoreCase))
         {
             helpLogger.LogRecord(new HelpIssue
             {
                 Target      = cmdlet.ClassName,
                 Severity    = 1,
                 Description = string.Format("Help missing for cmdlet {0} implemented by class {1}",
                                             cmdlet.CmdletName, cmdlet.ClassName),
                 Remediation = string.Format("Add Help record for cmdlet {0} to help file.", cmdlet.CmdletName)
             });
         }
     }
 }
Beispiel #14
0
        private void ValidateHelpRecords(IList <CmdletMetadata> cmdlets, IList <string> helpRecords,
                                         ReportLogger <HelpIssue> helpLogger)
        {
            var cmdletDict = new Dictionary <string, CmdletMetadata>();

            foreach (var cmdlet in cmdlets)
            {
                cmdletDict.Add(cmdlet.Name, cmdlet);
                if (!helpRecords.Contains(cmdlet.Name, StringComparer.OrdinalIgnoreCase))
                {
                    HelpIssue issue = new HelpIssue
                    {
                        Target      = cmdlet.ClassName,
                        Severity    = 1,
                        ProblemId   = MissingHelp,
                        Remediation = string.Format("Add Help record for cmdlet {0} to help file.", cmdlet.Name)
                    };
                    if (cmdlet.ClassName != null)
                    {
                        issue.Description = $"Help missing for cmdlet {cmdlet.Name} implemented by class {cmdlet.ClassName}";
                    }
                    else
                    {
                        issue.Description = $"Help missing for cmdlet {cmdlet.Name} implemented by functions";
                    }
                    helpLogger.LogRecord(issue);
                }
            }

            foreach (var helpRecord in helpRecords)
            {
                if (!cmdletDict.ContainsKey(helpRecord))
                {
                    Console.Error.WriteLine($"Help record {helpRecord} has no cmdlet.");
                }
            }
        }
        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(f => Path.GetFileNameWithoutExtension(f)).ToList();

            if (helpFiles.Any())
            {
                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);
                IEnumerable <string> nestedModules   = null;
                List <string>        requiredModules = null;
                PowerShell           powershell      = PowerShell.Create();
                powershell.AddScript("Import-LocalizedData -BaseDirectory " + parentDirectory +
                                     " -FileName " + psd1FileName +
                                     " -BindingVariable ModuleMetadata; $ModuleMetadata.NestedModules; $ModuleMetadata.RequiredModules | % { $_[\"ModuleName\"] };");
                var cmdletResult = powershell.Invoke();
                nestedModules   = cmdletResult.Where(c => c.ToString().StartsWith(".")).Select(c => c.ToString().Substring(2));
                requiredModules = cmdletResult.Where(c => !c.ToString().StartsWith(".")).Select(c => c.ToString()).ToList();
                if (nestedModules.Any())
                {
                    Directory.SetCurrentDirectory(directory);

                    requiredModules = requiredModules.Join(scopes,
                                                           module => 1,
                                                           dir => 1,
                                                           (module, dir) => Path.Combine(dir, module))
                                      .Where(f => Directory.Exists(f))
                                      .ToList();

                    requiredModules.Add(directory);
                    List <CmdletMetadata> allCmdlets = new List <CmdletMetadata>();
                    foreach (var nestedModule in nestedModules)
                    {
                        var assemblyFile = Directory.GetFiles(parentDirectory, nestedModule, SearchOption.AllDirectories).FirstOrDefault();
                        if (File.Exists(assemblyFile))
                        {
                            var assemblyFileName = Path.GetFileName(assemblyFile);
                            helpLogger.Decorator.AddDecorator((h) =>
                            {
                                h.HelpFile = assemblyFileName;
                                h.Assembly = assemblyFileName;
                            }, "Cmdlet");
                            processedHelpFiles.Add(assemblyFileName);
                            var proxy   = EnvironmentHelpers.CreateProxy <CmdletLoader>(directory, out _appDomain);
                            var module  = proxy.GetModuleMetadata(assemblyFile, requiredModules);
                            var cmdlets = module.Cmdlets;
                            allCmdlets.AddRange(cmdlets);
                            helpLogger.Decorator.Remove("Cmdlet");
                            AppDomain.Unload(_appDomain);
                        }
                    }

                    ValidateHelpRecords(allCmdlets, helpFiles, helpLogger);
                }

                Directory.SetCurrentDirectory(savedDirectory);
            }
        }
Beispiel #16
0
        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 ProcessDirectory(string directoryPath)
        {
            var savedDirectory = Directory.GetCurrentDirectory();

            Directory.SetCurrentDirectory(directoryPath);

// TODO: Remove IfDef
#if NETSTANDARD
            _loader = new AssemblyLoader();
#else
            _loader = EnvironmentHelpers.CreateProxy <AssemblyLoader>(directoryPath, out _testDomain);
#endif
            foreach (var file in Directory.GetFiles(directoryPath).Where(file => file.EndsWith(".dll")))
            {
                var assembly = CreateAssemblyRecord(file);
                _assemblies[assembly.Name] = assembly;
                if (RequiresExactVersionMatch(assembly))
                {
                    AddSharedAssemblyExactVersion(assembly);
                }
                else
                {
                    AddSharedAssembly(assembly);
                }
            }

            // Now check for assembly mismatches
            foreach (var assembly in _assemblies.Values)
            {
                foreach (var reference in assembly.Children)
                {
                    CheckAssemblyReference(reference, assembly);
                }
            }

            foreach (var assembly in _assemblies.Values)
            {
                if (!assembly.Name.Contains("System") && !assembly.Name.Contains("Microsoft.IdentityModel") &&
                    !assembly.Name.Equals("Newtonsoft.Json") && !assembly.Name.Equals("Microsoft.AspNetCore.WebUtilities"))
                {
                    foreach (var parent in assembly.ReferencingAssembly)
                    {
                        _dependencyMapLogger.LogRecord(
                            new DependencyMap
                        {
                            AssemblyName               = assembly.Name,
                            AssemblyVersion            = assembly.Version.ToString(),
                            ReferencingAssembly        = parent.Name,
                            ReferencingAssemblyVersion = parent.Version.ToString(),
                            Severity = 3
                        });
                    }
                }
            }

            FindExtraAssemblies();

// TODO: Remove IfDef code
#if !NETSTANDARD
            AppDomain.Unload(_testDomain);
#endif
            Directory.SetCurrentDirectory(savedDirectory);
        }
        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 allCmdlets = new List <CmdletMetadata>();


            string moduleName = psd1FileName.Replace(".psd1", "");

            Console.WriteLine(directory);
            Directory.SetCurrentDirectory(directory);

            processedHelpFiles.Add(moduleName);

            helpLogger.Decorator.AddDecorator(h =>
            {
                h.HelpFile = moduleName;
                h.Assembly = moduleName;
            }, "Cmdlet");
            var module  = MetadataLoader.GetModuleMetadata(moduleName);
            var cmdlets = module.Cmdlets;

            allCmdlets.AddRange(cmdlets);
            helpLogger.Decorator.Remove("Cmdlet");

            ValidateHelpRecords(allCmdlets, helpFiles, helpLogger);
            ValidateHelpMarkdown(helpFolder, helpFiles, helpLogger);

            Directory.SetCurrentDirectory(savedDirectory);
        }
Beispiel #19
0
        private void ProcessDirectory(string directoryPath)
        {
            var savedDirectory = Directory.GetCurrentDirectory();

            Directory.SetCurrentDirectory(directoryPath);
            var moduleAlcAssemblySet     = LoadModuleAclAssembly(directoryPath);
            var moduleAlcAssemblyNameSet = moduleAlcAssemblySet?.Select(a => Path.GetFileNameWithoutExtension(a))?.ToHashSet();

            foreach (var file in Directory.GetFiles(directoryPath).Where(file => file.EndsWith(".dll")))
            {
                //Ignore ALC assemblies for special handle later
                var fileName = Path.GetFileNameWithoutExtension(file);
                if (moduleAlcAssemblyNameSet?.Contains(fileName) == true)
                {
                    continue;
                }

                var assembly = CreateAssemblyRecord(file);
                if (assembly?.Name != null && !IsFrameworkAssembly(assembly.Name))
                {
                    _assemblies[assembly.Name] = assembly;
                    AddSharedAssembly(assembly);
                }
            }

            // Now check for assembly mismatches
            bool alcWrapperIsReferenced = false;

            foreach (var assembly in _assemblies.Values)
            {
                foreach (var reference in assembly.Children)
                {
                    if (reference.Name.Contains(AlcWrapperAssemblyKeyWord) ||
                        moduleAlcAssemblyNameSet?.Contains(reference.Name) == true)
                    {
                        alcWrapperIsReferenced = CheckDirectReferenceToAlcWrapperAssembly(moduleAlcAssemblyNameSet, assembly, reference) || alcWrapperIsReferenced;
                    }
                    else
                    {
                        CheckAssemblyReference(reference, assembly);
                    }
                }
            }

            CheckAlcAssemblyDependency(moduleAlcAssemblySet, alcWrapperIsReferenced);

            foreach (var assembly in _assemblies.Values)
            {
                if (!assembly.Name.Contains("Microsoft.IdentityModel") && !assembly.Name.Equals("Newtonsoft.Json") && !IsFrameworkAssembly(assembly.Name))
                {
                    foreach (var parent in assembly.ReferencingAssembly)
                    {
                        _dependencyMapLogger.LogRecord(
                            new DependencyMap
                        {
                            AssemblyName               = assembly.Name,
                            AssemblyVersion            = assembly.Version.ToString(),
                            ReferencingAssembly        = parent.Name,
                            ReferencingAssemblyVersion = parent.Version.ToString(),
                            Severity = 3
                        });
                    }
                }
            }

            FindExtraAssemblies();
            Directory.SetCurrentDirectory(savedDirectory);
        }
 private void ValidateHelpRecords(IList<CmdletHelpMetadata> cmdlets, IList<string> helpRecords, 
     ReportLogger<HelpIssue> helpLogger)
 {
     foreach (var cmdlet in cmdlets)
     {
         if (!helpRecords.Contains(cmdlet.CmdletName, StringComparer.OrdinalIgnoreCase))
         {
             helpLogger.LogRecord(new HelpIssue
             {
                 Target = cmdlet.ClassName,
                 Severity = 1,
                 ProblemId = MissingHelp,
                 Description = string.Format("Help missing for cmdlet {0} implemented by class {1}", 
                 cmdlet.CmdletName, cmdlet.ClassName),
                 Remediation = string.Format("Add Help record for cmdlet {0} to help file.", cmdlet.CmdletName)
             });
         }
     }
 }