Skip to content

Commit 1c1ccda

Browse files
authored
Merge pull request #19418 from github/redsun82/improve-codegen-codeql-requirement-message
Codegen: make missing `codeql` error clearer
2 parents 7106475 + 9958cc7 commit 1c1ccda

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

misc/codegen/generators/qlgen.py

+10
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import logging
2525
import pathlib
2626
import re
27+
import shutil
2728
import subprocess
2829
import typing
2930
import itertools
@@ -257,6 +258,15 @@ def format(codeql, files):
257258
if not ql_files:
258259
return
259260
format_cmd = [codeql, "query", "format", "--in-place", "--"] + ql_files
261+
if "/" in codeql or "\\" in codeql:
262+
if not pathlib.Path(codeql).exists():
263+
raise FormatError(f"Provided CodeQL binary `{codeql}` does not exist")
264+
else:
265+
codeql_path = shutil.which(codeql)
266+
if not codeql_path:
267+
raise FormatError(
268+
f"`{codeql}` not found in PATH. Either install it, or pass `-- --codeql-binary` with a full path")
269+
codeql = codeql_path
260270
res = subprocess.run(format_cmd, stderr=subprocess.PIPE, text=True)
261271
if res.returncode:
262272
for line in res.stderr.splitlines():

misc/codegen/test/test_qlgen.py

+21-3
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ def qlgen_opts(opts):
5252
opts.ql_format = True
5353
opts.root_dir = paths.root_dir
5454
opts.force = False
55+
opts.codeql_binary = "./my_fake_codeql"
56+
pathlib.Path(opts.codeql_binary).touch()
5557
return opts
5658

5759

@@ -499,7 +501,6 @@ def test_class_dir_imports(generate_import_list):
499501

500502

501503
def test_format(opts, generate, render_manager, run_mock):
502-
opts.codeql_binary = "my_fake_codeql"
503504
run_mock.return_value.stderr = "some\nlines\n"
504505
render_manager.written = [
505506
pathlib.Path("x", "foo.ql"),
@@ -508,13 +509,12 @@ def test_format(opts, generate, render_manager, run_mock):
508509
]
509510
generate([schema.Class('A')])
510511
assert run_mock.mock_calls == [
511-
mock.call(["my_fake_codeql", "query", "format", "--in-place", "--", "x/foo.ql", "bar.qll"],
512+
mock.call([opts.codeql_binary, "query", "format", "--in-place", "--", "x/foo.ql", "bar.qll"],
512513
stderr=subprocess.PIPE, text=True),
513514
]
514515

515516

516517
def test_format_error(opts, generate, render_manager, run_mock):
517-
opts.codeql_binary = "my_fake_codeql"
518518
run_mock.return_value.stderr = "some\nlines\n"
519519
run_mock.return_value.returncode = 1
520520
render_manager.written = [
@@ -526,6 +526,24 @@ def test_format_error(opts, generate, render_manager, run_mock):
526526
generate([schema.Class('A')])
527527

528528

529+
def test_format_no_codeql(opts, generate, render_manager, run_mock):
530+
pathlib.Path(opts.codeql_binary).unlink()
531+
render_manager.written = [
532+
pathlib.Path("bar.qll"),
533+
]
534+
with pytest.raises(qlgen.FormatError):
535+
generate([schema.Class('A')])
536+
537+
538+
def test_format_no_codeql_in_path(opts, generate, render_manager, run_mock):
539+
opts.codeql_binary = "my_fake_codeql"
540+
render_manager.written = [
541+
pathlib.Path("bar.qll"),
542+
]
543+
with pytest.raises(qlgen.FormatError):
544+
generate([schema.Class('A')])
545+
546+
529547
@pytest.mark.parametrize("force", [False, True])
530548
def test_manage_parameters(opts, generate, renderer, force):
531549
opts.force = force

0 commit comments

Comments
 (0)