Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
- Upcoming changes...

## [1.44.0] - 2026-01-06
### Added
- Added scan engine tuning parameters for snippet matching:
- `--min-snippet-hits` - Minimum snippet hits required (0 defers to server config)
- `--min-snippet-lines` - Minimum snippet lines required (0 defers to server config)
- `--snippet-range-tolerance` (`-srt`) - Snippet range tolerance (0 defers to server config)
- `--ranking` - Enable/disable result ranking (unset/true/false)
- `--ranking-threshold` - Ranking threshold value (-1 to 99, -1 defers to server config)
- `--honour-file-exts` - Honour file extensions during matching (unset/true/false)
- Added `file_snippet` section to scanoss.json settings schema for configuring tuning parameters
- Added `ScanSettingsBuilder` class for merging CLI and settings file configurations with priority: CLI > file_snippet > root settings

## [1.43.1] - 2026-01-05
### Changed
- Restored `--no-wfp-output` flag for backwards compatibility (deprecated, no effect)
Expand Down Expand Up @@ -772,4 +784,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[1.41.1]: https://github.com/scanoss/scanoss.py/compare/v1.41.0...v1.41.1
[1.42.0]: https://github.com/scanoss/scanoss.py/compare/v1.41.1...v1.42.0
[1.43.0]: https://github.com/scanoss/scanoss.py/compare/v1.42.0...v1.43.0
[1.43.1]: https://github.com/scanoss/scanoss.py/compare/v1.43.0...v1.43.1
[1.43.1]: https://github.com/scanoss/scanoss.py/compare/v1.43.0...v1.43.1
[1.44.0]: https://github.com/scanoss/scanoss.py/compare/v1.43.1...v1.44.0
54 changes: 54 additions & 0 deletions CLIENT_HELP.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,60 @@ Multiple Headers: You can specify any number of custom headers by repeating the
scanoss-py scan src -hdr "x-api-key:12345" -hdr "Authorization: Bearer <access_token>"
```

### Scan with Snippet Tuning Options
The following flags allow you to fine-tune snippet matching behavior during scanning:

#### Set minimum snippet hits
Require at least 5 snippet hits for a match. A value of 0 defers to server configuration:
```bash
scanoss-py scan -o scan-results.json --min-snippet-hits 5 src
```

#### Set minimum snippet lines
Require at least 3 snippet lines for a match. A value of 0 defers to server configuration:
```bash
scanoss-py scan -o scan-results.json --min-snippet-lines 3 src
```

#### Set snippet range tolerance
Set the snippet range tolerance. A value of 0 defers to server configuration:
```bash
scanoss-py scan -o scan-results.json --snippet-range-tolerance 5 src
```
Short form:
```bash
scanoss-py scan -o scan-results.json -srt 5 src
```

#### Enable or disable ranking
Enable ranking to prioritize results:
```bash
scanoss-py scan -o scan-results.json --ranking true src
```
Disable ranking:
```bash
scanoss-py scan -o scan-results.json --ranking false src
```

#### Set ranking threshold
Set the ranking threshold to 50 (valid range: 0-99). A value of -1 defers to server configuration:
```bash
scanoss-py scan -o scan-results.json --ranking-threshold=50 src
```
Note: Use `=` syntax for negative values: `--ranking-threshold=-1`

#### Honour file extensions
Control whether file extensions are considered during matching:
```bash
scanoss-py scan -o scan-results.json --honour-file-exts true src
```

#### Combine multiple tuning options
You can combine multiple tuning options in a single scan:
```bash
scanoss-py scan -o scan-results.json --min-snippet-hits 5 --min-snippet-lines 3 --ranking true --ranking-threshold=75 src
```

### Converting RAW results into other formats
The following command provides the capability to convert the RAW scan results from a SCANOSS scan into multiple different formats, including CycloneDX, SPDX Lite, CSV and GitLab Code Quality Report.
For the full set of formats, please run:
Expand Down
124 changes: 124 additions & 0 deletions docs/source/_static/scanoss-settings-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,130 @@
}
}
}
},
"proxy": {
"type": "object",
"description": "Proxy configuration for API requests",
"properties": {
"host": {
"type": "string",
"description": "Proxy host URL"
}
}
},
"http_config": {
"type": "object",
"description": "HTTP configuration for API requests",
"properties": {
"base_uri": {
"type": "string",
"description": "Base URI for API requests"
},
"ignore_cert_errors": {
"type": "boolean",
"description": "Whether to ignore certificate errors"
}
}
},
"file_snippet": {
"type": "object",
"description": "File snippet scanning configuration",
"properties": {
"proxy": {
"type": "object",
"description": "Proxy configuration for file snippet requests",
"properties": {
"host": {
"type": "string",
"description": "Proxy host URL"
}
}
},
"http_config": {
"type": "object",
"description": "HTTP configuration for file snippet requests",
"properties": {
"base_uri": {
"type": "string",
"description": "Base URI for file snippet API requests"
},
"ignore_cert_errors": {
"type": "boolean",
"description": "Whether to ignore certificate errors"
}
}
},
"ranking_enabled": {
"type": ["boolean", "null"],
"description": "Enable/disable ranking",
"default": null
},
"ranking_threshold": {
"type": ["integer", "null"],
"description": "Ranking threshold value. A value of -1 defers to server configuration",
"minimum": -1,
"maximum": 99,
"default": 0
},
"min_snippet_hits": {
"type": "integer",
"description": "Minimum snippet hits required",
"minimum": 0,
"default": 0
},
"min_snippet_lines": {
"type": "integer",
"description": "Minimum snippet lines required",
"minimum": 0,
"default": 0
},
"snippet_range_tolerance": {
"type": "integer",
"description": "Snippet range tolerance",
"minimum": 0,
"default": 0
},
"honour_file_exts": {
"type": ["boolean", "null"],
"description": "Ignores file extensions. When not set, defers to server configuration.",
"default": true
},
"dependency_analysis": {
"type": "boolean",
"description": "Enable dependency analysis"
},
"skip_headers": {
"type": "boolean",
"description": "Skip license headers, comments and imports at the beginning of files",
"default": false
},
"skip_headers_limit": {
"type": "integer",
"description": "Maximum number of lines to skip when filtering headers",
"default": 0
}
}
},
"hpfm": {
"type": "object",
"description": "HPFM (High Precision Folder Matching) configuration",
"properties": {
"ranking_enabled": {
"type": "boolean",
"description": "Enable ranking for HPFM"
},
"ranking_threshold": {
"type": ["integer", "null"],
"description": "Ranking threshold value. A value of -1 defers to server configuration",
"minimum": -1,
"maximum": 99,
"default": 0
}
}
},
"container": {
"type": "object",
"description": "Container scanning configuration"
}
}
},
Expand Down
3 changes: 3 additions & 0 deletions scanoss.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
"include": [
{
"purl": "pkg:github/scanoss/scanoss.py"
},
{
"purl": "pkg:github/scanoss/scanoss-winnowing.py"
}
],
"remove": []
Expand Down
2 changes: 1 addition & 1 deletion src/scanoss/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@
THE SOFTWARE.
"""

__version__ = '1.43.1'
__version__ = '1.44.0'
66 changes: 56 additions & 10 deletions src/scanoss/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,46 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
'--no-wfp-output', action='store_true',
help='DEPRECATED: Scans no longer generate scanner_output.wfp. Use "fingerprint -o" to create WFP files.'
)
# Snippet tuning options
p_scan.add_argument(
'--min-snippet-hits',
type=int,
default=None,
help='Minimum snippet hits required. A value of 0 defers to server configuration (optional)',
)
p_scan.add_argument(
'--min-snippet-lines',
type=int,
default=None,
help='Minimum snippet lines required. A value of 0 defers to server configuration (optional)',
)
p_scan.add_argument(
'-srt',
'--snippet-range-tolerance',
type=int,
default=None,
help='Snippet range tolerance. A value of 0 defers to server configuration (optional)',
)
p_scan.add_argument(
'--ranking',
type=str,
choices=['unset' ,'true', 'false'],
default='unset',
help='Enable or disable ranking (optional - default: server configuration)',
)
p_scan.add_argument(
'--ranking-threshold',
type=int,
default=None,
help='Ranking threshold value. Valid range: -1 to 99. A value of -1 defers to server configuration (optional)',
)
p_scan.add_argument(
'--honour-file-exts',
type=str,
choices=['unset','true', 'false'],
default='unset',
help='Honour file extensions during scanning. When not set, defers to server configuration (optional)',
)

# Sub-command: fingerprint
p_wfp = subparsers.add_parser(
Expand Down Expand Up @@ -1377,11 +1417,11 @@ def wfp(parser, args):
initialise_empty_file(args.output)

# Load scan settings
scan_settings = None
scanoss_settings = None
if not args.skip_settings_file:
scan_settings = ScanossSettings(debug=args.debug, trace=args.trace, quiet=args.quiet)
scanoss_settings = ScanossSettings(debug=args.debug, trace=args.trace, quiet=args.quiet)
try:
scan_settings.load_json_file(args.settings, args.scan_dir)
scanoss_settings.load_json_file(args.settings, args.scan_dir)
except ScanossSettingsError as e:
print_stderr(f'Error: {e}')
sys.exit(1)
Expand All @@ -1403,7 +1443,7 @@ def wfp(parser, args):
skip_md5_ids=args.skip_md5,
strip_hpsm_ids=args.strip_hpsm,
strip_snippet_ids=args.strip_snippet,
scan_settings=scan_settings,
scanoss_settings=scanoss_settings,
skip_headers=args.skip_headers,
skip_headers_limit=args.skip_headers_limit,
)
Expand Down Expand Up @@ -1487,20 +1527,20 @@ def scan(parser, args): # noqa: PLR0912, PLR0915
print_stderr('ERROR: Cannot specify both --settings and --skip-file-settings options.')
sys.exit(1)
# Figure out which settings (if any) to load before processing
scan_settings = None
scanoss_settings = None
if not args.skip_settings_file:
scan_settings = ScanossSettings(debug=args.debug, trace=args.trace, quiet=args.quiet)
scanoss_settings = ScanossSettings(debug=args.debug, trace=args.trace, quiet=args.quiet)
try:
if args.identify:
scan_settings.load_json_file(args.identify, args.scan_dir).set_file_type('legacy').set_scan_type(
scanoss_settings.load_json_file(args.identify, args.scan_dir).set_file_type('legacy').set_scan_type(
'identify'
)
elif args.ignore:
scan_settings.load_json_file(args.ignore, args.scan_dir).set_file_type('legacy').set_scan_type(
scanoss_settings.load_json_file(args.ignore, args.scan_dir).set_file_type('legacy').set_scan_type(
'blacklist'
)
else:
scan_settings.load_json_file(args.settings, args.scan_dir).set_file_type('new')
scanoss_settings.load_json_file(args.settings, args.scan_dir).set_file_type('new')

except ScanossSettingsError as e:
print_stderr(f'Error: {e}')
Expand Down Expand Up @@ -1596,9 +1636,15 @@ def scan(parser, args): # noqa: PLR0912, PLR0915
skip_md5_ids=args.skip_md5,
strip_hpsm_ids=args.strip_hpsm,
strip_snippet_ids=args.strip_snippet,
scan_settings=scan_settings,
scanoss_settings=scanoss_settings,
req_headers=process_req_headers(args.header),
use_grpc=args.grpc,
min_snippet_hits=args.min_snippet_hits,
min_snippet_lines=args.min_snippet_lines,
snippet_range_tolerance=args.snippet_range_tolerance,
ranking=args.ranking,
ranking_threshold=args.ranking_threshold,
honour_file_exts=args.honour_file_exts,
skip_headers=args.skip_headers,
skip_headers_limit=args.skip_headers_limit,
)
Expand Down
Loading