forked from pantsbuild/pants
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rules.py
161 lines (139 loc) · 5.72 KB
/
rules.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).
from dataclasses import dataclass
from pants.backend.codegen.thrift.scrooge import additional_fields
from pants.backend.codegen.thrift.scrooge.additional_fields import ScroogeFinagleBoolField
from pants.backend.codegen.thrift.scrooge.subsystem import ScroogeSubsystem
from pants.backend.codegen.thrift.target_types import (
ThriftSourceField,
ThriftSourcesGeneratorTarget,
ThriftSourceTarget,
)
from pants.core.goals.generate_lockfiles import GenerateToolLockfileSentinel
from pants.core.util_rules.source_files import SourceFiles, SourceFilesRequest
from pants.engine.fs import CreateDigest, Digest, Directory, MergeDigests, RemovePrefix, Snapshot
from pants.engine.internals.selectors import Get, MultiGet
from pants.engine.process import ProcessResult
from pants.engine.rules import collect_rules, rule
from pants.engine.target import (
TransitiveTargets,
TransitiveTargetsRequest,
WrappedTarget,
WrappedTargetRequest,
)
from pants.engine.unions import UnionRule
from pants.jvm.goals import lockfile
from pants.jvm.jdk_rules import InternalJdk, JvmProcess
from pants.jvm.resolve.coursier_fetch import ToolClasspath, ToolClasspathRequest
from pants.jvm.resolve.jvm_tool import GenerateJvmLockfileFromTool, GenerateJvmToolLockfileSentinel
from pants.jvm.target_types import PrefixedJvmJdkField, PrefixedJvmResolveField
from pants.source.source_root import SourceRootsRequest, SourceRootsResult
from pants.util.logging import LogLevel
@dataclass(frozen=True)
class GenerateScroogeThriftSourcesRequest:
thrift_source_field: ThriftSourceField
lang_id: str
lang_name: str
@dataclass(frozen=True)
class GeneratedScroogeThriftSources:
snapshot: Snapshot
class ScroogeToolLockfileSentinel(GenerateJvmToolLockfileSentinel):
resolve_name = ScroogeSubsystem.options_scope
@rule
async def generate_scrooge_thrift_sources(
request: GenerateScroogeThriftSourcesRequest,
jdk: InternalJdk,
scrooge: ScroogeSubsystem,
) -> GeneratedScroogeThriftSources:
output_dir = "_generated_files"
toolcp_relpath = "__toolcp"
lockfile_request = await Get(GenerateJvmLockfileFromTool, ScroogeToolLockfileSentinel())
tool_classpath, transitive_targets, empty_output_dir_digest, wrapped_target = await MultiGet(
Get(ToolClasspath, ToolClasspathRequest(lockfile=lockfile_request)),
Get(TransitiveTargets, TransitiveTargetsRequest([request.thrift_source_field.address])),
Get(Digest, CreateDigest([Directory(output_dir)])),
Get(
WrappedTarget,
WrappedTargetRequest(
request.thrift_source_field.address, description_of_origin="<infallible>"
),
),
)
transitive_sources, target_sources = await MultiGet(
Get(
SourceFiles,
SourceFilesRequest(
tgt[ThriftSourceField]
for tgt in transitive_targets.closure
if tgt.has_field(ThriftSourceField)
),
),
Get(SourceFiles, SourceFilesRequest([request.thrift_source_field])),
)
sources_roots = await Get(
SourceRootsResult,
SourceRootsRequest,
SourceRootsRequest.for_files(transitive_sources.snapshot.files),
)
deduped_source_root_paths = sorted({sr.path for sr in sources_roots.path_to_root.values()})
input_digest = await Get(
Digest,
MergeDigests(
[
transitive_sources.snapshot.digest,
target_sources.snapshot.digest,
empty_output_dir_digest,
]
),
)
maybe_include_paths = []
for path in deduped_source_root_paths:
maybe_include_paths.extend(["-i", path])
maybe_finagle_option = []
if wrapped_target.target[ScroogeFinagleBoolField].value:
maybe_finagle_option = ["--finagle"]
extra_immutable_input_digests = {
toolcp_relpath: tool_classpath.digest,
}
result = await Get(
ProcessResult,
JvmProcess(
jdk=jdk,
classpath_entries=tool_classpath.classpath_entries(toolcp_relpath),
argv=[
"com.twitter.scrooge.Main",
*maybe_include_paths,
"--dest",
output_dir,
"--language",
request.lang_id,
*maybe_finagle_option,
*target_sources.snapshot.files,
],
input_digest=input_digest,
extra_jvm_options=scrooge.jvm_options,
extra_immutable_input_digests=extra_immutable_input_digests,
extra_nailgun_keys=extra_immutable_input_digests,
description=f"Generating {request.lang_name} sources from {request.thrift_source_field.address}.",
level=LogLevel.DEBUG,
output_directories=(output_dir,),
),
)
output_snapshot = await Get(Snapshot, RemovePrefix(result.output_digest, output_dir))
return GeneratedScroogeThriftSources(output_snapshot)
@rule
def generate_scrooge_lockfile_request(
_: ScroogeToolLockfileSentinel, scrooge: ScroogeSubsystem
) -> GenerateJvmLockfileFromTool:
return GenerateJvmLockfileFromTool.create(scrooge)
def rules():
return [
*collect_rules(),
*additional_fields.rules(),
*lockfile.rules(),
UnionRule(GenerateToolLockfileSentinel, ScroogeToolLockfileSentinel),
ThriftSourceTarget.register_plugin_field(PrefixedJvmJdkField),
ThriftSourcesGeneratorTarget.register_plugin_field(PrefixedJvmJdkField),
ThriftSourceTarget.register_plugin_field(PrefixedJvmResolveField),
ThriftSourcesGeneratorTarget.register_plugin_field(PrefixedJvmResolveField),
]