Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased]

### Added

- `:Conan create [args...]` now forwards arbitrary additional arguments directly to Conan after
the configured recipe, profiles, and optional build policy.

### Fixed

- Reconfiguration now preserves the existing configuration when the wizard is cancelled or writing fails.
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@ offers a free-form optional input for the value following `--build=` (for exampl
`missing:zlib/*`). Leaving it empty preserves Conan's default behavior; when configured, the value
is stored as `build_policy` and commands append it as `--build=<value>`.

Package the configured recipe with optional additional Conan arguments:

```vim
:Conan create [args...]
:Conan create --version=1.2.3
```

All arguments following `create` are passed directly to Conan, in their original order, after the
configured recipe, profiles, and optional build policy.

-------

# 📋 Requirements
Expand Down
8 changes: 6 additions & 2 deletions doc/nvim-conan.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,12 @@ Available subcommands:
`lock`
Run `conan lock create` for the configured recipe.

`create`
Run `conan create`.
`:Conan create [args...]`
Run `conan create` for the configured recipe. Remaining arguments are
passed directly to Conan, after the configured profiles and optional build
policy. For example: >
:Conan create --version=1.2.3
<

`export [user] [channel]`
Run `conan export` for the configured recipe.
Expand Down
13 changes: 7 additions & 6 deletions lua/commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ end
-- Conan commands (terminal)
-- -------------------------

--- Runs `conan install` using config from `.nvim-conan.json`.
--- Runs `conan install` using config file.
--- Opens a floating terminal and shows statusline spinner until the command finishes.
function M.install()
local config = read_config()
Expand All @@ -105,7 +105,7 @@ function M.install()
run_terminal_with_status("📦 Conan: install", argv, "📦 Conan Install", true)
end

--- Runs `conan build` using config from `.nvim-conan.json`.
--- Runs `conan build` using config file.
--- Also attempts to symlink `compile_commands.json` into project root if it can be located.
function M.build()
local config = read_config()
Expand All @@ -127,7 +127,7 @@ function M.build()
end)
end

--- Runs `conan lock create` using config from `.nvim-conan.json`.
--- Runs `conan lock create` using config file.
function M.lock()
local config = read_config()
if config == nil then
Expand All @@ -139,15 +139,16 @@ function M.lock()
run_terminal_with_status("🔒 Conan: lock", argv, "🔒 Conan Lock", true)
end

--- Runs `conan create` using config from `.nvim-conan.json`.
function M.create()
--- Runs `conan create` using config file.
---@param args string[]|nil Additional arguments passed directly to `conan create`.
function M.create(args)
local config = read_config()
if config == nil then
vim.notify("Couldn't read config", vim.log.levels.ERROR)
return
end

local argv = command_builder.create(config)
local argv = command_builder.create(config, args)
run_terminal_with_status("📦 Conan: create", argv, "📦 Conan Create", true)
end

Expand Down
8 changes: 5 additions & 3 deletions lua/conan/command_builder.lua
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,13 @@ function M.lock(config)
return { "conan", "lock", "create", config.recipe or "." }
end

function M.create(config)
local argv = { "conan", "create" }
function M.create(config, additional_args)
local argv = { "conan", "create", config.recipe or "." }
append_profiles(argv, config)
append_build_policy(argv, config)
append(argv, config.recipe or ".")
for _, argument in ipairs(additional_args or {}) do
append(argv, argument)
end
return argv
end

Expand Down
3 changes: 2 additions & 1 deletion lua/conan_status.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ local function in_conan_project()
local cwd = vim.fn.getcwd()
return exists(cwd .. "/conanfile.py")
or exists(cwd .. "/conanfile.txt")
or exists(cwd .. "/.nvim-conan.json")
or exists(cwd .. "/conan-config.json")
or exists(cwd .. "/.vscode/conan-config.json")
or exists(cwd .. "/conan.lock")
end

Expand Down
83 changes: 76 additions & 7 deletions tests/test_command_builder.lua
Original file line number Diff line number Diff line change
Expand Up @@ -144,33 +144,102 @@ test_set["lock uses the configured recipe"] = function()
})
end

test_set["create preserves profile and recipe ordering"] = function()
test_set["create without additional arguments preserves existing configured arguments"] = function()
expect.equality(command_builder.create(config), {
"conan",
"create",
"recipes/conanfile.py",
"-pr:b",
"build-profile",
"-pr:h",
"host-profile",
"--build=missing",
"recipes/conanfile.py",
})
end

