Skip to content

Commit 53ae9ee

Browse files
committed
json: add support for 'arguments' [GH-3]
Arguments is now used by Bear, intercept-build and clang's -MJ flag.
1 parent 20a929a commit 53ae9ee

File tree

6 files changed

+107
-8
lines changed

6 files changed

+107
-8
lines changed

compdb/backend/json.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,17 @@ def get_all_files(self):
3333
os.path.join(entry['directory'], entry['file']))
3434

3535
def get_all_compile_commands(self):
36-
# PERFORMANCE: I think shlex is inherently slow,
37-
# something performing better may be necessary
3836
return map(self._dict_to_compile_command, self._data)
3937

4038
@staticmethod
4139
def _dict_to_compile_command(d):
42-
return CompileCommand(d['directory'], d['file'],
43-
shlex.split(d['command']))
40+
if 'arguments' in d:
41+
arguments = d['arguments']
42+
else:
43+
# PERFORMANCE: I think shlex is inherently slow,
44+
# something performing better may be necessary
45+
arguments = shlex.split(d['command'])
46+
return CompileCommand(d['directory'], d['file'], arguments)
4447

4548
@property
4649
def _data(self):

compdb/models.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,27 @@ def __init__(self, directory, file, arguments):
2020
self.file = file
2121
self.arguments = arguments
2222

23+
@property
24+
def normfile(self):
25+
return os.path.normpath(os.path.join(self.directory, self.file))
26+
2327
def __repr__(self):
2428
return "{{directory: {},\nfile: {},\n arguments: {}}}\n\n".format(
2529
self.directory, self.file, pprint.pformat(self.arguments))
2630

2731
def __str__(self):
2832
return self.__repr__()
2933

30-
@property
31-
def normfile(self):
32-
return os.path.normpath(os.path.join(self.directory, self.file))
34+
def _as_tuple(self):
35+
return (self.directory, self.file, self.arguments)
36+
37+
def __eq__(self, other):
38+
if isinstance(other, self.__class__):
39+
return self._as_tuple() == other._as_tuple()
40+
return NotImplemented
41+
42+
def __ne__(self, other):
43+
return not self == other
3344

3445

3546
class CompilationDatabaseInterface(object):
@@ -53,7 +64,10 @@ def get_compile_commands(self, filepath):
5364
raise compdb.NotImplementedError
5465

5566
def get_all_files(self):
56-
"""Return an iterable of path strings."""
67+
"""Return an iterable of path strings.
68+
69+
A same path can be returned multiple times,
70+
store the result in a set if uniqueness is required."""
5771
raise compdb.NotImplementedError
5872

5973
def get_all_compile_commands(self):

tests/unit/backend/__init__.py

Whitespace-only changes.

tests/unit/backend/test_json.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from __future__ import print_function, unicode_literals, absolute_import
2+
3+
import os
4+
import unittest
5+
6+
from compdb.backend.json import JSONCompilationDatabase
7+
from compdb.models import CompileCommand
8+
9+
10+
class JSONCompilationDatabaseTest(unittest.TestCase):
11+
LOCAL_PATH = os.path.abspath(os.path.dirname(__file__))
12+
TEST_DIR = os.path.join(LOCAL_PATH, 'test_json_data')
13+
14+
def setUp(self):
15+
self.db = JSONCompilationDatabase.probe_directory(self.TEST_DIR)
16+
17+
def tearDown(self):
18+
self.db = None
19+
20+
def test_get_compile_commands(self):
21+
a_commands = list(self.db.get_compile_commands("/tmp/a.cpp"))
22+
self.assertEqual(len(a_commands), 1)
23+
self.assertEqual(a_commands[0],
24+
CompileCommand("/tmp/", "/tmp/a.cpp",
25+
["clang", "-DA=1"]))
26+
b_commands = list(self.db.get_compile_commands("/tmp/b.cpp"))
27+
self.assertEqual(len(b_commands), 2)
28+
self.assertEqual(b_commands[0],
29+
CompileCommand("/tmp/", "/tmp/b.cpp",
30+
["clang", "-DB=1"]))
31+
self.assertEqual(b_commands[1],
32+
CompileCommand("/tmp/", "/tmp/b.cpp",
33+
["clang", "-DB=2"]))
34+
35+
def test_get_all_files(self):
36+
files = list(sorted(self.db.get_all_files()))
37+
self.assertEqual(
38+
files,
39+
[
40+
'/tmp/a.cpp',
41+
'/tmp/b.cpp',
42+
# note: it's debatable whether duplicates should be present
43+
'/tmp/b.cpp',
44+
])
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[
2+
{
3+
"directory": "/tmp/",
4+
"command": "clang -DA=1",
5+
"file": "/tmp/a.cpp"
6+
},
7+
{
8+
"directory": "/tmp/",
9+
"arguments": [ "clang", "-DB=1" ],
10+
"file": "/tmp/b.cpp"
11+
},
12+
{
13+
"directory": "/tmp/",
14+
"arguments": [ "clang", "-DB=2" ],
15+
"file": "/tmp/b.cpp"
16+
}
17+
]

tests/unit/test_models.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from __future__ import print_function, unicode_literals, absolute_import
2+
3+
import unittest
4+
5+
from compdb.models import CompileCommand
6+
7+
8+
class CompileCommandTest(unittest.TestCase):
9+
def test_comparable(self):
10+
a1 = CompileCommand("/", "a.c", ["cc"])
11+
a2 = CompileCommand("/", "a.c", ["cc"])
12+
b = CompileCommand("/", "b.c", ["cc"])
13+
self.assertTrue(a1 == a2)
14+
self.assertFalse(a1 == b)
15+
self.assertTrue(a1 != b)
16+
self.assertFalse(a1 != a2)
17+
self.assertEqual(a1, a2)
18+
19+
20+
if __name__ == "__main__":
21+
unittest.main()

0 commit comments

Comments
 (0)