Skip to content

Commit

Permalink
feat: projects v2, take 2
Browse files Browse the repository at this point in the history
  • Loading branch information
milogert committed Jan 13, 2024
1 parent adbec48 commit 842e5ee
Show file tree
Hide file tree
Showing 22 changed files with 649 additions and 44 deletions.
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,15 @@ Edit and review GitHub issues and pull requests from the comfort of your favorit
## 🎯 Requirements

- Install [GitHub CLI](https://cli.github.com/)
- If you'd like to use [Projects v2](https://docs.github.com/en/issues/planning-and-tracking-with-projects)
you will need to add the `read:project` scope to your `gh` token. You can
do so by running `gh auth refresh -s read:project`.
- If you'd like to actually modify projects you can instead add the `project`
scope to your token instead.
- Install [plenary.nvim](https://github.com/nvim-lua/plenary.nvim)
- Install [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim)
- Install one of:
- [telescope.nvim](https://github.com/nvim-telescope/telescope.nvim)
- [fzf-lua](https://github.com/ibhagwan/fzf-lua)
- Install [nvim-web-devicons](https://github.com/nvim-tree/nvim-web-devicons)

## 📦 Installation
Expand All @@ -73,6 +80,7 @@ use {
requires = {
'nvim-lua/plenary.nvim',
'nvim-telescope/telescope.nvim',
-- OR 'ibhagwan/fzf-lua',
'nvim-tree/nvim-web-devicons',
},
config = function ()
Expand Down Expand Up @@ -112,9 +120,14 @@ require"octo".setup({
snippet_context_lines = 4; -- number or lines around commented lines
gh_env = {}, -- extra environment variables to pass on to GitHub CLI, can be a table or function returning a table
timeout = 5000, -- timeout for requests between the remote server
default_to_projects_v2 = false, -- use projects v2 for the `Octo card ...` command by default. Both legacy and v2 commands are available under `Octo cardlegacy ...` and `Octo cardv2 ...` respectively.
ui = {
use_signcolumn = true, -- show "modified" marks on the sign column
},
picker = "telescope", -- "telescope" | "fzf-lua"
picker_config = {
use_emojis = false, -- Only used in fzf-lua picker. If you want emojis when viewing the picker set to true.
},
issues = {
order_by = { -- criteria to sort results of `Octo issue list`
field = "CREATED_AT", -- either COMMENTS, CREATED_AT or UPDATED_AT (https://docs.github.com/en/graphql/reference/enums#issueorderfield)
Expand Down
18 changes: 17 additions & 1 deletion doc/octo.txt
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,23 @@ Can I use treesitter markdown parser with octo buffers?~
>lua
vim.keymap.set("i", "@", "@<C-x><C-o>", { silent = true, buffer = true })
vim.keymap.set("i", "#", "#<C-x><C-o>", { silent = true, buffer = true })
<


I can't see my v2 projects in issues and/or pull requests!~

(and I see a warning when I open them)

You are missing a scope from the token gh uses. You can add the scope to
your gh token with

`gh auth refresh -s read:project`

Alternatively if you want to be able to modify projects (i.e. add/remove
cards) you need to add the `project` scope to your token instead.

If you don't care about projects v2 you can suppress the warning by setting
`suppress_missing_scope.project_v2 = true` in your Octo config.


CREDITS *octo-credits*

Expand Down
111 changes: 110 additions & 1 deletion lua/octo/commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,32 @@ function M.setup()
vim.api.nvim_create_user_command("Octo", function(opts)
require("octo.commands").octo(unpack(opts.fargs))
end, { complete = require("octo.completion").octo_command_complete, nargs = "*" })
local conf = config.values

local card_commands

if conf.default_to_projects_v2 then
card_commands = {
set = function()
M.set_project_v2_card()
end,
remove = function()
M.remove_project_v2_card()
end,
}
else
card_commands = {
add = function()
M.add_project_card()
end,
move = function()
M.move_project_card()
end,
remove = function()
M.remove_project_card()
end,
}
end

-- supported commands
M.commands = {
Expand Down Expand Up @@ -295,7 +321,16 @@ function M.setup()
M.reaction_action "HEART"
end,
},
card = {
card = card_commands,
cardv2 = {
set = function(...)
M.set_project_v2_card()
end,
remove = function()
M.remove_project_v2_card()
end,
},
cardlegacy = {
add = function()
M.add_project_card()
end,
Expand Down Expand Up @@ -1291,6 +1326,80 @@ function M.move_project_card()
end)
end

function M.set_project_v2_card()
local bufnr = vim.api.nvim_get_current_buf()
local buffer = octo_buffers[bufnr]
if not buffer then
return
end

-- show column selection picker
picker.project_columns_v2(function(project_id, field_id, value)
-- add new card
local add_query = graphql("add_project_v2_item_mutation", buffer.node.id, project_id)
gh.run {
args = { "api", "graphql", "--paginate", "-f", string.format("query=%s", add_query) },
cb = function(add_output, add_stderr)
if add_stderr and not utils.is_blank(add_stderr) then
utils.error(add_stderr)
elseif add_output then
local resp = vim.fn.json_decode(add_output)
local update_query = graphql(
"update_project_v2_item_mutation",
project_id,
resp.data.addProjectV2ItemById.item.id,
field_id,
value
)
gh.run {
args = { "api", "graphql", "--paginate", "-f", string.format("query=%s", update_query) },
cb = function(update_output, update_stderr)
if update_stderr and not utils.is_blank(update_stderr) then
utils.error(update_stderr)
elseif update_output then
-- TODO do update here
-- refresh issue/pr details
require("octo").load(buffer.repo, buffer.kind, buffer.number, function(obj)
writers.write_details(bufnr, obj, true)
buffer.node.projectCards = obj.projectCards
end)
end
end,
}
end
end,
}
end)
end

function M.remove_project_v2_card()
local bufnr = vim.api.nvim_get_current_buf()
local buffer = octo_buffers[bufnr]
if not buffer then
return
end

-- show card selection picker
picker.project_cards_v2(function(project_id, item_id)
-- delete card
local query = graphql("delete_project_v2_item_mutation", project_id, item_id)
gh.run {
args = { "api", "graphql", "--paginate", "-f", string.format("query=%s", query) },
cb = function(output, stderr)
if stderr and not utils.is_blank(stderr) then
utils.error(stderr)
elseif output then
-- refresh issue/pr details
require("octo").load(buffer.repo, buffer.kind, buffer.number, function(obj)
buffer.node.projectCards = obj.projectCards
writers.write_details(bufnr, obj, true)
end)
end
end,
}
end)
end

function M.reload(bufnr)
require("octo").load_buffer(bufnr)
end
Expand Down
6 changes: 2 additions & 4 deletions lua/octo/completion.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@ function M.octo_command_complete(argLead, cmdLine)
return get_options(command_keys)
elseif #parts == 2 and vim.tbl_contains(command_keys, parts[2]) or #parts == 3 then
local obj = octo_commands.commands[parts[2]]
if obj then
if type(obj) == "table" then
return get_options(vim.tbl_keys(obj))
end
if type(obj) == "table" then
return get_options(vim.tbl_keys(obj))
end
end
end
Expand Down
13 changes: 13 additions & 0 deletions lua/octo/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ local M = {}
---@field field string
---@field direction "ASC" | "DESC"

---@class OctoMissingScopeConfig
---@field projects_v2 boolean

---@class OctoConfig Octo configuration settings
---@field picker OctoPickers
---@field picker_config OctoPickerConfig
Expand All @@ -60,6 +63,8 @@ local M = {}
---@field snippet_context_lines number
---@field gh_env table
---@field timeout number
---@field default_to_projects_v2 boolean
---@field suppress_missing_scope OctoMissingScopeConfig
---@field ui OctoConfigUi
---@field issues OctoConfigIssues
---@field pull_requests OctoConfigPR
Expand Down Expand Up @@ -98,6 +103,10 @@ function M.get_default_values()
snippet_context_lines = 4,
gh_env = {},
timeout = 5000,
default_to_projects_v2 = false,
suppress_missing_scope = {
projects_v2 = false,
},
ui = {
use_signcolumn = true,
},
Expand Down Expand Up @@ -361,6 +370,10 @@ function M.validate_config()
validate_type(config.enable_builtin, "enable_builtin", "boolean")
validate_type(config.snippet_context_lines, "snippet_context_lines", "number")
validate_type(config.timeout, "timeout", "number")
validate_type(config.default_to_projects_v2, "default_to_projects_v2", "boolean")
if validate_type(config.suppress_missing_scope, "supress_missing_scope", "table") then
validate_type(config.suppress_missing_scope.projects_v2, "supress_missing_scope.projects_v2", "boolean")
end
validate_type(config.gh_env, "gh_env", "table")
validate_type(config.reaction_viewer_hint_icon, "reaction_viewer_hint_icon", "string")
validate_type(config.user_icon, "user_icon", "string")
Expand Down
28 changes: 28 additions & 0 deletions lua/octo/gh/fragments.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
local M = {}

M.projects_v2_fragment = [[
projectItems(first: 100) {
nodes {
id
project {
id
title
}
fieldValues(first: 100) {
nodes {
... on ProjectV2ItemFieldSingleSelectValue {
name
optionId
field {
... on ProjectV2SingleSelectField {
name
}
}
}
}
}
}
}
]]

return M
Loading

0 comments on commit 842e5ee

Please sign in to comment.