|
10 | 10 |
|
11 | 11 | import attr |
12 | 12 | import click |
| 13 | +import os |
| 14 | +import sys |
| 15 | +import uuid |
13 | 16 |
|
14 | 17 | from plugincode.scan import ScanPlugin |
15 | 18 | from plugincode.scan import scan_impl |
|
19 | 22 |
|
20 | 23 | from packagedcode import get_package_instance |
21 | 24 | from packagedcode import PACKAGE_MANIFEST_TYPES |
| 25 | +from packagedcode import PACKAGE_INSTANCES_BY_TYPE |
22 | 26 |
|
23 | 27 |
|
| 28 | +TRACE = os.environ.get('SCANCODE_DEBUG_PACKAGE', False) |
| 29 | + |
| 30 | +if TRACE: |
| 31 | + |
| 32 | + use_print = True |
| 33 | + |
| 34 | + if use_print: |
| 35 | + printer = print |
| 36 | + else: |
| 37 | + import logging |
| 38 | + |
| 39 | + logger = logging.getLogger(__name__) |
| 40 | + # logging.basicConfig(level=logging.DEBUG, stream=sys.stdout) |
| 41 | + logging.basicConfig(stream=sys.stdout) |
| 42 | + logger.setLevel(logging.DEBUG) |
| 43 | + printer = logger.debug |
| 44 | + |
| 45 | + def logger_debug(*args): |
| 46 | + return printer(' '.join(isinstance(a, str) and a or repr(a) |
| 47 | + for a in args)) |
| 48 | + |
24 | 49 | def print_packages(ctx, param, value): |
25 | 50 | if not value or ctx.resilient_parsing: |
26 | 51 | return |
@@ -51,8 +76,9 @@ class PackageScanner(ScanPlugin): |
51 | 76 |
|
52 | 77 | resource_attributes = {} |
53 | 78 | codebase_attributes = {} |
54 | | - resource_attributes['package_manifests'] = attr.ib(default=attr.Factory(list), repr=False) |
55 | 79 | codebase_attributes['packages'] = attr.ib(default=attr.Factory(list), repr=False) |
| 80 | + resource_attributes['package_manifests'] = attr.ib(default=attr.Factory(list), repr=False) |
| 81 | + #resource_attributes['for_packages'] = attr.ib(default=attr.Factory(list), repr=False) |
56 | 82 |
|
57 | 83 | sort_order = 6 |
58 | 84 |
|
@@ -102,13 +128,90 @@ def create_packages_from_manifests(codebase, **kwargs): |
102 | 128 | Create package instances from package manifests present in the codebase. |
103 | 129 | """ |
104 | 130 | package_manifests = [] |
| 131 | + package_instances_by_paths = {} |
| 132 | + package_instance_by_identifiers = {} |
105 | 133 |
|
106 | 134 | for resource in codebase.walk(topdown=False): |
107 | | - if resource.package_manifests: |
| 135 | + if not resource.package_manifests: |
| 136 | + continue |
| 137 | + |
| 138 | + # continue if resource.path already in `package_instances_by_paths` |
| 139 | + if resource.path in package_instances_by_paths: |
| 140 | + continue |
| 141 | + |
| 142 | + if TRACE: |
| 143 | + logger_debug( |
| 144 | + 'create_packages_from_manifests:', |
| 145 | + 'location:', resource.location, |
| 146 | + ) |
| 147 | + |
| 148 | + # Currently we assume there is only one PackageManifest |
| 149 | + # ToDo: Do this for multiple PackageManifests per resource |
| 150 | + manifest = resource.package_manifests[0] |
| 151 | + |
| 152 | + # Check if PackageInstance is implemented |
| 153 | + pk_instance_class = PACKAGE_INSTANCES_BY_TYPE.get(manifest["type"]) |
| 154 | + if not pk_instance_class: |
108 | 155 | package_manifests.extend(resource.package_manifests) |
| 156 | + continue |
109 | 157 |
|
| 158 | + # create a PackageInstance from the `default_type` |
| 159 | + pk_instance = pk_instance_class() |
| 160 | + pk_instance_uuid = uuid.uuid4() |
| 161 | + package_instance_by_identifiers[pk_instance_uuid] = pk_instance |
| 162 | + |
| 163 | + # use the get_other_manifests_for_instance to get other instances |
| 164 | + package_manifests_by_path = pk_instance.get_other_manifests_for_instance(resource, codebase) |
| 165 | + package_manifests_by_path[resource.path] = manifest |
| 166 | + |
| 167 | + if TRACE: |
| 168 | + logger_debug( |
| 169 | + 'create_packages_from_manifests:', |
| 170 | + 'package_manifests_by_path:', package_manifests_by_path, |
| 171 | + ) |
| 172 | + |
| 173 | + # add `path: Instance` into `package_instances_by_paths` for all manifests |
| 174 | + for path in package_manifests_by_path.keys(): |
| 175 | + print(f"Path: {path}") |
| 176 | + package_instances_by_paths[path] = pk_instance |
| 177 | + |
| 178 | + # populate PackageInstance with data from manifests |
| 179 | + pk_instance.populate_instance_from_manifests(package_manifests_by_path, uuid=pk_instance_uuid) |
| 180 | + |
| 181 | + # get files for this PackageInstance |
| 182 | + pk_instance.files = tuple(pk_instance.get_package_files(resource, codebase)) |
| 183 | + |
| 184 | + # add instance uuid to `for_packages` for all manifests (and files ?) |
| 185 | + update_files_with_package_instances(package_manifests_by_path, codebase, pk_instance) |
| 186 | + |
| 187 | + if TRACE: |
| 188 | + logger_debug( |
| 189 | + 'create_packages_from_manifests:', |
| 190 | + 'pk_instance:', pk_instance, |
| 191 | + ) |
| 192 | + |
| 193 | + # ToDo: replace this with PackageInstance objects once basic implementation is complete |
110 | 194 | codebase.attributes.packages.extend(package_manifests) |
111 | 195 |
|
| 196 | + if TRACE: |
| 197 | + logger_debug( |
| 198 | + 'create_packages_from_manifests:', |
| 199 | + 'package_instances_by_paths:', package_instances_by_paths, |
| 200 | + ) |
| 201 | + |
| 202 | + # Get unique PackageInstance objects from `package_instances_by_paths` |
| 203 | + |
| 204 | + package_instances = list(package_instance_by_identifiers.values()) |
| 205 | + codebase.attributes.packages.extend(package_instances) |
| 206 | + |
| 207 | + |
| 208 | +def update_files_with_package_instances(package_manifests_by_path, codebase, package_instance): |
| 209 | + |
| 210 | + for path in package_manifests_by_path.keys(): |
| 211 | + # Update `for_packages` attribute for resource at path with |
| 212 | + # reference to this package_instance |
| 213 | + continue |
| 214 | + |
112 | 215 |
|
113 | 216 | def set_packages_root(resource, codebase): |
114 | 217 | """ |
|
0 commit comments