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 +7 -0
- data/LICENSE.txt +11 -0
- data/README.md +32 -0
- data/Rakefile +10 -0
- data/lib/kafo_parsers.rb +1 -0
- data/lib/kafo_parsers/doc_parser.rb +129 -0
- data/lib/kafo_parsers/exceptions.rb +9 -0
- data/lib/kafo_parsers/puppet_module_parser.rb +82 -0
- data/lib/kafo_parsers/version.rb +3 -0
- metadata +152 -0
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
data/lib/kafo_parsers.rb
ADDED
@@ -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,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
|
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:
|