Skip to content

Commit

Permalink
Add an error message for failures of analyzing dependencies
Browse files Browse the repository at this point in the history
see #259 and #260
  • Loading branch information
kmyk committed May 21, 2020
1 parent 0ced5d5 commit 85a6f9a
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 1 deletion.
8 changes: 7 additions & 1 deletion onlinejudge_verify/languages/cplusplus.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import shlex
import shutil
import subprocess
import sys
import tempfile
from logging import getLogger
from typing import *
Expand Down Expand Up @@ -48,7 +49,12 @@ def _cplusplus_list_depending_files(path: pathlib.Path, *, CXX: pathlib.Path, jo
with tempfile.TemporaryDirectory() as temp_dir:
temp_file = pathlib.Path(temp_dir) / 'dependencies.txt'
command = [str(CXX), *shlex.split(joined_CXXFLAGS), '-MD', '-MF', str(temp_file), '-MM', str(path)]
subprocess.check_output(command)
try:
subprocess.check_call(command)
except subprocess.CalledProcessError:
logger.error("failed to analyze dependencies with %s: %s (hint: Please check #include directives of the file and its dependencies. The paths must exist, must not contain '\\', and must be case-sensitive.)", CXX, str(path))
print(f'::warning file={str(path)}::failed to analyze dependencies', file=sys.stderr)
raise
with open(temp_file, 'rb') as fp:
data = fp.read()
makefile_rule = shlex.split(data.decode().replace('\\\n', ''), posix=not (is_windows))
Expand Down
55 changes: 55 additions & 0 deletions tests/test_cplusplus.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import platform
import textwrap
import unittest
from typing import *

import onlinejudge_verify.languages.cplusplus as cplusplus
import tests.utils


class TestCPlusPlusListDependencies(unittest.TestCase):
def test_success(self) -> None:
files = {
'main.cpp': textwrap.dedent("""\
#include "included.hpp"
""").encode(),
'included.hpp': textwrap.dedent("""\
int main() {}
""").encode(),
}

with tests.utils.load_files(files) as tempdir:
with tests.utils.chdir(tempdir):
expected = sorted([tempdir / 'main.cpp', tempdir / 'included.hpp'])
actual = sorted(cplusplus.CPlusPlusLanguage().list_dependencies(tempdir / 'main.cpp', basedir=tempdir))
self.assertEqual(actual, expected)

@unittest.skipIf(platform.system() == 'Windows', "The path separator should be '/' for this test.")
def test_failure_with_backslash(self) -> None:
files = {
'main.cpp': textwrap.dedent("""\
#include ".\included.hpp"
""").encode(),
'included.hpp': textwrap.dedent("""\
int main() {}
""").encode(),
}

with tests.utils.load_files(files={}) as tempdir:
with tests.utils.chdir(tempdir):
self.assertRaises(Exception, lambda: cplusplus.CPlusPlusLanguage().list_dependencies(tempdir / 'main.cpp', basedir=tempdir))

@unittest.skipIf(platform.system() in ('Windows', 'Darwin'), "The filesystem should be case-sensitive for this test.")
def test_failure_with_case_insensitive(self) -> None:
files = {
'main.cpp': textwrap.dedent("""\
#include "INCLUDED.HPP"
""").encode(),
'included.hpp': textwrap.dedent("""\
int main() {}
""").encode(),
}

with tests.utils.load_files(files={}) as tempdir:
with tests.utils.chdir(tempdir):
self.assertRaises(Exception, lambda: cplusplus.CPlusPlusLanguage().list_dependencies(tempdir / 'main.cpp', basedir=tempdir))

0 comments on commit 85a6f9a

Please sign in to comment.