Skip to content

Commit

Permalink
Merge pull request #11 from erichlf/AddShell
Browse files Browse the repository at this point in the history
Add shell to DevcontainerExec
  • Loading branch information
erichlf authored Apr 26, 2024
2 parents cf193b2 + 717dce6 commit af3f409
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 91 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ make assumptions about how you work.
dotfiles_branch = "main", -- branch to clone from dotfiles_repository`
dotfiles_targetPath = "~/dotfiles", -- location to install dotfiles
dotfiles_intallCommand = "install.sh", -- script to run after dotfiles are cloned
shell = "bash", -- shell to use when executing commands
},
keys = {
-- stylua: ignore
Expand Down
14 changes: 10 additions & 4 deletions lua/devcontainer_cli/config/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,24 @@ local default_config = {
-- Folder where the nvim-devcontainer-cli is installed
nvim_plugin_folder = file_path:gsub("init.lua", "") .. "../../../",
-- Remove existing container each time DevcontainerUp is executed
-- If set to True [default_value] it can take extra time as you force to start from scratch
-- If set to True [default_value] it can take extra time as you force to
-- start from scratch
remove_existing_container = true,
-- dependencies that have to be installed in the devcontainer (remoteUser = root)
-- dotfiles to be downloaded
dotfiles_repository = "[email protected]:erichlf/dotfiles",
-- branch to checkout for repositories (this is a feature not supported by devcontainers in general, but we do)
-- branch to checkout for repositories (this is a feature not supported by
-- devcontainers in general, but we do)
dotfiles_repository = "devcontainer",
-- directory for the setup environment
dotfiles_targetPath = "~/dotfiles",
-- command that's executed for installed the dependencies from the setup_environment_repo
-- command that's executed for installed the dependencies from the
-- setup_environment_repo
dotfiles_installCommand = "install.sh",
-- The number of columns to wrap text at
terminal_columns = 80,
-- The shell to use for executing command. Available sh, bash, zsh or any
-- other that uses '-c' to signify a command is to follow
shell = 'bash',
}

local options
Expand Down
12 changes: 5 additions & 7 deletions lua/devcontainer_cli/devcontainer_cli.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,13 @@ local function define_autocommands()
end

-- executes a given command in the devcontainer of the current project directory
-- @param opts options for executing the command
---@param opts (table) options for executing the command
function M.exec(opts)
cwd = vim.loop.cwd()

vim.validate({ args = { opts.args, "string" } })
if opts.args == nil or opts.args == "" then
devcontainer_utils.exec(cwd)
devcontainer_utils.exec()
else
devcontainer_utils.exec_cmd(opts.args, cwd)
devcontainer_utils.exec_cmd(opts.args)
end
end

Expand All @@ -37,9 +35,9 @@ function M.up()
devcontainer_utils.bringup(vim.loop.cwd())
end

-- Thanks to the autocommand executed after leaving the UI, after closing the
-- neovim window the devcontainer will be automatically open in a new terminal
function M.connect()
-- Thanks to the autocommand executed after leaving the UI, after closing the
-- neovim window the devcontainer will be automatically open in a new terminal
define_autocommands()
vim.cmd("wqa")
end
Expand Down
92 changes: 40 additions & 52 deletions lua/devcontainer_cli/devcontainer_utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,24 @@ local on_detach = function()
end

-- on_fail callback
-- @param exit_code the exit code from the failed job
---@param exit_code (integer) the exit code from the failed job
local on_fail = function(exit_code)
vim.notify(
"Devcontainer process has failed! exit_code: " .. exit_code,
vim.log.levels.ERROR
"Devcontainer process has failed! exit_code: " .. exit_code,
vim.log.levels.ERROR
)

vim.cmd("silent! :checktime")
end

local on_success = function()
vim.notify("Devcontainer process succeeded!", vim.log.levels.INFO)
vim.notify("Devcontainer process succeeded!", vim.log.levels.INFO)
end

-- on_exit callback function to delete the open buffer when devcontainer exits
-- on_exit callback function to delete the open buffer when devcontainer exits
-- in a neovim terminal
-- @param job_id the id of the running job
-- @param code the exit code
-- @param event thrown by job
local on_exit = function(job_id, code, event)
---@param code (integer) the exit code
local on_exit = function(_, code, _)
if code == 0 then
on_success()
return
Expand All @@ -46,42 +44,40 @@ local on_exit = function(job_id, code, event)
end

--- execute command
-- @param cmd the command to execute in the devcontainer terminal
---@param cmd (string) the command to execute in the devcontainer terminal
local function exec_command(cmd)
vim.fn.termopen(
cmd,
{
cmd,
{
on_exit = on_exit,
on_stdout = function(_, data, _)
vim .api.nvim_win_call(
on_stdout = function(_, _, _)
vim.api.nvim_win_call(
win,
function()
vim.cmd("normal! G")
end
)
)
end,
}
)
vim.api.nvim_set_current_buf(buffer)
end

-- create a new window and execute the given command
-- @param cmd the command to execute in the devcontainer terminal
function spawn_and_execute(cmd)
---@param cmd (string) the command to execute in the devcontainer terminal
local function spawn_and_execute(cmd)
prev_win = vim.api.nvim_get_current_win()
win, buffer = windows_utils.open_floating_window()
win, buffer = windows_utils.open_floating_window(on_detach)
exec_command(cmd)
end

-- build the initial part of a devcontainer command
-- @param action the action for the devcontainer to perform
-- (see man devcontainer)
-- @param cwd the current working directory. Used as a starting place to find
-- .devcontainer directory
-- @return nil if no devcontainer_parent could be found otherwise
---@param action (string) the action for the devcontainer to perform
-- (see man devcontainer)
---@return (string|nil) nil if no devcontainer_parent could be found otherwise
-- the basic devcontainer command for the given type
local function devcontainer_command(action, cwd)
devcontainer_root = folder_utils.get_root(cwd)
local function devcontainer_command(action)
local devcontainer_root = folder_utils.get_root(config.toplevel)
if devcontainer_root == nil then
vim.notify("Unable to find devcontainer directory...", vim.log.levels.ERROR)
return nil
Expand All @@ -94,26 +90,24 @@ local function devcontainer_command(action, cwd)
end

-- helper function to generate devcontainer bringup command
-- @param cwd the current working directory. Used as a starting place to find
-- .devcontainer directory
-- @return nil if no devcontainer_parent could be found otherwise the
---@return (string|nil) nil if no devcontainer_parent could be found otherwise the
-- devcontainer bringup command
local function get_devcontainer_up_cmd(cwd)
local command = devcontainer_command("up", cwd)
local function get_devcontainer_up_cmd()
local command = devcontainer_command("up")
if command == nil then
return command
end

if config.remove_existing_container then
command = command .. " --remove-existing-container"
end
command = command .. " --update-remote-user-uid-default off"
command = command .. " --update-remote-user-uid-default off"

if config.dotfiles_repository == "" or config.dotfiles_repository == nil then
return command
end

command = command .. " --dotfiles-repository '" .. config.dotfiles_repository
command = command .. " --dotfiles-repository '" .. config.dotfiles_repository
-- only include the branch if it exists
if config.dotfiles_branch ~= "" and config.dotfiles_branch ~= nil then
command = command .. " -b " .. config.dotfiles_branch
Expand All @@ -132,19 +126,18 @@ local function get_devcontainer_up_cmd(cwd)
end

-- issues command to bringup devcontainer
-- @param cwd the current working directory. Used as a starting place to find
-- .devcontainer directory
function M.bringup(cwd)
local command = get_devcontainer_up_cmd(cwd)
function M.bringup()
local command = get_devcontainer_up_cmd()

if command == nil then
return
return
end

if config.interactive then
vim.ui.input(
{prompt=windows_utils.wrap_text(
"Spawning devcontainer with command: " .. command
{
prompt = windows_utils.wrap_text(
"Spawning devcontainer with command: " .. command
) .. "\n\n" .. "Press q to cancel or any other key to continue\n"
},
function(input)
Expand All @@ -164,29 +157,24 @@ function M.bringup(cwd)
end

-- execute the given cmd within the given devcontainer_parent
-- @param cmd the command to issue in the devcontainer terminal
-- @param cwd the current working directory. Used as a starting place to find
-- .devcontainer directory
function M.exec_cmd(cmd, cwd)
command = devcontainer_command("exec", cwd)
---@param cmd (string) the command to issue in the devcontainer terminal
function M.exec_cmd(cmd)
local command = devcontainer_command("exec")
if command == nil then
return
end

command = command .. " " .. cmd
command = command .. " " .. config.shell .. " -c '" .. cmd .. "'"
spawn_and_execute(command)
end

-- execute a given cmd within the given devcontainer_parent
-- @param cwd the current working directory. Used as a starting place to find
-- .devcontainer directory
-- @param devcontainer_parent the location guess for .devcontainer directory
function M.exec(cwd)
function M.exec()
vim.ui.input(
{prompt="Enter command:"},
{ prompt = "Enter command:" },
function(input)
if input ~= nil then
M.exec_cmd(input, devcontainer_parent)
M.exec_cmd(input)
end
end
)
Expand Down
20 changes: 10 additions & 10 deletions lua/devcontainer_cli/folder_utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,28 @@ local function directory_exists(target_folder)
end

-- get the devcontainer path for the given directory
-- @param directory the directory containing .devcontainer
-- @return directory if a devcontainer exists within it or nil otherwise
---@param directory (string) the directory containing .devcontainer
---@return (string|nil) directory if a devcontainer exists within it or nil otherwise
local function get_devcontainer_parent(directory)
local devcontainer_directory = directory .. '/.devcontainer'

if directory_exists(devcontainer_directory) then
return directory
end

return nil
return nil
end

-- get the root directory the devcontainer given a directory
-- @param directory to begin search in
-- @param toplevel flag indicating if the directory closes to root should be
---@param directory (string) to begin search in
---@param toplevel (boolean) flag indicating if the directory closes to root should be
-- returned
-- @return the devcontainer directory closest to the root directory
---@return (string|nil) the devcontainer directory closest to the root directory
-- or the first if toplevel is true, and nil if no directory was found
local function get_root_directory(directory, toplevel)
local parent_directory = vim.fn.fnamemodify(directory, ':h')
local devcontainer_parent = get_devcontainer_parent(directory)
local devcontainer_parent = get_devcontainer_parent(directory)

-- Base case: If we've reached the root directory
if parent_directory == directory then
return devcontainer_parent
Expand All @@ -49,9 +49,9 @@ end

-- find the .devcontainer directory closes to the root upward from the current
-- directory
-- @param toplevel flag indicating if the directory closes to root should be
---@param toplevel (boolean) flag indicating if the directory closes to root should be
-- returned
-- @return the devcontainer directory closest to the root directory
---@return (string|nil) the devcontainer directory closest to the root directory
-- or the first if toplevel is true, and nil if no directory was found
function M.get_root(toplevel)
local current_directory = vim.fn.getcwd()
Expand Down
10 changes: 5 additions & 5 deletions lua/devcontainer_cli/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ local config = require("devcontainer_cli.config")
local configured = false

-- setup the devcontainer-cli plugin
-- @param opts the options to set (see config/init.lua)
---@param opts (table) the options to set (see config/init.lua)
function M.setup(opts)
config.setup(opts)

Expand All @@ -18,7 +18,7 @@ function M.setup(opts)

-- Docker
vim.api.nvim_create_user_command(
"DevcontainerUp",
"DevcontainerUp",
devcontainer_cli.up,
{
nargs = 0,
Expand All @@ -27,16 +27,16 @@ function M.setup(opts)
)

vim.api.nvim_create_user_command(
"DevcontainerExec",
devcontainer_cli.exec,
"DevcontainerExec",
devcontainer_cli.exec,
{
nargs = "?",
desc = "Execute command in devcontainer.",
}
)

vim.api.nvim_create_user_command(
"DevcontainerConnect",
"DevcontainerConnect",
devcontainer_cli.connect,
{
nargs = 0,
Expand Down
Loading

0 comments on commit af3f409

Please sign in to comment.