|
30 | 30 |
|
31 | 31 | import pypac
|
32 | 32 |
|
| 33 | +from scanoss.scanners.folder_hasher import ( |
| 34 | + FolderHasher, |
| 35 | + create_folder_hasher_config_from_args, |
| 36 | +) |
33 | 37 | from scanoss.scanossgrpc import (
|
34 | 38 | ScanossGrpc,
|
35 | 39 | ScanossGrpcError,
|
@@ -316,6 +320,7 @@ def setup_args() -> None: # noqa: PLR0915
|
316 | 320 | for p in [c_crypto, c_vulns, c_semgrep]:
|
317 | 321 | p.add_argument('--purl', '-p', type=str, nargs='*', help='Package URL - PURL to process.')
|
318 | 322 | p.add_argument('--input', '-i', type=str, help='Input file name')
|
| 323 | + |
319 | 324 | # Common Component sub-command options
|
320 | 325 | for p in [c_crypto, c_vulns, c_search, c_versions, c_semgrep, c_provenance]:
|
321 | 326 | p.add_argument('--output', '-o', type=str, help='Output result file name (optional - default stdout).')
|
@@ -474,35 +479,68 @@ def setup_args() -> None: # noqa: PLR0915
|
474 | 479 | )
|
475 | 480 | p_undeclared.set_defaults(func=inspect_undeclared)
|
476 | 481 |
|
| 482 | + # Sub-command: folder-scan |
477 | 483 | p_folder_scan = subparsers.add_parser(
|
478 | 484 | 'folder-scan',
|
| 485 | + aliases=['fs'], |
479 | 486 | description=f'Scan the given directory using folder hashing: {__version__}',
|
480 | 487 | help='Scan the given directory using folder hashing',
|
481 | 488 | )
|
482 | 489 | p_folder_scan.add_argument('scan_dir', metavar='FILE/DIR', type=str, nargs='?', help='The root directory to scan')
|
483 | 490 | p_folder_scan.add_argument('--output', '-o', type=str, help='Output result file name (optional - default stdout).')
|
| 491 | + p_folder_scan.add_argument( |
| 492 | + '--timeout', |
| 493 | + '-M', |
| 494 | + type=int, |
| 495 | + default=600, |
| 496 | + help='Timeout (in seconds) for API communication (optional - default 600)', |
| 497 | + ) |
484 | 498 | p_folder_scan.add_argument(
|
485 | 499 | '--format',
|
486 | 500 | '-f',
|
487 | 501 | type=str,
|
488 |
| - choices=['plain', 'json'], |
489 |
| - help='Result output format (optional - default: plain)', |
| 502 | + choices=['json'], |
| 503 | + default='json', |
| 504 | + help='Result output format (optional - default: json)', |
490 | 505 | )
|
491 | 506 | p_folder_scan.add_argument(
|
492 | 507 | '--best-match',
|
493 | 508 | '-bm',
|
494 | 509 | action='store_true',
|
| 510 | + default=False, |
495 | 511 | help='Enable best match mode (optional - default: False)',
|
496 | 512 | )
|
497 | 513 | p_folder_scan.add_argument(
|
498 | 514 | '--threshold',
|
499 | 515 | type=int,
|
| 516 | + choices=range(1, 101), |
| 517 | + metavar='1-100', |
| 518 | + default=100, |
500 | 519 | help='Threshold for result matching (optional - default: 100)',
|
501 | 520 | )
|
502 | 521 | p_folder_scan.set_defaults(func=folder_hashing_scan)
|
503 | 522 |
|
| 523 | + # Sub-command: folder-hash |
| 524 | + p_folder_hash = subparsers.add_parser( |
| 525 | + 'folder-hash', |
| 526 | + aliases=['fh'], |
| 527 | + description=f'Produce a folder hash for the given directory: {__version__}', |
| 528 | + help='Produce a folder hash for the given directory', |
| 529 | + ) |
| 530 | + p_folder_hash.add_argument('scan_dir', metavar='FILE/DIR', type=str, nargs='?', help='A file or folder to scan') |
| 531 | + p_folder_hash.add_argument('--output', '-o', type=str, help='Output result file name (optional - default stdout).') |
| 532 | + p_folder_hash.add_argument( |
| 533 | + '--format', |
| 534 | + '-f', |
| 535 | + type=str, |
| 536 | + choices=['json'], |
| 537 | + default='json', |
| 538 | + help='Result output format (optional - default: json)', |
| 539 | + ) |
| 540 | + p_folder_hash.set_defaults(func=folder_hash) |
| 541 | + |
504 | 542 | # Scanoss settings options
|
505 |
| - for p in [p_folder_scan, p_scan, p_wfp]: |
| 543 | + for p in [p_folder_scan, p_scan, p_wfp, p_folder_hash]: |
506 | 544 | p.add_argument(
|
507 | 545 | '--settings',
|
508 | 546 | '-st',
|
@@ -530,7 +568,7 @@ def setup_args() -> None: # noqa: PLR0915
|
530 | 568 | p.add_argument('-s', '--status', type=str, help='Save summary data into Markdown file')
|
531 | 569 |
|
532 | 570 | # Global Scan command options
|
533 |
| - for p in [p_scan, p_folder_scan]: |
| 571 | + for p in [p_scan]: |
534 | 572 | p.add_argument(
|
535 | 573 | '--apiurl', type=str, help='SCANOSS API URL (optional - default: https://api.osskb.org/scan/direct)'
|
536 | 574 | )
|
@@ -614,6 +652,7 @@ def setup_args() -> None: # noqa: PLR0915
|
614 | 652 | p_undeclared,
|
615 | 653 | p_copyleft,
|
616 | 654 | p_folder_scan,
|
| 655 | + p_folder_hash, |
617 | 656 | ]:
|
618 | 657 | p.add_argument('--debug', '-d', action='store_true', help='Enable debug messages')
|
619 | 658 | p.add_argument('--trace', '-t', action='store_true', help='Enable trace messages, including API posts')
|
@@ -1499,6 +1538,39 @@ def folder_hashing_scan(parser, args):
|
1499 | 1538 | sys.exit(1)
|
1500 | 1539 |
|
1501 | 1540 |
|
| 1541 | +def folder_hash(parser, args): |
| 1542 | + """Run the "folder-hash" sub-command |
| 1543 | +
|
| 1544 | + Args: |
| 1545 | + parser (ArgumentParser): command line parser object |
| 1546 | + args (Namespace): Parsed arguments |
| 1547 | + """ |
| 1548 | + try: |
| 1549 | + if not args.scan_dir: |
| 1550 | + print_stderr('ERROR: Please specify a directory to scan') |
| 1551 | + parser.parse_args([args.subparser, '-h']) |
| 1552 | + sys.exit(1) |
| 1553 | + |
| 1554 | + if not os.path.exists(args.scan_dir) or not os.path.isdir(args.scan_dir): |
| 1555 | + print_stderr(f'ERROR: The specified directory {args.scan_dir} does not exist') |
| 1556 | + sys.exit(1) |
| 1557 | + |
| 1558 | + folder_hasher_config = create_folder_hasher_config_from_args(args) |
| 1559 | + scanoss_settings = get_scanoss_settings_from_args(args) |
| 1560 | + |
| 1561 | + folder_hasher = FolderHasher( |
| 1562 | + scan_dir=args.scan_dir, |
| 1563 | + config=folder_hasher_config, |
| 1564 | + scanoss_settings=scanoss_settings, |
| 1565 | + ) |
| 1566 | + |
| 1567 | + folder_hasher.hash_directory(args.scan_dir) |
| 1568 | + folder_hasher.present(output_file=args.output, output_format=args.format) |
| 1569 | + except Exception as e: |
| 1570 | + print_stderr(f'ERROR: {e}') |
| 1571 | + sys.exit(1) |
| 1572 | + |
| 1573 | + |
1502 | 1574 | def get_scanoss_settings_from_args(args):
|
1503 | 1575 | scanoss_settings = None
|
1504 | 1576 | if not args.skip_settings_file:
|
|
0 commit comments