-
Notifications
You must be signed in to change notification settings - Fork 379
/
util.py
108 lines (88 loc) · 3.24 KB
/
util.py
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
# -------------------------------------------------------------------------
#
# Part of the CodeChecker project, under the Apache License v2.0 with
# LLVM Exceptions. See LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# -------------------------------------------------------------------------
"""
Util module.
"""
import itertools
import json
from typing import TextIO
import os
import portalocker
from codechecker_common.logger import get_logger
LOG = get_logger('system')
def arg_match(options, args):
"""Checks and selects the option string specified in 'options'
that are present in parameter 'args'."""
matched_args = []
for option in options:
if any([arg if option.startswith(arg) else None
for arg in args]):
matched_args.append(option)
continue
return matched_args
def chunks(iterator, n):
"""
Yield the next chunk if an iterable object. A chunk consists of maximum n
elements.
"""
iterator = iter(iterator)
for first in iterator:
rest_of_chunk = itertools.islice(iterator, 0, n - 1)
yield itertools.chain([first], rest_of_chunk)
def load_json(path: str, default=None, lock=False, display_warning=True):
"""
Load the contents of the given file as a JSON and return it's value,
or default if the file can't be loaded.
path -- JSON file path to load.
defaut -- Value to return if JSON can't be loaded for some reason (e.g
file doesn't exist, bad JSON format, etc.)
lock -- Use portalocker to lock the JSON file for exclusive use.
display_warning -- Display warning messages why the JSON file can't be
loaded (e.g. bad format, failed to open file, etc.)
"""
ret = default
try:
with open(path, 'r', encoding='utf-8', errors='ignore') as handle:
if lock:
portalocker.lock(handle, portalocker.LOCK_SH)
ret = json.load(handle)
if lock:
portalocker.unlock(handle)
except IOError as ex:
if display_warning:
LOG.warning("Failed to open json file: %s", path)
LOG.warning(ex)
except OSError as ex:
if display_warning:
LOG.warning("Failed to open json file: %s", path)
LOG.warning(ex)
except ValueError as ex:
if display_warning:
LOG.warning("%s is not a valid json file.", path)
LOG.warning(ex)
except TypeError as ex:
if display_warning:
LOG.warning('Failed to process json file: %s', path)
LOG.warning(ex)
return ret
def get_linef(fp: TextIO, line_no: int) -> str:
"""'fp' should be (readable) file object.
Return the line content at line_no or an empty line
if there is less lines than line_no.
"""
fp.seek(0)
for line in fp:
line_no -= 1
if line_no == 0:
return line
return ''
def path_for_fake_root(full_path: str, root_path: str = '/') -> str:
"""Normalize and sanitize full_path, then make it relative to root_path."""
relative_path = os.path.relpath(full_path, '/')
fake_root_path = os.path.join(root_path, relative_path)
return os.path.realpath(fake_root_path)