Skip to content

Commit b5196ff

Browse files
Remove duplicate models and update docstrings
Signed-off-by: Ayan Sinha Mahapatra <ayansmahapatra@gmail.com>
1 parent d2b37a1 commit b5196ff

5 files changed

Lines changed: 90 additions & 84 deletions

File tree

src/packagedcode/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from packagedcode import freebsd
2121
from packagedcode import golang
2222
from packagedcode import haxe
23+
from packagedcode import jar_manifest
2324
from packagedcode import maven
2425
from packagedcode import models
2526
from packagedcode import msi
@@ -43,10 +44,11 @@
4344
debian.DebianPackage,
4445

4546
models.JavaJar,
47+
jar_manifest.JavaManifest,
4648
models.JavaEar,
4749
models.JavaWar,
4850
maven.MavenPomPackage,
49-
models.IvyJar,
51+
jar_manifest.IvyJar,
5052
models.JBossSar,
5153
models.Axis2Mar,
5254

src/packagedcode/jar_manifest.py

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from commoncode.fileutils import as_posixpath
1515
from packagedcode.utils import normalize_vcs_url
1616
from packagedcode.maven import parse_scm_connection
17-
from packagedcode.models import Package
17+
from packagedcode import models
1818

1919

2020
"""
@@ -28,19 +28,13 @@
2828

2929

3030
@attr.s()
31-
class JavaArchive(Package):
32-
file_patterns = ('META-INF/MANIFEST.MF',)
33-
extensions = ('.jar', '.war', '.ear')
31+
class JavaArchive(models.Package):
32+
3433
filetypes = ('java archive ', 'zip archive',)
3534
mimetypes = ('application/java-archive', 'application/zip',)
3635
default_type = 'jar'
3736
default_primary_language = 'Java'
3837

39-
@classmethod
40-
def recognize(cls, location):
41-
if is_manifest(location):
42-
yield parse_manifest(location)
43-
4438
@classmethod
4539
def get_package_root(cls, manifest_resource, codebase):
4640
if manifest_resource.path.lower().endswith('meta-inf/manifest.mf'):
@@ -50,11 +44,29 @@ def get_package_root(cls, manifest_resource, codebase):
5044
return manifest_resource
5145

5246

53-
def is_manifest(location):
54-
"""
55-
Return Trye if the file at location is a Manifest.
56-
"""
57-
return as_posixpath(location).lower().endswith('meta-inf/manifest.mf')
47+
@attr.s()
48+
class IvyJar(JavaArchive, models.PackageManifest):
49+
file_patterns = ('ivy.xml',)
50+
default_type = 'ivy'
51+
default_primary_language = 'Java'
52+
53+
54+
@attr.s()
55+
class JavaManifest(JavaArchive, models.PackageManifest):
56+
file_patterns = ('META-INF/MANIFEST.MF',)
57+
extensions = ('.jar', '.war', '.ear')
58+
59+
@classmethod
60+
def get_manifest_data(cls, location):
61+
if cls.is_manifest(location):
62+
yield parse_manifest(location)
63+
64+
@classmethod
65+
def is_manifest(cls, location):
66+
"""
67+
Return Trye if the file at location is a Manifest.
68+
"""
69+
return as_posixpath(location).lower().endswith('meta-inf/manifest.mf')
5870

5971

6072
def parse_manifest(location):

src/packagedcode/models.py

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
- in manifest file proper (such as a Maven POM, NPM package.json and many others)
5151
- in binaries (such as an Elf or LKM, Windows PE or RPM header).
5252
- in code (JavaDoc tags or Python __copyright__ magic)
53+
5354
There are collectively named "manifests" in ScanCode.
5455
5556
We handle package information at two levels:
@@ -60,25 +61,26 @@
6061
6162
The second requires the first to be computed.
6263
63-
Class Hierarchy:
64-
65-
Base Classes: (Classes to be inherited)
64+
These are case classes to extend:
6665
6766
- Package:
68-
Base Data class with package data
67+
Base class with shared package attributes and methods.
6968
- PackageManifest:
70-
Mixin class with manifest specific data and methods
69+
Mixin class that represents a specific package manifest file.
7170
- PackageInstance:
72-
Mixin class with package instance specific data and methods
73-
74-
- Package Ecosystem: (Classes which would have object instances)
75-
76-
- EcosystemPackage(Package):
77-
A class with ecosystem specific data (and data specific methods)
78-
- EcosystemPackageManifest(EcosystemPackage, PackageManifest):
79-
A class that overides and implements package manifest methods for that ecosystem
80-
- EcosystemPackageInstance(EcosystemPackage, PackageInstance):
81-
A class that overrides and implements package instance methods for that ecosystem
71+
Mixin class that represents a package that's constructed from one or more
72+
package manifests. It also tracks package files.
73+
74+
Here is an example of the classes that would need to exist to support a new fictitious
75+
package type or ecosystem `dummy`.
76+
77+
- DummyPackage(Package):
78+
This class provides type wide defaults and basic implementation for type specific methods.
79+
- DummyManifest(DummyPackage, PackageManifest):
80+
This class provides methods to recognize and parse a package manifest file format.
81+
- DummyPackageInstance(DummyPackage, PackageInstance):
82+
This class provides methods to create package instances for one or more manifests and to
83+
collect package file paths.
8284
"""
8385

