Skip to content

Commit d94733c

Browse files
Adding implementation for class based resources
1 parent 6ff3193 commit d94733c

File tree

4 files changed

+78
-2
lines changed

4 files changed

+78
-2
lines changed

Rules/DscExamplesPresent.cs

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,17 @@
1717
using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic;
1818
using System.ComponentModel.Composition;
1919
using System.Globalization;
20+
using System.IO;
21+
using System.Management.Automation;
2022

2123
namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules
2224
{
2325
/// <summary>
24-
/// DscExamplesExist: Checks that DSC examples for given resource are present
26+
/// DscExamplesPresent: Checks that DSC examples for given resource are present.
27+
/// Rule expects directory Examples to be present:
28+
/// For non-class based resources it should exist at the same folder level as DSCResources folder.
29+
/// For class based resources it should be present at the same folder level as resource psm1 file.
30+
/// Examples folder should contain sample configuration for given resource - file name should contain resource's name.
2531
/// </summary>
2632
[Export(typeof(IDSCResourceRule))]
2733
public class DscExamplesPresent : IDSCResourceRule
@@ -34,7 +40,29 @@ public class DscExamplesPresent : IDSCResourceRule
3440
/// <returns>The results of the analysis</returns>
3541
public IEnumerable<DiagnosticRecord> AnalyzeDSCResource(Ast ast, string fileName)
3642
{
43+
String fileNameOnly = fileName.Substring(fileName.LastIndexOf("\\", StringComparison.Ordinal) + 1);
44+
String resourceName = fileNameOnly.Substring(0, fileNameOnly.Length - ".psm1".Length);
45+
String examplesQuery = "*" + resourceName + "*";
46+
Boolean examplesPresent = false;
47+
String expectedExamplesPath = fileName + "\\..\\..\\..\\Examples";
3748

49+
// Verify examples are present
50+
if (Directory.Exists(expectedExamplesPath))
51+
{
52+
DirectoryInfo examplesFolder = new DirectoryInfo(expectedExamplesPath);
53+
FileInfo[] exampleFiles = examplesFolder.GetFiles(examplesQuery);
54+
if (exampleFiles.Length != 0)
55+
{
56+
examplesPresent = true;
57+
}
58+
}
59+
60+
// Return error if no examples present
61+
if (!examplesPresent)
62+
{
63+
yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.DscExamplesPresentNoExamplesError, resourceName),
64+
null, GetName(), DiagnosticSeverity.Information, fileName);
65+
}
3866
}
3967

4068
/// <summary>
@@ -45,9 +73,44 @@ public IEnumerable<DiagnosticRecord> AnalyzeDSCResource(Ast ast, string fileName
4573
/// <returns></returns>
4674
public IEnumerable<DiagnosticRecord> AnalyzeDSCClass(Ast ast, string fileName)
4775
{
76+
String resourceName = null;
4877

49-
}
78+
// Obtain class based resource name
79+
IEnumerable<Ast> typeDefinitionAsts = (ast.FindAll(dscAst => dscAst is TypeDefinitionAst, true));
80+
foreach (TypeDefinitionAst typeDefinitionAst in typeDefinitionAsts)
81+
{
82+
var attributes = typeDefinitionAst.Attributes;
83+
foreach(var attribute in attributes)
84+
{
85+
if (attribute.TypeName.FullName.Equals("DscResource"))
86+
{
87+
resourceName = typeDefinitionAst.Name;
88+
}
89+
}
90+
}
91+
92+
String examplesQuery = "*" + resourceName + "*";
93+
Boolean examplesPresent = false;
94+
String expectedExamplesPath = fileName + "\\..\\Examples";
5095

96+
// Verify examples are present
97+
if (Directory.Exists(expectedExamplesPath))
98+
{
99+
DirectoryInfo examplesFolder = new DirectoryInfo(expectedExamplesPath);
100+
FileInfo[] exampleFiles = examplesFolder.GetFiles(examplesQuery);
101+
if (exampleFiles.Length != 0)
102+
{
103+
examplesPresent = true;
104+
}
105+
}
106+
107+
// Return error if no examples present
108+
if (!examplesPresent)
109+
{
110+
yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.DscExamplesPresentNoExamplesError, resourceName),
111+
null, GetName(), DiagnosticSeverity.Information, fileName);
112+
}
113+
}
51114

52115
/// <summary>
53116
/// GetName: Retrieves the name of this rule.

Rules/ScriptAnalyzerBuiltinRules.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
<Compile Include="AvoidUsingPlainTextForPassword.cs" />
6969
<Compile Include="AvoidUsingWMIObjectCmdlet.cs" />
7070
<Compile Include="AvoidUsingWriteHost.cs" />
71+
<Compile Include="DscExamplesPresent.cs" />
7172
<Compile Include="UseOutputTypeCorrectly.cs" />
7273
<Compile Include="MissingModuleManifestField.cs" />
7374
<Compile Include="PossibleIncorrectComparisonWithNull.cs" />

Rules/Strings.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Rules/Strings.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,4 +699,7 @@
699699
<data name="DscExamplesPresentDescription" xml:space="preserve">
700700
<value>Every DSC resource module should contain folder "Examples" with sample configurations for every resource. Sample configurations should have resource name they are demonstrating in the title.</value>
701701
</data>
702+
<data name="DscExamplesPresentNoExamplesError" xml:space="preserve">
703+
<value>No examples found for resource '{0}'</value>
704+
</data>
702705
</root>

0 commit comments

Comments
 (0)