15
15
from pants .backend .native .targets .external_native_library import ExternalNativeLibrary
16
16
from pants .base .build_environment import get_pants_cachedir
17
17
from pants .base .exceptions import TaskError
18
+ from pants .goal .products import UnionProducts
18
19
from pants .invalidation .cache_manager import VersionedTargetSet
19
20
from pants .task .task import Task
20
21
from pants .util .contextutil import environment_as
21
- from pants .util .dirutil import safe_mkdir
22
22
from pants .util .memo import memoized_property
23
23
from pants .util .objects import Exactly , datatype
24
24
from pants .util .process_handler import subprocess
@@ -94,6 +94,10 @@ def register_options(cls, register):
94
94
register ('--conan-remotes' , type = list , default = ['https://conan.bintray.com' ], advanced = True ,
95
95
fingerprint = True , help = 'The conan remote to download conan packages from.' )
96
96
97
+ @classmethod
98
+ def implementation_version (cls ):
99
+ return super (NativeExternalLibraryFetch , cls ).implementation_version () + [('NativeExternalLibraryFetch' , 0 )]
100
+
97
101
@classmethod
98
102
def subsystem_dependencies (cls ):
99
103
return super (NativeExternalLibraryFetch , cls ).subsystem_dependencies () + (Conan .scoped (cls ),)
@@ -103,7 +107,10 @@ def product_types(cls):
103
107
return [NativeExternalLibraryFiles ]
104
108
105
109
@property
106
- def cache_target_dirs (self ):
110
+ def create_target_dirs (self ):
111
+ # We create per-target directories in order to act as isolated collections of fetched files.
112
+ # But do not attempt to automatically cache then (cache_target_dirs), because the entire resolve
113
+ # must be have its own merged cachekey/VT.
107
114
return True
108
115
109
116
@memoized_property
@@ -128,40 +135,35 @@ def execute(self):
128
135
with self .invalidated (native_lib_tgts ,
129
136
invalidate_dependents = True ) as invalidation_check :
130
137
resolve_vts = VersionedTargetSet .from_versioned_targets (invalidation_check .all_vts )
131
- vts_results_dir = self ._prepare_vts_results_dir (resolve_vts )
132
138
if invalidation_check .invalid_vts or not resolve_vts .valid :
133
139
for vt in invalidation_check .all_vts :
134
- self ._fetch_packages (vt , vts_results_dir )
140
+ self ._fetch_packages (vt )
135
141
136
- native_external_libs_product = self ._collect_external_libs (vts_results_dir )
142
+ native_external_libs_product = self ._collect_external_libs (invalidation_check . all_vts )
137
143
self .context .products .register_data (NativeExternalLibraryFiles ,
138
144
native_external_libs_product )
139
145
140
- def _prepare_vts_results_dir (self , vts ):
141
- """
142
- Given a `VersionedTargetSet`, prepare its results dir.
143
- """
144
- vt_set_results_dir = os .path .join (self .workdir , vts .cache_key .hash )
145
- safe_mkdir (vt_set_results_dir )
146
- return vt_set_results_dir
147
-
148
- def _collect_external_libs (self , results_dir ):
146
+ def _collect_external_libs (self , vts ):
149
147
"""
150
148
Sets the relevant properties of the task product (`NativeExternalLibraryFiles`) object.
151
149
"""
152
- lib_dir = os .path .join (results_dir , 'lib' )
153
- include_dir = os .path .join (results_dir , 'include' )
154
-
155
- lib_names = []
156
- if os .path .isdir (lib_dir ):
157
- for filename in os .listdir (lib_dir ):
158
- lib_name = self ._parse_lib_name_from_library_filename (filename )
159
- if lib_name :
160
- lib_names .append (lib_name )
161
-
162
- return NativeExternalLibraryFiles (include_dir = include_dir ,
163
- lib_dir = lib_dir ,
164
- lib_names = tuple (lib_names ))
150
+ product = UnionProducts ()
151
+ for vt in vts :
152
+ lib_dir = os .path .join (vt .results_dir , 'lib' )
153
+ include_dir = os .path .join (vt .results_dir , 'include' )
154
+
155
+ lib_names = []
156
+ if os .path .isdir (lib_dir ):
157
+ for filename in os .listdir (lib_dir ):
158
+ lib_name = self ._parse_lib_name_from_library_filename (filename )
159
+ if lib_name :
160
+ lib_names .append (lib_name )
161
+
162
+ nelf = NativeExternalLibraryFiles (include_dir = include_dir ,
163
+ lib_dir = lib_dir ,
164
+ lib_names = tuple (lib_names ))
165
+ product .add_for_target (vt .target , [nelf ])
166
+ return product
165
167
166
168
def _get_conan_data_dir_path_for_package (self , pkg_dir_path , pkg_sha ):
167
169
return os .path .join (self .workdir ,
@@ -237,14 +239,13 @@ def _copy_package_contents_from_conan_dir(self, results_dir, conan_requirement,
237
239
if os .path .exists (src_include ):
238
240
copy_tree (src_include , dest_include )
239
241
240
- def _fetch_packages (self , vt , vts_results_dir ):
242
+ def _fetch_packages (self , vt ):
241
243
"""
242
244
Invoke the conan pex to fetch conan packages specified by a
243
245
`ExternalLibLibrary` target.
244
246
245
- :param vt: a versioned target containing conan package specifications.
246
- :param vts_results_dir: the results directory of the VersionedTargetSet
247
- for the purpose of aggregating package contents.
247
+ :param vt: a versioned target containing conan package specifications, and with a results_dir
248
+ that we can clone outputs into.
248
249
"""
249
250
250
251
# NB: CONAN_USER_HOME specifies the directory to use for the .conan data directory.
@@ -274,4 +275,4 @@ def _fetch_packages(self, vt, vts_results_dir):
274
275
)
275
276
276
277
pkg_sha = conan_requirement .parse_conan_stdout_for_pkg_sha (stdout )
277
- self ._copy_package_contents_from_conan_dir (vts_results_dir , conan_requirement , pkg_sha )
278
+ self ._copy_package_contents_from_conan_dir (vt . results_dir , conan_requirement , pkg_sha )
0 commit comments