-
Notifications
You must be signed in to change notification settings - Fork 105
Add automatic kit scanning functionality #351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
drook207
wants to merge
33
commits into
Civitasv:master
Choose a base branch
from
drook207:feature-add-kit-scanner
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+298
−1
Open
Changes from 7 commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
822b317
Add basic implementation for kit scanner
drook207 09afee7
Fix call to make directory
drook207 206038a
Add global config dir for kit file
drook207 e4f2c2d
Fix version parsing
drook207 52f1efc
Add linker and toolchain to global kit file
drook207 4481b50
Add automatic kit scanning
drook207 e58c87d
Add user command for kit scanning
drook207 a1bc307
Use path from const table
drook207 adeb9e5
Use vim mkdir builtin
drook207 e0bd683
Fix: Config path for cmake kits
drook207 a6602cd
Feature: Use vim builtin json functions
drook207 b71824b
Feature: Add tests
drook207 49f717d
Merge pull request #1 from Civitasv/master
drook207 6f259b5
Merge branch 'master' into feature-add-kit-scanner
drook207 3022b5c
Fix: Make regex more simple
drook207 e547e0d
Fix: Use built in functions
drook207 e44aae1
Refactor: Improve kit detection
drook207 dd64e52
Merge branch 'Civitasv:master' into master
drook207 9bf4e1b
Refactor: Reimplement scanner function
drook207 8d06f2d
Merge branch 'master' into feature-add-kit-scanner
drook207 ea837cc
Refactor: Remove Debug logs
drook207 8975ae3
feat(constants): Add cmake-tools config path
drook207 12d1018
fix(scanner): Create config dir if not exists
drook207 9f1c58b
fix(scanner):Move initial scan for kits to setup
drook207 47b60a8
fix(autocommands): Add missing implementation for scan for kits
drook207 e3723fe
refactor: Use stdpath(config) for path expansion
drook207 9d46a1e
refactor: Reduce noise while scanning for kits
drook207 75c8279
refactor: name loop variable more meaningfull
drook207 684d9eb
refactor: Remove unused files
drook207 2898fd0
fix: make path separator system dependant
drook207 02a80c1
refactor: return boolean as the function name suggests
drook207 b83a051
refactor: move executable variable to global scope
drook207 757cd4a
refactor: remove unnecessary conditions
drook207 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,211 @@ | ||
| local scanner = {} | ||
| -- Configuration | ||
| scanner.HOME = os.getenv("HOME") or os.getenv("USERPROFILE") | ||
| scanner.KITS_FILE = scanner.HOME .. "/.config/cmake-tools/cmake-kits.json" | ||
|
drook207 marked this conversation as resolved.
Outdated
|
||
|
|
||
| --Helper functions | ||
| -- Simple JSON encoder | ||
| function scanner.json_encode(obj, indent) | ||
|
drook207 marked this conversation as resolved.
Outdated
|
||
| indent = indent or 0 | ||
| local spaces = string.rep(" ", indent) | ||
|
|
||
| if type(obj) == "table" then | ||
| local is_array = #obj > 0 | ||
| local result = "{\n" | ||
| local first = true | ||
|
|
||
| for k, v in pairs(obj) do | ||
| if not first then | ||
| result = result .. ",\n" | ||
| end | ||
| first = false | ||
|
|
||
| if is_array then | ||
| result = result .. spaces .. " " .. scanner.json_encode(v, indent + 1) | ||
| else | ||
| result = result .. spaces .. ' "' .. k .. '": ' .. scanner.json_encode(v, indent + 1) | ||
| end | ||
| end | ||
|
|
||
| return result .. "\n" .. spaces .. "}" | ||
| elseif type(obj) == "string" then | ||
| return '"' .. obj:gsub("\\", "\\\\"):gsub('"', '\\"') .. '"' | ||
| elseif type(obj) == "number" or type(obj) == "boolean" then | ||
| return tostring(obj) | ||
| elseif obj == nil then | ||
| return "null" | ||
| end | ||
| end | ||
|
|
||
| function scanner.execute_command(cmd) | ||
|
drook207 marked this conversation as resolved.
Outdated
|
||
| local handle = io.popen(cmd .. " 2>&1") | ||
| if handle == nil then | ||
| return false, -1, "" | ||
| end | ||
| local result = handle:read("*a") | ||
| if result == nil then | ||
| result = "" | ||
| end | ||
| local success, exit_type, exit_code = handle:close() | ||
| -- io.popen's close() returns: true on success, or nil, "exit", code on failure | ||
| if success == nil then | ||
| return false, exit_code or -1, result | ||
| end | ||
| return true, 0, result | ||
| end | ||
|
|
||
| function scanner.file_exists(path) | ||
|
drook207 marked this conversation as resolved.
Outdated
|
||
| local file = io.open(path, "r") | ||
| if file then | ||
| file:close() | ||
| return true | ||
| else | ||
| return false | ||
| end | ||
| end | ||
|
|
||
| function scanner.split_path(path_env) | ||
| local paths = {} | ||
| local sep = package.config:sub(1, 1) == "\\" and ";" or ":" | ||
| for path in string.gmatch(path_env, "([^" .. sep .. "]+)") do | ||
| table.insert(paths, path) | ||
| end | ||
| return paths | ||
| end | ||
|
|
||
| function scanner.get_gcc_version(gcc_path) | ||
| local success, exit_code, output = scanner.execute_command('"' .. gcc_path .. '" --version') | ||
| if output == nil then | ||
| return nil | ||
| end | ||
| -- Try multiple patterns to match different gcc output formats | ||
| local version = output:match("gcc%s+%(GCC%)%s+([%d%.]+)") -- "gcc (GCC) 15.2.1" | ||
|
drook207 marked this conversation as resolved.
Outdated
|
||
| or output:match("gcc version ([%d%.]+)") -- "gcc version 11.4.0" | ||
| return version | ||
| end | ||
|
|
||
| function scanner.get_clang_version(clang_path) | ||
|
drook207 marked this conversation as resolved.
Outdated
|
||
| local success, exit_code, output = scanner.execute_command('"' .. clang_path .. '" --version ') | ||
| if output == nil then | ||
| return nil | ||
|
drook207 marked this conversation as resolved.
Outdated
|
||
| end | ||
| local version_line = output:match("clang version ([%d%.]+)") | ||
| return version_line | ||
| end | ||
|
|
||
| function scanner.find_compiler_pair(dir, c_compiler) | ||
|
drook207 marked this conversation as resolved.
Outdated
|
||
| local base_name = c_compiler:match("([^/\\]+)$") | ||
| local cxx_name | ||
| if base_name:match("gcc") then | ||
| cxx_name = base_name:gsub("gcc", "g++") | ||
| elseif base_name:match("clang") then | ||
| cxx_name = base_name:gsub("clang", "clang++") | ||
| else | ||
| return nil | ||
| end | ||
| local cxx_path = dir .. "/" .. cxx_name | ||
|
drook207 marked this conversation as resolved.
Outdated
|
||
| if scanner.file_exists(cxx_path) then | ||
| return cxx_path | ||
| end | ||
| return nil | ||
| end | ||
|
|
||
| function scanner.find_linker_pair(dir, linker_name) | ||
|
drook207 marked this conversation as resolved.
Outdated
|
||
| if not linker_name then | ||
| return nil | ||
| end | ||
| local linker_path = dir .. "/" .. linker_name | ||
| if scanner.file_exists(linker_path) then | ||
| return linker_path | ||
| end | ||
| return nil | ||
| end | ||
|
|
||
| function scanner.get_toolchain_file() | ||
| local toolchainFile = os.getenv("CMAKE_TOOLCHAIN_FILE") | ||
| if toolchainFile and scanner.file_exists(toolchainFile) then | ||
| return toolchainFile | ||
| end | ||
| return nil | ||
| end | ||
|
|
||
| function scanner.ensure_directory(path) | ||
| local pattern = "(.*/)" | ||
| local dir = path:match(pattern) | ||
| if dir then | ||
| os.execute('mkdir -p "' .. dir .. '"') | ||
|
drook207 marked this conversation as resolved.
Outdated
|
||
| end | ||
| end | ||
|
|
||
| function scanner.save_kits(kits, filepath) | ||
| scanner.ensure_directory(filepath) | ||
| local file = io.open(filepath, "w") | ||
| if not file then | ||
| error("Failed to open file for writing: " .. filepath) | ||
| return false | ||
| end | ||
| local json_content = scanner.json_encode(kits) | ||
| file:write(json_content) | ||
| file:close() | ||
| return true | ||
| end | ||
|
|
||
| -- Main fucntion to scan for kits | ||
| function scanner.scan_for_kits() | ||
| local kits = {} | ||
|
|
||
| local path_env = os.getenv("PATH") or "" | ||
| local paths = scanner.split_path(path_env) | ||
|
|
||
| for _, dir in ipairs(paths) do | ||
| local linker_path = scanner.find_linker_pair(dir, "lld") | ||
| if linker_path == nil then | ||
| linker_path = scanner.find_linker_pair(dir, "ld") | ||
| end | ||
| local toolchainFile = scanner.get_toolchain_file() | ||
| local gcc_path = dir .. "/gcc" | ||
| if scanner.file_exists(gcc_path) then | ||
| local gcc_version = scanner.get_gcc_version(gcc_path) | ||
| local gxx_path = scanner.find_compiler_pair(dir, gcc_path) | ||
| if gxx_path then | ||
| local kit = { | ||
| name = "GCC-" .. (gcc_version or "unknown"), | ||
| compilers = { | ||
| C = gcc_path, | ||
| CXX = gxx_path, | ||
| }, | ||
| linker = (linker_path or ""), | ||
| toolchainFile = (toolchainFile or ""), | ||
| } | ||
| table.insert(kits, kit) | ||
| end | ||
| end | ||
|
|
||
| local clang_path = dir .. "/clang" | ||
| if scanner.file_exists(clang_path) then | ||
| local clang_version = scanner.get_clang_version(clang_path) | ||
| local clangxx_path = scanner.find_compiler_pair(dir, clang_path) | ||
| if clangxx_path then | ||
| local kit = { | ||
| name = "Clang-" .. (clang_version or "unknown"), | ||
| compilers = { | ||
| C = clang_path, | ||
| CXX = clangxx_path, | ||
| }, | ||
| linker = (linker_path or ""), | ||
| toolchainFile = (toolchainFile or ""), | ||
| } | ||
| table.insert(kits, kit) | ||
| end | ||
| end | ||
| end | ||
|
|
||
| if #kits == 0 then | ||
| print("No compilers found in PATH.") | ||
| return {} | ||
|
drook207 marked this conversation as resolved.
Outdated
|
||
| end | ||
| scanner.save_kits(kits, scanner.KITS_FILE) | ||
| return kits | ||
| end | ||
|
|
||
| return scanner | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,6 +18,7 @@ local Types = { | |
| "ANOTHER_JOB_RUNNING", | ||
| "CMAKE_RUN_FAILED", | ||
| "SETTINGS_ALREADY_OPENED", | ||
| "CANNOT_FIND_CMAKE_KITS", | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this return type is not used, is it? |
||
| } | ||
|
|
||
| Types[0] = "SUCCESS" | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.