77
88module KafoParsers
99 class PuppetStringsModuleParser
10+ STRINGS_TYPE_MAP = {
11+ 'hostclass' => 'puppet_classes' ,
12+ 'definition' => 'defined_types' ,
13+ }
14+
1015 # You can call this method to get all supported information from a given manifest
1116 #
1217 # @param [ String ] manifest file path to parse
1318 # @return [ Hash ] hash containing values, validations, documentation, types, groups and conditions
1419 def self . parse ( file )
15- content = new ( file )
16- docs = content . docs
17-
18- # data_type must be called before other validations
19- data = {
20- :object_type => content . data_type ,
21- :values => content . values ,
22- :validations => content . validations
23- }
24- data [ :parameters ] = data [ :values ] . keys
25- data . merge! ( docs )
26- data
20+ new ( [ file ] ) . by_file ( file )
2721 end
2822
2923 def self . available?
@@ -35,11 +29,10 @@ def self.available?
3529 end
3630 end
3731
38- def initialize ( file )
39- @file = file = File . expand_path ( file )
40- raise KafoParsers ::ModuleName , "File not found #{ file } , check your answer file" unless File . exist? ( file )
32+ def initialize ( paths )
33+ @paths = paths . map { |path | File . expand_path ( path ) }
4134
42- command = [ 'strings' , 'generate' , '--format' , 'json' , file ]
35+ command = [ 'strings' , 'generate' , '--format' , 'json' ] + @paths
4336 @raw_json , stderr , status = self . class . run_puppet ( command )
4437
4538 unless status . success?
@@ -51,9 +44,20 @@ def initialize(file)
5144 rescue ::JSON ::ParserError => e
5245 raise KafoParsers ::ParseError , "'#{ command } ' returned invalid json output: #{ e . message } \n #{ @raw_json } "
5346 end
54- self . data_type # we need to determine data_type before any further parsing
5547
56- self
48+ if STRINGS_TYPE_MAP . values . all? { |key | @complete_hash [ key ] . empty? }
49+ raise KafoParsers ::ModuleName , "Nothing found in #{ @paths . join ( ',' ) } "
50+ end
51+ end
52+
53+ def by_file ( file )
54+ data_type , parsed_hash = find_by_property ( 'file' , File . expand_path ( file ) )
55+ format_result ( data_type , parsed_hash )
56+ end
57+
58+ def by_name ( name )
59+ data_type , parsed_hash = find_by_property ( 'name' , name )
60+ format_result ( data_type , parsed_hash )
5761 end
5862
5963 # AIO and system default puppet bins are tested for existence, fallback to just `puppet` otherwise
@@ -67,29 +71,17 @@ def self.puppet_bin
6771 end
6872 end
6973
70- def data_type
71- @data_type ||= begin
72- if ( @parsed_hash = @complete_hash [ 'puppet_classes' ] . find { |klass | klass [ 'file' ] == @file } )
73- 'hostclass'
74- elsif ( @parsed_hash = @complete_hash [ 'defined_types' ] . find { |klass | klass [ 'file' ] == @file } )
75- 'definition'
76- else
77- raise KafoParsers ::ParseError , "unable to find manifest data, syntax error in manifest #{ @file } ?"
78- end
79- end
80- end
81-
82- def values
83- Hash [
84- # combine known parameters (from tags) with any defaults provided
85- tag_params . select { |param | !param [ 'types' ] . nil? } . map { |param | [ param [ 'name' ] , nil ] } +
86- @parsed_hash . fetch ( 'defaults' , { } ) . map { |name , value | [ name , value . nil? ? nil : sanitize ( value ) ] }
87- ]
88- end
74+ private
8975
90- # unsupported in puppet strings parser
91- def validations ( param = nil )
92- [ ]
76+ def format_result ( data_type , parsed_hash )
77+ data = {
78+ :object_type => data_type ,
79+ :values => values_for_parsed_hash ( parsed_hash ) ,
80+ :validations => [ ] ,
81+ }
82+ data [ :parameters ] = data [ :values ] . keys
83+ data . merge! ( docs_for_parsed_hash ( parsed_hash ) )
84+ data
9385 end
9486
9587 # returns data in following form
@@ -99,25 +91,24 @@ def validations(param = nil)
9991 # :groups => { $param1 => ['Parameters', 'Advanced']},
10092 # :conditions => { $param1 => '$db_type == "mysql"'},
10193 # }
102- def docs
94+ def docs_for_parsed_hash ( parsed_hash )
10395 data = { :docs => { } , :types => { } , :groups => { } , :conditions => { } }
104- if @parsed_hash . nil?
105- raise KafoParsers ::DocParseError , "no documentation found for manifest #{ @file } , parsing error?"
106- elsif !@parsed_hash [ 'docstring' ] . nil? && !@parsed_hash [ 'docstring' ] [ 'text' ] . nil?
96+
97+ if parsed_hash . dig ( 'docstring' , 'text' )
10798 # Lowest precedence: types given in the strings hash from class definition
108- tag_params . each do |param |
99+ tag_params ( parsed_hash ) . each do |param |
109100 data [ :types ] [ param [ 'name' ] ] = param [ 'types' ] [ 0 ] unless param [ 'types' ] . nil?
110101 end
111102
112103 # Next: types and other data from RDoc parser
113- rdoc_parser = DocParser . new ( @ parsed_hash[ 'docstring' ] [ 'text' ] ) . parse
104+ rdoc_parser = DocParser . new ( parsed_hash [ 'docstring' ] [ 'text' ] ) . parse
114105 data [ :docs ] = rdoc_parser . docs
115106 data [ :groups ] = rdoc_parser . groups
116107 data [ :conditions ] = rdoc_parser . conditions
117108 data [ :types ] . merge! rdoc_parser . types
118109
119110 # Highest precedence: data in YARD @param stored in the 'text' field
120- tag_params . each do |param |
111+ tag_params ( parsed_hash ) . each do |param |
121112 param_name = param [ 'name' ]
122113 unless param [ 'text' ] . nil? || param [ 'text' ] . empty?
123114 param_parser = ParamDocParser . new ( param_name , param [ 'text' ] . split ( $/) )
@@ -131,7 +122,23 @@ def docs
131122 data
132123 end
133124
134- private
125+ def values_for_parsed_hash ( parsed_hash )
126+ Hash [
127+ # combine known parameters (from tags) with any defaults provided
128+ tag_params ( parsed_hash ) . select { |param | !param [ 'types' ] . nil? } . map { |param | [ param [ 'name' ] , nil ] } +
129+ parsed_hash . fetch ( 'defaults' , { } ) . map { |name , value | [ name , value . nil? ? nil : sanitize ( value ) ] }
130+ ]
131+ end
132+
133+ def find_by_property ( property , value )
134+ STRINGS_TYPE_MAP . each do |data_type , key |
135+ if ( parsed_hash = @complete_hash [ key ] . find { |klass | klass [ property ] == value } )
136+ return [ data_type , parsed_hash ]
137+ end
138+ end
139+
140+ raise KafoParsers ::ParseError , "unable to find manifest data, syntax error in manifest #{ file } ?"
141+ end
135142
136143 def self . search_puppet_path ( bin_name )
137144 # Find the location of the puppet executable and use that to
@@ -194,9 +201,9 @@ def sanitize(value)
194201 value
195202 end
196203
197- def tag_params
198- if @ parsed_hash[ 'docstring' ] [ 'tags' ]
199- @ parsed_hash[ 'docstring' ] [ 'tags' ] . select { |tag | tag [ 'tag_name' ] == 'param' }
204+ def tag_params ( parsed_hash )
205+ if parsed_hash [ 'docstring' ] [ 'tags' ]
206+ parsed_hash [ 'docstring' ] [ 'tags' ] . select { |tag | tag [ 'tag_name' ] == 'param' }
200207 else
201208 [ ]
202209 end
0 commit comments