1717using Microsoft . Windows . Powershell . ScriptAnalyzer . Generic ;
1818using System . ComponentModel . Composition ;
1919using System . Globalization ;
20+ using System . IO ;
21+ using System . Management . Automation ;
2022
2123namespace 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.
0 commit comments