Skip to content

Commit 6f1cc0b

Browse files
committed
feat(d2d): enable mapping multiple binaries against single source #1949
Signed-off-by: rejzzzz <hoquerejwanulrh@gmail.com>
1 parent 8712d48 commit 6f1cc0b

2 files changed

Lines changed: 330 additions & 215 deletions

File tree

scanpipe/pipelines/deploy_to_develop.py

Lines changed: 79 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -120,22 +120,49 @@ def get_inputs(self):
120120

121121
def extract_inputs_to_codebase_directory(self):
122122
"""Extract input files to the project's codebase/ directory."""
123-
inputs_with_codebase_path_destination = [
124-
(self.from_files, self.project.codebase_path / d2d.FROM),
125-
(self.to_files, self.project.codebase_path / d2d.TO),
126-
]
127-
128-
for input_files, codebase_path in inputs_with_codebase_path_destination:
129-
for input_file_path in input_files:
130-
if input.is_archive(input_file_path):
131-
self.extract_archive(input_file_path, codebase_path)
132-
else:
133-
input.copy_input(input_file_path, codebase_path)
123+
# Extract from files to FROM
124+
from_path = self.project.codebase_path / d2d.FROM
125+
for input_file_path in self.from_files:
126+
if input.is_archive(input_file_path):
127+
self.extract_archive(input_file_path, from_path)
128+
else:
129+
input.copy_input(input_file_path, from_path)
130+
131+
# Extract each to file to a separate subdirectory under TO
132+
self.to_paths = []
133+
for i, input_file_path in enumerate(self.to_files):
134+
if len(self.to_files) > 1:
135+
to_subpath = self.project.codebase_path / d2d.TO / str(i)
136+
else:
137+
to_subpath = self.project.codebase_path / d2d.TO
138+
139+
self.to_paths.append(
140+
str(to_subpath.relative_to(self.project.codebase_path)) + "/"
141+
)
142+
143+
if input.is_archive(input_file_path):
144+
self.extract_archive(input_file_path, to_subpath)
145+
else:
146+
input.copy_input(input_file_path, to_subpath)
134147

135148
# Reload the project env post-extraction as the scancode-config.yml file
136149
# may be located in one of the extracted archives.
137150
self.env = self.project.get_env()
138151

152+
def run_d2d_step(self, func, *args, **kwargs):
153+
"""Run a d2d mapping step for each to_path."""
154+
to_paths = getattr(self, "to_paths", [None])
155+
for to_path in to_paths:
156+
if to_path:
157+
kwargs["to_queryset"] = self.project.codebaseresources.filter(
158+
path__startswith=to_path
159+
)
160+
kwargs["to_path"] = to_path
161+
if len(to_paths) > 1:
162+
self.log(f"Running {func.__name__} for {to_path}")
163+
164+
func(project=self.project, logger=self.log, *args, **kwargs)
165+
139166
def collect_and_create_codebase_resources(self):
140167
"""Collect and create codebase resources."""
141168
pipes.collect_and_create_codebase_resources(self.project)
@@ -159,23 +186,22 @@ def map_ruby(self):
159186

160187
def map_about_files(self):
161188
"""Map ``from/`` .ABOUT files to their related ``to/`` resources."""
162-
d2d.map_about_files(project=self.project, logger=self.log)
189+
self.run_d2d_step(d2d.map_about_files)
163190

164191
def map_checksum(self):
165192
"""Map using SHA1 checksum."""
166-
d2d.map_checksum(project=self.project, checksum_field="sha1", logger=self.log)
193+
self.run_d2d_step(d2d.map_checksum, checksum_field="sha1")
167194

168195
def match_archives_to_purldb(self):
169196
"""Match selected package archives by extension to PurlDB."""
170197
if not purldb.is_available():
171198
self.log("PurlDB is not available. Skipping.")
172199
return
173200

174-
d2d.match_purldb_resources(
175-
project=self.project,
201+
self.run_d2d_step(
202+
d2d.match_purldb_resources,
176203
extensions=self.ecosystem_config.matchable_package_extensions,
177204
matcher_func=d2d.match_purldb_package,
178-
logger=self.log,
179205
)
180206

181207
@optional_step("Java")
@@ -188,16 +214,12 @@ def find_java_packages(self):
188214
@optional_step("Java")
189215
def map_java_to_class(self):
190216
"""Map a .class compiled file to its .java source."""
191-
d2d.map_jvm_to_class(
192-
project=self.project, jvm_lang=jvm.JavaLanguage, logger=self.log
193-
)
217+
self.run_d2d_step(d2d.map_jvm_to_class, jvm_lang=jvm.JavaLanguage)
194218

195219
@optional_step("Java")
196220
def map_jar_to_java_source(self):
197221
"""Map .jar files to their related source directory."""
198-
d2d.map_jar_to_jvm_source(
199-
project=self.project, jvm_lang=jvm.JavaLanguage, logger=self.log
200-
)
222+
self.run_d2d_step(d2d.map_jar_to_jvm_source, jvm_lang=jvm.JavaLanguage)
201223

202224
@optional_step("Scala")
203225
def find_scala_packages(self):
@@ -209,16 +231,12 @@ def find_scala_packages(self):
209231
@optional_step("Scala")
210232
def map_scala_to_class(self):
211233
"""Map a .class compiled file to its .java source."""
212-
d2d.map_jvm_to_class(
213-
project=self.project, jvm_lang=jvm.ScalaLanguage, logger=self.log
214-
)
234+
self.run_d2d_step(d2d.map_jvm_to_class, jvm_lang=jvm.ScalaLanguage)
215235

216236
@optional_step("Scala")
217237
def map_jar_to_scala_source(self):
218238
"""Map .jar files to their related source directory."""
219-
d2d.map_jar_to_jvm_source(
220-
project=self.project, jvm_lang=jvm.ScalaLanguage, logger=self.log
221-
)
239+
self.run_d2d_step(d2d.map_jar_to_jvm_source, jvm_lang=jvm.ScalaLanguage)
222240

223241
@optional_step("Kotlin")
224242
def find_kotlin_packages(self):
@@ -230,16 +248,12 @@ def find_kotlin_packages(self):
230248
@optional_step("Kotlin")
231249
def map_kotlin_to_class(self):
232250
"""Map a .class compiled file to its .java source."""
233-
d2d.map_jvm_to_class(
234-
project=self.project, jvm_lang=jvm.KotlinLanguage, logger=self.log
235-
)
251+
self.run_d2d_step(d2d.map_jvm_to_class, jvm_lang=jvm.KotlinLanguage)
236252

237253
@optional_step("Kotlin")
238254
def map_jar_to_kotlin_source(self):
239255
"""Map .jar files to their related source directory."""
240-
d2d.map_jar_to_jvm_source(
241-
project=self.project, jvm_lang=jvm.KotlinLanguage, logger=self.log
242-
)
256+
self.run_d2d_step(d2d.map_jar_to_jvm_source, jvm_lang=jvm.KotlinLanguage)
243257

244258
@optional_step("Grammar")
245259
def find_grammar_packages(self):
@@ -251,16 +265,12 @@ def find_grammar_packages(self):
251265
@optional_step("Grammar")
252266
def map_grammar_to_class(self):
253267
"""Map a .class compiled file to its .g/.g4 source."""
254-
d2d.map_jvm_to_class(
255-
project=self.project, jvm_lang=jvm.GrammarLanguage, logger=self.log
256-
)
268+
self.run_d2d_step(d2d.map_jvm_to_class, jvm_lang=jvm.GrammarLanguage)
257269

258270
@optional_step("Grammar")
259271
def map_jar_to_grammar_source(self):
260272
"""Map .jar files to their related source directory."""
261-
d2d.map_jar_to_jvm_source(
262-
project=self.project, jvm_lang=jvm.GrammarLanguage, logger=self.log
263-
)
273+
self.run_d2d_step(d2d.map_jar_to_jvm_source, jvm_lang=jvm.GrammarLanguage)
264274

265275
@optional_step("Xtend")
266276
def find_xtend_packages(self):
@@ -272,125 +282,115 @@ def find_xtend_packages(self):
272282
@optional_step("Xtend")
273283
def map_xtend_to_class(self):
274284
"""Map a .class compiled file to its xtend source."""
275-
d2d.map_jvm_to_class(
276-
project=self.project, jvm_lang=jvm.XtendLanguage, logger=self.log
277-
)
285+
self.run_d2d_step(d2d.map_jvm_to_class, jvm_lang=jvm.XtendLanguage)
278286

279287
@optional_step("JavaScript")
280288
def map_javascript(self):
281289
"""
282290
Map a packed or minified JavaScript, TypeScript, CSS and SCSS
283291
to its source.
284292
"""
285-
d2d.map_javascript(project=self.project, logger=self.log)
293+
self.run_d2d_step(d2d.map_javascript)
286294

287295
@optional_step("JavaScript")
288296
def map_javascript_symbols(self):
289297
"""Map deployed JavaScript, TypeScript to its sources using symbols."""
290-
d2d.map_javascript_symbols(project=self.project, logger=self.log)
298+
self.run_d2d_step(d2d.map_javascript_symbols)
291299

292300
@optional_step("JavaScript")
293301
def map_javascript_strings(self):
294302
"""Map deployed JavaScript, TypeScript to its sources using string literals."""
295-
d2d.map_javascript_strings(project=self.project, logger=self.log)
303+
self.run_d2d_step(d2d.map_javascript_strings)
296304

297305
def get_symbols_from_binaries(self):
298306
"""Extract symbols from Elf, Mach0 and windows binaries for mapping."""
299-
d2d.extract_binary_symbols(
300-
project=self.project,
301-
options=self.selected_groups,
302-
logger=self.log,
303-
)
307+
self.run_d2d_step(d2d.extract_binary_symbols, options=self.selected_groups)
304308

305309
@optional_step("Elf")
306310
def map_elf(self):
307311
"""Map ELF binaries to their sources using dwarf paths and symbols."""
308-
d2d.map_elfs_with_dwarf_paths(project=self.project, logger=self.log)
309-
d2d.map_elfs_binaries_with_symbols(project=self.project, logger=self.log)
312+
self.run_d2d_step(d2d.map_elfs_with_dwarf_paths)
313+
self.run_d2d_step(d2d.map_elfs_binaries_with_symbols)
310314

311315
@optional_step("MacOS")
312316
def map_macho(self):
313317
"""Map mach0 binaries to their sources using symbols."""
314-
d2d.map_macho_binaries_with_symbols(project=self.project, logger=self.log)
318+
self.run_d2d_step(d2d.map_macho_binaries_with_symbols)
315319

316320
@optional_step("Windows")
317321
def map_winpe(self):
318322
"""Map winpe binaries to their sources using symbols."""
319-
d2d.map_winpe_binaries_with_symbols(project=self.project, logger=self.log)
323+
self.run_d2d_step(d2d.map_winpe_binaries_with_symbols)
320324

321325
@optional_step("Go")
322326
def map_go(self):
323327
"""Map Go binaries to their sources using paths and symbols."""
324-
d2d.map_go_paths(project=self.project, logger=self.log)
325-
d2d.map_go_binaries_with_symbols(project=self.project, logger=self.log)
328+
self.run_d2d_step(d2d.map_go_paths)
329+
self.run_d2d_step(d2d.map_go_binaries_with_symbols)
326330

327331
@optional_step("Rust")
328332
def map_rust(self):
329333
"""Map Rust binaries to their sources using symbols."""
330-
d2d.map_rust_binaries_with_symbols(project=self.project, logger=self.log)
334+
self.run_d2d_step(d2d.map_rust_binaries_with_symbols)
331335

332336
@optional_step("Python")
333337
def map_python(self):
334338
"""
335339
Map binaries from Python packages to their sources using dwarf paths and
336340
symbols.
337341
"""
338-
d2d.map_python_pyx_to_binaries(project=self.project, logger=self.log)
339-
d2d.map_python_protobuf_files(project=self.project, logger=self.log)
342+
self.run_d2d_step(d2d.map_python_pyx_to_binaries)
343+
self.run_d2d_step(d2d.map_python_protobuf_files)
340344

341345
def match_directories_to_purldb(self):
342346
"""Match selected directories in PurlDB."""
343347
if not purldb.is_available():
344348
self.log("PurlDB is not available. Skipping.")
345349
return
346350

347-
d2d.match_purldb_directories(
348-
project=self.project,
349-
logger=self.log,
350-
)
351+
self.run_d2d_step(d2d.match_purldb_directories)
351352

352353
def match_resources_to_purldb(self):
353354
"""Match selected files by extension in PurlDB."""
354355
if not purldb.is_available():
355356
self.log("PurlDB is not available. Skipping.")
356357
return
357358

358-
d2d.match_purldb_resources(
359-
project=self.project,
359+
self.run_d2d_step(
360+
d2d.match_purldb_resources,
360361
extensions=self.ecosystem_config.matchable_resource_extensions,
361362
matcher_func=d2d.match_purldb_resource,
362-
logger=self.log,
363363
)
364364

365365
@optional_step("JavaScript")
366366
def map_javascript_post_purldb_match(self):
367367
"""Map minified javascript file based on existing PurlDB match."""
368-
d2d.map_javascript_post_purldb_match(project=self.project, logger=self.log)
368+
self.run_d2d_step(d2d.map_javascript_post_purldb_match)
369369

370370
@optional_step("JavaScript")
371371
def map_javascript_path(self):
372372
"""Map javascript file based on path."""
373-
d2d.map_javascript_path(project=self.project, logger=self.log)
373+
self.run_d2d_step(d2d.map_javascript_path)
374374

375375
@optional_step("JavaScript")
376376
def map_javascript_colocation(self):
377377
"""Map JavaScript files based on neighborhood file mapping."""
378-
d2d.map_javascript_colocation(project=self.project, logger=self.log)
378+
self.run_d2d_step(d2d.map_javascript_colocation)
379379

380380
@optional_step("JavaScript")
381381
def map_thirdparty_npm_packages(self):
382382
"""Map thirdparty package using package.json metadata."""
383-
d2d.map_thirdparty_npm_packages(project=self.project, logger=self.log)
383+
self.run_d2d_step(d2d.map_thirdparty_npm_packages)
384384

385385
def map_path(self):
386386
"""Map using path similarities."""
387-
d2d.map_path(project=self.project, logger=self.log)
387+
self.run_d2d_step(d2d.map_path)
388388

389389
def flag_mapped_resources_archives_and_ignored_directories(self):
390390
"""Flag all codebase resources that were mapped during the pipeline."""
391391
flag.flag_mapped_resources(self.project)
392392
flag.flag_ignored_directories(self.project)
393-
d2d.flag_processed_archives(self.project)
393+
self.run_d2d_step(d2d.flag_processed_archives)
394394

395395
def perform_house_keeping_tasks(self):
396396
"""
@@ -404,17 +404,15 @@ def perform_house_keeping_tasks(self):
404404
On devel side
405405
- Update status for not deployed files.
406406
"""
407-
d2d.match_resources_with_no_java_source(project=self.project, logger=self.log)
408-
d2d.handle_dangling_deployed_legal_files(project=self.project, logger=self.log)
409-
d2d.ignore_unmapped_resources_from_config(
410-
project=self.project,
407+
self.run_d2d_step(d2d.match_resources_with_no_java_source)
408+
self.run_d2d_step(d2d.handle_dangling_deployed_legal_files)
409+
self.run_d2d_step(
410+
d2d.ignore_unmapped_resources_from_config,
411411
patterns_to_ignore=self.ecosystem_config.deployed_resource_path_exclusions,
412-
logger=self.log,
413412
)
414-
d2d.match_unmapped_resources(
415-
project=self.project,
413+
self.run_d2d_step(
414+
d2d.match_unmapped_resources,
416415
matched_extensions=self.ecosystem_config.matchable_resource_extensions,
417-
logger=self.log,
418416
)
419417
d2d.flag_undeployed_resources(project=self.project)
420418

0 commit comments

Comments
 (0)