feat(tools): add esp-clangd tool (version esp-21.1.3_20260304)

This commit is contained in:
Alexey Gerenkov
2026-05-07 17:42:38 +03:00
parent 97e6873e34
commit 6b5a00d4eb
4 changed files with 134 additions and 15 deletions
+56 -15
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
# SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2019-2026 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import json
import os
@@ -57,6 +57,8 @@ RISCV_ESP_GDB = 'riscv32-esp-elf-gdb'
ESP_ROM_ELFS = 'esp-rom-elfs'
QEMU_RISCV = 'qemu-riscv32'
QEMU_XTENSA = 'qemu-xtensa'
CLANGD = 'esp-clangd'
CLANGD_ARCHIVE = 'clangd'
# Win tools
CMAKE = 'cmake'
NINJA = 'ninja'
@@ -89,6 +91,7 @@ RISCV_ESP_GDB_VERSION = version_dict[RISCV_ESP_GDB]
ESP_ROM_ELFS_VERSION = version_dict[ESP_ROM_ELFS]
QEMU_RISCV_VERSION = version_dict[QEMU_RISCV]
QEMU_XTENSA_VERSION = version_dict[QEMU_XTENSA]
CLANGD_VERSION = version_dict[CLANGD]
# Win tools
CMAKE_VERSION = version_dict[CMAKE]
NINJA_VERSION = version_dict[NINJA]
@@ -377,8 +380,10 @@ class TestUsageUnix(TestUsage):
self.assertIn(f'- {RISCV_ELF_VERSION} (recommended)', output)
self.assertIn(f'* {XTENSA_ELF}:', output)
self.assertIn(f'- {XTENSA_ELF_VERSION} (recommended)', output)
self.assertIn(f'* {CLANGD}:', output)
self.assertIn(f'- {CLANGD_VERSION} (recommended)', output)
required_tools_installed = 7
required_tools_installed = 8
output = self.run_idf_tools_with_action(['install'])
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
self.assert_tool_installed(output, RISCV_ELF, RISCV_ELF_VERSION, RISCV_ELF_ARCHIVE_PATTERN)
@@ -387,6 +392,7 @@ class TestUsageUnix(TestUsage):
self.assert_tool_installed(output, XTENSA_ESP_GDB, XTENSA_ESP_GDB_VERSION)
self.assert_tool_installed(output, RISCV_ESP_GDB, RISCV_ESP_GDB_VERSION)
self.assert_tool_installed(output, ESP_ROM_ELFS, ESP_ROM_ELFS_VERSION)
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
self.assertEqual(required_tools_installed, output.count('Done'))
@@ -399,6 +405,7 @@ class TestUsageUnix(TestUsage):
XTENSA_ESP_GDB_VERSION,
RISCV_ESP_GDB_VERSION,
ESP_ROM_ELFS_VERSION,
CLANGD_VERSION,
]:
self.assertIn('version installed in tools directory: ' + tool_version, output)
@@ -416,6 +423,7 @@ class TestUsageUnix(TestUsage):
output,
)
self.assertIn(f'{self.temp_tools_dir}/tools/esp-rom-elfs/{ESP_ROM_ELFS_VERSION}/', output)
self.assertIn(f'{self.temp_tools_dir}/tools/esp-clangd/{CLANGD_VERSION}/esp-clangd/bin', output)
output = self.run_idf_tools_with_action(['list', '--outdated'])
self.assertEqual('', output)
@@ -443,7 +451,7 @@ class TestUsageUnix(TestUsage):
self.assertIn((f'{XTENSA_ELF}: version {XTENSA_ELF_VERSION} is outdated by {new_version}'), output)
def test_tools_for_esp32(self):
required_tools_installed = 5
required_tools_installed = 6
output = self.run_idf_tools_with_action(['install', '--targets=esp32'])
self.assert_tool_installed(output, XTENSA_ELF, XTENSA_ELF_VERSION, XTENSA_ELF_ARCHIVE_PATTERN)
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
@@ -452,6 +460,7 @@ class TestUsageUnix(TestUsage):
self.assert_tool_not_installed(output, RISCV_ELF, RISCV_ELF_VERSION, RISCV_ELF_ARCHIVE_PATTERN)
self.assert_tool_not_installed(output, RISCV_ESP_GDB, RISCV_ESP_GDB_VERSION)
self.assert_tool_installed(output, ESP_ROM_ELFS, ESP_ROM_ELFS_VERSION)
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
self.assertEqual(required_tools_installed, output.count('Done'))
@@ -462,6 +471,7 @@ class TestUsageUnix(TestUsage):
XTENSA_ELF_VERSION,
XTENSA_ESP_GDB_VERSION,
ESP_ROM_ELFS_VERSION,
CLANGD_VERSION,
]:
self.assertIn('version installed in tools directory: ' + tool_version, output)
@@ -479,9 +489,10 @@ class TestUsageUnix(TestUsage):
output,
)
self.assertIn(f'{self.temp_tools_dir}/tools/esp-rom-elfs/{ESP_ROM_ELFS_VERSION}/', output)
self.assertIn(f'{self.temp_tools_dir}/tools/esp-clangd/{CLANGD_VERSION}/esp-clangd/bin', output)
def test_tools_for_esp32c3(self):
required_tools_installed = 4
required_tools_installed = 5
output = self.run_idf_tools_with_action(['install', '--targets=esp32c3'])
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
self.assert_tool_installed(output, RISCV_ELF, RISCV_ELF_VERSION, RISCV_ELF_ARCHIVE_PATTERN)
@@ -490,6 +501,7 @@ class TestUsageUnix(TestUsage):
self.assert_tool_not_installed(output, ESP32ULP, ESP32ULP_VERSION)
self.assert_tool_not_installed(output, XTENSA_ESP_GDB, XTENSA_ESP_GDB_VERSION)
self.assert_tool_installed(output, ESP_ROM_ELFS, ESP_ROM_ELFS_VERSION)
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
self.assertEqual(required_tools_installed, output.count('Done'))
@@ -507,9 +519,10 @@ class TestUsageUnix(TestUsage):
output,
)
self.assertIn(f'{self.temp_tools_dir}/tools/esp-rom-elfs/{ESP_ROM_ELFS_VERSION}/', output)
self.assertIn(f'{self.temp_tools_dir}/tools/esp-clangd/{CLANGD_VERSION}/esp-clangd/bin', output)
def test_tools_for_esp32s2(self):
required_tools_installed = 6
required_tools_installed = 7
output = self.run_idf_tools_with_action(['install', '--targets=esp32s2'])
self.assert_tool_installed(output, XTENSA_ELF, XTENSA_ELF_VERSION, XTENSA_ELF_ARCHIVE_PATTERN)
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
@@ -518,6 +531,7 @@ class TestUsageUnix(TestUsage):
self.assert_tool_installed(output, XTENSA_ESP_GDB, XTENSA_ESP_GDB_VERSION)
self.assert_tool_installed(output, ESP_ROM_ELFS, ESP_ROM_ELFS_VERSION)
self.assert_tool_not_installed(output, RISCV_ESP_GDB, RISCV_ESP_GDB_VERSION)
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
self.assertEqual(required_tools_installed, output.count('Done'))
@@ -539,9 +553,10 @@ class TestUsageUnix(TestUsage):
output,
)
self.assertIn(f'{self.temp_tools_dir}/tools/esp-rom-elfs/{ESP_ROM_ELFS_VERSION}/', output)
self.assertIn(f'{self.temp_tools_dir}/tools/esp-clangd/{CLANGD_VERSION}/esp-clangd/bin', output)
def test_tools_for_esp32s3(self):
required_tools_installed = 6
required_tools_installed = 7
output = self.run_idf_tools_with_action(['install', '--targets=esp32s3'])
self.assert_tool_installed(output, XTENSA_ELF, XTENSA_ELF_VERSION, XTENSA_ELF_ARCHIVE_PATTERN)
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
@@ -550,6 +565,7 @@ class TestUsageUnix(TestUsage):
self.assert_tool_installed(output, XTENSA_ESP_GDB, XTENSA_ESP_GDB_VERSION)
self.assert_tool_installed(output, ESP_ROM_ELFS, ESP_ROM_ELFS_VERSION)
self.assert_tool_not_installed(output, RISCV_ESP_GDB, RISCV_ESP_GDB_VERSION)
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
self.assertEqual(required_tools_installed, output.count('Done'))
@@ -560,6 +576,7 @@ class TestUsageUnix(TestUsage):
XTENSA_ESP_GDB_VERSION,
RISCV_ESP_GDB_VERSION,
ESP_ROM_ELFS_VERSION,
CLANGD_VERSION,
]:
self.assertIn('version installed in tools directory: ' + tool_version, output)
@@ -577,9 +594,10 @@ class TestUsageUnix(TestUsage):
output,
)
self.assertIn(f'{self.temp_tools_dir}/tools/esp-rom-elfs/{ESP_ROM_ELFS_VERSION}/', output)
self.assertIn(f'{self.temp_tools_dir}/tools/esp-clangd/{CLANGD_VERSION}/esp-clangd/bin', output)
def test_tools_for_esp32p4(self):
required_tools_installed = 4
required_tools_installed = 5
output = self.run_idf_tools_with_action(['install', '--targets=esp32p4'])
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
self.assert_tool_installed(output, RISCV_ELF, RISCV_ELF_VERSION, RISCV_ELF_ARCHIVE_PATTERN)
@@ -588,6 +606,7 @@ class TestUsageUnix(TestUsage):
self.assert_tool_not_installed(output, XTENSA_ELF, XTENSA_ELF_VERSION, XTENSA_ELF_ARCHIVE_PATTERN)
self.assert_tool_not_installed(output, ESP32ULP, ESP32ULP_VERSION)
self.assert_tool_not_installed(output, XTENSA_ESP_GDB, XTENSA_ESP_GDB_VERSION)
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
self.assertEqual(required_tools_installed, output.count('Done'))
output = self.run_idf_tools_with_action(['check'])
@@ -614,10 +633,11 @@ class TestUsageUnix(TestUsage):
os.path.join(self.temp_tools_dir, 'tools', XTENSA_ESP_GDB, XTENSA_ESP_GDB_VERSION, XTENSA_ESP_GDB, 'bin'),
output,
)
self.assertIn(os.path.join(self.temp_tools_dir, 'tools', CLANGD, CLANGD_VERSION, CLANGD, 'bin'), output)
# a different test for qemu because of "on_request"
def test_tools_for_qemu_with_required(self):
required_tools_installed = 9
required_tools_installed = 10
output = self.run_idf_tools_with_action(['install', 'required', 'qemu-xtensa', 'qemu-riscv32'])
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
self.assert_tool_installed(output, RISCV_ELF, RISCV_ELF_VERSION, RISCV_ELF_ARCHIVE_PATTERN)
@@ -628,6 +648,7 @@ class TestUsageUnix(TestUsage):
self.assert_tool_installed(output, ESP_ROM_ELFS, ESP_ROM_ELFS_VERSION)
self.assert_tool_installed(output, QEMU_RISCV, QEMU_RISCV_VERSION)
self.assert_tool_installed(output, QEMU_XTENSA, QEMU_XTENSA_VERSION)
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
self.assertEqual(required_tools_installed, output.count('Done'))
@@ -652,7 +673,8 @@ class TestUsageWin(TestUsage):
self.assertIn(f'- {RISCV_ELF_VERSION} (recommended)', output)
self.assertIn(f'* {XTENSA_ELF}:', output)
self.assertIn(f'- {XTENSA_ELF_VERSION} (recommended)', output)
self.assertIn(f'* {CLANGD}:', output)
self.assertIn(f'- {CLANGD_VERSION} (recommended)', output)
required_tools_installed = 12
output = self.run_idf_tools_with_action(['install'])
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
@@ -667,6 +689,7 @@ class TestUsageWin(TestUsage):
self.assert_tool_installed(output, IDF_EXE, IDF_EXE_VERSION)
self.assert_tool_installed(output, CCACHE, CCACHE_VERSION)
self.assert_tool_installed(output, DFU_UTIL, DFU_UTIL_VERSION)
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
self.assertEqual(required_tools_installed, output.count('Done'))
@@ -684,6 +707,7 @@ class TestUsageWin(TestUsage):
IDF_EXE_VERSION,
CCACHE_VERSION,
DFU_UTIL_VERSION,
CLANGD_VERSION,
]:
self.assertIn('version installed in tools directory: ' + tool_version, output)
@@ -724,6 +748,7 @@ class TestUsageWin(TestUsage):
self.assertIn(
os.path.join(self.temp_tools_dir, 'tools', DFU_UTIL, DFU_UTIL_VERSION, 'dfu-util-0.11-win64'), output
)
self.assertIn(os.path.join(self.temp_tools_dir, 'tools', CLANGD, CLANGD_VERSION, CLANGD, 'bin'), output)
output = self.run_idf_tools_with_action(['list', '--outdated'])
self.assertEqual('', output)
@@ -751,7 +776,7 @@ class TestUsageWin(TestUsage):
self.assertIn((f'{XTENSA_ELF}: version {XTENSA_ELF_VERSION} is outdated by {new_version}'), output)
def test_tools_for_esp32_win(self):
required_tools_installed = 9
required_tools_installed = 10
output = self.run_idf_tools_with_action(['install', '--targets=esp32'])
self.assert_tool_installed(output, XTENSA_ELF, XTENSA_ELF_VERSION, XTENSA_ELF_ARCHIVE_PATTERN)
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
@@ -765,6 +790,7 @@ class TestUsageWin(TestUsage):
self.assert_tool_installed(output, IDF_EXE, IDF_EXE_VERSION)
self.assert_tool_installed(output, CCACHE, CCACHE_VERSION)
self.assert_tool_not_installed(output, DFU_UTIL, DFU_UTIL_VERSION)
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
self.assertEqual(required_tools_installed, output.count('Done'))
@@ -779,6 +805,7 @@ class TestUsageWin(TestUsage):
NINJA_VERSION,
IDF_EXE_VERSION,
CCACHE_VERSION,
CLANGD_VERSION,
]:
self.assertIn('version installed in tools directory: ' + tool_version, output)
self.assertNotIn('version installed in tools directory: ' + DFU_UTIL_VERSION, output)
@@ -828,9 +855,10 @@ class TestUsageWin(TestUsage):
self.assertNotIn(
os.path.join(self.temp_tools_dir, 'tools', DFU_UTIL, DFU_UTIL_VERSION, 'dfu-util-0.11-win64'), output
)
self.assertNotIn(os.path.join(self.temp_tools_dir, 'tools', CLANGD, CLANGD_VERSION, CLANGD, 'bin'), output)
def test_tools_for_esp32c3_win(self):
required_tools_installed = 8
required_tools_installed = 9
output = self.run_idf_tools_with_action(['install', '--targets=esp32c3'])
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
self.assert_tool_installed(output, RISCV_ELF, RISCV_ELF_VERSION, RISCV_ELF_ARCHIVE_PATTERN)
@@ -844,6 +872,7 @@ class TestUsageWin(TestUsage):
self.assert_tool_installed(output, IDF_EXE, IDF_EXE_VERSION)
self.assert_tool_installed(output, CCACHE, CCACHE_VERSION)
self.assert_tool_not_installed(output, DFU_UTIL, DFU_UTIL_VERSION)
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
self.assertEqual(required_tools_installed, output.count('Done'))
@@ -857,6 +886,7 @@ class TestUsageWin(TestUsage):
NINJA_VERSION,
IDF_EXE_VERSION,
CCACHE_VERSION,
CLANGD_VERSION,
]:
self.assertIn('version installed in tools directory: ' + tool_version, output)
self.assertNotIn('version installed in tools directory: ' + DFU_UTIL_VERSION, output)
@@ -900,9 +930,10 @@ class TestUsageWin(TestUsage):
self.assertNotIn(
os.path.join(self.temp_tools_dir, 'tools', DFU_UTIL, DFU_UTIL_VERSION, 'dfu-util-0.11-win64'), output
)
self.assertNotIn(os.path.join(self.temp_tools_dir, 'tools', CLANGD, CLANGD_VERSION, CLANGD, 'bin'), output)
def test_tools_for_esp32s2_win(self):
required_tools_installed = 11
required_tools_installed = 12
output = self.run_idf_tools_with_action(['install', '--targets=esp32s2'])
self.assert_tool_installed(output, XTENSA_ELF, XTENSA_ELF_VERSION, XTENSA_ELF_ARCHIVE_PATTERN)
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
@@ -916,6 +947,7 @@ class TestUsageWin(TestUsage):
self.assert_tool_installed(output, IDF_EXE, IDF_EXE_VERSION)
self.assert_tool_installed(output, CCACHE, CCACHE_VERSION)
self.assert_tool_installed(output, DFU_UTIL, DFU_UTIL_VERSION)
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
self.assertEqual(required_tools_installed, output.count('Done'))
@@ -930,6 +962,7 @@ class TestUsageWin(TestUsage):
NINJA_VERSION,
IDF_EXE_VERSION,
CCACHE_VERSION,
CLANGD_VERSION,
]:
self.assertIn('version installed in tools directory: ' + tool_version, output)
@@ -978,9 +1011,10 @@ class TestUsageWin(TestUsage):
self.assertIn(
os.path.join(self.temp_tools_dir, 'tools', DFU_UTIL, DFU_UTIL_VERSION, 'dfu-util-0.11-win64'), output
)
self.assertIn(os.path.join(self.temp_tools_dir, 'tools', CLANGD, CLANGD_VERSION, CLANGD, 'bin'), output)
def test_tools_for_esp32s3_win(self):
required_tools_installed = 11
required_tools_installed = 12
output = self.run_idf_tools_with_action(['install', '--targets=esp32s3'])
print(output)
self.assert_tool_installed(output, XTENSA_ELF, XTENSA_ELF_VERSION, XTENSA_ELF_ARCHIVE_PATTERN)
@@ -995,6 +1029,7 @@ class TestUsageWin(TestUsage):
self.assert_tool_installed(output, IDF_EXE, IDF_EXE_VERSION)
self.assert_tool_installed(output, CCACHE, CCACHE_VERSION)
self.assert_tool_installed(output, DFU_UTIL, DFU_UTIL_VERSION)
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
self.assertEqual(required_tools_installed, output.count('Done'))
@@ -1010,6 +1045,7 @@ class TestUsageWin(TestUsage):
NINJA_VERSION,
IDF_EXE_VERSION,
CCACHE_VERSION,
CLANGD_VERSION,
]:
self.assertIn('version installed in tools directory: ' + tool_version, output)
@@ -1058,9 +1094,10 @@ class TestUsageWin(TestUsage):
self.assertIn(
os.path.join(self.temp_tools_dir, 'tools', DFU_UTIL, DFU_UTIL_VERSION, 'dfu-util-0.11-win64'), output
)
self.assertIn(os.path.join(self.temp_tools_dir, 'tools', CLANGD, CLANGD_VERSION, CLANGD, 'bin'), output)
def test_tools_for_esp32p4_win(self):
required_tools_installed = 8
required_tools_installed = 9
output = self.run_idf_tools_with_action(['install', '--targets=esp32p4'])
self.assert_tool_installed(output, RISCV_ELF, RISCV_ELF_VERSION, RISCV_ELF_ARCHIVE_PATTERN)
self.assert_tool_installed(output, RISCV_ESP_GDB, RISCV_ESP_GDB_VERSION)
@@ -1074,6 +1111,7 @@ class TestUsageWin(TestUsage):
self.assert_tool_not_installed(output, ESP32ULP, ESP32ULP_VERSION)
self.assert_tool_not_installed(output, XTENSA_ESP_GDB, XTENSA_ESP_GDB_VERSION)
self.assert_tool_not_installed(output, DFU_UTIL, DFU_UTIL_VERSION)
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
self.assertEqual(required_tools_installed, output.count('Done'))
output = self.run_idf_tools_with_action(['check'])
@@ -1086,6 +1124,7 @@ class TestUsageWin(TestUsage):
NINJA_VERSION,
IDF_EXE_VERSION,
CCACHE_VERSION,
CLANGD_VERSION,
]:
self.assertIn(f'version installed in tools directory: {tool_version}', output)
@@ -1118,10 +1157,11 @@ class TestUsageWin(TestUsage):
self.assertNotIn(
os.path.join(self.temp_tools_dir, 'tools', DFU_UTIL, DFU_UTIL_VERSION, 'dfu-util-0.11-win64'), output
)
self.assertNotIn(os.path.join(self.temp_tools_dir, 'tools', CLANGD, CLANGD_VERSION, CLANGD, 'bin'), output)
# a different test for qemu because of "on_request"
def test_tools_for_qemu_with_required_win(self):
required_tools_installed = 14
required_tools_installed = 15
output = self.run_idf_tools_with_action(['install', 'required', 'qemu-xtensa', 'qemu-riscv32'])
self.assert_tool_installed(output, OPENOCD, OPENOCD_VERSION)
self.assert_tool_installed(output, RISCV_ELF, RISCV_ELF_VERSION, RISCV_ELF_ARCHIVE_PATTERN)
@@ -1137,6 +1177,7 @@ class TestUsageWin(TestUsage):
self.assert_tool_installed(output, IDF_EXE, IDF_EXE_VERSION)
self.assert_tool_installed(output, CCACHE, CCACHE_VERSION)
self.assert_tool_installed(output, DFU_UTIL, DFU_UTIL_VERSION)
self.assert_tool_installed(output, CLANGD, CLANGD_VERSION, CLANGD_ARCHIVE)
self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output)
self.assertEqual(required_tools_installed, output.count('Done'))