2022-04-04 11:22:00 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
require 'yaml'
|
|
|
|
|
|
|
|
namespace :tw do
|
|
|
|
desc 'Generates a list of codeowners for documentation pages.'
|
|
|
|
task :codeowners do
|
|
|
|
CodeOwnerRule = Struct.new(:category, :writer)
|
2022-07-23 23:45:48 +05:30
|
|
|
DocumentOwnerMapping = Struct.new(:path, :writer) do
|
|
|
|
def writer_owns_all_pages?(mappings)
|
|
|
|
mappings
|
|
|
|
.select { |mapping| mapping.directory == directory }
|
|
|
|
.all? { |mapping| mapping.writer == writer }
|
|
|
|
end
|
|
|
|
|
|
|
|
def directory
|
|
|
|
@directory ||= File.dirname(path)
|
|
|
|
end
|
|
|
|
end
|
2022-04-04 11:22:00 +05:30
|
|
|
|
|
|
|
CODE_OWNER_RULES = [
|
|
|
|
CodeOwnerRule.new('Activation', '@kpaizee'),
|
|
|
|
CodeOwnerRule.new("Adoption", '@kpaizee'),
|
|
|
|
CodeOwnerRule.new('Activation', '@kpaizee'),
|
|
|
|
CodeOwnerRule.new('Adoption', '@kpaizee'),
|
2022-06-21 17:19:12 +05:30
|
|
|
CodeOwnerRule.new('Authentication and Authorization', '@eread'),
|
2022-04-04 11:22:00 +05:30
|
|
|
CodeOwnerRule.new('Certify', '@msedlakjakubowski'),
|
|
|
|
CodeOwnerRule.new('Code Review', '@aqualls'),
|
|
|
|
CodeOwnerRule.new('Compliance', '@eread'),
|
|
|
|
CodeOwnerRule.new('Composition Analysis', '@rdickenson'),
|
2022-07-16 23:28:13 +05:30
|
|
|
CodeOwnerRule.new('Configure', '@sselhorn'),
|
2022-06-21 17:19:12 +05:30
|
|
|
CodeOwnerRule.new('Container Security', '@claytoncornell'),
|
2022-04-04 11:22:00 +05:30
|
|
|
CodeOwnerRule.new('Contributor Experience', '@eread'),
|
|
|
|
CodeOwnerRule.new('Conversion', '@kpaizee'),
|
2022-07-16 23:28:13 +05:30
|
|
|
CodeOwnerRule.new('Database', '@aqualls'),
|
|
|
|
CodeOwnerRule.new('Development', '@sselhorn'),
|
2022-04-04 11:22:00 +05:30
|
|
|
CodeOwnerRule.new('Distribution', '@axil'),
|
|
|
|
CodeOwnerRule.new('Distribution (Charts)', '@axil'),
|
|
|
|
CodeOwnerRule.new('Distribution (Omnibus)', '@axil'),
|
2022-07-16 23:28:13 +05:30
|
|
|
CodeOwnerRule.new('Documentation Guidelines', '@sselhorn'),
|
2022-04-04 11:22:00 +05:30
|
|
|
CodeOwnerRule.new('Dynamic Analysis', '@rdickenson'),
|
|
|
|
CodeOwnerRule.new('Ecosystem', '@kpaizee'),
|
|
|
|
CodeOwnerRule.new('Editor', '@aqualls'),
|
|
|
|
CodeOwnerRule.new('Expansion', '@kpaizee'),
|
|
|
|
CodeOwnerRule.new('Foundations', '@rdickenson'),
|
|
|
|
CodeOwnerRule.new('Fuzz Testing', '@rdickenson'),
|
|
|
|
CodeOwnerRule.new('Geo', '@axil'),
|
|
|
|
CodeOwnerRule.new('Gitaly', '@eread'),
|
2022-07-16 23:28:13 +05:30
|
|
|
CodeOwnerRule.new('Global Search', '@sselhorn'),
|
2022-06-21 17:19:12 +05:30
|
|
|
CodeOwnerRule.new('Import', '@eread'),
|
2022-07-16 23:28:13 +05:30
|
|
|
CodeOwnerRule.new('Infrastructure', '@sselhorn'),
|
2022-04-04 11:22:00 +05:30
|
|
|
CodeOwnerRule.new('Integrations', '@kpaizee'),
|
|
|
|
CodeOwnerRule.new('Knowledge', '@aqualls'),
|
2022-07-16 23:28:13 +05:30
|
|
|
CodeOwnerRule.new('Memory', '@sselhorn'),
|
2022-06-21 17:19:12 +05:30
|
|
|
CodeOwnerRule.new('Monitor', '@msedlakjakubowski'),
|
|
|
|
CodeOwnerRule.new('Observability', 'msedlakjakubowski'),
|
2022-04-04 11:22:00 +05:30
|
|
|
CodeOwnerRule.new('Optimize', '@fneill'),
|
2022-06-21 17:19:12 +05:30
|
|
|
CodeOwnerRule.new('Package', '@claytoncornell'),
|
2022-04-04 11:22:00 +05:30
|
|
|
CodeOwnerRule.new('Pipeline Authoring', '@marcel.amirault'),
|
|
|
|
CodeOwnerRule.new('Pipeline Execution', '@marcel.amirault'),
|
2022-06-21 17:19:12 +05:30
|
|
|
CodeOwnerRule.new('Pipeline Insights', '@marcel.amirault'),
|
2022-04-04 11:22:00 +05:30
|
|
|
CodeOwnerRule.new('Portfolio Management', '@msedlakjakubowski'),
|
2022-06-21 17:19:12 +05:30
|
|
|
CodeOwnerRule.new('Product Intelligence', '@claytoncornell'),
|
2022-04-04 11:22:00 +05:30
|
|
|
CodeOwnerRule.new('Product Planning', '@msedlakjakubowski'),
|
|
|
|
CodeOwnerRule.new('Project Management', '@msedlakjakubowski'),
|
2022-07-16 23:28:13 +05:30
|
|
|
CodeOwnerRule.new('Provision', '@fneill'),
|
|
|
|
CodeOwnerRule.new('Purchase', '@fneill'),
|
2022-04-04 11:22:00 +05:30
|
|
|
CodeOwnerRule.new('Redirect', 'Redirect'),
|
|
|
|
CodeOwnerRule.new('Release', '@rdickenson'),
|
2022-06-21 17:19:12 +05:30
|
|
|
CodeOwnerRule.new('Respond', '@msedlakjakubowski'),
|
2022-04-04 11:22:00 +05:30
|
|
|
CodeOwnerRule.new('Runner', '@sselhorn'),
|
2022-07-16 23:28:13 +05:30
|
|
|
CodeOwnerRule.new('Sharding', '@sselhorn'),
|
2022-04-04 11:22:00 +05:30
|
|
|
CodeOwnerRule.new('Source Code', '@aqualls'),
|
|
|
|
CodeOwnerRule.new('Static Analysis', '@rdickenson'),
|
|
|
|
CodeOwnerRule.new('Style Guide', '@sselhorn'),
|
|
|
|
CodeOwnerRule.new('Testing', '@eread'),
|
2022-06-21 17:19:12 +05:30
|
|
|
CodeOwnerRule.new('Threat Insights', '@claytoncornell'),
|
2022-07-16 23:28:13 +05:30
|
|
|
CodeOwnerRule.new('Utilization', '@fneill'),
|
2022-06-21 17:19:12 +05:30
|
|
|
CodeOwnerRule.new('Vulnerability Research', '@claytoncornell'),
|
2022-04-04 11:22:00 +05:30
|
|
|
CodeOwnerRule.new('Workspace', '@fneill')
|
|
|
|
].freeze
|
|
|
|
|
|
|
|
Document = Struct.new(:group, :redirect) do
|
|
|
|
def has_a_valid_group?
|
|
|
|
group && !redirect
|
|
|
|
end
|
|
|
|
|
|
|
|
def missing_metadata?
|
|
|
|
!group && !redirect
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.writer_for_group(category)
|
|
|
|
CODE_OWNER_RULES.find { |rule| rule.category == category }&.writer
|
|
|
|
end
|
|
|
|
|
|
|
|
errors = []
|
2022-07-23 23:45:48 +05:30
|
|
|
mappings = []
|
2022-04-04 11:22:00 +05:30
|
|
|
|
|
|
|
path = Rails.root.join("doc/**/*.md")
|
|
|
|
Dir.glob(path) do |file|
|
|
|
|
yaml_data = YAML.load_file(file)
|
|
|
|
document = Document.new(yaml_data['group'], yaml_data['redirect_to'])
|
|
|
|
|
|
|
|
if document.missing_metadata?
|
|
|
|
errors << file
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
writer = writer_for_group(document.group)
|
|
|
|
next unless writer
|
|
|
|
|
2022-07-23 23:45:48 +05:30
|
|
|
mappings << DocumentOwnerMapping.new(file.delete_prefix(Dir.pwd), writer) if document.has_a_valid_group?
|
2022-04-04 11:22:00 +05:30
|
|
|
end
|
|
|
|
|
2022-07-23 23:45:48 +05:30
|
|
|
deduplicated_mappings = Set.new
|
|
|
|
|
|
|
|
mappings.each do |mapping|
|
|
|
|
if mapping.writer_owns_all_pages?(mappings)
|
|
|
|
deduplicated_mappings.add("#{mapping.directory}/ #{mapping.writer}")
|
|
|
|
else
|
|
|
|
deduplicated_mappings.add("#{mapping.path} #{mapping.writer}")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
deduplicated_mappings.each { |mapping| puts mapping }
|
|
|
|
|
2022-04-04 11:22:00 +05:30
|
|
|
if errors.present?
|
|
|
|
puts "-----"
|
|
|
|
puts "ERRORS - the following files are missing the correct metadata:"
|
|
|
|
errors.map { |file| puts file.gsub(Dir.pwd, ".")}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|