pp-stats 0.0.3

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dddf9d6b5f0caa035bd417aa54e39c9d45232858
4
+ data.tar.gz: a133a637ffd03fdf8539bd97247915d45c549cf3
5
+ SHA512:
6
+ metadata.gz: a4ec883a92a3ce7c9bd07440f7df79986743d966b9496dd97f74cc08dba5627a44a264d5326e19e4385da862c593d709fe3ed34c410c4de9c29271f7ecddf6ec
7
+ data.tar.gz: 52fe50d0099e6551e0820256052e3a75e301ef7f16c90616b8849ee3b1f0b6c75a4575359285fd2292598417e8ef010337336f3b1fde6eefa899b11927b0ffd8
@@ -0,0 +1,54 @@
1
+ #################
2
+ ## IntelliJ
3
+ #################
4
+
5
+ .classpath
6
+ .project
7
+ .settings/
8
+ .idea/
9
+ *.iml
10
+ *.iws
11
+
12
+ #################
13
+ ## Eclipse
14
+ #################
15
+
16
+ *.pydevproject
17
+ .project
18
+ .metadata
19
+ #bin/
20
+ tmp/
21
+ *.tmp
22
+ *.bak
23
+ *.swp
24
+ *~.nib
25
+ local.properties
26
+ .classpath
27
+ .settings/
28
+ .loadpath
29
+
30
+ # External tool builders
31
+ .externalToolBuilders/
32
+
33
+ # Locally stored "Eclipse launch configurations"
34
+ *.launch
35
+
36
+ # CDT-specific
37
+ .cproject
38
+
39
+ # PDT-specific
40
+ .buildpath
41
+
42
+ ############
43
+ ## Windows
44
+ ############
45
+
46
+ # Windows image file caches
47
+ Thumbs.db
48
+
49
+ # Folder config file
50
+ Desktop.ini
51
+
52
+ *.gem
53
+ .bundle
54
+ Gemfile.lock
@@ -0,0 +1,20 @@
1
+ Copyright © 2014 Jason Thigpen
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Binary file
@@ -0,0 +1,27 @@
1
+ # pp-stats
2
+
3
+ Command line ruby program that generates stats for Puppet module(s).
4
+
5
+ ## Install
6
+
7
+ Get it from rubygems
8
+
9
+ ```
10
+ $ gem install pp-stats
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ With no arguments, `pp-stats` assumes you're in a directory full of Puppet modules. Alternatively, provide a path to a directory of Puppet modules.
16
+
17
+ ```
18
+ $ pp-stats ~/workspace/corp/puppet
19
+ ```
20
+
21
+ ![](PuppetSummary.png)
22
+
23
+ ## Credit
24
+
25
+ This tool was originally developed by Adam Denning ([adenning](https://github.com/adenning/pp-stats)).
26
+
27
+ When I found it, the repo only had a single commit almost one year old. It provided a very good starting point, so I have forked it and added some bits for my own needs. I have kept Adam's initial commit for posterity and I have added an [MIT License](LICENSE.txt) for good measure.
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pp-stats'
4
+ PPStats::CommandLine.new(ARGV).run
@@ -0,0 +1,11 @@
1
+ require 'pp-stats/format'
2
+ require 'pp-stats/utils'
3
+ require 'pp-stats/counter'
4
+ require 'pp-stats/summary'
5
+ require 'pp-stats/modules'
6
+ require 'pp-stats/processor'
7
+ require 'pp-stats/command-line'
8
+
9
+ module PPStats
10
+
11
+ end
@@ -0,0 +1,50 @@
1
+ require 'optparse'
2
+
3
+ module PPStats
4
+ class CommandLine
5
+
6
+ def initialize(args)
7
+ end
8
+
9
+ def run
10
+ options = {}
11
+ optparse = OptionParser.new do |opts|
12
+ opts.banner = "usage: pp-stats [options] modulepath"
13
+ opts.on('--single-module', 'process a single module') do |flag|
14
+ options[:single_module] = flag
15
+ end
16
+ end
17
+
18
+ # Enforce required options and more graceful error handling.
19
+ begin
20
+ optparse.parse!
21
+ # Not using required options anymore but I left it wired up.
22
+ required = []
23
+ missing = required.select { |param| options[param].nil? }
24
+ if not missing.empty?
25
+ PPStats::Format.errorf("missing options: #{missing.join(', ')}")
26
+ exit
27
+ end
28
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument
29
+ PPStats::Format.errorf($!.to_s) # $! is exception object
30
+ exit
31
+ end
32
+
33
+ if ARGV.first.nil?
34
+ options[:modulepath] = '.'
35
+ else
36
+ options[:modulepath] = ARGV.first
37
+ end
38
+ if !File.directory? options[:modulepath]
39
+ PPStats::Format.errorf "module folder '#{options[:modulepath]}' not found"
40
+ exit
41
+ end
42
+
43
+ processor = PPStats::Processor.new(options)
44
+ processor.run
45
+ processor.results
46
+ end
47
+
48
+
49
+ end
50
+ end
@@ -0,0 +1,41 @@
1
+ module PPStats
2
+ class Counter
3
+ attr_reader :count
4
+
5
+ def initialize
6
+ @count = {
7
+ :files => 0,
8
+ :lines => 0,
9
+ :max_lines => 0,
10
+ :max_file => nil,
11
+ :floor_lines => nil,
12
+ :floor_file => nil,
13
+ :commented_lines => 0,
14
+ :max_commented_lines => 0,
15
+ :max_commented_file => '',
16
+ :floor_commented_lines => 0,
17
+ :floor_commented_file => nil,
18
+ }
19
+ end
20
+
21
+ def adjust(file, lines, commented_lines)
22
+ @count[:files] += 1
23
+ @count[:lines] += lines
24
+ if lines > @count[:max_lines]
25
+ @count[:max_lines] += lines
26
+ @count[:max_file] = file
27
+ end
28
+ @count[:commented_lines] += commented_lines
29
+ if commented_lines > @count[:max_commented_lines]
30
+ @count[:max_commented_lines] = commented_lines
31
+ @count[:max_commented_file] = file
32
+ end
33
+ if commented_lines < @count[:floor_commented_lines] || @count[:floor_commented_lines] == 0
34
+ @count[:floor_commented_lines] = commented_lines
35
+ @count[:floor_commented_file] = file
36
+ end
37
+
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,68 @@
1
+ module PPStats
2
+ module Format
3
+ def self.warnf(msg)
4
+ warn("Warning: #{msg}".yellow)
5
+ end
6
+
7
+ def self.errorf(msg)
8
+ warn("Error: #{msg}".red)
9
+ end
10
+
11
+ def self.green(msg)
12
+ msg.green
13
+ end
14
+
15
+ def self.blue(msg)
16
+ msg.blue
17
+ end
18
+
19
+ def self.magenta(msg)
20
+ msg.magenta
21
+ end
22
+
23
+ def self.cyan(msg)
24
+ msg.cyan
25
+ end
26
+
27
+ def self.gray(msg)
28
+ msg.gray
29
+ end
30
+
31
+ end
32
+ end
33
+
34
+ class String
35
+ require 'Win32/Console/ANSI' if RbConfig::CONFIG['host_os'] =~ /mswin|win32|dos|mingw|cygwin/i
36
+
37
+ def colorize(color_code)
38
+ "\e[#{color_code}m#{self}\e[0m"
39
+ end
40
+
41
+ def red
42
+ colorize(31)
43
+ end
44
+
45
+ def green
46
+ colorize(32)
47
+ end
48
+
49
+ def yellow
50
+ colorize(33)
51
+ end
52
+
53
+ def blue
54
+ colorize(34)
55
+ end
56
+
57
+ def magenta
58
+ colorize(35)
59
+ end
60
+
61
+ def cyan
62
+ colorize(36)
63
+ end
64
+
65
+ def gray
66
+ colorize(37)
67
+ end
68
+ end
@@ -0,0 +1,128 @@
1
+ require 'pathname'
2
+
3
+ module PPStats
4
+ class Modules
5
+
6
+ attr_reader :types, :module_count, :classes, :defines
7
+
8
+ def initialize(options)
9
+ @options = options
10
+ @types = ModuleTypes.instance.types
11
+ @procssed_file = false
12
+ @previous_line = nil
13
+ @module_count = 0
14
+ @classes = 0
15
+ @defines = 0
16
+ end
17
+
18
+ def run
19
+ if @options[:single_module]
20
+ process_module(@options[:modulepath])
21
+ else
22
+ PPStats::Utils.files_dotless(@options[:modulepath]).each do |file|
23
+ file = File.join(@options[:modulepath], file)
24
+ process_module file if File.directory? file
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ def results
31
+ summary = PPStats::Summary.new(@types, @module_count, @classes, @defines)
32
+ summary.run
33
+ end
34
+
35
+ def process_module(moddir)
36
+ puts PPStats::Format.green "module #{moddir}"
37
+ @types.each do |k,v|
38
+ puts PPStats::Format.blue " #{k.to_s}"
39
+ process_type(moddir, v)
40
+ puts if @procssed_file
41
+ end
42
+ @module_count += 1
43
+ end
44
+
45
+ def process_type(moddir, type)
46
+ @procssed_file = false
47
+ return if !File.directory? moddir
48
+
49
+ type.dirs.each do |dir|
50
+ files = PPStats::Utils.files_recursive_nodirs(File.join(moddir, dir))
51
+ files.each_with_index do |file, index|
52
+ if filter_file(file, type)
53
+ count, commented_count = process_file(file, index+1, files.length)
54
+ type.counter.adjust(file, count, commented_count)
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ def filter_file(file, type)
61
+ ext = File.extname(file)
62
+ if type.file_exts == '*'
63
+ if ext =~ /\.\d/
64
+ return false
65
+ elsif type.exclude_exts.include? ext
66
+ return false
67
+ else
68
+ return true
69
+ end
70
+ end
71
+ type.file_exts.include? ext
72
+ end
73
+
74
+ def process_file(path, index, totfiles)
75
+ @procssed_file = true
76
+ file = Pathname.new(path).basename
77
+ line = "\r #{file} (#{index}/#{totfiles})"
78
+ STDOUT.write "\r" + " "*@previous_line.length if !@previous_line.nil?
79
+ @previous_line = line
80
+ STDOUT.write line
81
+ STDOUT.flush
82
+ lines = File.new(path).readlines
83
+ commented_lines = lines.select { |line| line =~ /^#/ }
84
+ c = lines.select { |line| line =~ /^class/ }
85
+ d = lines.select { |line| line =~ /^define/ }
86
+ sleep(0.05)
87
+ @classes += 1 if ! c.empty?
88
+ @defines += 1 if ! d.empty?
89
+ return lines.count, commented_lines.count
90
+ end
91
+
92
+ class ModuleTypes
93
+ require 'singleton'
94
+ include Singleton
95
+
96
+ attr_reader :types
97
+
98
+ def initialize
99
+ @types = {
100
+ :manifests => ModuleType.new(['manifests'], ['.pp']),
101
+ :templates => ModuleType.new(['templates'], ['.erb']),
102
+ :libraries => ModuleType.new(['lib'], ['.rb']),
103
+ :unit_tests => ModuleType.new(['spec/classes',
104
+ 'spec/defines',
105
+ 'spec/functions',
106
+ 'spec/host',
107
+ 'spec/unit'],
108
+ ['.rb']),
109
+ :system_tests => ModuleType.new(['spec/system'], ['.rb']),
110
+ #:file => ModuleType.new('files', '*')
111
+ }
112
+ end
113
+
114
+ end
115
+
116
+ class ModuleType
117
+ attr_reader :dirs, :file_exts, :counter, :exclude_exts
118
+
119
+ def initialize(dirs, file_exts='*')
120
+ @dirs = dirs
121
+ @file_exts = file_exts
122
+ @counter = PPStats::Counter.new
123
+ @exclude_exts = ['', '.png', '.exe', '.a']
124
+ end
125
+ end
126
+
127
+ end
128
+ end
@@ -0,0 +1,17 @@
1
+ module PPStats
2
+ class Processor
3
+ def initialize(options)
4
+ @options = options
5
+ @modules = PPStats::Modules.new(@options)
6
+ end
7
+
8
+ def run
9
+ @modules.run
10
+ end
11
+
12
+ def results
13
+ @modules.results
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,33 @@
1
+ module PPStats
2
+ class Summary
3
+ def initialize(types, module_count, classes, defines)
4
+ @types = types
5
+ @module_count = module_count
6
+ @classes = classes
7
+ @defines = defines
8
+ end
9
+
10
+ def run
11
+ puts PPStats::Format.cyan "-"*35
12
+ @types.each do |k,v|
13
+ puts PPStats::Format.cyan k.to_s
14
+ print_summary_line('files', v.counter.count[:files])
15
+ print_summary_line('lines', v.counter.count[:lines])
16
+ print_summary_line('max lines', "#{v.counter.count[:max_lines]} - #{v.counter.count[:max_file]}")
17
+ print_summary_line('commented lines', v.counter.count[:commented_lines])
18
+ print_summary_line('most commented', "#{v.counter.count[:max_commented_lines]} - #{v.counter.count[:max_commented_file]}")
19
+ print_summary_line('least commented', "#{v.counter.count[:floor_commented_lines]} - #{v.counter.count[:floor_commented_file]}")
20
+ end
21
+ puts PPStats::Format.cyan "-"*35
22
+ puts PPStats::Format.cyan "Totals"
23
+ print_summary_line('modules', "#{@module_count}")
24
+ print_summary_line('classes', "#{@classes}")
25
+ print_summary_line('defines', "#{@defines}")
26
+ end
27
+
28
+ def print_summary_line(label, data)
29
+ printf " %-20s #{data}\n", label
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,11 @@
1
+ module PPStats
2
+ module Utils
3
+ def self.files_dotless(path)
4
+ Dir.new(path).entries.reject { |f| f =~ /^\./}
5
+ end
6
+
7
+ def self.files_recursive_nodirs(path)
8
+ Dir.glob("#{path}/**/*").entries.reject { |f| File.directory? f }
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'pp-stats'
5
+ s.version = '0.0.3'
6
+ s.date = '2013-01-13'
7
+ s.summary = "Puppet Stats"
8
+ s.description = "Command line ruby program that generates stats for Puppet module(s)"
9
+ s.authors = ["Jason Thigpen"]
10
+ s.email = "darwin@sent.us"
11
+ s.files = `git ls-files`.split("\n")
12
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
13
+ s.require_paths = ["lib"]
14
+ s.homepage = 'https://github.com/cdarwin/pp-stats'
15
+ s.license = 'MIT'
16
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pp-stats
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Jason Thigpen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-01-13 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Command line ruby program that generates stats for Puppet module(s)
14
+ email: darwin@sent.us
15
+ executables:
16
+ - pp-stats
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".gitignore"
21
+ - LICENSE.txt
22
+ - PuppetSummary.png
23
+ - README.md
24
+ - bin/pp-stats
25
+ - lib/pp-stats.rb
26
+ - lib/pp-stats/command-line.rb
27
+ - lib/pp-stats/counter.rb
28
+ - lib/pp-stats/format.rb
29
+ - lib/pp-stats/modules.rb
30
+ - lib/pp-stats/processor.rb
31
+ - lib/pp-stats/summary.rb
32
+ - lib/pp-stats/utils.rb
33
+ - pp-stats.gemspec
34
+ homepage: https://github.com/cdarwin/pp-stats
35
+ licenses:
36
+ - MIT
37
+ metadata: {}
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubyforge_project:
54
+ rubygems_version: 2.2.1
55
+ signing_key:
56
+ specification_version: 4
57
+ summary: Puppet Stats
58
+ test_files: []