in asfyaml/asfyaml.py [0:0]
def __init__(self, repo: dataobjects.Repository, committer: str, config_data: str, branch: str | None = None):
self.repository = repo
self.committer = dataobjects.Committer(committer)
self.is_tag = False
if branch and branch.startswith("refs/heads/"):
self.branch = branch[11:] # If actual branch, crop and set
elif branch and branch.startswith("refs/tags/"):
print(f"For {repo.name}, got a tag event ({branch}) when expecting a branch event, not processing!")
self.is_tag = True
self.branch = dataobjects.UNKNOWN_BRANCH
else:
self.branch = dataobjects.UNKNOWN_BRANCH # Not a valid branch pattern, set to the "unknown branch" marker
# to avoid treating it as the main branch.
# Load YAML and, if any parsing errors happen, bail and raise exception
try:
self.yaml = strictyaml.dirty_load(config_data, label=f"{repo.name}.git/.asf.yaml", allow_flow_style=True)
except strictyaml.ruamel.scanner.ScannerError as e:
raise ASFYAMLException(repository=self.repository, branch=self.branch, feature="main", error_message=str(e))
self.features = FeatureList() # Placeholder for enabled and verified features during runtime.
self.environment = envvars.Environment()
self.no_cache = False # Set "cache: false" in the meta section to force a complete parse in all features.
# TODO: Set up repo details inside this class (repo name, file-path, project, private/public, etc)
# Sort out which environments we are going to be using. This will determine which
# features to add, or which version of a feature to use.
self.environments_enabled = {DEFAULT_ENVIRONMENT}
if "meta" in self.yaml:
# environment: fooenv
# merges a single environment with production
if "environment" in self.yaml["meta"]:
self.environments_enabled.add(str(self.yaml["meta"]["environment"]))
self.no_cache = self.yaml["meta"].get("cache", True) is False
# environments:
# - foobar
# - barbaz
# merges a list of environments with production.
# Merging happens in order of appearance in the yaml configuration, so having environments
# a, b, c in the configuration will be based off production, with features then added or
# overridden by a, then b, then c.
if "environments" in self.yaml["meta"]:
for env in self.yaml["meta"]["environments"]:
self.environments_enabled.add(str(env))
self.no_cache = self.yaml["meta"].get("cache", True) is False
if DEBUG:
print("")
print(f"Using environment(s): {', '.join(self.environments_enabled)}")
self.enabled_features = {}
""": FeatureList: This variable contains all features that are enabled for this run, as an object with of all the features that are enabled and their class instances as attributes.
Each feature is accessible as an attribute with the feature name as key, for instance :code:`self.instance.enabled_features.gitub`.
If a feature is not available (not enabled or not configured), a None value will be returned instead,
allowing you to easily test for whether a feature is enabled or not without running into key errors.
Example use::
class ASFTestFeature(ASFYamlFeature, name="test", priority=4):
def run(self):
# Check if we have notification features enabled for this repo or not
notifs = self.instance.enabled_features.notifications
if notifs: # If notifications are in use...
# The notifications feature runs before the rest, so we can
# access its data already.
print(f"We have these mailing lis targets: {notifs.valid_targets}")
else:
raise Exception("You need to enable notifications!")
As the :class:`FeatureList` object acts like a dictionary (more precisely, like an EasyDict),
you can inspect the list as a dictionary and learn which features are currently enabled::
def run(self):
features_we_have = ", ".join(self.instance.enabled_features) # Dicts act like lists of keys in join
print(f"The following is enabled: {features_we_have}") # Could be "notifications, github, jekyll"
"""
# Make a list of enabled features for this repo, based on the environments enabled for it.
# Features are loaded in environment order, sop later environments can override features from other envs.
# For instance, a production+test env list would load all production features and mix in test
# features, overriding any features that are already in production.
for env in self.environments_enabled:
for feat in ASFYamlFeature.features:
if feat.env == env:
self.enabled_features[feat.name] = feat
if DEBUG:
print(f"Enabled features for this run: {', '.join(self.enabled_features.keys())}")
print(f"Features seen inside .asf.yaml: {', '.join([str(x) for x in self.yaml.keys()])}")