Codegen has been used in production for multi-million line codebases to automatically delete “dead” (rolled-out) feature flags. This guide will walk you through analyzing feature flag usage and safely removing rolled out flags.
Every codebase does feature flags differently. This guide shows common techniques and syntax but likely requires adaptation to codebase-specific circumstances.
Analyzing Feature Flag Usage
Before removing a feature flag, it’s important to analyze its usage across the codebase. Codegen provides tools to help identify where and how feature flags are used.
For Python Codebases
For Python codebases using a FeatureFlags
class pattern like so:
class FeatureFlags:
FEATURE_1 = False
FEATURE_2 = True
You can use Class.get_attribute(…) and Attribute.usages to analyze the coverage of your flags, like so:
feature_flag_usage = {}
feature_flag_class = codebase.get_class('FeatureFlag')
if feature_flag_class:
# Initialize usage count for all attributes
for attr in feature_flag_class.attributes:
feature_flag_usage[attr.name] = 0
# Get all usages of the FeatureFlag class
for usage in feature_flag_class.usages:
usage_source = usage.usage_symbol.source if hasattr(usage, 'usage_symbol') else str(usage)
for flag_name in feature_flag_usage.keys():
if f"FeatureFlag.{flag_name}" in usage_source:
feature_flag_usage[flag_name] += 1
sorted_flags = sorted(feature_flag_usage.items(), key=lambda x: x[1], reverse=True)
print("Feature Flag Usage Table:")
print("-------------------------")
print(f"{'Feature Flag':<30} | {'Usage Count':<12}")
print("-" * 45)
for flag, count in sorted_flags:
print(f"{flag:<30} | {count:<12}")
print(f"\nTotal feature flags: {len(sorted_flags)}")
else:
print("❗ FeatureFlag enum not found in the codebase")
This will output a table showing all feature flags and their usage counts, helping identify which flags are candidates for removal.
Removing Rolled Out Flags
Once you’ve identified a flag that’s ready to be removed, Codegen can help safely delete it and its associated code paths.
Python Example
For Python codebases, here’s how to remove a feature flag and its usages:
flag_name = "FEATURE_TO_REMOVE"
# Get the feature flag variable
feature_flag_file = codebase.get_file("app/utils/feature_flags.py")
flag_class = feature_flag_file.get_class("FeatureFlag")
# Check if the flag exists
flag_var = flag_class.get_attribute(flag_name)
if not flag_var:
print(f'No such flag: {flag_name}')
return
# Remove all usages of the feature flag
for usage in flag_var.usages:
if isinstance(usage.parent, IfBlockStatement):
# For if statements, reduce the condition to True
usage.parent.reduce_condition(True)
elif isinstance(usage.parent, WithStatement):
# For with statements, keep the code block
usage.parent.code_block.unwrap()
else:
# For other cases, remove the usage
usage.remove()
# Remove the flag definition
flag_var.remove()
# Commit changes
codebase.commit()
React/TypeScript Example
For React applications using a hooks-based feature flag system:
feature_flag_name = "NEW_UI_ENABLED"
target_value = True # The value to reduce the flag to
print(f'Removing feature flag: {feature_flag_name}')
# 1. Remove from configuration
config_file = codebase.get_file("src/featureFlags/config.ts")
feature_flag_config = config_file.get_symbol("FEATURE_FLAG_CONFIG").value
if feature_flag_name in feature_flag_config.keys():
feature_flag_config.pop(feature_flag_name)
print('✅ Removed from feature flag config')
# 2. Find and reduce all hook usages
hook = codebase.get_function("useFeatureFlag")
for usage in hook.usages:
fcall = usage.match
if isinstance(fcall, FunctionCall):
# Check if this usage is for our target flag
first_arg = fcall.args[0].value
if isinstance(first_arg, String) and first_arg.content == feature_flag_name:
print(f'Reducing in: {fcall.parent_symbol.name}')
# This automatically handles:
# - Ternary expressions: flag ? <New /> : <Old />
# - If statements: if (flag) { ... }
# - Conditional rendering: {flag && <Component />}
fcall.reduce_condition(target_value)
# 3. Commit changes
codebase.commit()
This will:
- Remove the feature flag from the configuration
- Find all usages of the
useFeatureFlag
hook for this flag
- Automatically reduce any conditional logic using the flag
- Handle common React patterns like ternaries and conditional rendering