feat(s3): create bucket interactively during auth when unconfigured
Problem: when a user runs `:Pending s3 auth` with no bucket configured, auth succeeds but offers no way to create the bucket. The user must manually run `aws s3api create-bucket` and update their config. Solution: add `util.input()` coroutine-aware prompt wrapper and a `create_bucket()` flow in `s3.lua` that prompts for bucket name and region, handles the `us-east-1` LocationConstraint quirk, and logs a config snippet on success. Called automatically from `auth()` when `sync.s3.bucket` is absent.
This commit is contained in:
parent
ee75e6844e
commit
58804fcfc7
3 changed files with 303 additions and 0 deletions
|
|
@ -66,6 +66,49 @@ local function ensure_sync_id(task)
|
|||
return sync_id
|
||||
end
|
||||
|
||||
local function create_bucket()
|
||||
local name = util.input({ prompt = 'S3 bucket name: ', default = 'pending.nvim' })
|
||||
if not name or name == '' then
|
||||
log.info('s3: bucket creation cancelled')
|
||||
return
|
||||
end
|
||||
|
||||
local region_cmd = base_cmd()
|
||||
vim.list_extend(region_cmd, { 'configure', 'get', 'region' })
|
||||
local region_result = util.system(region_cmd, { text = true })
|
||||
local default_region = 'us-east-1'
|
||||
if region_result.code == 0 and region_result.stdout then
|
||||
local detected = vim.trim(region_result.stdout)
|
||||
if detected ~= '' then
|
||||
default_region = detected
|
||||
end
|
||||
end
|
||||
|
||||
local region = util.input({ prompt = 'AWS region: ', default = default_region })
|
||||
if not region or region == '' then
|
||||
region = 'us-east-1'
|
||||
end
|
||||
|
||||
local cmd = base_cmd()
|
||||
vim.list_extend(cmd, { 's3api', 'create-bucket', '--bucket', name, '--region', region })
|
||||
if region ~= 'us-east-1' then
|
||||
vim.list_extend(cmd, { '--create-bucket-configuration', 'LocationConstraint=' .. region })
|
||||
end
|
||||
|
||||
local result = util.system(cmd, { text = true })
|
||||
if result.code == 0 then
|
||||
log.info(
|
||||
's3: bucket created. Add to your config:\n sync = { s3 = { bucket = "'
|
||||
.. name
|
||||
.. '", region = "'
|
||||
.. region
|
||||
.. '" } }'
|
||||
)
|
||||
else
|
||||
log.error('s3: bucket creation failed — ' .. (result.stderr or 'unknown error'))
|
||||
end
|
||||
end
|
||||
|
||||
---@param args? string
|
||||
---@return nil
|
||||
function M.auth(args)
|
||||
|
|
@ -96,6 +139,10 @@ function M.auth(args)
|
|||
else
|
||||
log.info('s3: credentials valid')
|
||||
end
|
||||
local s3cfg = get_config()
|
||||
if not s3cfg or not s3cfg.bucket then
|
||||
create_bucket()
|
||||
end
|
||||
else
|
||||
local stderr = result.stderr or ''
|
||||
if stderr:find('SSO') or stderr:find('sso') then
|
||||
|
|
|
|||
|
|
@ -35,6 +35,21 @@ function M.system(args, opts)
|
|||
return coroutine.yield() --[[@as { code: integer, stdout: string, stderr: string }]]
|
||||
end
|
||||
|
||||
---@param opts? {prompt?: string, default?: string}
|
||||
---@return string?
|
||||
function M.input(opts)
|
||||
local co = coroutine.running()
|
||||
if not co then
|
||||
error('util.input() must be called inside a coroutine')
|
||||
end
|
||||
vim.ui.input(opts or {}, function(result)
|
||||
vim.schedule(function()
|
||||
coroutine.resume(co, result)
|
||||
end)
|
||||
end)
|
||||
return coroutine.yield() --[[@as string?]]
|
||||
end
|
||||
|
||||
---@param name string
|
||||
---@param fn fun(): nil
|
||||
function M.with_guard(name, fn)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue