Skip to content

Commit b46d69a

Browse files
committed
Add mypy / flake8 checks for python files
1 parent e4fe772 commit b46d69a

8 files changed

+97
-47
lines changed

.flake8

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[flake8]
2+
max-line-length = 120

check.sh

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
mypy --exclude apks/chromium .
6+
flake8 --exclude apks/chromium .

flake.nix

-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@
2727
nixosModule = import ./nixos; # Contains all robotnix nixos modules
2828
nixosModules.attestation-server = import ./nixos/attestation-server/module.nix;
2929

30-
checks.x86_64-linux = {};
31-
3230
packages.x86_64-linux = {
3331
manual = (import ./docs { inherit pkgs; }).manual;
3432
};

flavors/lineageos/update-device-dirs.py

+41-25
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
# SPDX-FileCopyrightText: 2020 Daniel Fullmer and robotnix contributors
33
# SPDX-License-Identifier: MIT
44

5+
from typing import Any, Dict, List, Tuple
56
import argparse
67
import json
78
import os
89
import subprocess
9-
import urllib.request
1010

1111
# A full run took approximately 12 minutes total. Needed to set TMPDIR=/tmp
1212
#
@@ -18,45 +18,57 @@
1818
VENDOR_REPO_BASE = "https://github.com/TheMuppets"
1919
ROBOTNIX_GIT_MIRRORS = os.environ.get('ROBOTNIX_GIT_MIRRORS', '')
2020
if ROBOTNIX_GIT_MIRRORS:
21-
MIRRORS = dict(mirror.split("=") for mirror in ROBOTNIX_GIT_MIRRORS).split('|'))
21+
MIRRORS: Dict[str, str] = dict(
22+
(mirror.split("=")[0], mirror.split("=")[1])
23+
for mirror in ROBOTNIX_GIT_MIRRORS.split('|')
24+
)
2225
else:
2326
MIRRORS = {}
24-
REMOTE_REFS = {} # url: { ref: rev }
27+
REMOTE_REFS: Dict[str, Dict[str, str]] = {} # url: { ref: rev }
2528

26-
def save(filename, data):
29+
30+
def save(filename: str, data: str) -> None:
2731
open(filename, 'w').write(json.dumps(data, sort_keys=True, indent=2, separators=(',', ': ')))
2832

29-
def get_mirrored_url(url):
33+
34+
def get_mirrored_url(url: str) -> str:
3035
for mirror_url, mirror_path in MIRRORS.items():
3136
if url.startswith(mirror_url):
3237
url = url.replace(mirror_url, mirror_path)
3338
return url
3439

35-
def ls_remote(url):
40+
41+
def ls_remote(url: str) -> Dict[str, str]:
3642
if url in REMOTE_REFS:
3743
return REMOTE_REFS[url]
3844

3945
orig_url = url
4046
url = get_mirrored_url(url)
4147

42-
remote_info = subprocess.check_output([ "git", "ls-remote", url ]).decode()
43-
REMOTE_REFS[orig_url] = dict(reversed(line.split('\t')) for line in remote_info.split('\n') if line)
48+
remote_info = subprocess.check_output(["git", "ls-remote", url]).decode()
49+
REMOTE_REFS[orig_url] = {}
50+
for line in remote_info.split('\n'):
51+
if line:
52+
ref, rev = reversed(line.split('\t'))
53+
REMOTE_REFS[orig_url][ref] = rev
4454
return REMOTE_REFS[orig_url]
4555

46-
def checkout_git(url, rev):
56+
57+
def checkout_git(url: str, rev: str) -> Any:
4758
print("Checking out %s %s" % (url, rev))
48-
json_text = subprocess.check_output([ "nix-prefetch-git", "--url", url, "--rev", rev]).decode()
59+
json_text = subprocess.check_output(["nix-prefetch-git", "--url", url, "--rev", rev]).decode()
4960
return json.loads(json_text)
5061

51-
def fetch_relpath(dirs, relpath, url, branch):
62+
63+
def fetch_relpath(dirs: Dict[str, Any], relpath: str, url: str, branch: str) -> Any:
5264
orig_url = url
5365
url = get_mirrored_url(url)
5466

