debian-mirror-gitlab/scripts/used-feature-flags

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

131 lines
4.2 KiB
Text
Raw Normal View History

2021-01-03 14:25:43 +05:30
#!/usr/bin/env ruby
2021-03-11 19:13:27 +05:30
# frozen_string_literal: true
2021-01-03 14:25:43 +05:30
2021-02-22 17:27:13 +05:30
require 'set'
2021-11-11 11:23:49 +05:30
require 'fileutils'
2022-03-02 08:16:31 +05:30
require_relative '../lib/gitlab_edition'
2021-02-22 17:27:13 +05:30
2021-01-03 14:25:43 +05:30
class String
def red
"\e[31m#{self}\e[0m"
end
def yellow
"\e[33m#{self}\e[0m"
end
def green
"\e[32m#{self}\e[0m"
end
def bold
"\e[1m#{self}\e[0m"
end
end
flags_paths = [
'config/feature_flags/**/*.yml'
]
# For EE additionally process `ee/` feature flags
2022-03-02 08:16:31 +05:30
if GitlabEdition.ee?
2021-01-03 14:25:43 +05:30
flags_paths << 'ee/config/feature_flags/**/*.yml'
2021-09-30 23:02:18 +05:30
# Geo feature flags are constructed dynamically and there's no explicit checks in the codebase so we mark all
# the replicators' derived feature flags as used.
# See https://gitlab.com/gitlab-org/gitlab/-/blob/54e802e8fe76b6f93656d75ef9b566bf57b60f41/ee/lib/gitlab/geo/replicator.rb#L183-185
Dir.glob('ee/app/replicators/geo/*_replicator.rb').each_with_object(Set.new) do |path, memo|
replicator_name = File.basename(path, '.rb')
feature_flag_name = "geo_#{replicator_name.delete_suffix('_replicator')}_replication"
FileUtils.touch(File.join('tmp', 'feature_flags', "#{feature_flag_name}.used"))
end
2021-01-03 14:25:43 +05:30
end
2021-12-11 22:18:48 +05:30
# For JH additionally process `jh/` feature flags
2022-03-02 08:16:31 +05:30
if GitlabEdition.jh?
2021-12-11 22:18:48 +05:30
flags_paths << 'jh/config/feature_flags/**/*.yml'
Dir.glob('jh/app/replicators/geo/*_replicator.rb').each_with_object(Set.new) do |path, memo|
replicator_name = File.basename(path, '.rb')
feature_flag_name = "geo_#{replicator_name.delete_suffix('_replicator')}_replication"
FileUtils.touch(File.join('tmp', 'feature_flags', "#{feature_flag_name}.used"))
end
end
2021-01-03 14:25:43 +05:30
all_flags = {}
additional_flags = Set.new
# Iterate all defined feature flags
# to discover which were used
flags_paths.each do |flags_path|
puts flags_path
Dir.glob(flags_path).each do |path|
feature_flag_name = File.basename(path, '.yml')
2021-02-22 17:27:13 +05:30
# TODO: we need a better way of tracking use of Gitaly FF across Gitaly and GitLab
2021-09-30 23:02:18 +05:30
if feature_flag_name.start_with?('gitaly_')
puts "Skipping the #{feature_flag_name} feature flag since it starts with 'gitaly_'."
next
end
2021-01-03 14:25:43 +05:30
all_flags[feature_flag_name] = File.exist?(File.join('tmp', 'feature_flags', feature_flag_name + '.used'))
end
end
# Iterate all used feature flags
# to discover which flags are undefined
Dir.glob('tmp/feature_flags/*.used').each do |path|
feature_flag_name = File.basename(path, '.used')
additional_flags.add(feature_flag_name) unless all_flags[feature_flag_name]
end
used_flags = all_flags.select { |name, used| used }
unused_flags = all_flags.reject { |name, used| used }
puts "=========================================".green.bold
puts "Feature Flags usage summary:".green.bold
puts
puts "- #{all_flags.count + additional_flags.count} was found"
puts "- #{unused_flags.count} appear(s) to be UNUSED".yellow
puts "- #{additional_flags.count} appear(s) to be unknown".yellow
puts "- #{used_flags.count} appear(s) to be used".green
puts
if additional_flags.count > 0
puts "==================================================".green.bold
2023-01-13 00:05:48 +05:30
puts "There are feature flags that appear to be unknown".yellow
2021-01-03 14:25:43 +05:30
puts
puts "They appear to be used by CI, but we do lack their YAML definition".yellow
puts "This is likely expected, so feel free to ignore that list:".yellow
puts
additional_flags.sort.each do |name|
puts "- #{name}".yellow
end
puts
end
if unused_flags.count > 0
puts "========================================".green.bold
2023-01-13 00:05:48 +05:30
puts "These feature flags appear to be UNUSED".red.bold
2021-01-03 14:25:43 +05:30
puts
puts "If they are really no longer needed REMOVE their .yml definition".red
puts "If they are needed you need to ENSURE that their usage is covered with specs to continue.".red
2023-03-04 22:38:38 +05:30
puts "Feature flag usage is detected via Rubocop, which is unable to resolve dynamic feature flag usage,".red.bold
puts "interpolated strings however are optimistically matched. For more details consult test suite:".red
puts "https://gitlab.com/gitlab-org/gitlab/-/blob/69cb5d36db95881b495966c95655672cfb816f62/spec/rubocop/cop/gitlab/mark_used_feature_flags_spec.rb".red
2021-01-03 14:25:43 +05:30
puts
unused_flags.keys.sort.each do |name|
puts "- #{name}".yellow
end
puts
puts "Feature flag usage check failed.".red.bold
exit(1)
end
puts "Everything is fine here!".green
puts