Skip to content

Commit 00b8137

Browse files
committed
update pants-plugins/sample_conf to pants 2.15
The Fmt/Lint plugin API changed in pants 2.15 It now requires a Subsystem with a SkipOption. I took advantage of this to consolidate the constants and all the address and pex request definitions in the Subsystem subclass. It now requires 2 rules instead of 1: to partition, then fmt/lint. That means the structure of the rule requests had to change slightly. The tests also had to account for the modified rules.
1 parent 11187ac commit 00b8137

3 files changed

Lines changed: 90 additions & 45 deletions

File tree

pants-plugins/sample_conf/rules.py

Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,14 @@
1313
# limitations under the License.
1414
from dataclasses import dataclass
1515

16-
from pants.backend.python.target_types import EntryPoint
1716
from pants.backend.python.util_rules import pex, pex_from_targets
1817
from pants.backend.python.util_rules.pex import (
1918
VenvPex,
2019
VenvPexProcess,
2120
)
2221
from pants.backend.python.util_rules.pex_from_targets import PexFromTargetsRequest
2322
from pants.core.goals.fmt import FmtResult, FmtTargetsRequest
24-
from pants.engine.addresses import Address
23+
from pants.core.util_rules.partitions import PartitionerType
2524
from pants.engine.fs import (
2625
CreateDigest,
2726
Digest,
@@ -31,17 +30,13 @@
3130
from pants.engine.process import FallibleProcessResult
3231
from pants.engine.rules import Get, collect_rules, rule
3332
from pants.engine.target import FieldSet
34-
from pants.engine.unions import UnionRule
3533
from pants.util.logging import LogLevel
34+
from pants.util.strutil import strip_v2_chroot_path
3635

36+
from sample_conf.subsystem import ConfigGen
3737
from sample_conf.target_types import SampleConfSourceField
3838

3939

40-
# these constants are also used in the tests.
41-
SCRIPT_DIR = "tools"
42-
SCRIPT = "config_gen"
43-
44-
4540
@dataclass(frozen=True)
4641
class GenerateSampleConfFieldSet(FieldSet):
4742
required_fields = (SampleConfSourceField,)
@@ -51,37 +46,25 @@ class GenerateSampleConfFieldSet(FieldSet):
5146

5247
class GenerateSampleConfViaFmtTargetsRequest(FmtTargetsRequest):
5348
field_set_type = GenerateSampleConfFieldSet
54-
name = SCRIPT
49+
tool_subsystem = ConfigGen
50+
partitioner_type = PartitionerType.DEFAULT_SINGLE_PARTITION
5551

5652

5753
@rule(
58-
desc=f"Update conf/st2.conf.sample with {SCRIPT_DIR}/{SCRIPT}.py",
54+
desc=f"Update conf/st2.conf.sample with {ConfigGen.directory}/{ConfigGen.script}.py",
5955
level=LogLevel.DEBUG,
6056
)
6157
async def generate_sample_conf_via_fmt(
62-
request: GenerateSampleConfViaFmtTargetsRequest,
58+
request: GenerateSampleConfViaFmtTargetsRequest.Batch,
59+
subsystem: ConfigGen,
6360
) -> FmtResult:
6461
# There will only be one target+field_set, but we iterate
6562
# to satisfy how fmt expects that there could be more than one.
6663
# If there is more than one, they will all get the same contents.
6764

6865
# actually generate it with an external script.
6966
# Generation cannot be inlined here because it needs to import the st2 code.
70-
pex = await Get(
71-
VenvPex,
72-
PexFromTargetsRequest(
73-
[
74-
Address(
75-
SCRIPT_DIR,
76-
target_name=SCRIPT_DIR,
77-
relative_file_path=f"{SCRIPT}.py",
78-
)
79-
],
80-
output_filename=f"{SCRIPT}.pex",
81-
internal_only=True,
82-
main=EntryPoint(SCRIPT),
83-
),
84-
)
67+
pex = await Get(VenvPex, PexFromTargetsRequest, subsystem.pex_request())
8568

8669
result = await Get(
8770
FallibleProcessResult,
@@ -91,23 +74,25 @@ async def generate_sample_conf_via_fmt(
9174
),
9275
)
9376

94-
contents = [
95-
FileContent(
96-
f"{field_set.address.spec_path}/{field_set.source.value}",
97-
result.stdout,
98-
)
99-
for field_set in request.field_sets
100-
]
77+
contents = [FileContent(file, result.stdout) for file in request.files]
10178

10279
output_digest = await Get(Digest, CreateDigest(contents))
10380
output_snapshot = await Get(Snapshot, Digest, output_digest)
104-
return FmtResult.create(request, result, output_snapshot, strip_chroot_path=True)
81+
82+
return FmtResult(
83+
input=request.snapshot,
84+
output=output_snapshot,
85+
# Drop result.stdout since we already wrote it to a file
86+
stdout="",
87+
stderr=strip_v2_chroot_path(result.stderr),
88+
tool_name=request.tool_name,
89+
)
10590

10691

10792
def rules():
10893
return [
10994
*collect_rules(),
110-
UnionRule(FmtTargetsRequest, GenerateSampleConfViaFmtTargetsRequest),
95+
*GenerateSampleConfViaFmtTargetsRequest.rules(),
11196
*pex.rules(),
11297
*pex_from_targets.rules(),
11398
]

pants-plugins/sample_conf/rules_test.py

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@
2323
from pants.engine.fs import CreateDigest, Digest, FileContent, Snapshot
2424
from pants.engine.target import Target
2525
from pants.core.goals.fmt import FmtResult
26+
from pants.core.util_rules.partitions import Partitions
2627
from pants.testutil.rule_runner import QueryRule, RuleRunner
2728

2829
from .rules import (
29-
SCRIPT,
30-
SCRIPT_DIR,
3130
GenerateSampleConfFieldSet,
3231
GenerateSampleConfViaFmtTargetsRequest,
3332
rules as sample_conf_rules,
3433
)
34+
from .subsystem import ConfigGen
3535
from .target_types import SampleConf
3636

3737

@@ -41,7 +41,10 @@ def rule_runner() -> RuleRunner:
4141
rules=[
4242
*sample_conf_rules(),
4343
*target_types_rules.rules(),
44-
QueryRule(FmtResult, (GenerateSampleConfViaFmtTargetsRequest,)),
44+
QueryRule(
45+
Partitions, (GenerateSampleConfViaFmtTargetsRequest.PartitionRequest,)
46+
),
47+
QueryRule(FmtResult, (GenerateSampleConfViaFmtTargetsRequest.Batch,)),
4548
QueryRule(SourceFiles, (SourceFilesRequest,)),
4649
],
4750
target_types=[SampleConf, PythonSourcesGeneratorTarget],
@@ -57,23 +60,35 @@ def run_st2_generate_sample_conf(
5760
rule_runner.set_options(
5861
[
5962
"--backend-packages=sample_conf",
60-
f"--source-root-patterns=/{SCRIPT_DIR}",
63+
f"--source-root-patterns=/{ConfigGen.directory}",
6164
*(extra_args or ()),
6265
],
6366
env_inherit={"PATH", "PYENV_ROOT", "HOME"},
6467
)
65-
field_sets = [GenerateSampleConfFieldSet.create(tgt) for tgt in targets]
68+
field_sets = tuple(GenerateSampleConfFieldSet.create(tgt) for tgt in targets)
6669
input_sources = rule_runner.request(
6770
SourceFiles,
6871
[
6972
SourceFilesRequest(field_set.source for field_set in field_sets),
7073
],
7174
)
75+
76+
# run DEFAULT_SINGLE_PARTITION rule
77+
partitions = rule_runner.request(
78+
Partitions,
79+
[GenerateSampleConfViaFmtTargetsRequest.PartitionRequest(field_sets)],
80+
)
81+
assert len(partitions) == 1
82+
83+
# run generate_schemas_via_fmt rule
7284
fmt_result = rule_runner.request(
7385
FmtResult,
7486
[
75-
GenerateSampleConfViaFmtTargetsRequest(
76-
field_sets, snapshot=input_sources.snapshot
87+
GenerateSampleConfViaFmtTargetsRequest.Batch(
88+
tool_name="",
89+
elements=partitions[0].elements, # ie: files
90+
partition_metadata=partitions[0].metadata,
91+
snapshot=input_sources.snapshot,
7792
),
7893
],
7994
)
@@ -112,9 +127,11 @@ def write_files(
112127
f"{sample_conf_dir}/{sample_conf_file}": before,
113128
f"{sample_conf_dir}/BUILD": f"sample_conf(name='t', source='{sample_conf_file}')",
114129
# add in the target that's hard-coded in the generate_sample_conf_via_fmt rue
115-
f"{SCRIPT_DIR}/{SCRIPT}.py": SCRIPT_PY.format(sample_conf_text=after),
116-
f"{SCRIPT_DIR}/__init__.py": "",
117-
f"{SCRIPT_DIR}/BUILD": "python_sources()",
130+
f"{ConfigGen.directory}/{ConfigGen.script}.py": SCRIPT_PY.format(
131+
sample_conf_text=after
132+
),
133+
f"{ConfigGen.directory}/__init__.py": "",
134+
f"{ConfigGen.directory}/BUILD": "python_sources()",
118135
}
119136

120137
rule_runner.write_files(files)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Copyright 2023 The StackStorm Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
from pants.backend.python.target_types import EntryPoint
15+
from pants.backend.python.util_rules.pex_from_targets import PexFromTargetsRequest
16+
from pants.engine.addresses import Address
17+
from pants.option.option_types import SkipOption
18+
from pants.option.subsystem import Subsystem
19+
20+
21+
class ConfigGen(Subsystem):
22+
name = "StackStorm Sample st2.conf Generator"
23+
options_scope = "st2-config-gen"
24+
skip = SkipOption("fmt", "lint")
25+
help = "The StackStorm st2.conf.sample generator."
26+
27+
directory = "tools"
28+
script = "config_gen"
29+
30+
def address(self) -> Address:
31+
return Address(
32+
self.directory,
33+
target_name=self.directory,
34+
relative_file_path=f"{self.script}.py",
35+
)
36+
37+
def pex_request(self) -> PexFromTargetsRequest:
38+
return PexFromTargetsRequest(
39+
[self.address()],
40+
output_filename=f"{self.script}.pex",
41+
internal_only=True,
42+
main=EntryPoint(self.script),
43+
)

0 commit comments

Comments
 (0)