fb_bookworm 0.0.1

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.
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