-
-
Notifications
You must be signed in to change notification settings - Fork 721
Expand file tree
/
Copy pathgolang.py
More file actions
136 lines (114 loc) · 4.44 KB
/
golang.py
File metadata and controls
136 lines (114 loc) · 4.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# Copyright (c) nexB Inc. and others. All rights reserved.
# ScanCode is a trademark of nexB Inc.
# SPDX-License-Identifier: Apache-2.0
# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
# See https://github.com/nexB/scancode-toolkit for support or download.
# See https://aboutcode.org for more information about nexB OSS projects.
#
from packagedcode import go_mod
from packagedcode import models
"""
Handle Go packages including go.mod and go.sum files.
"""
# FIXME: !!improve how we handle packages names vs. subpath.
# we need to have shorter names and use subpath
# TODO: go.mod file does not contain version number.
# valid download url need version number
# CHECK: https://forum.golangbridge.org/t/url-to-download-package/19811
# TODO: use the LICENSE file convention!
# TODO: support "vendor" layout
class BaseGoModuleHandler(models.DatafileHandler):
@classmethod
def assemble(cls, package_data, resource, codebase, package_adder):
"""
Always use go.mod first then go.sum
"""
yield from cls.assemble_from_many_datafiles(
datafile_name_patterns=('go.mod', 'go.sum',),
directory=resource.parent(codebase),
codebase=codebase,
package_adder=package_adder,
)
class GoModHandler(BaseGoModuleHandler):
datasource_id = 'go_mod'
path_patterns = ('*/go.mod',)
default_package_type = 'golang'
default_primary_language = 'Go'
description = 'Go modules file'
documentation_url = 'https://go.dev/ref/mod'
@classmethod
def parse(cls, location, package_only=False):
gomods = go_mod.parse_gomod(location)
dependencies = []
require = gomods.require or []
for gomod in require:
dependencies.append(
models.DependentPackage(
purl=gomod.purl(include_version=True),
extracted_requirement=gomod.version,
scope='require',
is_runtime=True,
is_optional=False,
is_pinned=False,
)
)
exclude = gomods.exclude or []
for gomod in exclude:
dependencies.append(
models.DependentPackage(
purl=gomod.purl(include_version=True),
extracted_requirement=gomod.version,
scope='exclude',
is_runtime=True,
is_optional=False,
is_pinned=False,
)
)
name = gomods.name
namespace = gomods.namespace
homepage_url = f'https://pkg.go.dev/{gomods.namespace}/{gomods.name}'
vcs_url = f'https://{gomods.namespace}/{gomods.name}.git'
repository_homepage_url = None
if namespace and name:
repository_homepage_url = f'https://pkg.go.dev/{namespace}/{name}'
package_data = dict(
datasource_id=cls.datasource_id,
type=cls.default_package_type,
name=name,
namespace=namespace,
vcs_url=vcs_url,
homepage_url=homepage_url,
repository_homepage_url=repository_homepage_url,
dependencies=dependencies,
primary_language=cls.default_primary_language,
)
yield models.PackageData.from_data(package_data, package_only)
class GoSumHandler(BaseGoModuleHandler):
datasource_id = 'go_sum'
path_patterns = ('*/go.sum',)
default_package_type = 'golang'
default_primary_language = 'Go'
description = 'Go module checksums file'
documentation_url = 'https://go.dev/ref/mod#go-sum-files'
@classmethod
def parse(cls, location, package_only=False):
gosums = go_mod.parse_gosum(location)
package_dependencies = []
for gosum in gosums:
package_dependencies.append(
models.DependentPackage(
purl=gosum.purl(),
extracted_requirement=gosum.version,
scope='dependency',
is_runtime=True,
is_optional=False,
is_pinned=True,
)
)
package_data = dict(
datasource_id=cls.datasource_id,
type=cls.default_package_type,
dependencies=package_dependencies,
primary_language=cls.default_primary_language,
)
yield models.PackageData.from_data(package_data, package_only)