fb_bookworm 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +201 -0
  3. data/README.md +161 -0
  4. data/lib/bookworm/configuration.rb +53 -0
  5. data/lib/bookworm/crawler.rb +69 -0
  6. data/lib/bookworm/exceptions.rb +20 -0
  7. data/lib/bookworm/infer_base_classes.rb +80 -0
  8. data/lib/bookworm/infer_engine.rb +45 -0
  9. data/lib/bookworm/keys.rb +77 -0
  10. data/lib/bookworm/knowledge_base.rb +117 -0
  11. data/lib/bookworm/load_hack.rb +21 -0
  12. data/lib/bookworm/report_builder.rb +93 -0
  13. data/lib/bookworm/reports/AllReferencedRecipes.rb +35 -0
  14. data/lib/bookworm/reports/AllRoleDescriptions.rb +25 -0
  15. data/lib/bookworm/reports/CookbookDependencyDot.rb +30 -0
  16. data/lib/bookworm/reports/DynamicRecipeInclusion.rb +29 -0
  17. data/lib/bookworm/reports/LeafCookbooks.rb +30 -0
  18. data/lib/bookworm/reports/LibraryDefinedModulesAndClassConstants.rb +27 -0
  19. data/lib/bookworm/reports/MissingReferencedRecipes.rb +61 -0
  20. data/lib/bookworm/reports/NoParsedRuby.rb +46 -0
  21. data/lib/bookworm/reports/NotReferencedRecipes.rb +37 -0
  22. data/lib/bookworm/reports/RecipesAssigningConstants.rb +27 -0
  23. data/lib/bookworm/reports/RoleRecipeEntrypoints.rb +30 -0
  24. data/lib/bookworm/reports/RoleReferencedRoles.rb +30 -0
  25. data/lib/bookworm/rules/ExplicitMetadataDepends.rb +22 -0
  26. data/lib/bookworm/rules/IncludeRecipeDynamic.rb +24 -0
  27. data/lib/bookworm/rules/IncludeRecipeLiterals.rb +37 -0
  28. data/lib/bookworm/rules/LibraryDefinedClassConstants.rb +22 -0
  29. data/lib/bookworm/rules/LibraryDefinedModuleConstants.rb +22 -0
  30. data/lib/bookworm/rules/NoParsedRuby.rb +30 -0
  31. data/lib/bookworm/rules/RecipeConstantAssignments.rb +22 -0
  32. data/lib/bookworm/rules/RoleDescription.rb +22 -0
  33. data/lib/bookworm/rules/RoleExplicitRoles.rb +29 -0
  34. data/lib/bookworm/rules/RoleName.rb +22 -0
  35. data/lib/bookworm/rules/RoleRunList.rb +22 -0
  36. data/lib/bookworm/rules/RoleRunListRecipes.rb +29 -0
  37. metadata +93 -0
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2022-present, Meta Platforms, Inc. and affiliates
4
+ # All rights reserved.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ module Bookworm
20
+ # These keys are how we generalize and generate a lot of code within Bookworm
21
+ #
22
+ # VALUES
23
+ # metakey: A metakey isn't crawled, but is useful as a place to store information
24
+ # plural: The pluralized form of the key - typically used in method creation
25
+ # source_dirs: Specify which array of source directories to crawl
26
+ # glob_pattern: Specify the glob pattern for which files to crawl in source directories
27
+ # dont_init_kb_key: Don't initialize the keys on knowledge base creation
28
+ # determine_cookbook_name: Determines the cookbook name from the given path
29
+ # path_name_regex: A regex with a capture to determine the prettified name of the file
30
+ BOOKWORM_KEYS = {
31
+ 'cookbook' => {
32
+ 'metakey' => true,
33
+ 'dont_init_kb_key' => true,
34
+ },
35
+ 'role' => {
36
+ 'source_dirs' => 'role_dirs',
37
+ 'glob_pattern' => '*.rb',
38
+ 'path_name_regex' => '([\w-]+)\.rb',
39
+ },
40
+ 'metadatarb' => {
41
+ 'glob_pattern' => '*/metadata.rb',
42
+ 'determine_cookbook_name' => true,
43
+ 'path_name_regex' => '(metadata\.rb)',
44
+ },
45
+ 'recipe' => {
46
+ 'determine_cookbook_name' => true,
47
+ 'path_name_regex' => 'recipes/(.*)\.rb',
48
+ },
49
+ 'attribute' => {
50
+ 'determine_cookbook_name' => true,
51
+ 'path_name_regex' => 'attributes/(.*)\.rb',
52
+ },
53
+ 'library' => {
54
+ 'plural' => 'libraries', # <-- the troublemaker that prompted keys first ;-)
55
+ 'determine_cookbook_name' => true,
56
+ 'path_name_regex' => 'libraries\/(.*)\.rb',
57
+ },
58
+ 'resource' => {
59
+ 'determine_cookbook_name' => true,
60
+ 'path_name_regex' => 'resources/(.*)\.rb',
61
+ },
62
+ 'provider' => {
63
+ 'determine_cookbook_name' => true,
64
+ 'path_name_regex' => 'providers/(.*)\.rb',
65
+ },
66
+ }.freeze
67
+
68
+ # Set defaults
69
+ BOOKWORM_KEYS.each do |k, v|
70
+ BOOKWORM_KEYS[k]['determine_cookbook_name'] ||= false
71
+ BOOKWORM_KEYS[k]['plural'] ||= "#{k}s"
72
+ BOOKWORM_KEYS[k]['source_dirs'] ||= 'cookbook_dirs'
73
+ BOOKWORM_KEYS[k]['glob_pattern'] ||= "*/#{v['plural']}/*.rb"
74
+ end
75
+
76
+ BOOKWORM_KEYS.freeze
77
+ end
@@ -0,0 +1,117 @@
1
+ # Copyright (c) 2022-present, Meta Platforms, Inc. and affiliates
2
+ # All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ require 'pathname'
17
+ module Bookworm
18
+ module KnowledgeBaseBackends
19
+ # The SimpleHash backend stores the KnowledgeBase information as ... a
20
+ # simple hash. No concurrency guarantees, caching, etc. Each bookworm run
21
+ # will run all the rules, every time.
22
+ module SimpleHash
23
+ def init_hooks
24
+ @kb_internal_hash = {}
25
+ end
26
+
27
+ def [](key)
28
+ @kb_internal_hash[key]
29
+ end
30
+
31
+ def []=(key, value)
32
+ @kb_internal_hash[key] = value
33
+ end
34
+ end
35
+ end
36
+
37
+ # The KnowledgeBase is a backend-agnostic way of storing and querying
38
+ # information that's generated about the files via InferRules.
39
+ #
40
+ # We provide indirect access to the information stored by the
41
+ # knowledge base, so that we'll soon be able to leverage different
42
+ # backends (for concurrent writes, caching rule output across runs, etc).
43
+ class KnowledgeBase
44
+ def initialize(opts)
45
+ extend Bookworm::KnowledgeBaseBackends::SimpleHash
46
+
47
+ init_hooks
48
+
49
+ # TODO: Only initialize keys required by rules
50
+ BOOKWORM_KEYS.each do |k, v|
51
+ unless v['dont_init_kb_key']
52
+ if v['determine_cookbook_name']
53
+ init_key_with_cookbook_name(k, opts[k] || [])
54
+ else
55
+ init_key(k, opts[k] || [])
56
+ end
57
+ end
58
+ create_pluralized_getter(k)
59
+ end
60
+ end
61
+
62
+ def backend_missing
63
+ fail 'Need to specify a backend for KnowledgeBase class'
64
+ end
65
+
66
+ def [](_key)
67
+ backend_missing
68
+ end
69
+
70
+ def []=(_key, _value)
71
+ backend_missing
72
+ end
73
+
74
+ def init_hooks
75
+ # This is optional for KnowledgeBaseBackends
76
+ end
77
+
78
+ private
79
+
80
+ # This creates a method based off the (pluralized) Bookworm key.
81
+ # Syntactical sugar that can make some rules/reports easier to read.
82
+ def create_pluralized_getter(key)
83
+ define_singleton_method(BOOKWORM_KEYS[key]['plural'].to_sym) do
84
+ self[key]
85
+ end
86
+ end
87
+
88
+ def init_key(key, files)
89
+ self[key] = {}
90
+ path_name_regex = BOOKWORM_KEYS[key]['path_name_regex']
91
+ files.each do |path, ast|
92
+ m = path.match(/#{path_name_regex}/)
93
+ file_name = m[1]
94
+ self[key][file_name] = { 'path' => path, 'ast' => ast }
95
+ end
96
+ end
97
+
98
+ # The difference between this method and init_key is that it:
99
+ # 1. initializes cookbook metakey if it doesn't already exist
100
+ # 2. instead of using the filename for file key, uses COOKBOOK::FILENAME
101
+ # where FILENAME has the '.rb' suffix stripped (making it similar to the
102
+ # include_recipe calling conventions in Chef
103
+ def init_key_with_cookbook_name(key, files)
104
+ self[key] = {}
105
+ self['cookbook'] ||= {}
106
+ path_name_regex = BOOKWORM_KEYS[key]['path_name_regex']
107
+ files.each do |path, ast|
108
+ m = path.match(%r{/?([\w-]+)/#{path_name_regex}})
109
+ cookbook_name = m[1]
110
+ file_name = m[2]
111
+ self['cookbook'][cookbook_name] ||= {}
112
+ self[key]["#{cookbook_name}::#{file_name}"] =
113
+ { 'path' => path, 'cookbook' => cookbook_name, 'ast' => ast }
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,21 @@
1
+ # Copyright (c) 2022-present, Meta Platforms, Inc. and affiliates
2
+ # All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ # TODO: This is gross, and I seem to recall there was some way to get a gem's
17
+ # library directory, but this should work for now.
18
+ module Bookworm
19
+ BUILTIN_REPORTS_DIR = "#{__dir__}/reports/".freeze
20
+ BUILTIN_RULES_DIR = "#{__dir__}/rules/".freeze
21
+ end
@@ -0,0 +1,93 @@
1
+ # Copyright (c) 2022-present, Meta Platforms, Inc. and affiliates
2
+ # All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ require 'json'
17
+ require 'pathname'
18
+
19
+ module Bookworm
20
+ class BaseReport
21
+ class << self
22
+ {
23
+ 'description' => '',
24
+ 'needs_rules' => [],
25
+ }.each do |attribute, default_value|
26
+ instance_variable_set("@#{attribute}".to_sym, default_value)
27
+ define_method(attribute.to_sym) do |val = nil|
28
+ instance_variable_set("@#{attribute}", val) unless val.nil?
29
+ instance_variable_get("@#{attribute}")
30
+ end
31
+ end
32
+ end
33
+
34
+ def initialize(knowledge_base)
35
+ @kb = knowledge_base
36
+ output
37
+ end
38
+
39
+ def to_plain
40
+ ''
41
+ end
42
+
43
+ def to_json(*_args)
44
+ JSON.dump({})
45
+ end
46
+
47
+ def default_output
48
+ :to_plain
49
+ end
50
+
51
+ def output
52
+ send(default_output)
53
+ end
54
+ end
55
+
56
+ # Initialize constant for Bookworm::Reports
57
+ module Reports; end
58
+
59
+ class ReportBuilder
60
+ def initialize(knowledge_base, report_name)
61
+ klass = Module.const_get("Bookworm::Reports::#{report_name}")
62
+ output = klass.new(knowledge_base).output
63
+
64
+ puts output
65
+ end
66
+ end
67
+
68
+ def self.get_report_rules(report_name)
69
+ klass = Module.const_get("Bookworm::Reports::#{report_name}")
70
+ klass.needs_rules
71
+ end
72
+
73
+ def self.load_report_class(name, dir: '')
74
+ f = File.read "#{dir}/#{name.to_sym}.rb"
75
+ ::Bookworm::Reports.const_set(name.to_sym, ::Class.new(::Bookworm::BaseReport))
76
+ ::Bookworm::Reports.const_get(name.to_sym).class_eval(f)
77
+ rescue StandardError
78
+ raise Bookworm::ClassLoadError
79
+ end
80
+
81
+ def self.load_reports_dir(dir)
82
+ files = Dir.glob("#{dir}/*.rb")
83
+ files.each do |f|
84
+ name = Pathname(f).basename.to_s.gsub('.rb', '')
85
+ begin
86
+ Bookworm.load_report_class name, :dir => dir
87
+ rescue Bookworm::ClassLoadError
88
+ puts "Unable to load report #{f}"
89
+ exit(false)
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,35 @@
1
+ # Copyright (c) 2022-present, Meta Platforms, Inc. and affiliates
2
+ # All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ description 'Determines all recipes that are directly referenced by all roles'
16
+ needs_rules ['RoleRunListRecipes', 'IncludeRecipeLiterals']
17
+
18
+ def to_a
19
+ buffer = Set.new
20
+ @kb.roles.each do |_, metadata|
21
+ metadata['RoleRunListRecipes'].each do |role|
22
+ buffer << role
23
+ end
24
+ end
25
+ @kb.recipes.each do |_, metadata|
26
+ metadata['IncludeRecipeLiterals'].each do |recipe|
27
+ buffer << recipe
28
+ end
29
+ end
30
+ buffer.sort.to_a
31
+ end
32
+
33
+ def output
34
+ to_a
35
+ end
@@ -0,0 +1,25 @@
1
+ # Copyright (c) 2022-present, Meta Platforms, Inc. and affiliates
2
+ # All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ description 'Basic report to show extraction of description from roles'
16
+ needs_rules ['RoleName', 'RoleDescription']
17
+
18
+ def to_plain
19
+ buffer = ''
20
+ @kb.roles.sort_by { |k, _| k }.each do |name, metadata|
21
+ # buffer << name
22
+ buffer << "role: #{name} desc: #{metadata['RoleDescription']}\n"
23
+ end
24
+ buffer
25
+ end
@@ -0,0 +1,30 @@
1
+ # Copyright (c) 2023-present, Meta Platforms, Inc. and affiliates
2
+ # All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ description 'Determine cookbook dependencies from cookbook metadata.rb, output to Dot language'
16
+ needs_rules ['ExplicitMetadataDepends']
17
+
18
+ def to_s
19
+ cookbook_deps = []
20
+ @kb.metadatarbs.each do |x, metadata|
21
+ metadata['ExplicitMetadataDepends'].each do |cb|
22
+ cookbook_deps << [x.gsub(/:.*/, ''), cb]
23
+ end
24
+ end
25
+ "digraph deps {\n#{cookbook_deps.map { |arr| arr.join('->') }.join("\n")}\n}"
26
+ end
27
+
28
+ def output
29
+ to_s
30
+ end
@@ -0,0 +1,29 @@
1
+ # Copyright (c) 2022-present, Meta Platforms, Inc. and affiliates
2
+ # All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ description 'Determines all recipes using dynamic recipe inclusion (ie not string literals)'
16
+ needs_rules ['IncludeRecipeDynamic']
17
+
18
+ def to_a
19
+ buffer = []
20
+ @kb.recipes.each do |recipe, metadata|
21
+ buffer << recipe if metadata['IncludeRecipeDynamic']
22
+ end
23
+ buffer.sort!
24
+ buffer
25
+ end
26
+
27
+ def output
28
+ to_a
29
+ end
@@ -0,0 +1,30 @@
1
+ # Copyright (c) 2022-present, Meta Platforms, Inc. and affiliates
2
+ # All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ description 'Determine all leaf cookbooks, where no other cookbook depends on it via metadata.rb'
16
+ needs_rules ['ExplicitMetadataDepends']
17
+
18
+ def to_a
19
+ buffer = Set.new
20
+ @kb.metadatarbs.each do |_, metadata|
21
+ metadata['ExplicitMetadataDepends'].each do |cb|
22
+ buffer << cb
23
+ end
24
+ end
25
+ (@kb.cookbooks.keys.to_set - buffer).sort.to_a
26
+ end
27
+
28
+ def output
29
+ to_a
30
+ end
@@ -0,0 +1,27 @@
1
+ # Copyright (c) 2022-present, Meta Platforms, Inc. and affiliates
2
+ # All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ description 'Get modules and classes constants that are explicitly defined in library files'
16
+ needs_rules ['LibraryDefinedClassConstants', 'LibraryDefinedModuleConstants']
17
+
18
+ def output
19
+ buffer = ''
20
+ buffer << "file\tmodules\tconstants\n"
21
+ @kb.libraries.sort_by { |k, _| k }.each do |name, metadata|
22
+ # buffer << name
23
+ buffer << "#{name}:\t#{metadata['LibraryDefinedModuleConstants'].join(',')}" +
24
+ "\t#{metadata['LibraryDefinedClassConstants'].join(',')}\n"
25
+ end
26
+ buffer
27
+ end
@@ -0,0 +1,61 @@
1
+ # Copyright (c) 2022-present, Meta Platforms, Inc. and affiliates
2
+ # All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ description 'Determines all recipes that are directly referenced in roles and recipes' +
16
+ ' but were not found by the crawler'
17
+ needs_rules ['RoleRunListRecipes', 'IncludeRecipeLiterals']
18
+
19
+ def to_h
20
+ known_recipes = Set.new @kb.recipes.keys
21
+ missing = { 'roles' => {}, 'recipes' => {} }
22
+ @kb.roles.each do |role, metadata|
23
+ metadata['RoleRunListRecipes'].each do |recipe|
24
+ unless known_recipes.include? recipe
25
+ missing['roles'][role] ||= []
26
+ missing['roles'][role].append recipe
27
+ end
28
+ end
29
+ end
30
+ @kb.recipes.each do |kbrecipe, metadata|
31
+ metadata['IncludeRecipeLiterals'].each do |recipe|
32
+ unless known_recipes.include? recipe
33
+ missing['recipes'][kbrecipe] ||= []
34
+ missing['recipes'][kbrecipe].append recipe
35
+ end
36
+ end
37
+ end
38
+ missing
39
+ end
40
+
41
+ def to_plain
42
+ hsh = to_h
43
+ buffer = ''
44
+ if hsh['roles'].empty?
45
+ buffer << "No missing recipes coming from the roles files\n"
46
+ else
47
+ buffer << "Roles:\n"
48
+ hsh['roles'].each do |role, recipes|
49
+ buffer << "\t#{role}\t#{recipes.join(', ')}\n"
50
+ end
51
+ end
52
+ if hsh['recipes'].empty?
53
+ buffer << 'No missing recipes coming from the recipe files'
54
+ else
55
+ buffer << "Recipes:\n"
56
+ hsh['recipes'].each do |kbrecipe, recipes|
57
+ buffer << "\t#{kbrecipe}\t#{recipes.join(', ')}\n"
58
+ end
59
+ end
60
+ buffer
61
+ end
@@ -0,0 +1,46 @@
1
+ # Copyright (c) 2022-present, Meta Platforms, Inc. and affiliates
2
+ # All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ description 'Ruby files which are empty, comments-only, ' +
16
+ 'or unparseable by RuboCop'
17
+ needs_rules ['NoParsedRuby']
18
+
19
+ def to_h
20
+ no_parsed_ruby = {}
21
+ Bookworm::InferRules::NoParsedRuby.keys.each do |key|
22
+ plural = BOOKWORM_KEYS[key]['plural']
23
+ no_parsed_ruby[plural] = []
24
+ @kb.send(plural.to_sym).each do |k, metadata|
25
+ no_parsed_ruby[plural].append(k) if metadata['NoParsedRuby']
26
+ end
27
+ end
28
+ no_parsed_ruby
29
+ end
30
+
31
+ def to_plain
32
+ hsh = to_h
33
+ buffer = ''
34
+ Bookworm::InferRules::NoParsedRuby.keys.each do |key|
35
+ plural = BOOKWORM_KEYS[key]['plural']
36
+ if hsh[plural].empty?
37
+ buffer << "No non-AST #{plural} files\n"
38
+ else
39
+ buffer << "#{plural.capitalize}:\n"
40
+ hsh[plural].sort.each do |keys|
41
+ buffer << "\t#{keys}\n"
42
+ end
43
+ end
44
+ end
45
+ buffer
46
+ end
@@ -0,0 +1,37 @@
1
+ # Copyright (c) 2023-present, Meta Platforms, Inc. and affiliates
2
+ # All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ description 'Determines all recipes that are not directly referenced either in roles or recipes'
16
+ needs_rules ['RoleRunListRecipes', 'IncludeRecipeLiterals']
17
+
18
+ def to_a
19
+ referenced_recipes = Set.new
20
+ @kb.roles.each do |_, metadata|
21
+ metadata['RoleRunListRecipes'].each do |role|
22
+ referenced_recipes << role
23
+ end
24
+ end
25
+ @kb.recipes.each do |_, metadata|
26
+ metadata['IncludeRecipeLiterals'].each do |recipe|
27
+ referenced_recipes << recipe
28
+ end
29
+ end
30
+ all_recipes = Set.new(@kb.recipes.keys)
31
+ # Any recipes which weren't included via roles or include_recipe are not referenced
32
+ (all_recipes - referenced_recipes).sort.to_a
33
+ end
34
+
35
+ def output
36
+ to_a
37
+ end
@@ -0,0 +1,27 @@
1
+ # Copyright (c) 2022-present, Meta Platforms, Inc. and affiliates
2
+ # All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ description 'Determine all recipes that are assigning a constant in the recipe file'
16
+ needs_rules ['RecipeConstantAssignments']
17
+
18
+ def output
19
+ buffer = ''
20
+
21
+ @kb.recipes.each do |name, metadata|
22
+ unless metadata['RecipeConstantAssignments'].empty?
23
+ buffer << "#{name} #{metadata['RecipeConstantAssignments'].join(', ')}\n"
24
+ end
25
+ end
26
+ buffer
27
+ end