Skip to content

Commit

Permalink
Implement tailor goal for Helm charts (pantsbuild#15191)
Browse files Browse the repository at this point in the history
Implementation of the `tailor` goal based on finding `PutativeTargets` by searching for the Helm chart metadata file.
  • Loading branch information
alonsodomin authored Apr 20, 2022
1 parent f8b672c commit b6e6215
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/python/pants/backend/experimental/helm/register.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright 2022 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from pants.backend.helm.goals import lint, package, publish
from pants.backend.helm.goals import lint, package, publish, tailor
from pants.backend.helm.target_types import (
HelmArtifactTarget,
HelmChartTarget,
Expand All @@ -28,6 +28,7 @@ def rules():
*lint.rules(),
*package.rules(),
*publish.rules(),
*tailor.rules(),
*test_rules(),
*sources.rules(),
*tool.rules(),
Expand Down
56 changes: 56 additions & 0 deletions src/python/pants/backend/helm/goals/tailor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright 2022 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from __future__ import annotations

import os
from dataclasses import dataclass
from itertools import chain

from pants.backend.helm.target_types import HelmChartTarget
from pants.backend.helm.util_rules.chart_metadata import HELM_CHART_METADATA_FILENAMES
from pants.core.goals.tailor import (
AllOwnedSources,
PutativeTarget,
PutativeTargets,
PutativeTargetsRequest,
)
from pants.engine.fs import PathGlobs, Paths
from pants.engine.rules import Get, MultiGet, collect_rules, rule
from pants.engine.unions import UnionRule
from pants.util.logging import LogLevel


@dataclass(frozen=True)
class PutativeHelmChartTargetsRequest(PutativeTargetsRequest):
pass


@rule(desc="Determine candidate Helm chart targets to create", level=LogLevel.DEBUG)
async def find_putative_helm_targets(
request: PutativeHelmChartTargetsRequest, all_owned_sources: AllOwnedSources
) -> PutativeTargets:
found_chart_paths = await MultiGet(
Get(Paths, PathGlobs, request.search_paths.path_globs(filename))
for filename in HELM_CHART_METADATA_FILENAMES
)
all_chart_files = chain.from_iterable([p.files for p in found_chart_paths])
unowned_chart_files = set(all_chart_files) - set(all_owned_sources)

putative_targets = []
for chart_file in sorted(unowned_chart_files):
dirname, filename = os.path.split(chart_file)
putative_targets.append(
PutativeTarget.for_target_type(
HelmChartTarget,
name=os.path.basename(dirname),
path=dirname,
triggering_sources=[filename],
)
)

return PutativeTargets(putative_targets)


def rules():
return [*collect_rules(), UnionRule(PutativeTargetsRequest, PutativeHelmChartTargetsRequest)]
55 changes: 55 additions & 0 deletions src/python/pants/backend/helm/goals/tailor_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

import os

import pytest

from pants.backend.helm.goals.tailor import PutativeHelmChartTargetsRequest
from pants.backend.helm.goals.tailor import rules as helm_tailor_rules
from pants.backend.helm.target_types import HelmChartTarget
from pants.core.goals.tailor import (
AllOwnedSources,
PutativeTarget,
PutativeTargets,
PutativeTargetsSearchPaths,
)
from pants.engine.rules import QueryRule
from pants.testutil.rule_runner import RuleRunner


@pytest.fixture
def rule_runner() -> RuleRunner:
return RuleRunner(
target_types=[HelmChartTarget],
rules=[
*helm_tailor_rules(),
QueryRule(PutativeTargets, (PutativeHelmChartTargetsRequest, AllOwnedSources)),
],
)


def test_find_helm_charts(rule_runner: RuleRunner) -> None:
rule_runner.write_files(
{"src/owned/Chart.yaml": "", "src/foo/Chart.yaml": "", "src/bar/Chart.yml": ""}
)

putative_targets = rule_runner.request(
PutativeTargets,
[
PutativeHelmChartTargetsRequest(PutativeTargetsSearchPaths(("src/",))),
AllOwnedSources(["src/owned/Chart.yaml"]),
],
)

def expected_target(path: str, triggering_source: str) -> PutativeTarget:
return PutativeTarget.for_target_type(
HelmChartTarget,
name=os.path.basename(path),
path=path,
triggering_sources=[triggering_source],
)

assert putative_targets == PutativeTargets(
[expected_target("src/foo", "Chart.yaml"), expected_target("src/bar", "Chart.yml")]
)

0 comments on commit b6e6215

Please sign in to comment.