Skip to content

Commit 30b116f

Browse files
committed
update pants-plugins/schemas 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 00b8137 commit 30b116f

File tree

3 files changed

+83
-44
lines changed

3 files changed

+83
-44
lines changed

pants-plugins/schemas/rules.py

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,35 +11,28 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14+
import os
1415
from dataclasses import dataclass
1516

16-
from pants.backend.python.target_types import EntryPoint
1717
from pants.backend.python.util_rules import pex, pex_from_targets
1818
from pants.backend.python.util_rules.pex import (
1919
VenvPex,
2020
VenvPexProcess,
2121
)
2222
from pants.backend.python.util_rules.pex_from_targets import PexFromTargetsRequest
2323
from pants.core.goals.fmt import FmtResult, FmtTargetsRequest
24-
from pants.engine.addresses import Address
24+
from pants.core.util_rules.partitions import PartitionerType
2525
from pants.engine.fs import MergeDigests, Snapshot
2626
from pants.engine.process import FallibleProcessResult
2727
from pants.engine.rules import Get, MultiGet, collect_rules, rule
2828
from pants.engine.target import FieldSet
29-
from pants.engine.unions import UnionRule
3029
from pants.util.logging import LogLevel
3130
from pants.util.strutil import strip_v2_chroot_path
3231

32+
from schemas.subsystem import GenerateSchemas
3333
from schemas.target_types import SchemasSourcesField
3434

3535

36-
# these constants are also used in the tests.
37-
CMD_SOURCE_ROOT = "st2common"
38-
CMD_DIR = "st2common/st2common/cmd"
39-
CMD_MODULE = "st2common.cmd"
40-
CMD = "generate_schemas"
41-
42-
4336
@dataclass(frozen=True)
4437
class GenerateSchemasFieldSet(FieldSet):
4538
required_fields = (SchemasSourcesField,)
@@ -49,37 +42,24 @@ class GenerateSchemasFieldSet(FieldSet):
4942

5043
class GenerateSchemasViaFmtTargetsRequest(FmtTargetsRequest):
5144
field_set_type = GenerateSchemasFieldSet
52-
name = CMD
45+
tool_subsystem = GenerateSchemas
46+
partitioner_type = PartitionerType.DEFAULT_SINGLE_PARTITION
5347

5448

5549
@rule(
5650
desc="Update contrib/schemas/*.json with st2-generate-schemas",
5751
level=LogLevel.DEBUG,
5852
)
5953
async def generate_schemas_via_fmt(
60-
request: GenerateSchemasViaFmtTargetsRequest,
54+
request: GenerateSchemasViaFmtTargetsRequest.Batch,
55+
subsystem: GenerateSchemas,
6156
) -> FmtResult:
6257
# We use a pex to actually generate the schemas with an external script.
6358
# Generation cannot be inlined here because it needs to import the st2 code.
64-
pex = await Get(
65-
VenvPex,
66-
PexFromTargetsRequest(
67-
[
68-
Address(
69-
CMD_DIR,
70-
target_name="cmd",
71-
relative_file_path=f"{CMD}.py",
72-
)
73-
],
74-
output_filename=f"{CMD}.pex",
75-
internal_only=True,
76-
main=EntryPoint.parse(f"{CMD_MODULE}.{CMD}:main"),
77-
),
78-
)
59+
pex = await Get(VenvPex, PexFromTargetsRequest, subsystem.pex_request())
7960

80-
# There will probably only be one target+field_set, but we iterate
81-
# to satisfy how fmt expects that there could be more than one.
82-
output_directories = [fs.address.spec_path for fs in request.field_sets]
61+
# There will probably only be one target+field_set, and therefor only one directory
62+
output_directories = {os.path.dirname(f) for f in request.files}
8363

