├── .gitignore ├── CHANGELOG.md ├── Gemfile ├── LICENSE.md ├── README.md ├── lib ├── puppet-maint.rb └── puppet-maint │ ├── code.rb │ ├── modules.rb │ ├── nodes.rb │ ├── resource.rb │ ├── resources │ ├── classes.rb │ ├── defines.rb │ ├── facts.rb │ ├── functions.rb │ ├── modules.rb │ ├── nodes.rb │ ├── providers.rb │ └── types.rb │ ├── tasks │ └── puppet-maint.rb │ └── version.rb └── puppet-maint.gemspec /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | Gemfile.lock 7 | InstalledFiles 8 | _yardoc 9 | coverage 10 | doc/ 11 | lib/bundler/man 12 | pkg 13 | rdoc 14 | spec/reports 15 | test/tmp 16 | test/version_tmp 17 | tmp 18 | vendor/ 19 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/liamjbennett/puppet-maint/8311cffcc5352ef662ad3b0da31d17057415abc8/CHANGELOG.md -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in puppet-syntax.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Liam Bennett 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Puppet-maint 2 | 3 | Puppet-maint is a set of rake tasks built to aid in the maintenance of site or control repository. 4 | 5 | ## Installation 6 | 7 | Add this line to your application's Gemfile: 8 | 9 | gem 'puppet-maint' 10 | 11 | And then execute: 12 | 13 | $ bundle 14 | 15 | Or install it yourself as: 16 | 17 | $ gem install puppet-maint 18 | 19 | ## Usage 20 | 21 | Include the following in your `Rakefile`: 22 | 23 | require 'puppet-maint/tasks/puppet-maint' 24 | 25 | Test all manifests and templates relative to your `Rakefile`: 26 | 27 | ➜ puppet git:(master) bundle exec rake maint 28 | ---> maint:outdated 29 | ---> maint:unused_code 30 | ---> maint:unused_modules 31 | ---> maint:unused_nodes 32 | 33 | ## Configuration 34 | Environment can be excluded with: 35 | 36 | PuppetMaint.exclude_environments = ["vagrant"] 37 | 38 | For the `maint:unused_nodes` task you will need to configure your PuppetDB servers for lookup: 39 | 40 | PuppetMaint.db_servers = ["prod-puppetdb-01.mycorp.com"] 41 | 42 | For the `maint:unused_modules` and `maint:unused_code` tasks you want want to configure additional directories conainting modules: 43 | 44 | PuppetMaint.module_dirs = [ 45 | "app_modules/**/*.pp", 46 | "manifests/**/*.pp", 47 | "environments/**/*.pp", 48 | "roles/**/*.pp", 49 | "profiles/**/*.pp" 50 | ] 51 | 52 | ## Contributing 53 | 54 | 1. Fork it 55 | 2. Create your feature branch (`git checkout -b my-new-feature`) 56 | 3. Commit your changes (`git commit -am 'Add some feature'`) 57 | 4. Push to the branch (`git push origin my-new-feature`) 58 | 5. Create new Pull Request 59 | -------------------------------------------------------------------------------- /lib/puppet-maint.rb: -------------------------------------------------------------------------------- 1 | require 'puppet-maint/code' 2 | require 'puppet-maint/modules' 3 | require 'puppet-maint/nodes' 4 | require 'puppet-maint/resource' 5 | require 'puppet' 6 | 7 | module PuppetMaint 8 | 9 | @db_servers = [] 10 | @exclude_environments = [] 11 | @module_dirs = [ 12 | "manifests/**/*.pp", 13 | "environments/**/*.pp", 14 | "roles/**/*.pp", 15 | "profiles/**/*.pp" 16 | ] 17 | 18 | class << self 19 | attr_accessor :module_dirs, :db_servers, :exclude_environments 20 | 21 | def tokenize(file) 22 | lexer = Puppet::Parser::Lexer.new 23 | lexer.string = File.read(file) 24 | lexer.fullscan 25 | end 26 | 27 | def output(type, collection, show_file=nil) 28 | puts "Unused #{type} (#{collection.length}):" if collection.length > 0 29 | collection.each do |t, f| 30 | line = " #{t}" 31 | line += " in #{f}" if show_file 32 | puts line 33 | end 34 | end 35 | 36 | end 37 | 38 | end 39 | -------------------------------------------------------------------------------- /lib/puppet-maint/code.rb: -------------------------------------------------------------------------------- 1 | require 'puppet-maint/resources/classes' 2 | require 'puppet-maint/resources/defines' 3 | 4 | module PuppetMaint 5 | class Code 6 | def check 7 | PuppetMaint.output(:CLASS, PuppetMaint::Resources::Classes.new.unused(PuppetMaint.module_dirs)) 8 | PuppetMaint.output(:DEFINE, PuppetMaint::Resources::Defines.new.unused(PuppetMaint.module_dirs)) 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/puppet-maint/modules.rb: -------------------------------------------------------------------------------- 1 | require 'puppet-maint/resources/modules' 2 | 3 | module PuppetMaint 4 | class Modules 5 | def check 6 | PuppetMaint.output("Modules", PuppetMaint::Resources::Modules.new.unused) 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/puppet-maint/nodes.rb: -------------------------------------------------------------------------------- 1 | require 'puppet-maint/resources/nodes' 2 | 3 | module PuppetMaint 4 | class Nodes 5 | def check 6 | file_list = FileList.new('environments/**/manifests/*.pp') do |f1| 7 | PuppetMaint.exclude_environments.each do |env| 8 | f1.exclude("environments/#{env}/**/*.pp") 9 | end 10 | end 11 | 12 | nodes = PuppetMaint::Resources::Nodes.new 13 | known_nodes = nodes.used(PuppetMaint.db_servers) 14 | 15 | unused_defs = file_list.flat_map do |node_file| 16 | nodes.defined(node_file).reject do |node_def| 17 | re = Regexp.new node_def 18 | known_nodes.any? { |node| re =~ node } 19 | end.map { |node_def| [node_def, node_file] } 20 | end 21 | 22 | PuppetMaint.output("NODES",unused_defs,true) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/puppet-maint/resource.rb: -------------------------------------------------------------------------------- 1 | module PuppetMaint 2 | module Resources 3 | class Resource 4 | 5 | def get_files(module_dirs) 6 | FileList.new do |f| 7 | module_dirs.each do |dir| 8 | f.include(dir) 9 | end 10 | end 11 | end 12 | 13 | def self.used(type_obj, module_dirs) 14 | file_list = get_files(module_dirs) 15 | 16 | types = [] 17 | files = [] 18 | file_list.each do |file| 19 | type = type_obj.used(file) 20 | if type and !type.empty? 21 | type.each do |t| 22 | if !types.include?(t) 23 | types.push(t) 24 | files.push(file) 25 | end 26 | end 27 | end 28 | end 29 | Hash[types.zip files] 30 | end 31 | 32 | def self.declared(type_obj, module_dirs) 33 | file_list = get_files(module_dirs) 34 | 35 | types = [] 36 | files = [] 37 | file_list.each do |file| 38 | type = type_obj.declared(file) 39 | if type and !type.empty? 40 | type.each do |t| 41 | if !types.include?(t) 42 | types.push(t) 43 | files.push(file) 44 | end 45 | end 46 | end 47 | end 48 | Hash[types.zip files] 49 | end 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /lib/puppet-maint/resources/classes.rb: -------------------------------------------------------------------------------- 1 | require 'puppet-maint/resource' 2 | 3 | module PuppetMaint 4 | module Resources 5 | class Classes < Resource 6 | def get_files(module_dirs) 7 | super(module_dirs) 8 | end 9 | 10 | def used(module_dirs) 11 | file_list = get_files(module_dirs) 12 | 13 | classes = [] 14 | files = [] 15 | file_list.each do |file| 16 | tokens = PuppetMaint.tokenize(file) 17 | tokens.each_with_index do |token,i| 18 | if [:CLASS].include? token.first 19 | if [:LBRACE].include? tokens[i+1].first 20 | classes.push(tokens[i+2].last[:value].sub(/^::/,'')) 21 | end 22 | elsif [:NAME].include? token.first 23 | if ["include","contain","require"].include? token.last[:value] 24 | classes.push(tokens[i+1].last[:value].sub(/^::/,'')) 25 | elsif ["create_resources","ensure_resource"].include? token.last[:value] 26 | classes.push(tokens[i+2].last[:value]) 27 | end 28 | elsif [:CLASSREF].include? token.first 29 | classes.push(token.last[:value].downcase) 30 | elsif [:INHERITS].include? token.first 31 | classes.push(tokens[i+1].last[:value]) 32 | end 33 | end 34 | classes.uniq! 35 | files.push(file) 36 | end 37 | Hash[classes.zip files] 38 | end 39 | 40 | def declared(module_dirs) 41 | file_list = get_files(module_dirs) 42 | 43 | classes = [] 44 | files = [] 45 | file_list.each do |file| 46 | tokens = PuppetMaint.tokenize(file) 47 | tokens.each_with_index do |token,i| 48 | if [:CLASS].include? token.first 49 | classes.push(tokens[i+1].last[:value].sub(/^{/,'')) 50 | break 51 | end 52 | end 53 | classes.delete("") 54 | classes.compact 55 | classes.uniq 56 | files.push(file) 57 | end 58 | Hash[classes.zip files] 59 | end 60 | 61 | def unused(module_dirs) 62 | used_classes = used(module_dirs) 63 | declared_resources = declared(module_dirs) 64 | used_classes.each do |type,file| 65 | declared_resources.reject! {|t,f| type.eql?(t) } 66 | end 67 | return declared_resources 68 | end 69 | end 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /lib/puppet-maint/resources/defines.rb: -------------------------------------------------------------------------------- 1 | module PuppetMaint 2 | module Resources 3 | class Defines < Resource 4 | def get_files(module_dirs) 5 | super(module_dirs) 6 | end 7 | 8 | def used(module_dirs) 9 | file_list = get_files(module_dirs) 10 | 11 | defines = [] 12 | files = [] 13 | file_list.each do |file| 14 | tokens = PuppetMaint.tokenize(file) 15 | tokens.each_with_index do |token, i| 16 | if [:NAME].include? token.first 17 | if [:LBRACE].include? tokens[i+1].first and [:STRING, :SSTRING, :VARIABLE, :DQPRE, :LBRACK].include? tokens[i+2].first 18 | defines.push(token.last[:value]) 19 | elsif ["create_resources","ensure_resource"].include? token.last[:value] 20 | defines.push(tokens[i+2].last[:value]) 21 | end 22 | elsif [:CLASSREF].include? token.first 23 | defines.push(token.last[:value].downcase) 24 | end 25 | end 26 | defines.uniq! 27 | files.push(file) 28 | end 29 | Hash[defines.zip files] 30 | end 31 | 32 | def declared(module_dirs) 33 | file_list = get_files(module_dirs) 34 | 35 | defines = [] 36 | files = [] 37 | file_list.each do |file| 38 | tokens = PuppetMaint.tokenize(file) 39 | tokens.each_with_index do |token,i| 40 | if [:DEFINE].include? token.first 41 | defines.push(tokens[i+1].last[:value].sub(/^{/,'')) 42 | break 43 | end 44 | end 45 | defines.delete("") 46 | defines.compact 47 | defines.uniq 48 | files.push(file) 49 | end 50 | Hash[defines.zip files] 51 | end 52 | 53 | def unused(module_dirs) 54 | used_defines = used(module_dirs) 55 | declared_resources = declared(module_dirs) 56 | used_defines.each do |type, file| 57 | declared_resources.reject! {|t,f| type.eql?(t) } 58 | end 59 | return declared_resources 60 | end 61 | end 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /lib/puppet-maint/resources/facts.rb: -------------------------------------------------------------------------------- 1 | module PuppetMaint 2 | module Resources 3 | class Facts < Resource 4 | def get_files(module_dirs) 5 | super(module_dirs) 6 | end 7 | 8 | def used(module_dirs) 9 | file_list = get_files(module_dirs) 10 | 11 | facts = [] 12 | files = [] 13 | file_list.each do |file| 14 | content = File.open(file).read 15 | content.each_line do |line| 16 | if line =~ /\$::\w+/ 17 | facts.push(line.match(/\$::\w+/)[0].sub("$::","")) 18 | end 19 | end 20 | facts.uniq! 21 | files.push(file) 22 | end 23 | Hash[facts.zip files] 24 | end 25 | 26 | def declared(module_dirs) 27 | file_list = get_files(module_dirs) 28 | 29 | facts = [] 30 | files = [] 31 | file_list.each do |file| 32 | content = File.open(file).read 33 | content.each_line do |line| 34 | if line.include?("Facter.add") 35 | f = line.lstrip.split("do")[0].split("{")[0].sub("Facter.add(","").sub(")","") 36 | if f.start_with?('"') or f.start_with?("'") 37 | fact_name = f.gsub('"','').gsub("'",'').strip 38 | elsif f.start_with?(":") 39 | fact_name = f.sub(":","").strip 40 | end 41 | facts.push(fact_name) 42 | files.push(file) 43 | end 44 | end 45 | end 46 | Hash[facts.zip files] 47 | end 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /lib/puppet-maint/resources/functions.rb: -------------------------------------------------------------------------------- 1 | module PuppetMaint 2 | module Resources 3 | class Functions < Resource 4 | def get_files(module_dirs) 5 | super(module_dirs) 6 | end 7 | 8 | def used(module_dirs) 9 | file_list = get_files(module_dirs) 10 | 11 | functions = [] 12 | files = [] 13 | file_list.each do |file| 14 | tokens = PuppetMaint.tokenize(file) 15 | tokens.each_with_index do |token,i| 16 | if [:NAME].include? token.first 17 | if [:LPAREN].include? tokens[i+1].first 18 | functions.push(token.last[:value]) if i >= 1 19 | end 20 | end 21 | end 22 | functions.uniq! 23 | files.push(file) 24 | end 25 | Hash[functions.zip files] 26 | end 27 | 28 | def declared(module_dirs) 29 | file_list = get_files(module_dirs) 30 | 31 | functions = [] 32 | files = [] 33 | file_list.each do |file| 34 | content = File.open(file).read 35 | content.each_line do |line| 36 | if line.include?("newfunction") 37 | f = line.sub("Puppet::Parser::Functions::","").split(",")[0].sub("newfunction(","").sub(":","").strip 38 | functions.push(f) 39 | end 40 | end 41 | functions.uniq! 42 | files.push(file) 43 | end 44 | Hash[functions.zip files] 45 | end 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /lib/puppet-maint/resources/modules.rb: -------------------------------------------------------------------------------- 1 | require 'puppet-maint/resources/types' 2 | require 'puppet-maint/resources/facts' 3 | require 'puppet-maint/resources/functions' 4 | require 'puppet-maint/resources/providers' 5 | 6 | module PuppetMaint 7 | module Resources 8 | class Modules < Resource 9 | def defined 10 | modules = [] 11 | File.open("Puppetfile") do |f| 12 | f.each_line do |line| 13 | if line.start_with?('mod') 14 | mod = line.split(" ")[1].gsub("'","").gsub('"',"").gsub(",","").split("/")[1] 15 | modules.push(mod) 16 | end 17 | end 18 | end 19 | return modules 20 | end 21 | 22 | def used(file) 23 | if file.include?("lib") 24 | selector = "lib" 25 | else 26 | selector = "manifests" 27 | end 28 | 29 | module_name = "" 30 | parts = file.split("/") 31 | parts.each_with_index do |item,i| 32 | if item.eql?(selector) 33 | module_name = parts[i-1] 34 | end 35 | end 36 | return module_name 37 | end 38 | 39 | #TODO: this method is funky and still needs refactoring 40 | def unused 41 | used_modules = [] 42 | 43 | used_classes = PuppetMaint::Resources::Classes.new.used(PuppetMaint.module_dirs) 44 | used_classes.each do |c| 45 | used_modules.push(c[0].split("::")[0]) 46 | end 47 | 48 | defines = PuppetMaint::Resources::Defines.new 49 | declared_defines = defines.declared(["modules/**/*.pp"]) 50 | declared_types = PuppetMaint::Resources::Types.new.declared(["modules/*/lib/puppet/type/*.rb"]) 51 | 52 | used_defines = defines.used(PuppetMaint.module_dirs) 53 | 54 | used_defines.each do |c| 55 | declared_defines.each do |d| 56 | if d[0].eql?(c[0]) 57 | used_modules.push(used(d[1])) 58 | end 59 | end 60 | 61 | declared_types.each do |d| 62 | if d[0].eql?(c[0]) 63 | used_modules.push(used(d[1])) 64 | end 65 | end 66 | end 67 | 68 | facts = PuppetMaint::Resources::Facts.new 69 | declared_facts = facts.declared(["modules/*/lib/facter/*.rb"]) 70 | used_facts = facts.used(PuppetMaint.module_dirs) 71 | 72 | used_facts.each do |c| 73 | declared_facts.each do |d| 74 | if d[0].eql?(c[0]) 75 | used_modules.push(used(d[1])) 76 | end 77 | end 78 | end 79 | 80 | functions = PuppetMaint::Resources::Functions.new 81 | declared_functions = functions.declared(["modules/*/lib/puppet/parser/functions/*.rb"]) 82 | used_functions = functions.used(PuppetMaint.module_dirs) 83 | 84 | used_functions.each do |c| 85 | declared_functions.each do |d| 86 | if d[0].eql?(c[0]) 87 | used_modules.push(used(d[1])) 88 | end 89 | end 90 | end 91 | 92 | providers = PuppetMaint::Resources::Providers.new 93 | declared_providers = providers.declared(["modules/*/lib/puppet/provider/**/*.rb"]) 94 | used_providers = providers.used(PuppetMaint.module_dirs) 95 | 96 | used_providers.each do |c| 97 | declared_providers.each do |d| 98 | if d[0].eql?(c[0]) 99 | used_modules.push(used(d[1])) 100 | end 101 | end 102 | end 103 | 104 | used_modules.uniq! 105 | 106 | modules = defined 107 | used_modules.each do |um| 108 | modules.reject! { |m| um.eql?(m) } 109 | end 110 | 111 | modules.sort! 112 | end 113 | end 114 | end 115 | end 116 | -------------------------------------------------------------------------------- /lib/puppet-maint/resources/nodes.rb: -------------------------------------------------------------------------------- 1 | module PuppetMaint 2 | module Resources 3 | class Nodes < Resource 4 | def defined(file) 5 | tokens = PuppetMaint.tokenize(file) 6 | tokens.each_with_index.select do |token, _| 7 | token.first == :NODE 8 | end.flat_map do |token, idx| 9 | tokens[idx+1..-1].take_while do |tok| 10 | tok.first != :LBRACE 11 | end.map do |tok| 12 | tok.last[:value] 13 | end.reject do |tok| 14 | tok == "," || tok == "default" 15 | end 16 | end 17 | end 18 | 19 | def puppetdb_nodes(db) 20 | http = Net::HTTP.new(db, 8080) 21 | nodes = http.request(Net::HTTP::Get.new("/v3/nodes")) 22 | JSON.parse(nodes.body) 23 | end 24 | 25 | def used(db_servers) 26 | db_servers.flat_map do |db| 27 | puppetdb_nodes(db).map { |node| node["name"] } 28 | end 29 | end 30 | 31 | def unused 32 | 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/puppet-maint/resources/providers.rb: -------------------------------------------------------------------------------- 1 | module PuppetMaint 2 | module Resources 3 | class Providers < Resource 4 | def get_files(module_dirs) 5 | super(module_dirs) 6 | end 7 | 8 | def used(module_dirs) 9 | file_list = get_files(module_dirs) 10 | 11 | providers = [] 12 | files = [] 13 | 14 | file_list.each do |file| 15 | tokens = PuppetMaint.tokenize(file) 16 | tokens.each_with_index do |token,i| 17 | if [:NAME].include? token.first 18 | if token.last[:value].eql?("provider") and [:FARROW].include? tokens[i+1].first 19 | providers.push(tokens[i+2].last[:value]) 20 | end 21 | end 22 | end 23 | providers.uniq! 24 | files.push(file) 25 | end 26 | Hash[providers.zip files] 27 | end 28 | 29 | def declared(module_dirs) 30 | file_list = get_files(module_dirs) 31 | 32 | providers = [] 33 | files = [] 34 | 35 | file_list.each do |file| 36 | content = File.open(file).read 37 | content.each_line do |line| 38 | if line.include?("Puppet::Type.type") and !line.start_with?("#") 39 | f = line.split(".provide").last.sub("(","").sub(")","").sub(" do","").strip 40 | f = f.split(",").first 41 | f.sub!(":","") if !f.nil? 42 | providers.push(f) 43 | break 44 | end 45 | providers.uniq! 46 | files.push(file) 47 | end 48 | end 49 | Hash[providers.zip files] 50 | end 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /lib/puppet-maint/resources/types.rb: -------------------------------------------------------------------------------- 1 | module PuppetMaint 2 | module Resources 3 | class Types < Resource 4 | def get_files(module_dirs) 5 | super(module_dirs) 6 | end 7 | 8 | def used(module_dirs) 9 | 10 | end 11 | 12 | def declared(module_dirs) 13 | file_list = get_files(module_dirs) 14 | 15 | types = [] 16 | files = [] 17 | file_list.each do |file| 18 | content = File.open(file).read 19 | content.each_line do |line| 20 | if line.include?("Puppet::Type.newtype") 21 | f = line.sub("Puppet::Type.newtype(","").split("do")[0].sub(")","").sub(":","").strip 22 | types.push(f) 23 | end 24 | end 25 | types.uniq 26 | files.push(file) 27 | end 28 | return Hash[types.zip files] 29 | end 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/puppet-maint/tasks/puppet-maint.rb: -------------------------------------------------------------------------------- 1 | require 'puppet-maint' 2 | require 'rake' 3 | require 'rake/tasklib' 4 | 5 | module PuppetMaint 6 | class RakeTask < ::Rake::TaskLib 7 | def initialize(*args) 8 | 9 | desc "Run full maintenance report" 10 | task :maint => [ 11 | 'maint:outdated', 12 | 'maint:unused_code', 13 | 'maint:unused_modules', 14 | 'maint:unused_nodes' 15 | ] 16 | 17 | namespace :maint do 18 | desc "Check for unused classes/defines" 19 | task :unused_code do |t| 20 | puts "---> #{t.name}" 21 | c = PuppetMaint::Code.new 22 | c.check 23 | end 24 | 25 | task :unused_modules do |t| 26 | puts "---> #{t.name}" 27 | m = PuppetMaint::Modules.new 28 | m.check 29 | end 30 | 31 | desc "Check for node definitions that no longer apply to any nodes" 32 | task :unused_nodes do |t| 33 | puts "---> #{t.name}" 34 | n = PuppetMaint::Nodes.new 35 | n.check 36 | end 37 | 38 | desc "Check for modules that need updating" 39 | task :outdated do |t| 40 | puts "---> #{t.name}" 41 | output = %x( librarian-puppet outdated ) 42 | outdated = output.split("\n").delete_if {|x| x.start_with?("Module") or x.start_with?("Unable") } 43 | PuppetMaint.output("Outdated Modules", outdated) 44 | end 45 | end 46 | end 47 | end 48 | end 49 | 50 | PuppetMaint::RakeTask.new 51 | -------------------------------------------------------------------------------- /lib/puppet-maint/version.rb: -------------------------------------------------------------------------------- 1 | module PuppetMaint 2 | VERSION = "0.0.1" 3 | end 4 | -------------------------------------------------------------------------------- /puppet-maint.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'puppet-maint/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "puppet-maint" 8 | spec.version = PuppetMaint::VERSION 9 | spec.authors = ["Liam Bennett"] 10 | spec.email = ["liamjbennett@gmail.com"] 11 | spec.description = %q{Maintenance tasks for Puppet} 12 | spec.summary = %q{Maintenance tasks for Puppet} 13 | spec.homepage = "https://github.com/liamjbennett/puppet-maint" 14 | spec.license = "MIT" 15 | spec.files = `git ls-files`.split($/) 16 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 17 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) 18 | spec.require_paths = ["lib"] 19 | 20 | spec.add_dependency "rake" 21 | spec.add_dependency "json" 22 | spec.add_dependency "puppet" 23 | 24 | spec.add_development_dependency "rspec" 25 | spec.add_development_dependency "gem_publisher", "~> 1.3" 26 | end 27 | --------------------------------------------------------------------------------