puppet-cleaner 0.1.0
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.
- data/COPYRIGHT +26 -0
- data/Changelog +8 -0
- data/README.md +40 -0
- data/bin/puppet-clean +101 -0
- data/bin/puppet-diff +49 -0
- data/bin/puppet-inspect +17 -0
- data/lib/puppet-cleaner/inspect.rb +11 -0
- data/lib/puppet-cleaner/line.rb +108 -0
- data/lib/puppet-cleaner/parts.rb +137 -0
- data/lib/puppet-cleaner/workers/alignfarrow.rb +55 -0
- data/lib/puppet-cleaner/workers/ensurefirst.rb +27 -0
- data/lib/puppet-cleaner/workers/multilinecomments.rb +18 -0
- data/lib/puppet-cleaner/workers/octalmode.rb +18 -0
- data/lib/puppet-cleaner/workers/quotedbooleans.rb +14 -0
- data/lib/puppet-cleaner/workers/softtabs.rb +43 -0
- data/lib/puppet-cleaner/workers/symlink.rb +47 -0
- data/lib/puppet-cleaner/workers/trailingwhitespace.rb +11 -0
- data/lib/puppet-cleaner/workers/trailingwhitespaceincomments.rb +11 -0
- data/lib/puppet-cleaner/workers/unneededquotes.rb +16 -0
- data/lib/puppet-cleaner/workers/worker.rb +59 -0
- data/lib/puppet-cleaner/workers.rb +2 -0
- data/lib/puppet-cleaner.rb +36 -0
- metadata +88 -0
data/COPYRIGHT
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
Copyright (c) 2013, Gerardo Santana Gomez Garrido <gerardo.santana@gmail.com>
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions
|
6
|
+
are met:
|
7
|
+
|
8
|
+
1. Redistributions of source code must retain the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer.
|
10
|
+
2. Redistributions in binary form must reproduce the above copyright
|
11
|
+
notice, this list of conditions and the following disclaimer in the
|
12
|
+
documentation and/or other materials provided with the distribution.
|
13
|
+
3. The name of the author may not be used to endorse or promote products
|
14
|
+
derived from this software without specific prior written permission.
|
15
|
+
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
17
|
+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
19
|
+
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
20
|
+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
21
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
22
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
23
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
24
|
+
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
25
|
+
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
26
|
+
POSSIBILITY OF SUCH DAMAGE.
|
data/Changelog
ADDED
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
Puppet Cleaner
|
2
|
+
==============
|
3
|
+
|
4
|
+
Puppet DSL source code cleaner and helper utilities
|
5
|
+
|
6
|
+
Motivation
|
7
|
+
----------
|
8
|
+
http://santanatechnotes.blogspot.mx/2013/04/puppet-cleaner-010-released.html
|
9
|
+
|
10
|
+
Requirements
|
11
|
+
------------
|
12
|
+
|
13
|
+
* puppet
|
14
|
+
|
15
|
+
it has been tested with puppet 2.7.11 only
|
16
|
+
|
17
|
+
Utilities
|
18
|
+
------------
|
19
|
+
|
20
|
+
### puppet-clean
|
21
|
+
|
22
|
+
Receives a puppet manifest file as input and outputs the result of
|
23
|
+
applying a set of transformation rules that makes it comply with
|
24
|
+
a subset of the current puppet style guide.
|
25
|
+
|
26
|
+
### puppet-diff
|
27
|
+
|
28
|
+
Receives two puppet manifest files and outputs its difference, after
|
29
|
+
converting them to YAML. Useful for verifying what (if anything) has
|
30
|
+
changed after applying puppet-clean.
|
31
|
+
|
32
|
+
### puppet-inspect
|
33
|
+
|
34
|
+
Receives a puppet manifest file and converts its objects (defined types,
|
35
|
+
classes and nodes) to YAML.
|
36
|
+
|
37
|
+
Help & Feedback
|
38
|
+
------------
|
39
|
+
|
40
|
+
Mail me directly if you need help or have any feedback about it.
|
data/bin/puppet-clean
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'getoptlong'
|
4
|
+
require 'puppet-cleaner'
|
5
|
+
|
6
|
+
def usage
|
7
|
+
warn <<-EOS
|
8
|
+
Usage:
|
9
|
+
|
10
|
+
#{File.basename($0)} [-h] [-t n] [-abedlmovw ] file.pp [file2.pp...]
|
11
|
+
|
12
|
+
Options:
|
13
|
+
-h, --help this help message
|
14
|
+
-d, --debug prints tokens before and after the transformation
|
15
|
+
|
16
|
+
-a, --alignfarrow aligns fat arrow (=>)
|
17
|
+
-b, --quotedbooleans removes unneeded quotes around boolean literals
|
18
|
+
-e, --ensurefirst moves 'ensure' parameter to the top
|
19
|
+
-l, --link uses ensure => link and target for symbolic links
|
20
|
+
-m, --mlcomments converts /* */ style comments into #
|
21
|
+
-o, --octalmode uses a 4 digit string for file modes
|
22
|
+
-t n, --softtabs n indents by n spaces
|
23
|
+
-v, --quotedvariables removes unneeded quotes around variables
|
24
|
+
-w, --trailingws removes trailing white space
|
25
|
+
EOS
|
26
|
+
exit 1
|
27
|
+
end
|
28
|
+
|
29
|
+
opts = GetoptLong.new(
|
30
|
+
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
31
|
+
[ '--debug', '-d', GetoptLong::NO_ARGUMENT ],
|
32
|
+
|
33
|
+
[ '--alignfarrow', '-a', GetoptLong::NO_ARGUMENT ],
|
34
|
+
[ '--quotedbooleans', '-b', GetoptLong::NO_ARGUMENT ],
|
35
|
+
[ '--ensurefirst', '-e', GetoptLong::NO_ARGUMENT ],
|
36
|
+
[ '--link', '-l', GetoptLong::NO_ARGUMENT ],
|
37
|
+
[ '--mlcomments', '-m', GetoptLong::NO_ARGUMENT ],
|
38
|
+
[ '--octalmode', '-o', GetoptLong::NO_ARGUMENT ],
|
39
|
+
[ '--softtabs', '-t', GetoptLong::REQUIRED_ARGUMENT ],
|
40
|
+
[ '--quotedvariables', '-v', GetoptLong::NO_ARGUMENT ],
|
41
|
+
[ '--trailingws', '-w', GetoptLong::NO_ARGUMENT ]
|
42
|
+
)
|
43
|
+
|
44
|
+
debug = false
|
45
|
+
workers = []
|
46
|
+
|
47
|
+
opts.each do |opt, arg|
|
48
|
+
case opt
|
49
|
+
when '--help'
|
50
|
+
usage
|
51
|
+
when '--debug'
|
52
|
+
debug = true
|
53
|
+
when '--alignfarrow'
|
54
|
+
workers << Puppet::Cleaner::AlignFarrow.new
|
55
|
+
when '--quotedbooleans'
|
56
|
+
workers << Puppet::Cleaner::QuotedBooleans.new
|
57
|
+
when '--ensurefirst'
|
58
|
+
workers << Puppet::Cleaner::EnsureFirst.new
|
59
|
+
when '--link'
|
60
|
+
workers << Puppet::Cleaner::Symlink.new
|
61
|
+
when '--mlcomments'
|
62
|
+
workers << Puppet::Cleaner::MultilineComments.new
|
63
|
+
when '--octalmode'
|
64
|
+
workers << Puppet::Cleaner::OctalMode.new
|
65
|
+
when '--softtabs'
|
66
|
+
tabstop = arg.to_i <= 2 ? 2 : arg.to_i
|
67
|
+
workers << Puppet::Cleaner::SoftTabs.new(tabstop)
|
68
|
+
when '--quotedvariables'
|
69
|
+
workers << Puppet::Cleaner::UnneededQuotes.new
|
70
|
+
when '--trailingws'
|
71
|
+
workers << Puppet::Cleaner::TrailingWhitespace.new
|
72
|
+
workers << Puppet::Cleaner::TrailingWhitespaceInComments.new
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
usage if ARGV.size < 1
|
77
|
+
|
78
|
+
ALL = [
|
79
|
+
Puppet::Cleaner::MultilineComments.new,
|
80
|
+
Puppet::Cleaner::SoftTabs.new,
|
81
|
+
Puppet::Cleaner::UnneededQuotes.new,
|
82
|
+
Puppet::Cleaner::TrailingWhitespace.new,
|
83
|
+
Puppet::Cleaner::TrailingWhitespaceInComments.new,
|
84
|
+
Puppet::Cleaner::AlignFarrow.new,
|
85
|
+
Puppet::Cleaner::OctalMode.new,
|
86
|
+
Puppet::Cleaner::EnsureFirst.new,
|
87
|
+
Puppet::Cleaner::QuotedBooleans.new,
|
88
|
+
Puppet::Cleaner::Symlink.new
|
89
|
+
]
|
90
|
+
|
91
|
+
|
92
|
+
workers = ALL if workers.empty?
|
93
|
+
|
94
|
+
ARGV.each do |filename|
|
95
|
+
line = Puppet::Cleaner.open(filename)
|
96
|
+
line.hire(workers)
|
97
|
+
puts line.inspect if debug
|
98
|
+
line.transform!
|
99
|
+
line.show
|
100
|
+
puts line.inspect if debug
|
101
|
+
end
|
data/bin/puppet-diff
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'puppet-cleaner/inspect'
|
4
|
+
|
5
|
+
def usage
|
6
|
+
warn <<-EOS
|
7
|
+
Usage:
|
8
|
+
#{File.basename $0} [-h] [-w] old.pp new.pp
|
9
|
+
|
10
|
+
Options:
|
11
|
+
-h, --help this help message
|
12
|
+
-w, --write write a YAML file for each pp file if they are different
|
13
|
+
EOS
|
14
|
+
exit 1
|
15
|
+
end
|
16
|
+
|
17
|
+
opts = GetoptLong.new(
|
18
|
+
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
19
|
+
[ '--write', '-w', GetoptLong::NO_ARGUMENT ]
|
20
|
+
)
|
21
|
+
|
22
|
+
writedown = false
|
23
|
+
|
24
|
+
opts.each do |opt, arg|
|
25
|
+
case opt
|
26
|
+
when '--help'
|
27
|
+
usage
|
28
|
+
when '--write'
|
29
|
+
writedown = true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
usage if ARGV.size != 2
|
34
|
+
|
35
|
+
filenames = ARGV
|
36
|
+
|
37
|
+
old, new = filenames.collect do |filename|
|
38
|
+
catalog = Puppet::Cleaner.inspect(filename)
|
39
|
+
catalog.to_yaml.gsub(/^.*(?:file(?:_index)?|line):.*$/, "")
|
40
|
+
end
|
41
|
+
|
42
|
+
if old != new
|
43
|
+
puts "#{filenames[0]} and #{filenames[1]} differ"
|
44
|
+
|
45
|
+
if writedown
|
46
|
+
File.open("#{filenames[0]}.yaml", "w") {|f| f.write old }
|
47
|
+
File.open("#{filenames[1]}.yaml", "w") {|f| f.write new }
|
48
|
+
end
|
49
|
+
end
|
data/bin/puppet-inspect
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'puppet-cleaner/inspect'
|
4
|
+
|
5
|
+
def usage
|
6
|
+
warn <<-EOS
|
7
|
+
Usage:
|
8
|
+
#{File.basename $0} file.pp
|
9
|
+
EOS
|
10
|
+
exit 1
|
11
|
+
end
|
12
|
+
|
13
|
+
usage if ARGV.size != 1
|
14
|
+
|
15
|
+
filename = ARGV[0]
|
16
|
+
catalog = Puppet::Cleaner.inspect(filename)
|
17
|
+
catalog.each {|e| puts e.to_yaml }
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'puppet/parser'
|
2
|
+
|
3
|
+
module Puppet::Cleaner
|
4
|
+
def self.inspect(filename)
|
5
|
+
Puppet[:manifest] = filename
|
6
|
+
tc = Puppet::Node::Environment.new(Puppet[:environment]).known_resource_types
|
7
|
+
catalog = [:nodes, :hostclasses, :definitions].collect {|meth| tc.send(meth) }
|
8
|
+
tc.clear
|
9
|
+
catalog
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'puppet-cleaner/parts'
|
2
|
+
|
3
|
+
module Puppet::Cleaner
|
4
|
+
class Line
|
5
|
+
attr :position
|
6
|
+
|
7
|
+
def initialize(parts)
|
8
|
+
@parts = parts.map {|part| Part.create(part) }
|
9
|
+
@workers = Hash.new {|h, k| h[k] = []}
|
10
|
+
@position = 0
|
11
|
+
end
|
12
|
+
|
13
|
+
def hire(workers)
|
14
|
+
@workers.clear
|
15
|
+
workers.each do |worker|
|
16
|
+
worker.part_names.each {|part_name| @workers[part_name] << worker }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def transform!
|
21
|
+
start do |part|
|
22
|
+
@workers[part.name].each do |worker|
|
23
|
+
worker.operate(self)
|
24
|
+
if part.object_id != current.object_id
|
25
|
+
back!
|
26
|
+
break
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def inspect
|
33
|
+
@parts.inject("") {|m, part| m += "#{part.name.inspect}\t#{part.value.inspect}\n"}
|
34
|
+
end
|
35
|
+
|
36
|
+
def show
|
37
|
+
start {|part| context = {:before => prev, :after => self.next}; part.show(context) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def start
|
41
|
+
reset!
|
42
|
+
while !empty?
|
43
|
+
yield current
|
44
|
+
advance!
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def size
|
49
|
+
@parts.size
|
50
|
+
end
|
51
|
+
|
52
|
+
def reset!
|
53
|
+
@position = 0
|
54
|
+
end
|
55
|
+
|
56
|
+
def advance!(n = 1)
|
57
|
+
@position += n
|
58
|
+
end
|
59
|
+
|
60
|
+
def back!(n = 1)
|
61
|
+
@position -= n
|
62
|
+
end
|
63
|
+
|
64
|
+
def empty?
|
65
|
+
@position >= 0 && @position >= size
|
66
|
+
end
|
67
|
+
|
68
|
+
def parts
|
69
|
+
@parts
|
70
|
+
end
|
71
|
+
|
72
|
+
def current
|
73
|
+
@parts[@position]
|
74
|
+
end
|
75
|
+
|
76
|
+
def next(n = 1)
|
77
|
+
(@position + n) >= size ? NoPart : @parts[@position + n]
|
78
|
+
end
|
79
|
+
|
80
|
+
def prev(n = 1)
|
81
|
+
(@position - n) < 0 ? NoPart : @parts[@position - n]
|
82
|
+
end
|
83
|
+
|
84
|
+
def last?
|
85
|
+
@position == (size - 1)
|
86
|
+
end
|
87
|
+
|
88
|
+
def lookup(name, ignore = [])
|
89
|
+
position = @position
|
90
|
+
while position < size && !(ignore + [name]).include?(@parts[position].name)
|
91
|
+
position += 1
|
92
|
+
end
|
93
|
+
position == size || @parts[position].name != name ? nil : position
|
94
|
+
end
|
95
|
+
|
96
|
+
def remove(pos)
|
97
|
+
@parts.delete_at(pos)
|
98
|
+
end
|
99
|
+
|
100
|
+
def insert(pos, parts)
|
101
|
+
@parts.insert(pos, *parts)
|
102
|
+
end
|
103
|
+
|
104
|
+
def append(pos, parts)
|
105
|
+
@parts.insert(pos + 1, *parts)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module Puppet::Cleaner
|
2
|
+
class Part
|
3
|
+
# what makes a double quote string special
|
4
|
+
DQSPECIAL = {
|
5
|
+
"\n" => "\\n",
|
6
|
+
"\r" => "\\r",
|
7
|
+
"\t" => "\\t"
|
8
|
+
}
|
9
|
+
|
10
|
+
DQESCAPE = DQSPECIAL.dup
|
11
|
+
DQESCAPE["\""] = "\\\""
|
12
|
+
DQESCAPE["\\"] = "\\\\"
|
13
|
+
DQESCAPE["$"] = "\\$"
|
14
|
+
|
15
|
+
SQESCAPE = {
|
16
|
+
"'" => "\\'"
|
17
|
+
}
|
18
|
+
|
19
|
+
DQPATTERN = /[#{DQESCAPE.keys.map{|key| key.inspect[1..-2]}.join}]/
|
20
|
+
SQPATTERN = /[#{SQESCAPE.keys.map{|key| key.inspect[1..-2]}.join}]/
|
21
|
+
|
22
|
+
SPECIAL_ESCAPE_SEQUENCES = /[#{DQSPECIAL.keys.map{|key| key.inspect[1..-2]}.join}]/
|
23
|
+
|
24
|
+
def self.create(raw)
|
25
|
+
begin
|
26
|
+
klass = Puppet::Cleaner.const_get(raw[0].to_s.capitalize.to_sym)
|
27
|
+
klass.new(raw)
|
28
|
+
rescue NameError => e
|
29
|
+
Part.new(raw)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(raw)
|
34
|
+
@raw = raw
|
35
|
+
end
|
36
|
+
|
37
|
+
def has_special_escape_sequences?
|
38
|
+
value =~ SPECIAL_ESCAPE_SEQUENCES
|
39
|
+
end
|
40
|
+
|
41
|
+
def show(context)
|
42
|
+
print to_s
|
43
|
+
end
|
44
|
+
|
45
|
+
def name
|
46
|
+
@raw[0]
|
47
|
+
end
|
48
|
+
|
49
|
+
def name=(name)
|
50
|
+
@raw[0] = name
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_s
|
54
|
+
value.to_s
|
55
|
+
end
|
56
|
+
|
57
|
+
def value
|
58
|
+
@raw[1][:value]
|
59
|
+
end
|
60
|
+
|
61
|
+
def value=(value)
|
62
|
+
@raw[1][:value] = value
|
63
|
+
end
|
64
|
+
|
65
|
+
def dqescape
|
66
|
+
value.gsub(Part::DQPATTERN) {|match| Part::DQESCAPE[match]}
|
67
|
+
end
|
68
|
+
|
69
|
+
def sqescape
|
70
|
+
ret = value.gsub(Part::SQPATTERN) {|match| Part::SQESCAPE[match]}
|
71
|
+
ret =~ /\\+$/
|
72
|
+
ret += "\\" if $& && $&.size % 2 == 1
|
73
|
+
ret
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
class Variable < Part
|
79
|
+
def to_s
|
80
|
+
"$#{value}"
|
81
|
+
end
|
82
|
+
|
83
|
+
def show(context)
|
84
|
+
if [:DQPRE, :DQMID].include?(context[:before].name)
|
85
|
+
print value
|
86
|
+
else
|
87
|
+
super
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class Comment < Part
|
93
|
+
def to_s
|
94
|
+
value.empty? ? "#" : "# #{value}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
class Mlcomment < Part
|
99
|
+
def to_s
|
100
|
+
"/*#{value}*/"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class Dqpre < Part
|
105
|
+
def to_s
|
106
|
+
"\"#{dqescape}${"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class Dqmid < Part
|
111
|
+
def to_s
|
112
|
+
"}#{dqescape}${"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
class Dqpost < Part
|
117
|
+
def to_s
|
118
|
+
"}#{dqescape}\""
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
class String < Part
|
123
|
+
def to_s
|
124
|
+
has_special_escape_sequences? ? "\"#{dqescape}\"" : "'#{sqescape}'"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
class Class < Part; end
|
129
|
+
|
130
|
+
class Regex < Part
|
131
|
+
def to_s
|
132
|
+
value.inspect
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
NoPart = Part.new([:NOPART, {:value => ""}])
|
137
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Puppet::Cleaner
|
2
|
+
class AlignFarrow < Worker
|
3
|
+
def part_names
|
4
|
+
[:LBRACE]
|
5
|
+
end
|
6
|
+
|
7
|
+
def operate(line)
|
8
|
+
max, params = get_params(line)
|
9
|
+
params.each do |param|
|
10
|
+
nblanks = max - param[:name].to_s.size + 1
|
11
|
+
param[:before].value = ' '*nblanks if param[:before].value.size != nblanks
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_params(line)
|
16
|
+
depth = 1
|
17
|
+
max = 0
|
18
|
+
pos = line.position
|
19
|
+
params = []
|
20
|
+
|
21
|
+
loop do
|
22
|
+
pos += 1
|
23
|
+
break if depth == 0 || pos >= line.parts.size
|
24
|
+
case line.parts[pos].name
|
25
|
+
when :LBRACE
|
26
|
+
depth += 1
|
27
|
+
when :RBRACE
|
28
|
+
depth -= 1
|
29
|
+
when :FARROW
|
30
|
+
next if depth != 1
|
31
|
+
|
32
|
+
if line.parts[pos - 1].name == :BLANK
|
33
|
+
name = line.parts[pos - 2]
|
34
|
+
before = line.parts[pos - 1]
|
35
|
+
else
|
36
|
+
name = line.parts[pos - 1]
|
37
|
+
before = Part.create([:BLANK, {:value => ''}])
|
38
|
+
line.insert(pos, [before])
|
39
|
+
pos += 1
|
40
|
+
end
|
41
|
+
|
42
|
+
if line.parts[pos + 1].name == :BLANK
|
43
|
+
line.parts[pos + 1].value = ' ' if line.parts[pos + 1].value != ' '
|
44
|
+
else
|
45
|
+
line.append(pos, Part.create([:BLANK, {:value => ' '}]))
|
46
|
+
end
|
47
|
+
|
48
|
+
max = name.to_s.size if name.to_s.size > max
|
49
|
+
params << {:name => name, :before => before}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
[max, params]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end # module
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Puppet::Cleaner
|
2
|
+
class EnsureFirst < Worker
|
3
|
+
def part_names
|
4
|
+
[:COLON]
|
5
|
+
end
|
6
|
+
|
7
|
+
def operate(line)
|
8
|
+
pos = line.position + 1
|
9
|
+
pos += 1 while [:BLANK, :RETURN, :COMMENT, :MLCOMMENT].include?(line.parts[pos].name)
|
10
|
+
return if line.parts[pos].name == :NAME && line.parts[pos].value == 'ensure'
|
11
|
+
start, pos = get_param(line, 'ensure', line.position)
|
12
|
+
return if start.nil?
|
13
|
+
|
14
|
+
ensure_param = line.parts.slice!(start..pos)
|
15
|
+
ensure_param += [Part.create([:COMMA, {:value => ","}])] unless ensure_param[-1].name == :COMMA
|
16
|
+
|
17
|
+
pos = start
|
18
|
+
if line.parts[pos].name == :SEMIC
|
19
|
+
commapos = start - 1
|
20
|
+
commapos -= 1 while [:RETURN, :BLANK].include?(line.parts[commapos])
|
21
|
+
line.parts.delete_at(commapos)
|
22
|
+
end
|
23
|
+
|
24
|
+
line.append(line.position, ensure_param)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Puppet::Cleaner
|
2
|
+
class MultilineComments < Worker
|
3
|
+
def part_names
|
4
|
+
[:MLCOMMENT]
|
5
|
+
end
|
6
|
+
|
7
|
+
def operate(line)
|
8
|
+
pos = line.position
|
9
|
+
comments = line.current.value.split("\n")
|
10
|
+
line.remove(pos)
|
11
|
+
comments.map! do |comment|
|
12
|
+
[Part.create([:COMMENT, {:value => comment}]),
|
13
|
+
Part.create([:RETURN, {:value => "\n"}])]
|
14
|
+
end
|
15
|
+
line.insert(pos, comments.flatten)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Puppet::Cleaner
|
2
|
+
class OctalMode < Worker
|
3
|
+
def part_names
|
4
|
+
[:FARROW]
|
5
|
+
end
|
6
|
+
|
7
|
+
def operate(line)
|
8
|
+
prev = line.prev.name == :BLANK ? line.prev(2) : line.prev
|
9
|
+
return if prev.value != "mode"
|
10
|
+
pos = line.next.name == :BLANK ? line.position + 2 : line.position + 1
|
11
|
+
mode = line.parts[pos]
|
12
|
+
|
13
|
+
if mode.value =~ /^0?[0-7]{1,4}$/
|
14
|
+
line.parts[pos] = Part.create([:STRING, {:value => mode.value.rjust(4, "0")}])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Puppet::Cleaner
|
2
|
+
class QuotedBooleans
|
3
|
+
def part_names
|
4
|
+
[:STRING]
|
5
|
+
end
|
6
|
+
|
7
|
+
def operate(line)
|
8
|
+
value = line.current.value
|
9
|
+
return if !['true', 'false'].include?(value)
|
10
|
+
line.parts.delete_at(line.position)
|
11
|
+
line.insert(line.position, [Part.create([:NAME, {:value => value}])])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Puppet::Cleaner
|
2
|
+
class SoftTabs < Worker
|
3
|
+
def initialize(tabstop = 2)
|
4
|
+
@depth = 0
|
5
|
+
@tabstop = tabstop
|
6
|
+
@resource_tab = {:size => 0, :depth => nil}
|
7
|
+
end
|
8
|
+
|
9
|
+
def part_names
|
10
|
+
[:LBRACE, :RBRACE, :LBRACK, :RBRACK, :LPAREN, :RPAREN, :COLON, :SEMIC, :RETURN]
|
11
|
+
end
|
12
|
+
|
13
|
+
def operate(line)
|
14
|
+
case line.current.name
|
15
|
+
when :LBRACE, :LBRACK, :LPAREN
|
16
|
+
@depth += 1
|
17
|
+
when :RBRACE, :RBRACK, :RPAREN
|
18
|
+
@resource_tab[:size] = 0 if line.current.name == :RBRACE && @resource_tab[:depth] == @depth
|
19
|
+
@depth -= 1
|
20
|
+
when :SEMIC
|
21
|
+
@resource_tab[:size] = 0
|
22
|
+
@resource_tab[:depth] = nil
|
23
|
+
when :COLON
|
24
|
+
pos = line.position - 1
|
25
|
+
pos -= 1 while pos >= 0 && ![:LBRACE, :RETURN].include?(line.parts[pos].name)
|
26
|
+
return if pos < 0 || line.parts[pos].name != :RETURN
|
27
|
+
pos = line.position + 1
|
28
|
+
pos += 1 while pos < line.parts.size && [:BLANK, :RETURN].include?(line.parts[pos].name)
|
29
|
+
return if pos == line.parts.size || line.parts[pos].name == :LBRACE
|
30
|
+
|
31
|
+
@resource_tab[:size] = 1
|
32
|
+
@resource_tab[:depth] = @depth
|
33
|
+
when :RETURN
|
34
|
+
return if line.last? || line.next.name == :RETURN
|
35
|
+
line.append(line.position, Part.create([:BLANK, {:value => ''}])) if line.next.name != :BLANK
|
36
|
+
n = [:RBRACE, :RBRACK, :RPAREN].include?(line.next(2).name) ? 1 : 0
|
37
|
+
@resource_tab[:size] = 0 if line.next(2).name == :RBRACE && @resource_tab[:depth] == @depth
|
38
|
+
blanks = ' '*@tabstop*(@depth - n + @resource_tab[:size])
|
39
|
+
line.next.value = blanks if line.next.value != blanks
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Puppet::Cleaner
|
2
|
+
class Symlink < Worker
|
3
|
+
def part_names
|
4
|
+
[:NAME]
|
5
|
+
end
|
6
|
+
|
7
|
+
def operate(line)
|
8
|
+
return if line.current.value != 'file'
|
9
|
+
pos = line.position + 1
|
10
|
+
pos += 1 while pos < line.parts.size && [:BLANK, :RETURN, :COMMENT, :MLCOMMENT].include?(line.parts[pos].name)
|
11
|
+
return if pos >= line.parts.size || line.parts[pos].name != :LBRACE
|
12
|
+
|
13
|
+
foreach_colon(line) {|colonpos|
|
14
|
+
start, pos = get_param(line, 'ensure', colonpos)
|
15
|
+
next if start.nil?
|
16
|
+
pos -= 1 if line.parts[pos].name == :COMMA
|
17
|
+
value = line.parts[pos].value
|
18
|
+
next if [:NAME, :STRING].include?(line.parts[pos].name) && %w(present absent file directory link symlink).include?(value)
|
19
|
+
next if line.parts[pos].name == :VARIABLE
|
20
|
+
ensure_param = [ [:RETURN, {:value => "\n"}], [:NAME, {:value => "ensure"}], [:FARROW, {:value => '=>'}], [:NAME, {:value => 'link'}], [:COMMA, {:value => ","}] ].map {|e| Part.create(e) }
|
21
|
+
start += 1 while line.parts[start].name != :NAME
|
22
|
+
line.parts[start].value = 'target'
|
23
|
+
line.append(colonpos, ensure_param)
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def foreach_colon(line)
|
28
|
+
pos = line.position
|
29
|
+
pos += 1 while pos < line.parts.size && line.parts[pos].name != :LBRACE
|
30
|
+
depth = 1
|
31
|
+
|
32
|
+
loop do
|
33
|
+
pos += 1
|
34
|
+
break if depth == 0 || pos >= line.parts.size
|
35
|
+
case line.parts[pos].name
|
36
|
+
when :LBRACE
|
37
|
+
depth += 1
|
38
|
+
when :RBRACE
|
39
|
+
depth -= 1
|
40
|
+
when :COLON
|
41
|
+
next if depth != 1
|
42
|
+
yield pos
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Puppet::Cleaner
|
2
|
+
class UnneededQuotes < Worker
|
3
|
+
def part_names
|
4
|
+
[:VARIABLE]
|
5
|
+
end
|
6
|
+
|
7
|
+
def operate(line)
|
8
|
+
return unless line.prev.name == :DQPRE && line.next.name == :DQPOST
|
9
|
+
return unless line.prev.value.empty? && line.next.value.empty?
|
10
|
+
pos = line.position
|
11
|
+
line.remove(pos + 1)
|
12
|
+
line.remove(pos - 1)
|
13
|
+
line.back!
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Puppet::Cleaner
|
2
|
+
class Worker
|
3
|
+
def part_names
|
4
|
+
raise "Must be implemented in subclass"
|
5
|
+
end
|
6
|
+
|
7
|
+
def operate
|
8
|
+
raise "Must be implemented in subclass"
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_param(line, param_name, pos)
|
12
|
+
depth = 1
|
13
|
+
|
14
|
+
loop do
|
15
|
+
pos += 1
|
16
|
+
break if depth == 0 || pos >= line.parts.size
|
17
|
+
case line.parts[pos].name
|
18
|
+
when :LBRACE, :COLON
|
19
|
+
depth += 1
|
20
|
+
when :RBRACE
|
21
|
+
depth -= 1
|
22
|
+
when :SEMIC
|
23
|
+
depth -= 1
|
24
|
+
when :FARROW
|
25
|
+
next if depth != 1
|
26
|
+
|
27
|
+
parampos = pos - 1
|
28
|
+
parampos -= 1 while [:BLANK, :RETURN].include?(line.parts[parampos].name)
|
29
|
+
next unless line.parts[parampos].name == :NAME && line.parts[parampos].value == param_name
|
30
|
+
start = parampos - 1
|
31
|
+
start -= 1 while [:BLANK, :RETURN].include?(line.parts[start].name)
|
32
|
+
start += 1
|
33
|
+
|
34
|
+
loop do
|
35
|
+
pos += 1
|
36
|
+
break if depth < 0 || pos >= line.parts.size
|
37
|
+
case line.parts[pos].name
|
38
|
+
when :LBRACE
|
39
|
+
depth += 1
|
40
|
+
when :COMMA, :SEMIC, :RBRACE
|
41
|
+
depth -= 1 if line.parts[pos].name == :RBRACE
|
42
|
+
next if depth > 1
|
43
|
+
pos += 1 if line.parts[pos].name == :RBRACE && depth == 1
|
44
|
+
pos += 1 while pos < line.parts.size && ![:COMMA, :SEMIC, :RBRACE].include?(line.parts[pos].name)
|
45
|
+
break
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
return nil if pos >= line.parts.size
|
50
|
+
pos -= 1 unless line.parts[pos].name == :COMMA
|
51
|
+
pos -= 1 while [:BLANK, :RETURN].include?(line.parts[pos].name)
|
52
|
+
|
53
|
+
return [start, pos]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end # module
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'puppet/parser'
|
2
|
+
require 'puppet-cleaner/line'
|
3
|
+
require 'puppet-cleaner/workers'
|
4
|
+
|
5
|
+
class Puppet::Parser::Lexer
|
6
|
+
class LexingContext < Hash
|
7
|
+
def []=(key, value)
|
8
|
+
return if key == :after && value == :BLANK
|
9
|
+
super
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
TOKENS[:COMMENT].skip = false
|
14
|
+
TOKENS[:MLCOMMENT].skip = false
|
15
|
+
TOKENS[:RETURN].skip = false
|
16
|
+
TOKENS.add_token :BLANK, %r{[ \t\r]+} do |lexer,value|
|
17
|
+
value.gsub!(/[\t\r]/,' ')
|
18
|
+
[self, value]
|
19
|
+
end
|
20
|
+
|
21
|
+
def lexing_context
|
22
|
+
@face_lexing_context ||= LexingContext.new.merge(@lexing_context)
|
23
|
+
end
|
24
|
+
|
25
|
+
def skip; end
|
26
|
+
end
|
27
|
+
|
28
|
+
module Puppet::Cleaner
|
29
|
+
def self.open(filename)
|
30
|
+
lexer = Puppet::Parser::Lexer.new
|
31
|
+
lexer.file = filename
|
32
|
+
tokens = lexer.fullscan
|
33
|
+
lexer.clear
|
34
|
+
Line.new(tokens[0..-2])
|
35
|
+
end
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: puppet-cleaner
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Gerardo Santana Gomez Garrido
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2013-04-18 00:00:00 Z
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Cleans puppet source code
|
22
|
+
email: gerardo.santana@gmail.com
|
23
|
+
executables:
|
24
|
+
- puppet-diff
|
25
|
+
- puppet-inspect
|
26
|
+
- puppet-clean
|
27
|
+
extensions: []
|
28
|
+
|
29
|
+
extra_rdoc_files: []
|
30
|
+
|
31
|
+
files:
|
32
|
+
- lib/puppet-cleaner.rb
|
33
|
+
- lib/puppet-cleaner/parts.rb
|
34
|
+
- lib/puppet-cleaner/line.rb
|
35
|
+
- lib/puppet-cleaner/inspect.rb
|
36
|
+
- lib/puppet-cleaner/workers.rb
|
37
|
+
- lib/puppet-cleaner/workers/quotedbooleans.rb
|
38
|
+
- lib/puppet-cleaner/workers/worker.rb
|
39
|
+
- lib/puppet-cleaner/workers/unneededquotes.rb
|
40
|
+
- lib/puppet-cleaner/workers/multilinecomments.rb
|
41
|
+
- lib/puppet-cleaner/workers/trailingwhitespaceincomments.rb
|
42
|
+
- lib/puppet-cleaner/workers/trailingwhitespace.rb
|
43
|
+
- lib/puppet-cleaner/workers/symlink.rb
|
44
|
+
- lib/puppet-cleaner/workers/alignfarrow.rb
|
45
|
+
- lib/puppet-cleaner/workers/ensurefirst.rb
|
46
|
+
- lib/puppet-cleaner/workers/octalmode.rb
|
47
|
+
- lib/puppet-cleaner/workers/softtabs.rb
|
48
|
+
- COPYRIGHT
|
49
|
+
- Changelog
|
50
|
+
- README.md
|
51
|
+
- bin/puppet-diff
|
52
|
+
- bin/puppet-inspect
|
53
|
+
- bin/puppet-clean
|
54
|
+
homepage: http://puppet-cleaner.rubyforge.org/
|
55
|
+
licenses: []
|
56
|
+
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options: []
|
59
|
+
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
hash: 3
|
68
|
+
segments:
|
69
|
+
- 0
|
70
|
+
version: "0"
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 3
|
77
|
+
segments:
|
78
|
+
- 0
|
79
|
+
version: "0"
|
80
|
+
requirements: []
|
81
|
+
|
82
|
+
rubyforge_project: puppet-cleaner
|
83
|
+
rubygems_version: 1.8.15
|
84
|
+
signing_key:
|
85
|
+
specification_version: 3
|
86
|
+
summary: Puppet Source Code Cleaner
|
87
|
+
test_files: []
|
88
|
+
|