abide_dev_utils 0.5.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,66 +1,155 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'abide_dev_utils/ppt/coverage'
4
- require 'abide_dev_utils/ppt/new_obj'
3
+ require 'abide_dev_utils/output'
4
+ require 'abide_dev_utils/validate'
5
+ require 'abide_dev_utils/errors'
6
+ require 'abide_dev_utils/ppt/class_utils'
5
7
 
6
8
  module AbideDevUtils
7
9
  module Ppt
8
- # Given a directory holding Puppet manifests, returns
9
- # the full namespace for all classes in that directory.
10
- # @param puppet_class_dir [String] path to a dir containing Puppet manifests
11
- # @return [String] The namespace for all classes in manifests in the dir
12
- def self.find_class_namespace(puppet_class_dir)
13
- path = Pathname.new(puppet_class_dir)
14
- mod_root = nil
15
- ns_parts = []
16
- found_manifests = false
17
- path.ascend do |p|
18
- if found_manifests
19
- mod_root = find_mod_root(p)
20
- break
21
- end
22
- if File.basename(p) == 'manifests'
23
- found_manifests = true
24
- next
25
- else
26
- ns_parts << File.basename(p)
27
- end
10
+ # Renames a Puppet class by renaming the class declaration and class file
11
+ # @param from [String] fully-namespaced existing Puppet class name
12
+ # @param to [String] fully-namespaced new Puppet class name
13
+ def self.rename_puppet_class(from, to, **kwargs)
14
+ from_path = ClassUtils.path_from_class_name(from)
15
+ to_path = ClassUtils.path_from_class_name(to)
16
+ file_path = kwargs.fetch(:declaration_in_to_file, false) ? to_path : from_path
17
+ raise ClassFileNotFoundError, "Path:#{file_path}" if !File.file?(file_path) && kwargs.fetch(:validate_path, true)
18
+
19
+ rename_puppet_class_declaration(from, to, file_path, **kwargs)
20
+ AbideDevUtils::Output.simple("Renamed #{from} to #{to} at #{file_path}.")
21
+ return unless kwargs.fetch(:declaration_only, false)
22
+
23
+ rename_class_file(from_path, to_path, **kwargs)
24
+ AbideDevUtils::Output.simple("Renamed file #{from_path} to #{to_path}.")
25
+ end
26
+
27
+ def self.audit_class_names(dir, **kwargs)
28
+ mismatched = ClassUtils.find_all_mismatched_class_declarations(dir)
29
+ outfile = kwargs.key?(:file) ? File.open(kwargs[:file], 'a') : nil
30
+ quiet = kwargs.fetch(:quiet, false)
31
+ mismatched.each do |class_file|
32
+ AbideDevUtils::Output.simple("Mismatched class name in file #{class_file}") unless quiet
33
+ outfile << "MISMATCHED_CLASS_NAME: #{class_file}\n" unless outfile.nil?
28
34
  end
29
- "#{mod_root}::#{ns_parts.reverse.join('::')}::"
35
+ outfile&.close
36
+ AbideDevUtils::Output.simple("Found #{mismatched.length} mismatched classes in #{dir}.") unless quiet
37
+ ensure
38
+ outfile&.close
30
39
  end
31
40
 
32
- # Given a Pathname object of the 'manifests' directory in a Puppet module,
33
- # determines the module namespace root. Does this by consulting
34
- # metadata.json, if it exists, or by using the parent directory name.
35
- # @param pathname [Pathname] A Pathname object of the module's manifests dir
36
- # @return [String] The module's namespace root
37
- def self.find_mod_root(pathname)
38
- metadata_file = nil
39
- pathname.entries.each do |e|
40
- metadata_file = "#{pathname}/metadata.json" if File.basename(e) == 'metadata.json'
41
+ def self.fix_class_names_file_rename(dir, **kwargs)
42
+ mismatched = ClassUtils.find_all_mismatched_class_declarations(dir)
43
+ progress = AbideDevUtils::Output.progress(title: 'Renaming files', total: mismatched.length)
44
+ mismatched.each do |class_path|
45
+ should = ClassUtils.path_from_class_name(class_name_from_declaration(class_path))
46
+ ClassUtils.rename_class_file(class_path, should, **kwargs)
47
+ progress.increment
48
+ AbideDevUtils::Output.simple("Renamed file #{class_path} to #{should}...") if kwargs.fetch(:verbose, false)
41
49
  end
