kafo_parsers 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|