diff --git a/src/commoncode/resource.py b/src/commoncode/resource.py index 1da2dc95..9920a3f2 100644 --- a/src/commoncode/resource.py +++ b/src/commoncode/resource.py @@ -1995,6 +1995,12 @@ def _populate(self, scan_data): if not name: name = file_name(path) + extension = fdata.get('extension', None) or None + if extension: + if not name.endswith(extension): + # Ensure the filename also contains the extension + name = f'{name}{extension}' + is_file = fdata.get('type', 'file') == 'file' parent = self._get_parent_directory(path_segments=path_segments) diff --git a/tests/data/resource/virtual_codebase/no_extensions_in_names.json b/tests/data/resource/virtual_codebase/no_extensions_in_names.json new file mode 100644 index 00000000..88a6b42a --- /dev/null +++ b/tests/data/resource/virtual_codebase/no_extensions_in_names.json @@ -0,0 +1,149 @@ +{ +"headers": [ +{ + "tool_name": "scanpipe", + "tool_version": "30.2.0", + "notice": "Generated with ScanCode.io and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied.\nNo content created from ScanCode.io should be considered or used as legal advice.\nConsult an Attorney for any legal advice.\nScanCode.io is a free software code scanning tool from nexB Inc. and others\nlicensed under the Apache License version 2.0.\nScanCode is a trademark of nexB Inc.\nVisit https://github.com/nexB/scancode.io for support and download.\n", + "uuid": "ccdd92d2-2312-4fe4-8fd3-9b3999f9c98c", + "created_date": "2022-08-24T23:39:49.181Z", + "input_sources": [ + { + "filename": "test.tar.gz", + "source": "uploaded" + } + ], + "runs": [ + { + "pipeline_name": "scan_codebase", + "status": "success", + "description": "A pipeline to scan a codebase resource with ScanCode-toolkit.\n\nInput files are copied to the project's codebase/ directory and are extracted\nin place before running the scan.\nAlternatively, the code can be manually copied to the project codebase/\ndirectory.", + "uuid": "06e65389-1285-4d85-9967-0b084c8aad38", + "created_date": "2022-08-24T23:39:49.183032Z", + "scancodeio_version": "30.2.0", + "task_id": "06e65389-1285-4d85-9967-0b084c8aad38", + "task_start_date": "2022-08-24T23:39:49.191698Z", + "task_end_date": "2022-08-24T23:39:52.362668Z", + "task_exitcode": 0, + "task_output": "", + "log": "2022-08-24 23:39:49.19 Pipeline [scan_codebase] starting\n2022-08-24 23:39:49.19 Step [copy_inputs_to_codebase_directory] starting\n2022-08-24 23:39:49.19 Step [copy_inputs_to_codebase_directory] completed in 0.00 seconds\n2022-08-24 23:39:49.19 Step [extract_archives] starting\n2022-08-24 23:39:49.20 Step [extract_archives] completed in 0.01 seconds\n2022-08-24 23:39:49.20 Step [collect_and_create_codebase_resources] starting\n2022-08-24 23:39:49.22 Step [collect_and_create_codebase_resources] completed in 0.01 seconds\n2022-08-24 23:39:49.22 Step [tag_empty_files] starting\n2022-08-24 23:39:49.22 Step [tag_empty_files] completed in 0.00 seconds\n2022-08-24 23:39:49.23 Step [scan_for_application_packages] starting\n2022-08-24 23:39:49.29 Step [scan_for_application_packages] completed in 0.06 seconds\n2022-08-24 23:39:49.29 Step [scan_for_files] starting\n2022-08-24 23:39:52.35 Step [scan_for_files] completed in 3.06 seconds\n2022-08-24 23:39:52.35 Pipeline completed\n", + "execution_time": 3 + } + ], + "extra_data": {} +}], +"packages": [ +], +"files": [ +{ + "for_packages": [], + "compliance_alert": "", + "path": "test.tar.gz", + "size": 146, + "sha1": "9868617c1a544fb6254b770ed60fad2f2aeee9d2", + "md5": "359a8965b0a78f58f52e424867f9a058", + "extra_data": {}, + "copyrights": [], + "holders": [], + "authors": [], + "licenses": [], + "license_expressions": [], + "emails": [], + "urls": [], + "status": "scanned", + "type": "file", + "name": "test", + "extension": ".tar.gz", + "programming_language": "", + "mime_type": "application/gzip", + "file_type": "gzip compressed data, last modified: Wed Aug 24 23:39:23 2022, from Unix, original size modulo 2^32 10240", + "is_binary": true, + "is_text": false, + "is_archive": true, + "is_key_file": false, + "is_media": false +}, +{ + "for_packages": [], + "compliance_alert": "", + "path": "test.tar.gz-extract", + "size": 4096, + "sha1": "", + "md5": "", + "extra_data": {}, + "copyrights": [], + "holders": [], + "authors": [], + "licenses": [], + "license_expressions": [], + "emails": [], + "urls": [], + "status": "scanned", + "type": "directory", + "name": "test", + "extension": ".tar.gz-extract", + "programming_language": "", + "mime_type": "", + "file_type": "", + "is_binary": false, + "is_text": false, + "is_archive": false, + "is_key_file": false, + "is_media": false +}, +{ + "for_packages": [], + "compliance_alert": "", + "path": "test.tar.gz-extract/test", + "size": 4096, + "sha1": "", + "md5": "", + "extra_data": {}, + "copyrights": [], + "holders": [], + "authors": [], + "licenses": [], + "license_expressions": [], + "emails": [], + "urls": [], + "status": "scanned", + "type": "directory", + "name": "test", + "extension": "", + "programming_language": "", + "mime_type": "", + "file_type": "", + "is_binary": false, + "is_text": false, + "is_archive": false, + "is_key_file": false, + "is_media": false +}, +{ + "for_packages": [], + "compliance_alert": "", + "path": "test.tar.gz-extract/test/foo", + "size": null, + "sha1": "", + "md5": "", + "extra_data": {}, + "copyrights": [], + "holders": [], + "authors": [], + "licenses": [], + "license_expressions": [], + "emails": [], + "urls": [], + "status": "ignored-empty-file", + "type": "file", + "name": "foo", + "extension": "", + "programming_language": "", + "mime_type": "inode/x-empty", + "file_type": "empty", + "is_binary": false, + "is_text": true, + "is_archive": false, + "is_key_file": false, + "is_media": false +}] +} \ No newline at end of file diff --git a/tests/test_resource.py b/tests/test_resource.py index 907436d7..a6e17cb0 100644 --- a/tests/test_resource.py +++ b/tests/test_resource.py @@ -1527,3 +1527,18 @@ def test_virtualcode_Resource_can_walk(self): ] assert results == expected + + def test_virtualcode_creation_resource_name_no_extension(self): + test_file = self.get_test_loc('resource/virtual_codebase/no_extensions_in_names.json') + codebase = VirtualCodebase(location=test_file) + results = [r.path for r in codebase.walk(topdown=True)] + + expected = [ + 'virtual_root', + 'virtual_root/test.tar.gz', + 'virtual_root/test.tar.gz-extract', + 'virtual_root/test.tar.gz-extract/test', + 'virtual_root/test.tar.gz-extract/test/foo', + ] + + assert results == expected