8464
results = await MultiGet(
8565
Get(
@@ -112,14 +92,14 @@ async def generate_schemas_via_fmt(
11292
output=output_snapshot,
11393
stdout=stdout,
11494
stderr=stderr,
115-
formatter_name=request.name,
95+
tool_name=request.tool_name,
11696
)
11797

11898

11999
def rules():
120100
return [
121101
*collect_rules(),
122-
UnionRule(FmtTargetsRequest, GenerateSchemasViaFmtTargetsRequest),
102+
*GenerateSchemasViaFmtTargetsRequest.rules(),
123103
*pex.rules(),
124104
*pex_from_targets.rules(),
125105
]

pants-plugins/schemas/rules_test.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,15 @@
2525
from pants.engine.fs import CreateDigest, Digest, FileContent, Snapshot
2626
from pants.engine.target import Target
2727
from pants.core.goals.fmt import FmtResult
28+
from pants.core.util_rules.partitions import Partitions
2829
from pants.testutil.rule_runner import QueryRule, RuleRunner
2930

3031
from .rules import (
31-
CMD,
32-
CMD_DIR,
33-
CMD_SOURCE_ROOT,
3432
GenerateSchemasFieldSet,
3533
GenerateSchemasViaFmtTargetsRequest,
3634
rules as schemas_rules,
3735
)
36+
from .subsystem import GenerateSchemas
3837
from .target_types import Schemas
3938

4039

@@ -44,7 +43,10 @@ def rule_runner() -> RuleRunner:
4443
rules=[
4544
*schemas_rules(),
4645
*target_types_rules.rules(),
47-
QueryRule(FmtResult, (GenerateSchemasViaFmtTargetsRequest,)),
46+
QueryRule(
47+
Partitions, (GenerateSchemasViaFmtTargetsRequest.PartitionRequest,)
48+
),
49+
QueryRule(FmtResult, (GenerateSchemasViaFmtTargetsRequest.Batch,)),
4850
QueryRule(SourceFiles, (SourceFilesRequest,)),
4951
],
5052
target_types=[Schemas, PythonSourcesGeneratorTarget],
@@ -60,23 +62,35 @@ def run_st2_generate_schemas(
6062
rule_runner.set_options(
6163
[
6264
"--backend-packages=schemas",
63-
f"--source-root-patterns=/{CMD_SOURCE_ROOT}",
65+
f"--source-root-patterns=/{GenerateSchemas.source_root}",
6466
*(extra_args or ()),
6567
],
6668
env_inherit={"PATH", "PYENV_ROOT", "HOME"},
6769
)
68-
field_sets = [GenerateSchemasFieldSet.create(tgt) for tgt in targets]
70+
field_sets = tuple(GenerateSchemasFieldSet.create(tgt) for tgt in targets)
6971
input_sources = rule_runner.request(
7072
SourceFiles,
7173
[
7274
SourceFilesRequest(field_set.sources for field_set in field_sets),
7375
],
7476
)
77+
78+
# run generate_schemas_partitioner rule
79+
partitions = rule_runner.request(
80+
Partitions,
81+
[GenerateSchemasViaFmtTargetsRequest.PartitionRequest(field_sets)],
82+
)
83+
assert len(partitions) == 1
84+
85+
# run generate_schemas_via_fmt rule
7586
fmt_result = rule_runner.request(
7687
FmtResult,
7788
[
78-
GenerateSchemasViaFmtTargetsRequest(
79-
field_sets, snapshot=input_sources.snapshot
89+
GenerateSchemasViaFmtTargetsRequest.Batch(
90+
tool_name="",
91+
elements=partitions[0].elements, # ie: files
92+
partition_metadata=partitions[0].metadata,
93+
snapshot=input_sources.snapshot,
8094
),
8195
],
8296
)
@@ -114,14 +128,14 @@ def write_files(
114128
f"{schemas_dir}/{schema_file}": before,
115129
f"{schemas_dir}/BUILD": "schemas(name='t')",
116130
# add in the target that's hard-coded in the generate_schemas_via_fmt rue
117-
f"{CMD_DIR}/{CMD}.py": GENERATE_SCHEMAS_PY.format(
131+
f"{GenerateSchemas.directory}/{GenerateSchemas.cmd}.py": GENERATE_SCHEMAS_PY.format(
118132
schemas_dir=schemas_dir, schema_text=after
119133
),
120-
f"{CMD_DIR}/BUILD": "python_sources()",
134+
f"{GenerateSchemas.directory}/BUILD": "python_sources()",
121135
}
122136

123-
module = CMD_DIR
124-
while module != CMD_SOURCE_ROOT:
137+
module = GenerateSchemas.directory
138+
while module != GenerateSchemas.source_root:
125139
files[f"{module}/__init__.py"] = ""
126140
module = os.path.dirname(module)
127141

pants-plugins/schemas/subsystem.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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 GenerateSchemas(Subsystem):
22+
name = "StackStorm Content Schemas Generator"
23+
options_scope = "st2-generate-schemas"
24+
skip = SkipOption("fmt", "lint")
25+
help = "The StackStorm content schemas generator."
26+
27+
source_root = "st2common"
28+
directory = "st2common/st2common/cmd"
29+
module = "st2common.cmd"
30+
cmd = "generate_schemas"
31+
32+
def address(self) -> Address:
33+
return Address(
34+
self.directory,
35+
target_name="cmd",
36+
relative_file_path=f"{self.cmd}.py",
37+
)
38+
39+
def pex_request(self) -> PexFromTargetsRequest:
40+
return PexFromTargetsRequest(
41+
[self.address()],
42+
output_filename=f"{self.cmd}.pex",
43+
internal_only=True,
44+
main=EntryPoint.parse(f"{self.module}.{self.cmd}:main"),
45+
)

0 commit comments

Comments
 (0)