Skip to content
Merged
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Upcoming changes...

## [1.19.6] - 2025-01-30
### Added
- Omit settings file if it does not exist instead of throwing an error.
- Look settings file inside the folder being scanned instead of the cwd.

## [1.19.5] - 2025-01-14
### Added
- Add Docker image with SCANOSS user
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.19.5"
__version__ = "1.19.6"
6 changes: 3 additions & 3 deletions src/scanoss/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -575,11 +575,11 @@ def scan(parser, args):
scan_settings = ScanossSettings(debug=args.debug, trace=args.trace, quiet=args.quiet)
try:
if args.identify:
scan_settings.load_json_file(args.identify).set_file_type('legacy').set_scan_type('identify')
scan_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).set_file_type('legacy').set_scan_type('blacklist')
scan_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).set_file_type('new').set_scan_type('identify')
scan_settings.load_json_file(args.settings, args.scan_dir).set_file_type('new').set_scan_type('identify')
except ScanossSettingsError as e:
print_stderr(f'Error: {e}')
exit(1)
Expand Down
12 changes: 6 additions & 6 deletions src/scanoss/cyclonedx.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,12 @@ def produce_from_json(self, data: json, output_file: str = None) -> bool:
'name': 'scanoss-py',
'version': __version__,
}
]
},
'component': {
'type': 'application',
'name': 'NOASSERTION',
'version': 'NOASSERTION'
],
'component': {
'type': 'application',
'name': 'NOASSERTION',
'version': 'NOASSERTION'
}
},
'components': [],
'vulnerabilities': []
Expand Down
18 changes: 13 additions & 5 deletions src/scanoss/scanoss_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
from jsonschema import validate

from .scanossbase import ScanossBase
from .utils.file import validate_json_file
from .utils.file import JSON_ERROR_FILE_NOT_FOUND, JSON_ERROR_FILE_EMPTY, validate_json_file

DEFAULT_SCANOSS_JSON_FILE = 'scanoss.json'
DEFAULT_SCANOSS_JSON_FILE = Path('scanoss.json')


class BomEntry(TypedDict, total=False):
Expand Down Expand Up @@ -96,16 +96,20 @@ def __init__(
if filepath:
self.load_json_file(filepath)

def load_json_file(self, filepath: 'str | None' = None) -> 'ScanossSettings':
def load_json_file(self, filepath: 'str | None' = None, scan_root: 'str | None' = None) -> 'ScanossSettings':
"""
Load the scan settings file. If no filepath is provided, scanoss.json will be used as default.

Args:
filepath (str): Path to the SCANOSS settings file
"""

if not filepath:
filepath = DEFAULT_SCANOSS_JSON_FILE
json_file = Path(filepath).resolve()

filepath = Path(scan_root) / filepath if scan_root else Path(filepath)

json_file = filepath.resolve()

if filepath == DEFAULT_SCANOSS_JSON_FILE and not json_file.exists():
self.print_debug(f'Default settings file "{filepath}" not found. Skipping...')
Expand All @@ -114,7 +118,11 @@ def load_json_file(self, filepath: 'str | None' = None) -> 'ScanossSettings':

result = validate_json_file(json_file)
if not result.is_valid:
raise ScanossSettingsError(f'Problem with settings file. {result.error}')
if result.error_code == JSON_ERROR_FILE_NOT_FOUND or result.error_code == JSON_ERROR_FILE_EMPTY:
self.print_msg(f'WARNING: The supplied settings file "{filepath}" was not found or is empty. Skipping...')
return self
else:
raise ScanossSettingsError(f'Problem with settings file. {result.error}')
try:
validate(result.data, self.schema)
except Exception as e:
Expand Down
35 changes: 31 additions & 4 deletions src/scanoss/utils/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,24 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""

import json
import os
import sys
from dataclasses import dataclass
from typing import Optional

JSON_ERROR_PARSE = 1
JSON_ERROR_FILE_NOT_FOUND = 2
JSON_ERROR_FILE_EMPTY = 3
JSON_ERROR_FILE_SIZE = 4


@dataclass
class JsonValidation:
is_valid: bool
data: Optional[dict] = None
error: Optional[str] = None
error_code: Optional[int] = None


def validate_json_file(json_file_path: str) -> JsonValidation:
Expand All @@ -46,12 +52,33 @@ def validate_json_file(json_file_path: str) -> JsonValidation:
Tuple[bool, str]: A tuple containing a boolean indicating if the file is valid and a message
"""
if not json_file_path:
return JsonValidation(is_valid=False, error='No JSON file specified')
return JsonValidation(is_valid=False, error="No JSON file specified")
if not os.path.isfile(json_file_path):
return JsonValidation(is_valid=False, error=f'File not found: {json_file_path}')
return JsonValidation(
is_valid=False,
error=f"File not found: {json_file_path}",
error_code=JSON_ERROR_FILE_NOT_FOUND,
)
try:
if os.stat(json_file_path).st_size == 0:
return JsonValidation(
is_valid=False,
error=f"File is empty: {json_file_path}",
error_code=JSON_ERROR_FILE_EMPTY,
)
except OSError as e:
return JsonValidation(
is_valid=False,
error=f"Problem checking file size: {json_file_path}: {e}",
error_code=JSON_ERROR_FILE_SIZE,
)
try:
with open(json_file_path) as f:
data = json.load(f)
return JsonValidation(is_valid=True, data=data)
except json.JSONDecodeError as e:
return JsonValidation(is_valid=False, error=f'Problem parsing JSON file: "{json_file_path}": {e}')
return JsonValidation(
is_valid=False,
error=f'Problem parsing JSON file: "{json_file_path}": {e}',
error_code=JSON_ERROR_PARSE,
)