42
- if metadata_file.nil?
43
- File.basename(p)
44
- else
45
- File.open(metadata_file) do |f|
46
- file = JSON.parse(f.read)
47
- File.basename(p) unless file.key?('name')
48
- file['name'].split('-')[-1]
49
- end
50
+ AbideDevUtils::Output.simple('Successfully fixed all classes.')
51
+ end
52
+
53
+ def self.fix_class_names_class_rename(dir, **kwargs)
54
+ mismatched = ClassUtils.find_all_mismatched_class_declarations(dir)
55
+ progress = AbideDevUtils::Output.progress(title: 'Renaming classes', total: mismatched.length)
56
+ mismatched.each do |class_path|
57
+ current = ClassUtils.class_name_from_declaration(class_path)
58
+ should = ClassUtils.class_name_from_path(class_path)
59
+ ClassUtils.rename_puppet_class_declaration(current, should, class_path, **kwargs)
60
+ progress.increment
61
+ AbideDevUtils::Output.simple("Renamed #{from} to #{to} at #{file_path}...") if kwargs.fetch(:verbose, false)
62
+ end
63
+ AbideDevUtils::Output.simple('Successfully fixed all classes.')
64
+ end
65
+
66
+ def self.generate_coverage_report(puppet_class_dir, hiera_path, profile = nil)
67
+ require 'abide_dev_utils/ppt/coverage'
68
+ CoverageReport.generate(puppet_class_dir, hiera_path, profile)
69
+ end
70
+
71
+ def self.build_new_object(type, name, opts)
72
+ require 'abide_dev_utils/ppt/new_obj'
73
+ AbideDevUtils::Ppt::NewObjectBuilder.new(
74
+ type,
75
+ name,
76
+ opts: opts,
77
+ vars: opts.fetch(:vars, '').split(',').map { |i| i.split('=') }.to_h # makes the str a hash
78
+ ).build
79
+ end
80
+
81
+ def self.add_cis_comment(path, xccdf, number_format: false)
82
+ require 'abide_dev_utils/xccdf'
83
+
84
+ parsed_xccdf = AbideDevUtils::XCCDF::Benchmark.new(xccdf)
85
+ return add_cis_comment_to_all(path, parsed_xccdf, number_format: number_format) if File.directory?(path)
86
+ return add_cis_comment_to_single(path, parsed_xccdf, number_format: number_format) if File.file?(path)
87
+
88
+ raise AbideDevUtils::Errors::FileNotFoundError, path
89
+ end
90
+
91
+ def self.add_cis_comment_to_single(path, xccdf, number_format: false)
92
+ write_cis_comment_to_file(
93
+ path,
94
+ cis_recommendation_comment(
95
+ path,
96
+ xccdf,
97
+ number_format
98
+ )
99
+ )
100
+ end
101
+
102
+ def self.add_cis_comment_to_all(path, xccdf, number_format: false)
103
+ comments = {}
104
+ Dir[File.join(path, '*.pp')].each do |puppet_file|
105
+ comment = cis_recommendation_comment(puppet_file, xccdf, number_format)
106
+ comments[puppet_file] = comment unless comment.nil?
107
+ end
108
+ comments.each do |key, value|
109
+ write_cis_comment_to_file(key, value)
50
110
  end
111
+ AbideDevUtils::Output.simple('Successfully added comments.')
51
112
  end
52
113
 
53
- # @return [Array] An array of frozen arrays where each sub-array's
54
- # index 0 is class_name and index 1 is the full path to the file.
55
- def self.find_all_classes_and_paths(puppet_class_dir)
56
- all_cap = []
57
- Dir.each_child(puppet_class_dir) do |c|
58
- path = "#{puppet_class_dir}/#{c}"
59
- next if File.directory?(path) || File.extname(path) != '.pp'
114
+ def self.write_cis_comment_to_file(path, comment)
115
+ require 'tempfile'
116
+ tempfile = Tempfile.new
117
+ begin
118
+ File.open(tempfile, 'w') do |nf|
119
+ nf.write("#{comment}\n")
120
+ File.foreach(path) do |line|
121
+ nf.write(line) unless line == "#{comment}\n"
122
+ end
123
+ end
124
+ File.rename(path, "#{path}.old")
125
+ tempfile.close
126
+ File.rename(tempfile.path, path)
127
+ File.delete("#{path}.old")
128
+ AbideDevUtils::Output.simple("Added CIS recomendation comment to #{path}...")
129
+ ensure
130
+ tempfile.close
131
+ tempfile.unlink
132
+ end
133
+ end
60
134
 
61
- all_cap << [File.basename(path, '.pp'), path].freeze
135
+ def self.cis_recommendation_comment(puppet_file, xccdf, number_format)
136
+ _, control = xccdf.find_cis_recommendation(
137
+ File.basename(puppet_file, '.pp'),
138
+ number_format: number_format
139
+ )
140
+ if control.nil?
141
+ AbideDevUtils::Output.simple("Could not find recommendation text for #{puppet_file}...")
142
+ return nil
62
143
  end
63
- all_cap
144
+ control_title = xccdf.resolve_control_reference(control).xpath('./xccdf:title').text
145
+ "# #{control_title}"
146
+ end
147
+
148
+ def self.score_module(module_path, outfile: nil, quiet: false, checks: ['all'], **_)
149
+ AbideDevUtils::Output.simple 'This command is not currently implemented'
150
+ # require 'abide_dev_utils/ppt/score_module'
151
+ # score = {}
152
+ # score[:lint_check] = ScoreModule.lint if checks.include?('all') || checks.include?('lint')
64
153
  end
65
154
  end
66
155
  end
@@ -8,9 +8,13 @@ module AbideDevUtils
8
8
  raise AbideDevUtils::Errors::FileNotFoundError, path unless File.exist?(path)
9
9
  end
10
10
 
11
- def self.file(path)
11
+ def self.file(path, extension: nil)
12
12
  filesystem_path(path)
13
13
  raise AbideDevUtils::Errors::PathNotFileError, path unless File.file?(path)
14
+ return if extension.nil?
15
+
16
+ file_ext = extension.match?(/^\.[A-Za-z0-9]+$/) ? extension : ".#{extension}"
17
+ raise AbideDevUtils::Errors::FileExtensionIncorrectError, extension unless File.extname(path) == file_ext
14
18
  end
15
19
 
16
20
  def self.directory(path)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AbideDevUtils
4
- VERSION = "0.5.2"
4
+ VERSION = "0.9.0"
5
5
  end