Skip to content

Commit 022dc2e

Browse files
committed
refactor(v-onboard): make _ops_category data-driven (named signal sets + rule dispatch)
1 parent e564751 commit 022dc2e

1 file changed

Lines changed: 47 additions & 26 deletions

File tree

scripts/compound-v-onboard.py

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -217,35 +217,56 @@ def detect_ui(repo: str) -> bool:
217217
return False
218218

219219

220+
# Operations-file taxonomy, kept as named signal sets so the surface is documented in ONE place and
221+
# widening coverage is a data edit, not new control flow. Two literal kinds, matched by _ops_category:
222+
# _OPS_PATH_FILES — full repo-relative path (root-anchored configs like .circleci/config.yml)
223+
# _OPS_BASE_FILES — exact basename, at any depth (Jenkinsfile, Procfile, ...)
224+
# The remaining signals are shape-based (prefix/suffix/path-segment) and live in the predicates below.
225+
_YAML_EXT = (".yml", ".yaml")
226+
_OPS_PATH_FILES = {
227+
"ci_cd": frozenset((".gitlab-ci.yml", ".circleci/config.yml", ".travis.yml",
228+
"azure-pipelines.yml", "bitbucket-pipelines.yml")),
229+
}
230+
_OPS_BASE_FILES = {
231+
"ci_cd": frozenset(("jenkinsfile",)),
232+
"containers": frozenset(("kustomization.yaml", "chart.yaml")),
233+
"deploy": frozenset(("procfile", "fly.toml", "vercel.json", "netlify.toml",
234+
"render.yaml", "serverless.yml", "app.yaml")),
235+
}
236+
237+
238+
def _is_ci_cd(low, base):
239+
return (base in _OPS_BASE_FILES["ci_cd"]
240+
or low in _OPS_PATH_FILES["ci_cd"]
241+
or (low.startswith(".github/workflows/") and low.endswith(_YAML_EXT)))
242+
243+
244+
def _is_containers(low, base):
245+
return (base == "dockerfile" or base.startswith("dockerfile.")
246+
or base in _OPS_BASE_FILES["containers"]
247+
or low.endswith((".tf", ".tfvars"))
248+
or ((base.startswith("docker-compose") or base.startswith("compose.")) and low.endswith(_YAML_EXT))
249+
# k8s: filename/dir heuristic — it cannot see manifest content.
250+
or low.startswith("k8s/") or "/k8s/" in low)
251+
252+
253+
def _is_deploy(low, base):
254+
return (base in _OPS_BASE_FILES["deploy"]
255+
or (base.startswith("deploy") and base.endswith(".sh")))
256+
257+
258+
# Evaluated in order; the first category whose predicate matches wins.
259+
_OPS_RULES = (("ci_cd", _is_ci_cd), ("containers", _is_containers), ("deploy", _is_deploy))
260+
261+
220262
def _ops_category(rel: str):
221-
"""Classify a repo-relative path as an operations file, or None. Deterministic signal set;
222-
k8s detection is a filename/dir heuristic (documented as such — it cannot see manifest content)."""
263+
"""Classify a repo-relative path into an operations category (ci_cd | containers | deploy),
264+
or None. Signal surface lives in the _OPS_* sets and the _is_* predicates above."""
223265
low = rel.lower()
224266
base = low.rsplit("/", 1)[-1]
225-
# --- CI/CD ---
226-
if low.startswith(".github/workflows/") and low.endswith((".yml", ".yaml")):
227-
return "ci_cd"
228-
if low in (".gitlab-ci.yml", ".circleci/config.yml", ".travis.yml",
229-
"azure-pipelines.yml", "bitbucket-pipelines.yml"):
230-
return "ci_cd"
231-
if base == "jenkinsfile":
232-
return "ci_cd"
233-
# --- containers / infra ---
234-
if base == "dockerfile" or base.startswith("dockerfile."):
235-
return "containers"
236-
if (base.startswith("docker-compose") or base.startswith("compose.")) \
237-
and low.endswith((".yml", ".yaml")):
238-
return "containers"
239-
if low.endswith((".tf", ".tfvars")):
240-
return "containers"
241-
if base in ("kustomization.yaml", "chart.yaml") or low.startswith("k8s/") or "/k8s/" in low:
242-
return "containers"
243-
# --- deploy / PaaS ---
244-
if base in ("procfile", "fly.toml", "vercel.json", "netlify.toml",
245-
"render.yaml", "serverless.yml", "app.yaml"):
246-
return "deploy"
247-
if base.startswith("deploy") and base.endswith(".sh"):
248-
return "deploy"
267+
for category, matches in _OPS_RULES:
268+
if matches(low, base):
269+
return category
249270
return None
250271

251272

0 commit comments

Comments
 (0)