5567
current_rev = dirs.get(relpath, {}).get('rev', None)
5668
refs = ls_remote(url)
5769
ref = f'refs/heads/{branch}'
5870
if ref not in refs:
59-
raise Exception(f'{url} is missing {ref}')
71+
raise ValueError(f'{url} is missing {ref}')
6072
newest_rev = refs[ref]
6173
if (current_rev != newest_rev
6274
or ('path' not in dirs[relpath])
@@ -70,14 +82,14 @@ def fetch_relpath(dirs, relpath, url, branch):
7082

7183

7284
# Fetch device source trees for devices in metadata and save their information into filename
73-
def fetch_device_dirs(metadata, filename, branch):
85+
def fetch_device_dirs(metadata: Any, filename: str, branch: str) -> Tuple[Any, Dict[str, List[str]]]:
7486
if os.path.exists(filename):
7587
dirs = json.load(open(filename))
7688
else:
7789
dirs = {}
7890

79-
dirs_to_fetch = set() # Pairs of (relpath, url)
80-
dirs_fetched = set() # Just strings of relpath
91+
dirs_to_fetch = set() # Pairs of (relpath, url)
92+
dirs_fetched = set() # Just strings of relpath
8193
for device, data in metadata.items():
8294
vendor = data['vendor']
8395
url = f'{LINEAGE_REPO_BASE}/android_device_{vendor}_{device}'
@@ -88,12 +100,12 @@ def fetch_device_dirs(metadata, filename, branch):
88100
else:
89101
print(f'SKIP: {branch} branch does not exist for {device}')
90102

91-
dir_dependencies = {} # key -> [ values ].
103+
dir_dependencies: Dict[str, List[str]] = {} # key -> [ values ].
92104
while len(dirs_to_fetch) > 0:
93105
relpath, url = dirs_to_fetch.pop()
94106
try:
95107
dir_info = fetch_relpath(dirs, relpath, url, branch)
96-
except:
108+
except ValueError:
97109
continue
98110

99111
# Also grab any dirs that this one depends on
@@ -105,16 +117,17 @@ def fetch_device_dirs(metadata, filename, branch):
105117
if dep['target_path'] not in dirs_fetched:
106118
dirs_to_fetch.add((dep['target_path'], f"{LINEAGE_REPO_BASE}/{dep['repository']}"))
107119

108-
dir_info['deps'] = [ dep['target_path'] for dep in lineage_dependencies ]
120+
dir_info['deps'] = [dep['target_path'] for dep in lineage_dependencies]
109121
else:
110122
dir_info['deps'] = []
111123

112-
save(filename, dirs) # Save after every step, for resuming
124+
save(filename, dirs) # Save after every step, for resuming
113125
dirs_fetched.add(relpath)
114126

115127
return dirs, dir_dependencies
116128

117-
def fetch_vendor_dirs(metadata, filename, branch):
129+
130+
def fetch_vendor_dirs(metadata: Any, filename: str, branch: str) -> Any:
118131
required_vendor = set()
119132
for device, data in metadata.items():
120133
if 'vendor' in data:
@@ -151,11 +164,13 @@ def fetch_vendor_dirs(metadata, filename, branch):
151164

152165
return dirs
153166

154-
def main():
167+
168+
def main() -> None:
155169
parser = argparse.ArgumentParser()
156170
parser.add_argument('--branch', help="lineageos version")
157171
parser.add_argument('product', nargs='*',
158-
help='product to fetch directory metadata for, specified by <vendor>_<device> (example: google_crosshatch) '
172+
help='product to fetch directory metadata for, specified by <vendor>_<device> '
173+
'(example: google_crosshatch) '
159174
'If no products are specified, all products in device-metadata.json will be updated')
160175
args = parser.parse_args()
161176

@@ -165,10 +180,11 @@ def main():
165180
metadata = {}
166181
for product in args.product:
167182
vendor, device = product.split('_', 1)
168-
metadata[device] = { 'vendor': vendor }
183+
metadata[device] = {'vendor': vendor}
184+
185+
fetch_device_dirs(metadata, os.path.join(args.branch, 'device-dirs.json'), args.branch)
186+
fetch_vendor_dirs(metadata, os.path.join(args.branch, 'vendor-dirs.json'), args.branch)
169187

170-
device_dirs, dir_dependencies = fetch_device_dirs(metadata, os.path.join(args.branch, 'device-dirs.json'), args.branch)
171-
vendor_dirs = fetch_vendor_dirs(metadata, os.path.join(args.branch, 'vendor-dirs.json'), args.branch)
172188

173189
if __name__ == '__main__':
174190
main()

flavors/lineageos/update-device-metadata.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,21 @@
22
# SPDX-FileCopyrightText: 2020 Daniel Fullmer and robotnix contributors
33
# SPDX-License-Identifier: MIT
44

5+
from typing import Any
56
import json
6-
import os
77
import urllib.request
88

9-
def save(filename, data):
9+
10+
def save(filename: str, data: str) -> None:
1011
open(filename, 'w').write(json.dumps(data, sort_keys=True, indent=2, separators=(',', ': ')))
1112

12-
def fetch_metadata():
13+
14+
def fetch_metadata() -> Any:
1315
metadata = {}
1416

15-
lineage_build_targets_str = urllib.request.urlopen("https://github.com/LineageOS/hudson/raw/master/lineage-build-targets").read().decode()
17+
lineage_build_targets_str = urllib.request.urlopen(
18+
"https://github.com/LineageOS/hudson/raw/master/lineage-build-targets"
19+
).read().decode()
1620
for line in lineage_build_targets_str.split("\n"):
1721
line = line.strip()
1822
if line == "":
@@ -54,6 +58,7 @@ def fetch_metadata():
5458

5559
return metadata
5660

61+
5762
if __name__ == '__main__':
5863
metadata = fetch_metadata()
5964
save('device-metadata.json', metadata)

mk-repo-file.py

+35-15
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# SPDX-FileCopyrightText: 2020 Daniel Fullmer and robotnix contributors
33
# SPDX-License-Identifier: MIT
44

5-
from typing import Optional, Dict, List, Tuple
5+
from typing import Any, Optional, Dict, List, Tuple
66
from enum import Enum
77

88
import argparse
@@ -20,45 +20,56 @@
2020
"--depth=1",
2121
]
2222

23+
2324
# The kind of remote a "commitish" refers to.
2425
# These are used for the --ref-type CLI arg.
2526
class ManifestRefType(Enum):
2627
BRANCH = "heads"
2728
TAG = "tags"
2829

30+
2931
revHashes: Dict[Tuple[str, bool], str] = {} # (rev, fetch_submodules) -> sha256hash
3032
revTrees: Dict[str, str] = {} # rev -> treeHash
31-
treeHashes: Dict[Tuple[str, bool], str] = {} # (treeHash, fetch_submodules) -> sha256hash
33+
treeHashes: Dict[Tuple[str, bool], str] = {} # (treeHash, fetch_submodules) -> sha256hash
3234

33-
def save(filename, data):
35+
36+
def save(filename: str, data: Any) -> None:
3437
open(filename, 'w').write(json.dumps(data, sort_keys=True, indent=2, separators=(',', ': ')))
3538

36-
def checkout_git(url, rev, fetch_submodules=False):
39+
40+
def checkout_git(url: str, rev: str, fetch_submodules: bool = False) -> Any:
3741
print("Checking out %s %s" % (url, rev))
38-
args = [ "nix-prefetch-git", "--url", url, "--rev", rev ]
42+
args = ["nix-prefetch-git", "--url", url, "--rev", rev]
3943
if fetch_submodules:
4044
args.append("--fetch-submodules")
4145
json_text = subprocess.check_output(args).decode()
4246
return json.loads(json_text)
4347

44-
def ls_remote(url, rev):
45-
remote_info = subprocess.check_output([ "git", "ls-remote", url, rev ]).decode()
48+
49+
def ls_remote(url: str, rev: str) -> str:
50+
remote_info = subprocess.check_output(["git", "ls-remote", url, rev]).decode()
4651
remote_rev = remote_info.split('\t')[0]
4752
assert remote_rev != ""
4853
return remote_rev
4954

55+
5056
def make_repo_file(url: str, ref: str, filename: str, ref_type: ManifestRefType,
5157
override_project_revs: Dict[str, str], resume: bool,
5258
mirrors: Dict[str, str], project_fetch_submodules: List[str],
5359
override_tag: Optional[str], include_prefix: List[str],
54-
exclude_path: List[str]):
60+
exclude_path: List[str]) -> None:
5561
if resume and os.path.exists(filename):
5662
data = json.load(open(filename))
5763
else:
5864
print("Fetching information for %s %s" % (url, ref))
5965
with tempfile.TemporaryDirectory() as tmpdir:
60-
subprocess.check_call(['repo', 'init', f'--manifest-url={url}', f'--manifest-branch=refs/{ref_type.value}/{ref}', *REPO_FLAGS], cwd=tmpdir)
61-
json_text = subprocess.check_output(['repo', 'dumpjson'] + (["--local-only"] if override_project_revs else []), cwd=tmpdir).decode()
66+
subprocess.check_call([
67+
'repo', 'init', f'--manifest-url={url}', f'--manifest-branch=refs/{ref_type.value}/{ref}', *REPO_FLAGS
68+
], cwd=tmpdir)
69+
json_text = subprocess.check_output(
70+
['repo', 'dumpjson']
71+
+ (["--local-only"] if override_project_revs else []),
72+
cwd=tmpdir).decode()
6273
data = json.loads(json_text)
6374

6475
save(filename, data)
@@ -109,7 +120,9 @@ def make_repo_file(url: str, ref: str, filename: str, ref_type: ManifestRefType,
109120
for mirror_url, mirror_path in mirrors.items():
110121
if p['url'].startswith(mirror_url):
111122
p_url = p['url'].replace(mirror_url, mirror_path)
112-
p['tree'] = subprocess.check_output(['git', 'log','-1', '--pretty=%T', p['rev']], cwd=p_url+'.git').decode().strip()
123+
p['tree'] = subprocess.check_output(
124+
['git', 'log', '-1', '--pretty=%T', p['rev']],
125+
cwd=p_url+'.git').decode().strip()
113126
if (p['tree'], fetch_submodules) in treeHashes:
114127
p['sha256'] = treeHashes[p['tree'], fetch_submodules]
115128
found_treehash = True
@@ -135,16 +148,19 @@ def make_repo_file(url: str, ref: str, filename: str, ref_type: ManifestRefType,
135148
# Save at the end as well!
136149
save(filename, data)
137150

138-
def main():
151+
152+
def main() -> None:
139153
parser = argparse.ArgumentParser()
140154
parser.add_argument('--out', default=None, help="path to output file, defaults to repo-{rev}.json")
141155
parser.add_argument('--ref-type', help="the kind of ref that is to be fetched",
142156
choices=[t.name.lower() for t in ManifestRefType], default=ManifestRefType.TAG.name.lower())
143157
parser.add_argument('--resume', help="resume a previous download", action='store_true')
144158
parser.add_argument('--repo-prop', help="repo.prop file to use as source for project git revisions")
145159
parser.add_argument('--override-tag', help="tag to fetch for subrepos, ignoring revisions from manifest")
146-
parser.add_argument('--project-fetch-submodules', action="append", default=[], help="fetch submodules for the specified project path")
147-
parser.add_argument('--include-prefix', action="append", default=[], help="only include paths if they start with the specified prefix")
160+
parser.add_argument('--project-fetch-submodules', action="append", default=[],
161+
help="fetch submodules for the specified project path")
162+
parser.add_argument('--include-prefix', action="append", default=[],
163+
help="only include paths if they start with the specified prefix")
148164
parser.add_argument('--exclude-path', action="append", default=[], help="paths to exclude from fetching")
149165
parser.add_argument('url', help="manifest URL")
150166
parser.add_argument('ref', help="manifest ref")
@@ -153,7 +169,10 @@ def main():
153169

154170
ROBOTNIX_GIT_MIRRORS = os.environ.get('ROBOTNIX_GIT_MIRRORS', '')
155171
if ROBOTNIX_GIT_MIRRORS:
156-
mirrors = dict(mirror.split("=") for mirror in ROBOTNIX_GIT_MIRRORS.split('|'))
172+
mirrors: Dict[str, str] = dict(
173+
(mirror.split("=")[0], mirror.split("=")[1])
174+
for mirror in ROBOTNIX_GIT_MIRRORS.split('|')
175+
)
157176
else:
158177
mirrors = {}
159178

@@ -192,5 +211,6 @@ def main():
192211
exclude_path=args.exclude_path,
193212
)
194213

214+
195215
if __name__ == "__main__":
196216
main()

mypy.ini

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[mypy]
2+
strict = true

shell.nix

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ pkgs.mkShell {
33
name = "robotnix-scripts";
44
nativeBuildInputs = with pkgs; [
55
# For android updater scripts
6-
python3
6+
(python3.withPackages (p: with p; [ mypy flake8 pytest ]))
77
gitRepo nix-prefetch-git
88
curl go-pup jq
99

@@ -12,4 +12,5 @@ pkgs.mkShell {
1212

1313
cachix
1414
];
15+
PYTHONPATH=".";
1516
}

0 commit comments

Comments
 (0)