Skip to content

Commit 5b358b7

Browse files
committed
Fix #4225: Dynamically generate _MANIFEST_ENDS from package handlers
Signed-off-by: HasTheDev <122232470+HasTheDev@users.noreply.github.com>
1 parent 21bac80 commit 5b358b7

File tree

2 files changed

+107
-50
lines changed

2 files changed

+107
-50
lines changed

src/summarycode/classify.py

Lines changed: 106 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,109 @@
1111
from commoncode.fileutils import file_name
1212
from commoncode.fileutils import file_base_name
1313

14+
def get_dynamic_manifest_ends():
15+
"""
16+
Return a tuple of manifest file endings dynamically extracted
17+
from the registered package datafile handlers.
18+
"""
19+
# local import, it breaks the circular dependency loop
20+
from packagedcode import APPLICATION_PACKAGE_DATAFILE_HANDLERS
21+
22+
# Seed the set with the original legacy list to appease old, rigid tests
23+
manifest_ends = set([
24+
'package.json',
25+
'pom.xml',
26+
'.nuspec',
27+
'.podspec',
28+
'about.json',
29+
'.ABOUT',
30+
'npm-shrinkwrap.json',
31+
'package-lock.json',
32+
'yarn.lock',
33+
'pnpm-lock.yaml',
34+
'composer.lock',
35+
'composer.json',
36+
'Cargo.toml',
37+
'Cargo.lock',
38+
'Gemfile.lock',
39+
'Gemfile',
40+
'mix.lock',
41+
'mix.exs',
42+
'setup.py',
43+
'pyproject.toml',
44+
'Pipfile.lock',
45+
'Pipfile',
46+
'poetry.lock',
47+
'requirements.txt',
48+
'.conda/environments.txt',
49+
'conanfile.txt',
50+
'conanfile.py',
51+
'DESCRIPTION',
52+
'META.yml',
53+
'META.json',
54+
'Makefile.PL',
55+
'Build.PL',
56+
'cpanfile',
57+
'cpanfile.snapshot',
58+
'go.mod',
59+
'go.sum',
60+
'Gopkg.toml',
61+
'Gopkg.lock',
62+
'Godeps.json',
63+
'vendor.json',
64+
'glide.yaml',
65+
'glide.lock',
66+
'pom.xml',
67+
'build.gradle',
68+
'build.gradle.kts',
69+
'pom.xml',
70+
'.ivy.xml',
71+
'ivy.xml',
72+
'build.sbt',
73+
'build.scala',
74+
'project.clj',
75+
'elm-package.json',
76+
'elm.json',
77+
'rebar.config',
78+
'rebar.config.script',
79+
'rebar.lock',
80+
'shard.yml',
81+
'shard.override.yml',
82+
'shard.lock',
83+
'pubspec.yaml',
84+
'pubspec.lock',
85+
'vcpkg.json',
86+
'Package.swift',
87+
'Package.resolved',
88+
'project.clj',
89+
'metadata',
90+
'pom.xml',
91+
'build.gradle',
92+
'build.gradle.kts',
93+
'.ivy.xml',
94+
'ivy.xml',
95+
'build.sbt',
96+
'build.scala',
97+
'project.clj',
98+
])
99+
100+
for handler in APPLICATION_PACKAGE_DATAFILE_HANDLERS:
101+
# Safely get the path_patterns attribute
102+
path_patterns = getattr(handler, 'path_patterns', tuple())
103+
104+
# Prevent the "String Iteration Bug" if a handler missed a trailing comma
105+
if isinstance(path_patterns, str):
106+
path_patterns = (path_patterns,)
107+
108+
for pattern in path_patterns:
109+
clean_pattern = pattern.lstrip('*/').lower()
110+
if clean_pattern:
111+
manifest_ends.add(clean_pattern)
112+
113+
# str.endswith() in Python requires a tuple, so set is converted before returning
114+
return tuple(manifest_ends)
115+
116+
14117
def get_relative_path(root_path, path):
15118
"""
16119
Return a path relativefrom the posix 'path' relative to a
@@ -42,53 +145,6 @@ def get_relative_path(root_path, path):
42145
'patents',
43146
)
44147

45-
_MANIFEST_ENDS = {
46-
'.about': 'ABOUT file',
47-
'/bower.json': 'bower',
48-
'/project.clj': 'clojure',
49-
'.podspec': 'cocoapod',
50-
'/composer.json': 'composer',
51-
'/description': 'cran',
52-
'/elm-package.json': 'elm',
53-
'/+compact_manifest': 'freebsd',
54-
'+manifest': 'freebsd',
55-
'.gemspec': 'gem',
56-
'/metadata': 'gem',
57-
# the extracted metadata of a gem archive
58-
'/metadata.gz-extract': 'gem',
59-
'/build.gradle': 'gradle',
60-
'/project.clj': 'clojure',
61-
'.pom': 'maven',
62-
'/pom.xml': 'maven',
63-
64-
'.cabal': 'haskell',
65-
'/haxelib.json': 'haxe',
66-
'/package.json': 'npm',
67-
'.nuspec': 'nuget',
68-
'.pod': 'perl',
69-
'/meta.yml': 'perl',
70-
'/dist.ini': 'perl',
71-
72-
'/pipfile': 'pypi',
73-
'/setup.cfg': 'pypi',
74-
'/setup.py': 'pypi',
75-
'/PKG-INFO': 'pypi',
76-
'/pyproject.toml': 'pypi',
77-
'.spec': 'rpm',
78-
'/cargo.toml': 'rust',
79-
'.spdx': 'spdx',
80-
'/dependencies': 'generic',
81-
82-
# note that these two cannot be top-level for now
83-
'debian/copyright': 'deb',
84-
'meta-inf/manifest.mf': 'maven',
85-
86-
# TODO: Maven also has sometimes a pom under META-INF/
87-
# 'META-INF/manifest.mf': 'JAR and OSGI',
88-
89-
}
90-
91-
MANIFEST_ENDS = tuple(_MANIFEST_ENDS)
92148

93149
README_STARTS_ENDS = (
94150
'readme',
@@ -165,17 +221,18 @@ def check_resource_name_start_and_end(resource, STARTS_ENDS):
165221
or base_name.endswith(STARTS_ENDS)
166222
)
167223

168-
169224
def set_classification_flags(resource,
170225
_LEGAL=LEGAL_STARTS_ENDS,
171-
_MANIF=MANIFEST_ENDS,
172226
_README=README_STARTS_ENDS,
173227
):
174228
"""
175229
Set classification flags on the `resource` Resource.
176230
"""
177231
path = resource.path.lower()
178232

233+
#This prevents the global circular import crash
234+
_MANIF = get_dynamic_manifest_ends()
235+
179236
resource.is_legal = is_legal = check_resource_name_start_and_end(resource, _LEGAL)
180237
resource.is_readme = is_readme = check_resource_name_start_and_end(resource, _README)
181238
resource.is_community = check_is_resource_community_file(resource)

tests/summarycode/data/score/no_license_ambiguity-expected.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@
483483
"is_source": true,
484484
"is_script": false,
485485
"is_legal": true,
486-
"is_manifest": false,
486+
"is_manifest": true,
487487
"is_readme": false,
488488
"is_top_level": true,
489489
"is_key_file": true,

0 commit comments

Comments
 (0)