forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdeps_parser.py
126 lines (103 loc) · 3.34 KB
/
deps_parser.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/env python3
#
# Copyright 2013 The Flutter Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# Usage: deps_parser.py --deps <DEPS file> --output <flattened deps>
#
# This script parses the DEPS file, extracts the fully qualified dependencies
# and writes the to a file. This file will be later used to validate the dependencies
# are pinned to a hash.
import argparse
import os
import re
import sys
SCRIPT_DIR = os.path.dirname(sys.argv[0])
CHECKOUT_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..'))
CHROMIUM_README_FILE = 'third_party/accessibility/README.md'
CHROMIUM_README_COMMIT_LINE = 4 # the fifth line will always contain the commit hash
CHROMIUM = 'https://chromium.googlesource.com/chromium/src'
# Used in parsing the DEPS file.
class VarImpl:
_env_vars = {
'host_cpu': 'x64',
'host_os': 'linux',
}
def __init__(self, local_scope):
self._local_scope = local_scope
def lookup(self, var_name):
"""Implements the Var syntax."""
if var_name in self._local_scope.get('vars', {}):
return self._local_scope['vars'][var_name]
# Inject default values for env variables
if var_name in self._env_vars:
return self._env_vars[var_name]
raise Exception('Var is not defined: %s' % var_name)
def parse_deps_file(deps_file):
local_scope = {}
var = VarImpl(local_scope)
global_scope = {
'Var': var.lookup,
'deps_os': {},
}
# Read the content.
with open(deps_file, 'r') as file:
deps_content = file.read()
# Eval the content.
exec(deps_content, global_scope, local_scope)
# Extract the deps and filter.
deps = local_scope.get('deps', {})
filtered_deps = []
for _, dep in deps.items():
# We currently do not support packages or cipd which are represented
# as dictionaries.
if isinstance(dep, str):
filtered_deps.append(dep)
return filtered_deps
def parse_readme(deps):
"""
Opens the Flutter Accessibility Library README and uses the commit hash
found in the README to check for viulnerabilities.
The commit hash in this README will always be in the same format
"""
file_path = os.path.join(CHECKOUT_ROOT, CHROMIUM_README_FILE)
with open(file_path) as file:
# read the content of the file opened
content = file.readlines()
commit_line = content[CHROMIUM_README_COMMIT_LINE]
commit = re.search(r'(?<=\[).*(?=\])', commit_line)
deps.append(CHROMIUM + '@' + commit.group())
return deps
def write_manifest(deps, manifest_file):
print('\n'.join(sorted(deps)))
with open(manifest_file, 'w') as manifest:
manifest.write('\n'.join(sorted(deps)))
def parse_args(args):
args = args[1:]
parser = argparse.ArgumentParser(
description='A script to flatten a gclient DEPS file.'
)
parser.add_argument(
'--deps',
'-d',
type=str,
help='Input DEPS file.',
default=os.path.join(CHECKOUT_ROOT, 'DEPS')
)
parser.add_argument(
'--output',
'-o',
type=str,
help='Output flattened deps file.',
default=os.path.join(CHECKOUT_ROOT, 'deps_flatten.txt')
)
return parser.parse_args(args)
def main(argv):
args = parse_args(argv)
deps = parse_deps_file(args.deps)
deps = parse_readme(deps)
write_manifest(deps, args.output)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv))