Skip to content

Commit c6f75d8

Browse files
committed
Format source files
1 parent 979b237 commit c6f75d8

File tree

3 files changed

+146
-57
lines changed

3 files changed

+146
-57
lines changed

codeql_postproc/cli.py

Lines changed: 91 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,53 @@
33
from sys import exit
44
from typing import Optional, cast
55

6+
67
@click.group()
78
def cli() -> None:
89
pass
910

11+
1012
@cli.group()
1113
def database() -> None:
1214
pass
1315

16+
1417
@database.command("add-vcs-provenance")
15-
@click.option("-u", "--repository-uri", required=True, help="An absolute URI that specifies the location of the repository.")
16-
@click.option("-r", "--revision-id", required=True, help="A string that uniquely and permanently identifies the revision.")
18+
@click.option(
19+
"-u",
20+
"--repository-uri",
21+
required=True,
22+
help="An absolute URI that specifies the location of the repository.",
23+
)
24+
@click.option(
25+
"-r",
26+
"--revision-id",
27+
required=True,
28+
help="A string that uniquely and permanently identifies the revision.",
29+
)
1730
@click.argument("database", type=click.Path(exists=True, path_type=Path), required=True)
18-
def database_add_provenance(repository_uri: str, revision_id: str, database: Path) -> None:
31+
def database_add_provenance(
32+
repository_uri: str, revision_id: str, database: Path
33+
) -> None:
1934
from codeql_postproc.helpers.codeql import CodeQLDatabase, InvalidCodeQLDatabase
2035

2136
try:
2237
codeql_db = CodeQLDatabase(database)
23-
vcs_provenance = [{
24-
'repositoryUri': repository_uri,
25-
'revisionId': revision_id
26-
}]
38+
vcs_provenance = [{"repositoryUri": repository_uri, "revisionId": revision_id}]
2739
codeql_db.set_property(versionControlProvenance=vcs_provenance)
2840
except InvalidCodeQLDatabase as e:
2941
click.echo(e, err=True)
3042
exit(1)
3143

44+
3245
@database.command("get-property")
33-
@click.option("-f", "--format", "output_format", type=click.Choice(["json", "yaml"]), default="json")
46+
@click.option(
47+
"-f",
48+
"--format",
49+
"output_format",
50+
type=click.Choice(["json", "yaml"]),
51+
default="json",
52+
)
3453
@click.argument("key", required=True)
3554
@click.argument("database", type=click.Path(exists=True, path_type=Path), required=True)
3655
def get_property(output_format: str, key: str, database: Path) -> None:
@@ -42,57 +61,99 @@ def get_property(output_format: str, key: str, database: Path) -> None:
4261
try:
4362
codeql_db = CodeQLDatabase(database)
4463
value = codeql_db.get_property(key)
45-
if output_format == "yaml":
46-
yaml.dump(value, sys.stdout)
47-
elif output_format == "json":
48-
json.dump(value, sys.stdout)
64+
if value:
65+
if output_format == "yaml":
66+
yaml.dump(value, sys.stdout)
67+
elif output_format == "json":
68+
json.dump(value, sys.stdout)
69+
else:
70+
click.echo(f"Unimplemented output format {output_format}!")
71+
exit(1)
4972
else:
50-
click.echo(f"Unimplemented output format {output_format}!")
73+
click.echo(
74+
f"The database does not have a property with key {key}.", err=True
75+
)
5176
exit(1)
52-
except KeyError:
53-
click.echo(f"The database does not have a property with key {key}.", err=True)
54-
exit(1)
5577
except InvalidCodeQLDatabase as e:
5678
click.echo(e, err=True)
5779
exit(1)
5880

81+
5982
@cli.group("sarif")
6083
def sarif() -> None:
6184
pass
6285

86+
6387
@sarif.command("add-vcs-provenance")
6488
@click.option("-d", "--from-database", is_flag=True)
65-
@click.option("-u", "--repository-uri", help="An absolute URI that specifies the location of the repository.")
66-
@click.option("-r", "--revision-id", help="A string that uniquely and permanently identifies the revision.")
67-
@click.argument("sarif_path", type=click.Path(exists=True, path_type=Path, dir_okay=False), required=True)
68-
@click.argument("database_path", type=click.Path(exists=True, path_type=Path), required=False)
69-
def sarif_add_provenance(from_database: bool, repository_uri: str, revision_id: str, sarif_path: Path, database_path: Optional[Path]) -> None:
89+
@click.option(
90+
"-u",
91+
"--repository-uri",
92+
help="An absolute URI that specifies the location of the repository.",
93+
)
94+
@click.option(
95+
"-r",
96+
"--revision-id",
97+
help="A string that uniquely and permanently identifies the revision.",
98+
)
99+
@click.argument(
100+
"sarif_path",
101+
type=click.Path(exists=True, path_type=Path, dir_okay=False),
102+
required=True,
103+
)
104+
@click.argument(
105+
"database_path", type=click.Path(exists=True, path_type=Path), required=False
106+
)
107+
def sarif_add_provenance(
108+
from_database: bool,
109+
repository_uri: str,
110+
revision_id: str,
111+
sarif_path: Path,
112+
database_path: Optional[Path],
113+
) -> None:
70114
from codeql_postproc.helpers.codeql import CodeQLDatabase, InvalidCodeQLDatabase
71115
from codeql_postproc.helpers.sarif import Sarif, InvalidSarif
72116

73117
if from_database and not database_path:
74-
raise click.BadArgumentUsage("A database must be specified when using the --from-database option!")
75-
118+
raise click.BadArgumentUsage(
119+
"A database must be specified when using the --from-database option!"
120+
)
121+
76122
if not from_database and not repository_uri:
77-
raise click.BadOptionUsage("--repository-uri", "The option '--repository-uri' must be specified if not importing from a database!")
123+
raise click.BadOptionUsage(
124+
"--repository-uri",
125+
"The option '--repository-uri' must be specified if not importing from a database!",
126+
)
78127
if not from_database and not revision_id:
79-
raise click.BadOptionUsage("--revision-id", "The option '--revision-id' must be specified if not importing from a database!")
128+
raise click.BadOptionUsage(
129+
"--revision-id",
130+
"The option '--revision-id' must be specified if not importing from a database!",
131+
)
80132

81133
if from_database:
82134
try:
83135
codeql_db = CodeQLDatabase(cast(Path, database_path))
84136
# Assume there is only one array element for now.
85137
vcp = codeql_db.get_property("versionControlProvenance")[0]
86138
if not "repositoryUri" in vcp:
87-
click.echo(f"The database's version control provenance misses the 'repositoryUri' property!", err=True)
139+
click.echo(
140+
f"The database's version control provenance misses the 'repositoryUri' property!",
141+
err=True,
142+
)
88143
exit(1)
89144
repository_uri = vcp["repositoryUri"]
90145
if not "revisionId" in vcp:
91-
click.echo(f"The database's version control provenance misses the 'revisionId' property!", err=True)
146+
click.echo(
147+
f"The database's version control provenance misses the 'revisionId' property!",
148+
err=True,
149+
)
92150
exit(1)
93151
revision_id = vcp["revisionId"]
94152
except KeyError:
95-
click.echo(f"The database does not have any version control provenance property.", err=True)
153+
click.echo(
154+
f"The database does not have any version control provenance property.",
155+
err=True,
156+
)
96157
exit(1)
97158
except InvalidCodeQLDatabase as e:
98159
click.echo(e, err=True)
@@ -105,7 +166,6 @@ def sarif_add_provenance(from_database: bool, repository_uri: str, revision_id:
105166
click.echo(f"Unable to process invalid Sarif file with reason: {e}")
106167
exit(1)
107168

108-
109-
169+
110170
if __name__ == "__main__":
111-
cli()
171+
cli()

codeql_postproc/helpers/codeql.py

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
from tempfile import TemporaryDirectory
77
from jsonpointer import JsonPointer
88

9+
910
class InvalidCodeQLDatabase(Exception):
1011
pass
1112

13+
1214
class CodeQLDatabase:
1315
def __init__(self, database: Path) -> None:
1416
if not database.exists():
@@ -20,24 +22,35 @@ def __init__(self, database: Path) -> None:
2022
with db_metadata.open() as fd:
2123
database_info = yaml.safe_load(fd)
2224
else:
23-
raise InvalidCodeQLDatabase("Invalid database, missing 'codeql-database.yml'!")
25+
raise InvalidCodeQLDatabase(
26+
"Invalid database, missing 'codeql-database.yml'!"
27+
)
2428
elif is_zipfile(database):
2529
with ZipFile(database) as fd:
30+
2631
def is_db_metadata(zi: ZipInfo) -> bool:
2732
path_parts = zi.filename.split("/")
28-
return len(path_parts) == 2 and path_parts[1] == "codeql-database.yml"
33+
return (
34+
len(path_parts) == 2 and path_parts[1] == "codeql-database.yml"
35+
)
2936

3037
db_metadata_candidates = list(filter(is_db_metadata, fd.infolist()))
3138
if len(db_metadata_candidates) == 0:
32-
raise InvalidCodeQLDatabase("Invalid database, missing 'codeql-database.yml'!")
39+
raise InvalidCodeQLDatabase(
40+
"Invalid database, missing 'codeql-database.yml'!"
41+
)
3342
elif len(db_metadata_candidates) > 1:
34-
raise InvalidCodeQLDatabase("Invalid database, found multiple 'codeql-database.yml'!")
43+
raise InvalidCodeQLDatabase(
44+
"Invalid database, found multiple 'codeql-database.yml'!"
45+
)
3546
else:
3647
self.db_metadata_filename = db_metadata_candidates[0].filename
3748
database_info = yaml.safe_load(fd.read(self.db_metadata_filename))
38-
49+
3950
else:
40-
raise InvalidCodeQLDatabase("Expected a database directory or database zip archive!")
51+
raise InvalidCodeQLDatabase(
52+
"Expected a database directory or database zip archive!"
53+
)
4154

4255
self.database_info = database_info
4356
self.database = database
@@ -54,19 +67,21 @@ def update_or_set_props(database: Path, **kwargs: Any):
5467
with user_properties.open("r") as fd:
5568
existing_props = yaml.safe_load(fd)
5669
if existing_props and not isinstance(existing_props, dict):
57-
raise InvalidCodeQLDatabase("The 'user-properties.yml' is not a YAML dictionary!")
70+
raise InvalidCodeQLDatabase(
71+
"The 'user-properties.yml' is not a YAML dictionary!"
72+
)
5873
else:
59-
props = existing_props | props
74+
props = existing_props | props
6075
with user_properties.open("w") as fd:
6176
fd.write(yaml.dump(props))
6277

6378
if self.database.is_dir():
64-
update_or_set_props(self.database, **kwargs)
79+
update_or_set_props(self.database, **kwargs)
6580
else:
6681
with TemporaryDirectory() as tmp_dir:
6782
with ZipFile(str(self.database), mode="r") as fd:
6883
fd.extractall(tmp_dir)
69-
database = Path(tmp_dir) / self.db_metadata_filename.split('/')[0]
84+
database = Path(tmp_dir) / self.db_metadata_filename.split("/")[0]
7085
update_or_set_props(database, **kwargs)
7186
with ZipFile(self.database, mode="w") as fd:
7287
for f in database.glob("**/*"):
@@ -79,11 +94,12 @@ def __translate_key(self, key: str) -> JsonPointer:
7994
if not path.startswith("/"):
8095
path = "/" + path
8196
return JsonPointer(path)
82-
8397

8498
def get_property(self, key: str) -> Any:
8599

86-
database_property = self.__translate_key(key).get(self.database_info, default=None)
100+
database_property = self.__translate_key(key).get(
101+
self.database_info, default=None
102+
)
87103
if database_property is not None:
88104
return database_property
89105

@@ -94,14 +110,19 @@ def get_property(self, key: str) -> Any:
94110
with user_properties_path.open() as fd:
95111
user_properties = yaml.safe_load(fd)
96112
else:
113+
97114
def is_user_property_file(zi: ZipInfo) -> bool:
98115
return zi.filename.endswith("user-properties.yml")
116+
99117
with ZipFile(str(self.database)) as fd:
100-
user_property_candidates = list(filter(is_user_property_file, fd.infolist()))
118+
user_property_candidates = list(
119+
filter(is_user_property_file, fd.infolist())
120+
)
101121
if len(user_property_candidates) == 0:
102122
raise InvalidCodeQLDatabase("Found no 'user-properties.yml' files!")
103123
if len(user_property_candidates) > 1:
104-
raise InvalidCodeQLDatabase("Found multiple 'user-properties.yml' files!")
124+
raise InvalidCodeQLDatabase(
125+
"Found multiple 'user-properties.yml' files!"
126+
)
105127
user_properties = yaml.safe_load(fd.read(user_property_candidates[0]))
106128
return self.__translate_key(key).get(user_properties, default=None)
107-

codeql_postproc/helpers/sarif.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,51 @@
44
import jsonschema
55
import jsonschema.exceptions
66

7+
78
class InvalidSarif(Exception):
89
pass
910

11+
1012
class Sarif:
1113
def __init__(self, path: Path) -> None:
1214
self.path = path
1315

14-
schema_path = Path(__file__).parent.parent / "schemas" / "sarif-schema-2.1.0.json"
16+
schema_path = (
17+
Path(__file__).parent.parent / "schemas" / "sarif-schema-2.1.0.json"
18+
)
1519
self.schema = json.loads(schema_path.read_text())
16-
20+
1721
try:
1822
self.content: Dict[str, Any] = json.loads(self.path.read_text())
1923
jsonschema.validate(self.content, self.schema)
2024
except json.decoder.JSONDecodeError:
2125
raise InvalidSarif("Invalid JSON file!")
2226

23-
def add_version_control_provenance(self, repository_url: str, revision_id: str) -> None:
27+
def add_version_control_provenance(
28+
self, repository_url: str, revision_id: str
29+
) -> None:
2430
if not "runs" in self.content or len(self.content["runs"]) == 0:
2531
raise InvalidSarif("Missing or no run objects in 'runs' property!")
2632

2733
for run in self.content["runs"]:
2834
if "versionControlProvenance" in run:
2935
vcp: Any = run["versionControlProvenance"]
3036
if not isinstance(vcp, list):
31-
raise InvalidSarif("The 'versionControlProvenance' property is not an array!")
37+
raise InvalidSarif(
38+
"The 'versionControlProvenance' property is not an array!"
39+
)
3240
else:
3341
run["versionControlProvenance"] = []
34-
35-
cast(List[Dict[str, str]], run["versionControlProvenance"]).append({
36-
"repositoryUri": repository_url,
37-
"revisionId": revision_id
38-
})
42+
43+
cast(List[Dict[str, str]], run["versionControlProvenance"]).append(
44+
{"repositoryUri": repository_url, "revisionId": revision_id}
45+
)
3946

4047
try:
4148
jsonschema.validate(self.content, self.schema)
4249
except jsonschema.exceptions.ValidationError as e:
43-
raise InvalidSarif(f"Adding the version control provenance information results in an invalid Sarif file because {e.message}!")
50+
raise InvalidSarif(
51+
f"Adding the version control provenance information results in an invalid Sarif file because {e.message}!"
52+
)
4453
with self.path.open(mode="w") as fd:
4554
json.dump(self.content, fd)
46-

0 commit comments

Comments
 (0)