8486
SCANCODE_DEBUG_PACKAGE_API = os.environ.get('SCANCODE_DEBUG_PACKAGE_API', False)
@@ -685,7 +687,8 @@ class PackageManifest:
685687
"""
686688
A mixin for package manifest that can be recognized.
687689
688-
Subclasses must extend a Package subclass for a given ecosystem.
690+
When creating a new package manifest, a class should be created that extends
691+
both PackageManifest and Package.
689692
"""
690693

691694
# class-level attributes used to recognize a package
@@ -828,25 +831,6 @@ class JBossSar(Package, PackageManifest):
828831
default_primary_language = 'Java'
829832

830833

831-
@attr.s()
832-
class IvyJar(JavaJar):
833-
file_patterns = ('ivy.xml',)
834-
default_type = 'ivy'
835-
default_primary_language = 'Java'
836-
837-
838-
# FIXME: move to bower.py
839-
@attr.s()
840-
class BowerPackage(Package, PackageManifest):
841-
file_patterns = ('bower.json',)
842-
default_type = 'bower'
843-
default_primary_language = 'JavaScript'
844-
845-
@classmethod
846-
def get_package_root(cls, manifest_resource, codebase):
847-
return manifest_resource.parent(codebase)
848-
849-
850834
@attr.s()
851835
class MeteorPackage(Package, PackageManifest):
852836
file_patterns = ('package.js',)

src/packagedcode/recognize.py

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -54,45 +54,47 @@ def recognize_package_manifests(location):
5454

5555
recognized_package_manifests = []
5656
for package_manifest_type in PACKAGE_MANIFEST_TYPES:
57-
if package_manifest_type.is_manifest(location):
58-
try:
59-
for recognized in package_manifest_type.recognize(location):
60-
if TRACE:
61-
logger_debug(
62-
'recognize_package_manifests: metafile matching: recognized:',
63-
recognized,
64-
)
65-
if recognized and not recognized.license_expression:
66-
# compute and set a normalized license expression
67-
try:
68-
recognized.license_expression = recognized.compute_normalized_license()
69-
except Exception:
70-
if SCANCODE_DEBUG_PACKAGE_API:
71-
raise
72-
recognized.license_expression = 'unknown'
73-
74-
if TRACE:
75-
logger_debug(
76-
'recognize_package_manifests: recognized.license_expression:',
77-
recognized.license_expression
78-
)
79-
recognized_package_manifests.append(recognized)
80-
return recognized_package_manifests
81-
82-
except NotImplementedError:
83-
# build a plain package if recognize is not yet implemented
84-
recognized = package_manifest_type()
57+
if not package_manifest_type.is_manifest(location):
58+
continue
59+
60+
try:
61+
for recognized in package_manifest_type.recognize(location):
8562
if TRACE:
8663
logger_debug(
87-
'recognize_package_manifests: NotImplementedError: recognized', recognized
64+
'recognize_package_manifests: metafile matching: recognized:',
65+
recognized,
8866
)
67+
if recognized and not recognized.license_expression:
68+
# compute and set a normalized license expression
69+
try:
70+
recognized.license_expression = recognized.compute_normalized_license()
71+
except Exception:
72+
if SCANCODE_DEBUG_PACKAGE_API:
73+
raise
74+
recognized.license_expression = 'unknown'
8975

76+
if TRACE:
77+
logger_debug(
78+
'recognize_package_manifests: recognized.license_expression:',
79+
recognized.license_expression
80+
)
9081
recognized_package_manifests.append(recognized)
82+
return recognized_package_manifests
9183

92-
if SCANCODE_DEBUG_PACKAGE_API:
93-
raise
84+
except NotImplementedError:
85+
# build a plain package if recognize is not yet implemented
86+
recognized = package_manifest_type()
87+
if TRACE:
88+
logger_debug(
89+
'recognize_package_manifests: NotImplementedError: recognized', recognized
90+
)
9491

95-
return recognized_package_manifests
92+
recognized_package_manifests.append(recognized)
93+
94+
if SCANCODE_DEBUG_PACKAGE_API:
95+
raise
96+
97+
return recognized_package_manifests
9698

9799
if TRACE: logger_debug(
98100
'recognize_package_manifests: no match for type:', package_manifest_type

tests/packagedcode/data/plugin/help.txt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,8 @@ Package: iso
202202

203203
--------------------------------------------
204204
Package: ivy
205-
class: packagedcode.models:IvyJar
205+
class: packagedcode.jar_manifest:IvyJar
206206
file_patterns: ivy.xml
207-
extensions: .jar
208207
filetypes: java archive , zip archive
209208

210209
--------------------------------------------
@@ -214,6 +213,13 @@ Package: jar
214213
extensions: .jar
215214
filetypes: java archive , zip archive
216215

216+
--------------------------------------------
217+
Package: jar
218+
class: packagedcode.jar_manifest:JavaManifest
219+
file_patterns: META-INF/MANIFEST.MF
220+
extensions: .jar, .war, .ear
221+
filetypes: java archive , zip archive
222+
217223
--------------------------------------------
218224
Package: jboss
219225
class: packagedcode.models:JBossSar

0 commit comments

Comments
 (0)