kafo_parsers 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b30e88b47bab4b2e93f985edad54bbaf15d39f88
4
+ data.tar.gz: e55504058e7761a4007713304e4fa7f170aec79e
5
+ SHA512:
6
+ metadata.gz: dda98ff6406272517880053973c475be3edd7ceeebd9133996fd0ba0a31f03d20f9ea36502f20149a9fdcaa22d5b5964fbd35c7ffc96bf964c5e5956501af570
7
+ data.tar.gz: 4bc186885a9e4a0890343741c85bc8049bd26c18a3ed94cccf4aeb4d8e4d00f4a3dc8c48289012397ee3ccdf643835e2d4c2592d81113dbdfc6f37664102aeb5
data/LICENSE.txt ADDED
@@ -0,0 +1,11 @@
1
+ This program and entire repository is free software: you can redistribute it
2
+ and/or modify it under the terms of the GNU General Public License as
3
+ published by the Free Software Foundation, either version 3 of the License,
4
+ or any later version.
5
+
6
+ This program is distributed in the hope that it will be useful, but WITHOUT
7
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
9
+
10
+ You should have received a copy of the GNU General Public License along with
11
+ this program. If not, see http://www.gnu.org/licenses/.
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # KafoParsers
2
+
3
+ This gem can parse values, validations, documentation, types, groups and
4
+ conditions of parameters from your puppet modules. Only thing you have
5
+ to do is provide a path to manifest file you want to be parsed.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'kafo_parsers'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install kafo_parsers
20
+
21
+ ## Usage
22
+
23
+ To parse file and see parsed information
24
+ ```ruby
25
+ require 'kafo_parsers/kafo_module_parser'
26
+ hash = KafoParsers::KafoModuleParser.parse('/puppet/module/manifests/init.pp')
27
+ p hash
28
+ ```
29
+
30
+ # License
31
+
32
+ This project is licensed under the GPLv3+.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'rake/testtask'
2
+ require "bundler/gem_tasks"
3
+ load 'tasks/jenkins.rake'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << 'lib' << 'test'
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ t.verbose = true
9
+ end
10
+
@@ -0,0 +1 @@
1
+ require 'kafo_parsers/version'
@@ -0,0 +1,129 @@
1
+ # encoding: UTF-8
2
+ require 'rdoc'
3
+ require 'rdoc/markup' # required for RDoc < 0.9.5
4
+ require 'rdoc/markup/parser' # required for RDoc < 0.9.5
5
+
6
+ module KafoParsers
7
+ class DocParser
8
+ ATTRIBUTE_LINE = /^(condition|type)\s*:\s*(.*)/
9
+ HEADER_CONDITION = /\A(.+)\s*condition:\s*(.+)\Z/
10
+
11
+ def initialize(text)
12
+ @text = text
13
+ @nesting_buffer = []
14
+ @docs = {}
15
+ @groups = {}
16
+ @conditions = {}
17
+ @types = Hash.new('string')
18
+ @rdoc = rdoc_parser.parse(@text)
19
+ end
20
+
21
+ attr_reader :docs, :groups, :types, :conditions
22
+
23
+ # items is array of RDoc::Markup::* on one level
24
+ def parse(items = @rdoc.parts)
25
+ items.each do |item|
26
+ if item.is_a?(RDoc::Markup::Heading)
27
+ parse_header(item)
28
+ elsif item.is_a?(RDoc::Markup::List) && item.respond_to?(:items)
29
+ parse(item.items)
30
+ elsif item.is_a?(RDoc::Markup::ListItem)
31
+ parse_paragraph(item)
32
+ end
33
+ end
34
+ self
35
+ end
36
+
37
+ private
38
+
39
+ def parse_paragraph(para)
40
+ # Skip rdoc paras that aren't paragraphs
41
+ return unless (para.parts.to_s.scan("RDoc::Markup::Paragraph") == ["RDoc::Markup::Paragraph"])
42
+ # RDoc (>= 4) makes label an array
43
+ label = para.label.is_a?(Array) ? para.label.first : para.label
44
+ # Documentation must be a list - if there's no label then skip
45
+ return if label.nil?
46
+ key = label.gsub(/[^A-Za-z0-9_-]/, '')
47
+ @groups[key] = current_groups
48
+ text_parts = para.parts.first.parts.map!(&:strip)
49
+ attributes, docs = text_parts.partition { |line| line =~ ATTRIBUTE_LINE }
50
+ parse_attributes(key, attributes)
51
+ @docs[key] = docs
52
+ end
53
+
54
+ def parse_attributes(parameter, attributes)
55
+ condition = nil
56
+ attributes.each do |attribute|
57
+ data = attribute.match(ATTRIBUTE_LINE)
58
+ name, value = data[1], data[2]
59
+
60
+ case name
61
+ when 'type'
62
+ @types[parameter] = value
63
+ when 'condition'
64
+ if condition.nil?
65
+ condition = value
66
+ else
67
+ raise DocParseError, "Two or more conditions defined for #{name}"
68
+ end
69
+ else
70
+ raise DocParseError, "Unknown attribute #{name}"
71
+ end
72
+
73
+ end
74
+ condition = [current_condition, condition].compact.join(' && ')
75
+ @conditions[parameter] = condition.empty? ? nil : condition
76
+ end
77
+
78
+ def parse_header(heading)
79
+ if heading.level > current_level
80
+ @nesting_buffer.push nesting(heading)
81
+ elsif heading.level == current_level
82
+ @nesting_buffer.pop
83
+ @nesting_buffer.push nesting(heading)
84
+ else
85
+ while current_level >= heading.level do
86
+ @nesting_buffer.pop
87
+ end
88
+ @nesting_buffer.push nesting(heading)
89
+ end
90
+ end
91
+
92
+ def nesting(heading)
93
+ if heading.text =~ HEADER_CONDITION
94
+ text, condition = $1, $2
95
+ else
96
+ text, condition = heading.text, nil
97
+ end
98
+ Nesting.new(text.strip, heading.level, condition)
99
+ end
100
+
101
+ def current_groups
102
+ @nesting_buffer.map(&:name)
103
+ end
104
+
105
+ def current_level
106
+ current_nesting.nil? ? 0 : current_nesting.level
107
+ end
108
+
109
+ def current_condition
110
+ condition = @nesting_buffer.map(&:condition).select { |c| !c.nil? }.join(' && ')
111
+ condition.empty? ? nil : condition
112
+ end
113
+
114
+ def current_nesting
115
+ @nesting_buffer.last
116
+ end
117
+
118
+ def rdoc_parser
119
+ if RDoc::Markup.respond_to?(:parse)
120
+ RDoc::Markup
121
+ else # RDoc < 3.10.0
122
+ RDoc::Markup::Parser
123
+ end
124
+ end
125
+
126
+ class Nesting < Struct.new(:name, :level, :condition);
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: UTF-8
2
+ module KafoParsers
3
+ class DocParseError < StandardError
4
+ end
5
+
6
+ class ModuleName < StandardError
7
+ end
8
+
9
+ end
@@ -0,0 +1,82 @@
1
+ # encoding: UTF-8
2
+ require 'puppet'
3
+ require 'kafo_parsers/doc_parser'
4
+
5
+ module KafoParsers
6
+ # Based on ideas from puppet-parse by Johan van den Dorpe
7
+ # we don't build any tree structure since e.g. params from doc does not
8
+ # have to be defined in puppet DSL and vice versa, we just gather all info
9
+ # we can read from the whole manifest
10
+ class PuppetModuleParser
11
+ # You can call this method to get all supported information from a given manifest
12
+ #
13
+ # @param [ String ] manifest file path to parse
14
+ # @return [ Hash ] hash containing values, validations, documentation, types, groups and conditions
15
+ def self.parse(file)
16
+ content = new(file)
17
+ docs = content.docs
18
+
19
+ data = {
20
+ :values => content.values,
21
+ :validations => content.validations
22
+ }
23
+ data[:parameters] = data[:values].keys
24
+ data.merge!(docs)
25
+ data
26
+ end
27
+
28
+ def initialize(file)
29
+ @file = file
30
+ raise ModuleName, "File not found #{file}, check you answer file" unless File.exists?(file)
31
+ Puppet.settings[:confdir] ||= '/' # just some stubbing
32
+ if Puppet::Node::Environment.respond_to?(:create)
33
+ env = Puppet::Node::Environment.create(:production, [], '')
34
+ else
35
+ env = Puppet::Node::Environment.new(:production)
36
+ end
37
+ parser = Puppet::Parser::Parser.new(env)
38
+ parser.import(@file)
39
+
40
+ # Find object corresponding to class defined in init.pp in list of hostclasses
41
+ parser.environment.known_resource_types.hostclasses.each do |ast_objects|
42
+ ast_type = ast_objects.last
43
+ @object = ast_type if ast_type.file == file
44
+ end
45
+
46
+ parser
47
+ end
48
+
49
+ # TODO - store parsed object type (Puppet::Parser::AST::Variable must be dumped later)
50
+ def values
51
+ parameters = {}
52
+ arguments = @object.respond_to?(:arguments) ? @object.arguments : {}
53
+ arguments.each { |k, v| parameters[k] = v.respond_to?(:value) ? v.value : nil }
54
+ parameters
55
+ end
56
+
57
+ def validations(param = nil)
58
+ @object.code.select { |stmt| stmt.is_a?(Puppet::Parser::AST::Function) && stmt.name =~ /^validate_/ }
59
+ end
60
+
61
+ # returns data in following form
62
+ # {
63
+ # :docs => { $param1 => 'documentation without types and conditions'}
64
+ # :types => { $param1 => 'boolean'},
65
+ # :groups => { $param1 => ['Parameters', 'Advanced']},
66
+ # :conditions => { $param1 => '$db_type == "mysql"'},
67
+ # }
68
+ def docs
69
+ data = { :docs => {}, :types => {}, :groups => {}, :conditions => {} }
70
+ if @object.nil?
71
+ raise DocParseError, "no documentation found for manifest #{@file}, parsing error?"
72
+ elsif !@object.doc.nil?
73
+ parser = DocParser.new(@object.doc).parse
74
+ data[:docs] = parser.docs
75
+ data[:groups] = parser.groups
76
+ data[:types] = parser.types
77
+ data[:conditions] = parser.conditions
78
+ end
79
+ data
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,3 @@
1
+ module KafoParsers
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kafo_parsers
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Marek Hulan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '4.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '4.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: ci_reporter
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: puppet
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rdoc
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: 3.9.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: 3.9.0
111
+ description: This gem can parse values, validations, documentation, types, groups
112
+ and conditions of parameters from your puppet modules
113
+ email:
114
+ - mhulan@redhat.com
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - lib/kafo_parsers/puppet_module_parser.rb
120
+ - lib/kafo_parsers/doc_parser.rb
121
+ - lib/kafo_parsers/exceptions.rb
122
+ - lib/kafo_parsers/version.rb
123
+ - lib/kafo_parsers.rb
124
+ - LICENSE.txt
125
+ - Rakefile
126
+ - README.md
127
+ homepage: https://github.com/theforeman/kafo_parsers
128
+ licenses:
129
+ - GPLv3+
130
+ metadata: {}
131
+ post_install_message:
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - '>='
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubyforge_project:
147
+ rubygems_version: 2.0.3
148
+ signing_key:
149
+ specification_version: 4
150
+ summary: Puppet module parsers
151
+ test_files: []
152
+ has_rdoc: