Skip to content

Commit 4c4b2a8

Browse files
Nisha Krnjudge
Nisha K
authored andcommitted
Prospector 1.4.1 fixes
Major changes: - Return None in mount_single_layer function when something goes wrong. Do a check for the target_dir string existing before passing it on for analysis. - Return None for DriverManager try-except calls when there is a NoMatches exception. This modifies all instantiations of Stevedore's DriverManager class. - Iterate over the dictionary using .items() rather than just the plain dictionary. - Use "with" to open files and subprocess pipes. This may result in certain errors not being raised, but it is hard to know at this point. Minor changes: - Used the "maxsplit" argument in __main__.py as we only need the first item. - Used [] rather than list() to initialize lists. - Specify encoding as 'utf-8' when opening files. - Update re-raises to explicitly state which exception they are re-raising from using "from". - Use "enumerate" for looping through list's index while throwing out the unused value. - Suppressed the "useless-suppression" message along with "too-many-branches" suppression due to pylint bug: pylint-dev/pylint#2366 - Wraped some lines that were too long, except in the HTML format file due to the need to keep the literal HTML formatting. - Updated the year on some modified files. Signed-off-by: Nisha K <[email protected]>
1 parent 9bbb5dd commit 4c4b2a8

File tree

23 files changed

+72
-62
lines changed

23 files changed

+72
-62
lines changed

tern/__main__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def main():
152152
"default option.")
153153

154154
# sys.version gives more information than we care to print
155-
py_ver = sys.version.replace('\n', '').split('[')[0]
155+
py_ver = sys.version.replace('\n', '').split('[', maxsplit=1)[0]
156156
parser.add_argument('-v', '--version', action='version',
157157
version="{ver_str}\n python version = {py_v}".format(
158158
ver_str=get_version(), py_v=py_ver))

tern/analyze/common.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ def get_licenses_from_deb_copyright(deb_copyright):
166166
3. returns a list of unique licenses found inside
167167
the copyright text
168168
'''
169-
collected_paragraphs = list()
169+
collected_paragraphs = []
170170
pkg_licenses = set()
171171
for paragraph in iter(debcon.get_paragraphs_data(deb_copyright)):
172172
if 'license' in paragraph:
@@ -190,7 +190,7 @@ def get_deb_package_licenses(deb_copyrights):
190190
Given a list of debian copyrights for the same number of packages,
191191
returns a list package licenses for each of the packages
192192
'''
193-
deb_licenses = list()
193+
deb_licenses = []
194194
for deb_copyright in deb_copyrights:
195195
deb_licenses.append(get_licenses_from_deb_copyright(deb_copyright))
196196
return deb_licenses

tern/analyze/default/command_lib/command_lib.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@
2929

