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
1 change: 1 addition & 0 deletions src/packagedcode/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@

phpcomposer.PhpComposerJsonHandler,
phpcomposer.PhpComposerLockHandler,
phpcomposer.PhpSymfonyLockHandler,

pubspec.DartPubspecYamlHandler,
pubspec.DartPubspecLockHandler,
Expand Down
55 changes: 55 additions & 0 deletions src/packagedcode/phpcomposer.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,61 @@ def parse(cls, location, package_only=False):
for package in packages + packages_dev:
yield package

class PhpSymfonyLockHandler(models.DatafileHandler):
datasource_id = 'php_symfony_lock'
path_patterns = ('*symfony.lock',)
default_package_type = 'composer'
default_primary_language = 'PHP'
is_lockfile = True
description = 'Symfony Flex lockfile'
documentation_url = 'https://symfony.com/doc/current/setup/flex.html'

@classmethod
def parse(cls, location, package_only=False):
with io.open(location, encoding='utf-8') as loc:
lock_data = json.load(loc)

if not isinstance(lock_data, dict):
return

dependencies = []

for package_name, package_details in lock_data.items():
if not isinstance(package_details, dict):
continue

namespace, separator, name = package_name.rpartition('/')

if not separator or not namespace or not name:
continue

version = package_details.get('version')
if not isinstance(version, str):
version = None
else:
version = version.strip()

if not version:
version = None

purl = models.PackageURL(
type=cls.default_package_type,
namespace=namespace,
name=name,
version=version,
).to_string()

dependency = models.DependentPackage(
purl=purl,
extracted_requirement=version,
is_pinned=bool(version),
)

dependencies.append(dependency)

yield cls.create_default_package_data(
dependencies=dependencies,
)

def licensing_mapper(licenses, package, is_private=False):
"""
Expand Down
11 changes: 11 additions & 0 deletions tests/packagedcode/data/phpcomposer/symfony.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"composer/pcre": {
"version": "1.0.0"
},
"symfony/console": {
"version": "5.4"
},
"symfony/flex": {
"version": "1.20"
}
}
7 changes: 7 additions & 0 deletions tests/packagedcode/data/plugin/plugins_list_linux.txt
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,13 @@ Package type: composer
description: PHP composer lockfile
path_patterns: '*composer.lock'
--------------------------------------------
Package type: composer
datasource_id: php_symfony_lock
documentation URL: https://symfony.com/doc/current/setup/flex.html
primary language: PHP
description: Symfony Flex lockfile
path_patterns: '*symfony.lock'
--------------------------------------------
Package type: conan
datasource_id: conan_conandata_yml
documentation URL: https://docs.conan.io/2/tutorial/creating_packages/handle_sources_in_packages.html#using-the-conandata-yml-file
Expand Down
24 changes: 24 additions & 0 deletions tests/packagedcode/test_phpcomposer.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,27 @@ def test_parse_composer_lock(self):
expected_loc = self.get_test_loc('phpcomposer/composer.lock-expected.json')
packages = phpcomposer.PhpComposerLockHandler.parse(test_file)
self.check_packages_data(packages, expected_loc, regen=REGEN_TEST_FIXTURES)

def test_is_manifest_php_symfony_lock(self):
test_file = self.get_test_loc('phpcomposer/symfony.lock')
assert phpcomposer.PhpSymfonyLockHandler.is_datafile(test_file)

def test_parse_symfony_lock(self):
test_file = self.get_test_loc('phpcomposer/symfony.lock')

package_data = list(
phpcomposer.PhpSymfonyLockHandler.parse(test_file)
)

assert len(package_data) == 1

dependencies = package_data[0].dependencies
actual_purls = {dependency.purl for dependency in dependencies}

expected_purls = {
'pkg:composer/composer/pcre@1.0.0',
'pkg:composer/symfony/console@5.4',
'pkg:composer/symfony/flex@1.20',
}

assert actual_purls == expected_purls