test_set["create omits a blank build policy without changing argument ordering"] = function()
local create_config = vim.tbl_extend("force", config, { build_policy = " \t" })

expect.equality(command_builder.create(create_config), {
test_set["create forwards a version argument after configured arguments"] = function()
expect.equality(command_builder.create(config, { "--version=1.0.0" }), {
"conan",
"create",
"recipes/conanfile.py",
"-pr:b",
"build-profile",
"-pr:h",
"host-profile",
"recipes/conanfile.py",
"--build=missing",
"--version=1.0.0",
})
end

test_set["create preserves multiple additional arguments in their original order"] = function()
expect.equality(
command_builder.create(config, {
"--version=1.2.3",
"--user=alice",
"--channel=testing",
}),
{
"conan",
"create",
"recipes/conanfile.py",
"-pr:b",
"build-profile",
"-pr:h",
"host-profile",
"--build=missing",
"--version=1.2.3",
"--user=alice",
"--channel=testing",
}
)
end

test_set["create preserves spaces and shell metacharacters as literal arguments"] = function()
expect.equality(
command_builder.create(config, {
"value with spaces",
"$(touch unsafe);&|*",
}),
{
"conan",
"create",
"recipes/conanfile.py",
"-pr:b",
"build-profile",
"-pr:h",
"host-profile",
"--build=missing",
"value with spaces",
"$(touch unsafe);&|*",
}
)
end

test_set["create omits missing, empty, and blank build policies"] = function()
local configs = {
{
recipe = config.recipe,
profile_build = config.profile_build,
profile_host = config.profile_host,
},
vim.tbl_extend("force", config, { build_policy = "" }),
vim.tbl_extend("force", config, { build_policy = " \t" }),
}

for _, create_config in ipairs(configs) do
expect.equality(command_builder.create(create_config, { "--version=1.0.0" }), {
"conan",
"create",
"recipes/conanfile.py",
"-pr:b",
"build-profile",
"-pr:h",
"host-profile",
"--version=1.0.0",
})
end
end

test_set["export includes user and channel before the recipe"] = function()
expect.equality(command_builder.export(config, "alice", "stable"), {
"conan",
Expand Down
76 changes: 76 additions & 0 deletions tests/test_create_command.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
local test_set = MiniTest.new_set()
local expect = MiniTest.expect

test_set["Conan create propagates dispatcher arguments through the handler"] = function()
local utils = require("utils")
local conan_status = require("conan_status")
local plugin_root = vim.fn.getcwd()
local original = {
cwd = vim.fn.getcwd(),
create_user_command = vim.api.nvim_create_user_command,
open_floating_terminal = utils.open_floating_terminal,
status_start = conan_status.start,
status_stop = conan_status.stop,
}
local project_dir = vim.fn.tempname()
local captured_argv
local dispatcher

vim.fn.mkdir(project_dir, "p")
local config_file = assert(io.open(project_dir .. "/conan-config.json", "w"))
assert(config_file:write(vim.json.encode({
recipe = "recipes/conanfile.py",
profile_build = "build-profile",
profile_host = "host-profile",
build_policy = "missing",
})))
assert(config_file:close())

local ok, err = xpcall(function()
vim.api.nvim_create_user_command = function(name, callback)
if name == "Conan" then
dispatcher = callback
end
end
dofile(plugin_root .. "/lua/conan.lua")
vim.api.nvim_create_user_command = original.create_user_command

vim.fn.chdir(project_dir)
conan_status.start = function() end
conan_status.stop = function() end
utils.open_floating_terminal = function(argv)
captured_argv = argv
end

dispatcher({
fargs = { "create", "--version=1.2.3", "--user=alice", "--channel=testing" },
})

expect.equality(captured_argv, {
"conan",
"create",
"recipes/conanfile.py",
"-pr:b",
"build-profile",
"-pr:h",
"host-profile",
"--build=missing",
"--version=1.2.3",
"--user=alice",
"--channel=testing",
})
end, debug.traceback)

vim.api.nvim_create_user_command = original.create_user_command
utils.open_floating_terminal = original.open_floating_terminal
conan_status.start = original.status_start
conan_status.stop = original.status_stop
vim.fn.chdir(original.cwd)
vim.fn.delete(project_dir, "rf")

if not ok then
error(err)
end
end

return test_set
Loading