3030
# command library
3131
command_lib = {'common': {}, 'base': {}, 'snippets': {}}
32-
with open(os.path.abspath(common_file)) as f:
32+
with open(os.path.abspath(common_file), encoding='utf-8') as f:
3333
command_lib['common'] = yaml.safe_load(f)
34-
with open(os.path.abspath(base_file)) as f:
34+
with open(os.path.abspath(base_file), encoding='utf-8') as f:
3535
command_lib['base'] = yaml.safe_load(f)
36-
with open(os.path.abspath(snippet_file)) as f:
36+
with open(os.path.abspath(snippet_file), encoding='utf-8') as f:
3737
command_lib['snippets'] = yaml.safe_load(f)
3838
# list of package information keys that the command library can accomodate
3939
base_keys = {'names', 'versions', 'licenses', 'copyrights', 'proj_urls',

tern/analyze/default/container/single_layer.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def find_os_release(host_path):
4040
return ''
4141
etc_path = lib_path
4242
# file exists at this point, try to read it
43-
with open(etc_path, 'r') as f:
43+
with open(etc_path, 'r', encoding='utf-8') as f:
4444
lines = f.readlines()
4545
# Create dictionary from os-release values
4646
os_release_dict = {}
@@ -106,9 +106,11 @@ def mount_first_layer(layer_obj):
106106
except subprocess.CalledProcessError as e: # nosec
107107
logger.critical("Cannot mount filesystem and/or device nodes: %s", e)
108108
dcom.abort_analysis()
109+
return None
109110
except KeyboardInterrupt:
110111
logger.critical(errors.keyboard_interrupt)
111112
dcom.abort_analysis()
113+
return None
112114

113115

114116
def analyze_first_layer(image_obj, master_list, options):
@@ -155,7 +157,8 @@ def analyze_first_layer(image_obj, master_list, options):
155157
# mount the first layer
156158
target_dir = mount_first_layer(image_obj.layers[0])
157159
# set the host path to the mount point
158-
prereqs.host_path = target_dir
160+
if target_dir:
161+
prereqs.host_path = target_dir
159162
# core default execution on the first layer
160163
core.execute_base(image_obj.layers[0], prereqs)
161164
# unmount

tern/analyze/default/dockerfile/lock.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -264,5 +264,5 @@ def write_locked_dockerfile(dfile, destination=None):
264264
file_name = destination
265265
else:
266266
file_name = constants.locked_dockerfile
267-
with open(file_name, 'w') as f:
267+
with open(file_name, 'w', encoding='utf-8') as f:
268268
f.write(dfile)

tern/analyze/default/dockerfile/parse.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def get_dockerfile_obj(dockerfile_name, prev_env=None):
7272
previous stages in a multistage docker build. Should be a python dictionary
7373
of the form {'ENV': 'value',...}'''
7474
dfobj = Dockerfile()
75-
with open(dockerfile_name) as f:
75+
with open(dockerfile_name, encoding='utf-8') as f:
7676
parser = DockerfileParser(parent_env=prev_env, fileobj=f)
7777
dfobj.filepath = dockerfile_name
7878
dfobj.structure = parser.structure
@@ -180,8 +180,8 @@ def expand_from_images(dfobj, image_list):
180180
if command_dict['instruction'] in import_str:
181181
dfobj.structure[index]['content'] = import_str + '\n'
182182
else:
183-
dfobj.structure[index]['content'] = command_dict['instruction'] + \
184-
' ' + import_str + '\n'
183+
dfobj.structure[index]['content'] = \
184+
command_dict['instruction'] + ' ' + import_str + '\n'
185185
image_count += 1
186186

187187

tern/analyze/default/dockerfile/run.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ def write_dockerfile_stages(dfobj):
233233
for stage in stages:
234234
stagefile = os.path.join(
235235
filepath, '{}_{}'.format(filename, stages.index(stage) + 1))
236-
with open(stagefile, 'w') as f:
236+
with open(stagefile, 'w', encoding='utf-8') as f:
237237
f.write(stage)
238238
dockerfiles.append(stagefile)
239239
return dockerfiles

tern/analyze/default/live/collect.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def create_script(command, prereqs, method):
4040
if method == 'host':
4141
script = host_script.format(host_shell=prereqs.host_shell,
4242
snip=command)
43-
with open(script_path, 'w') as f:
43+
with open(script_path, 'w', encoding='utf-8') as f:
4444
f.write(script)
4545
os.chmod(script_path, 0o700)
4646
return script_path
@@ -54,8 +54,8 @@ def snippets_to_script(snippet_list):
5454
final_list = []
5555
for snippet in snippet_list:
5656
# replace the escaped characters
57-
for key in replace_dict:
58-
snippet = re.sub(key, replace_dict[key], snippet)
57+
for key, val in replace_dict.items():
58+
snippet = re.sub(key, val, snippet)
5959
final_list.append(snippet)
6060
return " && ".join(final_list)
6161

tern/analyze/default/live/run.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def get_context_layers(reports, format_string):
106106
)
107107
return mgr.driver.consume_layer(reports)
108108
except NoMatches:
109-
pass
109+
return None
110110

111111

112112
def resolve_context_packages(layers):

tern/analyze/passthrough.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def run_extension(image_obj, ext_string, redo=False):
9999
)
100100
return mgr.driver.execute(image_obj, redo)
101101
except NoMatches:
102-
pass
102+
return None
103103

104104

105105
def run_extension_layer(image_layer, ext_string, redo=False):
@@ -113,4 +113,4 @@ def run_extension_layer(image_layer, ext_string, redo=False):
113113
)
114114
return mgr.driver.execute_layer(image_layer, redo)
115115
except NoMatches:
116-
pass
116+
return None

tern/classes/docker_image.py

+9-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- coding: utf-8 -*-
22
#
3-
# Copyright (c) 2017-2020 VMware, Inc. All Rights Reserved.
3+
# Copyright (c) 2017-2021 VMware, Inc. All Rights Reserved.
44
# SPDX-License-Identifier: BSD-2-Clause
55

66
import json
@@ -62,7 +62,7 @@ def get_image_manifest(self):
6262
an image inside, get a dict of the manifest.json file'''
6363
temp_path = rootfs.get_working_dir()
6464
with general.pushd(temp_path):
65-
with open(manifest_file) as f:
65+
with open(manifest_file, encoding='utf-8') as f:
6666
json_obj = json.loads(f.read())
6767
return json_obj
6868

@@ -94,7 +94,7 @@ def get_image_config(self, manifest):
9494
# manifest file
9595
temp_path = rootfs.get_working_dir()
9696
with general.pushd(temp_path):
97-
with open(config_file) as f:
97+
with open(config_file, encoding='utf-8') as f:
9898
json_obj = json.loads(f.read())
9999
return json_obj
100100

@@ -151,9 +151,11 @@ def load_image(self, load_until_layer=0):
151151
layer_count = 1
152152
while layer_diffs and layer_paths:
153153
layer = ImageLayer(layer_diffs.pop(0), layer_paths.pop(0))
154-
# Only load metadata for the layers we need to report on according to the --layers command line option
154+
# Only load metadata for the layers we need to report on
155+
# according to the --layers command line option
155156
# If --layers option is not present, load all the layers
156-
if self.load_until_layer >= layer_count or self.load_until_layer == 0:
157+
if (self.load_until_layer >= layer_count
158+
or self.load_until_layer == 0):
157159
layer.set_checksum(checksum_type, layer.diff_id)
158160
layer.gen_fs_hash()
159161
layer.layer_index = layer_count
@@ -166,9 +168,9 @@ def load_image(self, load_until_layer=0):
166168
self._load_until_layer = 0
167169
self.set_layer_created_by()
168170
except NameError as e:
169-
raise NameError(e)
171+
raise NameError(e) from e
170172
except subprocess.CalledProcessError as e:
171173
raise subprocess.CalledProcessError(
172174
e.returncode, cmd=e.cmd, output=e.output, stderr=e.stderr)
173175
except IOError as e:
174-
raise IOError(e)
176+
raise IOError(e) from e

tern/classes/file_data.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- coding: utf-8 -*-
22
#
3-
# Copyright (c) 2020 VMware, Inc. All Rights Reserved.
3+
# Copyright (c) 2020-2021 VMware, Inc. All Rights Reserved.
44
# SPDX-License-Identifier: BSD-2-Clause
55

66
import datetime
@@ -98,8 +98,9 @@ def date(self, date):
9898
if date:
9999
try:
100100
datetime.datetime.strptime(date, '%Y-%m-%d')
101-
except ValueError:
102-
raise ValueError("Incorrect date format, should be YYYY-MM-DD")
101+
except ValueError as vr:
102+
raise ValueError(
103+
"Incorrect date format, should be YYYY-MM-DD") from vr
103104
self.__date = date
104105

105106
@property

tern/classes/image_layer.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- coding: utf-8 -*-
22
#
3-
# Copyright (c) 2017-2020 VMware, Inc. All Rights Reserved.
3+
# Copyright (c) 2017-2021 VMware, Inc. All Rights Reserved.
44
# SPDX-License-Identifier: BSD-2-Clause
55
import os
66
import re
@@ -241,7 +241,7 @@ def remove_file(self, file_path):
241241
in the layer'''
242242
rem_index = 0
243243
success = False
244-
for index in range(0, len(self.__files)):
244+
for index, _ in enumerate(self.__files):
245245
if self.__files[index].path == file_path:
246246
rem_index = index
247247
success = True
@@ -313,7 +313,7 @@ def add_files(self):
313313
hash_file = os.path.join(os.path.dirname(fs_path),
314314
self.__fs_hash) + '.txt'
315315
pattern = re.compile(r'([\w\-|]+)\s+(.+)')
316-
with open(hash_file) as f:
316+
with open(hash_file, encoding='utf-8') as f:
317317
content = f.readlines()
318318
for line in content:
319319
m = pattern.search(line)

tern/extensions/scancode/executor.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- coding: utf-8 -*-
22
#
3-
# Copyright (c) 2019-2020 VMware, Inc. All Rights Reserved.
3+
# Copyright (c) 2019-2021 VMware, Inc. All Rights Reserved.
44
# SPDX-License-Identifier: BSD-2-Clause
55

66
"""
@@ -119,7 +119,7 @@ def add_scancode_headers(layer_obj, headers):
119119
'''Given a list of headers from scancode data, add unique headers to
120120
the list of existing headers in the layer object'''
121121
unique_notices = {header.get("notice") for header in headers}
122-
layer_headers = layer_obj.extension_info.get("headers", list())
122+
layer_headers = layer_obj.extension_info.get("headers", [])
123123
for lh in layer_headers:
124124
unique_notices.add(lh)
125125
layer_obj.extension_info["headers"] = list(unique_notices)

tern/formats/html/generator.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- coding: utf-8 -*-
22
#
3-
# Copyright (c) 2020 VMware, Inc. All Rights Reserved.
3+
# Copyright (c) 2020-2021 VMware, Inc. All Rights Reserved.
44
# SPDX-License-Identifier: BSD-2-Clause
55

66
"""
@@ -215,8 +215,7 @@ def list_handler(list_obj, indent):
215215
return html_string
216216

217217

218-
# pylint: disable=too-many-branches
219-
def dict_handler(dict_obj, indent):
218+
def dict_handler(dict_obj, indent): # pylint: disable=too-many-branches, useless-suppression
220219
'''Writes html code for dictionary in report dictionary'''
221220
html_string = ''
222221
html_string = html_string + ' '*indent + '<ul class ="nested"> \n'

tern/formats/json/consumer.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ def create_image_layer(report):
3030
# expect a json input, raise an error if it is not
3131
content = {}
3232
try:
33-
f = open(os.path.abspath(report))
34-
content = json.load(f)
33+
with open(os.path.abspath(report), encoding='utf-8') as f:
34+
content = json.load(f)
3535
except OSError as err:
3636
logger.critical("Cannot access file %s: %s", report, err)
37-
raise ConsumerError(f"Error with given report file: {report}")
37+
raise ConsumerError(f"Error with given report file: {report}") from err
3838
except json.JSONDecodeError as err:
3939
logger.critical("Cannot parse JSON in file %s: %s", report, err)
40-
raise ConsumerError(f"Error with given report file: {report}")
40+
raise ConsumerError(f"Error with given report file: {report}") from err
4141
# we should have some content but it may be empty
4242
if not content:
4343
raise ConsumerError("No content consumed from given report file")

tern/formats/spdx/spdxjson/consumer.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,14 @@ def create_image_layer(report):
5454
# expect a json input, raise an error if it is not
5555
content = {}
5656
try:
57-
f = open(os.path.abspath(report))
58-
content = json.load(f)
57+
with open(os.path.abspath(report), encoding='utf-8') as f:
58+
content = json.load(f)
5959
except OSError as err:
6060
logger.critical("Cannot access file %s: %s", report, err)
61-
raise ConsumerError(f"Error with given report file: {report}")
61+
raise ConsumerError(f"Error with given report file: {report}") from err
6262
except json.JSONDecodeError as err:
6363
logger.critical("Cannot parse JSON in file %s: %s", report, err)
64-
raise ConsumerError(f"Error with given report file: {report}")
64+
raise ConsumerError(f"Error with given report file: {report}") from err
6565
# we should have some content but it may be empty
6666
if not content:
6767
raise ConsumerError("No content consumed from given report file")

tern/formats/spdx/spdxjson/file_helpers.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ def get_file_dict(filedata, template, layer_id):
3131
'SPDXID': spdx_common.get_file_spdxref(filedata, layer_id),
3232
'checksums': [{
3333
'algorithm':
34-
spdx_common.get_file_checksum(filedata).split(': ')[0],
34+
spdx_common.get_file_checksum(filedata).split(
35+
': ', maxsplit=1)[0],
3536
'checksumValue':
3637
spdx_common.get_file_checksum(filedata).split(': ')[1]
3738
}],

tern/formats/spdx/spdxjson/layer_helpers.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ def get_layer_dict(layer_obj):
149149
'filesAnalyzed': 'true' if layer_obj.files_analyzed else 'false',
150150
'checksums': [{
151151
'algorithm':
152-
spdx_common.get_layer_checksum(layer_obj).split(': ')[0],
152+
spdx_common.get_layer_checksum(layer_obj).split(
153+
': ', maxsplit=1)[0],
153154
'checksumValue':
154155
spdx_common.get_layer_checksum(layer_obj).split(': ')[1]
155156
}],

tern/load/docker_api.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def build_image(dfile, client):
5858
dfcontents = ''
5959
dfcontext = os.path.dirname(df_path)
6060
try:
61-
with open(df_path) as f:
61+
with open(df_path, encoding='utf-8') as f:
6262
dfcontents = f.read()
6363
# terrible bypass of the API
6464
docker.api.build.process_dockerfile = lambda dockerfile, path: (

tern/report/report.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def write_report(report, args):
2424
'''Write the report to a file'''
2525
if args.output_file:
2626
file_name = args.output_file
27-
with open(file_name, 'w') as f:
27+
with open(file_name, 'w', encoding='utf-8') as f:
2828
f.write(report)
2929

3030

@@ -64,7 +64,7 @@ def generate_format(images, format_string, print_inclusive):
6464
)
6565
return mgr.driver.generate(images, print_inclusive)
6666
except NoMatches:
67-
pass
67+
return None
6868

6969

7070
def generate_format_layer(layer, format_string):
@@ -78,7 +78,7 @@ def generate_format_layer(layer, format_string):
7878
)
7979
return mgr.driver.generate_layer(layer)
8080
except NoMatches:
81-
pass
81+
return None
8282

8383

8484
def report_out(args, *images):

0 commit comments

Comments
 (0)