Add option to choose random server port (#65)
Updates the plugin to automatically choose a random port when started when no port is provided. This will allow multiple Neovim instances to open at the same time in different projects.
This commit is contained in:
11
README.md
11
README.md
@@ -13,7 +13,6 @@ And a lot more!
|
|||||||
|
|
||||||
https://github.com/harrisoncramer/gitlab.nvim/assets/32515581/50f44eaf-5f99-4cb3-93e9-ed66ace0f675
|
https://github.com/harrisoncramer/gitlab.nvim/assets/32515581/50f44eaf-5f99-4cb3-93e9-ed66ace0f675
|
||||||
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- <a href="https://go.dev/">Go</a> >= v1.19
|
- <a href="https://go.dev/">Go</a> >= v1.19
|
||||||
@@ -22,10 +21,10 @@ https://github.com/harrisoncramer/gitlab.nvim/assets/32515581/50f44eaf-5f99-4cb3
|
|||||||
|
|
||||||
1. Install Go
|
1. Install Go
|
||||||
2. Install reviewer: <a href="https://github.com/dandavison/delta">delta</a> or <a href="https://github.com/sindrets/diffview.nvim">diffview</a>
|
2. Install reviewer: <a href="https://github.com/dandavison/delta">delta</a> or <a href="https://github.com/sindrets/diffview.nvim">diffview</a>
|
||||||
2. Add configuration (see Installation section)
|
3. Add configuration (see Installation section)
|
||||||
3. Checkout your feature branch: `git checkout feature-branch`
|
4. Checkout your feature branch: `git checkout feature-branch`
|
||||||
4. Open Neovim
|
5. Open Neovim
|
||||||
5. Run `:lua require("gitlab").review()` to open the reviewer pane
|
6. Run `:lua require("gitlab").review()` to open the reviewer pane
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -85,7 +84,7 @@ Here is the default setup function. All of these values are optional, and if you
|
|||||||
|
|
||||||
```lua
|
```lua
|
||||||
require("gitlab").setup({
|
require("gitlab").setup({
|
||||||
port = 21036, -- The port of the Go server, which runs in the background
|
port = nil, -- The port of the Go server, which runs in the background, if omitted or `nil` the port will be chosen automatically
|
||||||
log_path = vim.fn.stdpath("cache") .. "/gitlab.nvim.log", -- Log path for the Go server
|
log_path = vim.fn.stdpath("cache") .. "/gitlab.nvim.log", -- Log path for the Go server
|
||||||
reviewer = "delta", -- The reviewer type ("delta" or "diffview")
|
reviewer = "delta", -- The reviewer type ("delta" or "diffview")
|
||||||
attachment_dir = nil, -- The local directory for files (see the "summary" section)
|
attachment_dir = nil, -- The local directory for files (see the "summary" section)
|
||||||
|
|||||||
55
cmd/main.go
55
cmd/main.go
@@ -4,10 +4,12 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -29,6 +31,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m := http.NewServeMux()
|
m := http.NewServeMux()
|
||||||
|
m.Handle("/ping", http.HandlerFunc(PingHandler))
|
||||||
m.Handle("/mr/summary", withGitlabContext(http.HandlerFunc(SummaryHandler), c))
|
m.Handle("/mr/summary", withGitlabContext(http.HandlerFunc(SummaryHandler), c))
|
||||||
m.Handle("/mr/attachment", withGitlabContext(http.HandlerFunc(AttachmentHandler), c))
|
m.Handle("/mr/attachment", withGitlabContext(http.HandlerFunc(AttachmentHandler), c))
|
||||||
m.Handle("/mr/reviewer", withGitlabContext(http.HandlerFunc(ReviewersHandler), c))
|
m.Handle("/mr/reviewer", withGitlabContext(http.HandlerFunc(ReviewersHandler), c))
|
||||||
@@ -44,19 +47,45 @@ func main() {
|
|||||||
m.Handle("/pipeline", withGitlabContext(http.HandlerFunc(PipelineHandler), c))
|
m.Handle("/pipeline", withGitlabContext(http.HandlerFunc(PipelineHandler), c))
|
||||||
m.Handle("/job", withGitlabContext(http.HandlerFunc(JobHandler), c))
|
m.Handle("/job", withGitlabContext(http.HandlerFunc(JobHandler), c))
|
||||||
|
|
||||||
port := fmt.Sprintf(":%s", os.Args[3])
|
port := os.Args[3]
|
||||||
server := &http.Server{
|
if port == "" {
|
||||||
Addr: port,
|
// port was not specified
|
||||||
Handler: m,
|
port = "0"
|
||||||
|
}
|
||||||
|
addr := fmt.Sprintf("localhost:%s", port)
|
||||||
|
listener, err := net.Listen("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
fmt.Fprintf(os.Stderr, "Error starting server: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
listner_port := listener.Addr().(*net.TCPAddr).Port
|
||||||
|
|
||||||
|
errCh := make(chan error)
|
||||||
|
go func() {
|
||||||
|
err := http.Serve(listener, m)
|
||||||
|
errCh <- err
|
||||||
|
}()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
resp, err := http.Get("http://localhost:" + fmt.Sprintf("%d", listner_port) + "/ping")
|
||||||
|
if resp.StatusCode == 200 && err == nil {
|
||||||
|
/* This print is detected by the Lua code and used to fetch project information */
|
||||||
|
fmt.Println("Server started on port: ", listner_port)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Wait for healthcheck to pass - at most 1 sec.
|
||||||
|
time.Sleep(100 * time.Microsecond)
|
||||||
|
}
|
||||||
|
errCh <- err
|
||||||
|
}()
|
||||||
|
|
||||||
|
if err := <-errCh; err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error starting server: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
done := make(chan bool)
|
|
||||||
go server.ListenAndServe()
|
|
||||||
|
|
||||||
/* This print is detected by the Lua code and used to fetch project information */
|
|
||||||
fmt.Println("Server started.")
|
|
||||||
|
|
||||||
<-done
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func withGitlabContext(next http.HandlerFunc, c Client) http.Handler {
|
func withGitlabContext(next http.HandlerFunc, c Client) http.Handler {
|
||||||
@@ -77,3 +106,7 @@ func getCurrentBranch() (res string, e error) {
|
|||||||
|
|
||||||
return strings.TrimSpace(string(output)), nil
|
return strings.TrimSpace(string(output)), nil
|
||||||
}
|
}
|
||||||
|
func PingHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
fmt.Fprintln(w, "pong")
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,40 +7,70 @@ local M = {}
|
|||||||
|
|
||||||
-- Starts the Go server and call the callback provided
|
-- Starts the Go server and call the callback provided
|
||||||
M.start = function(callback)
|
M.start = function(callback)
|
||||||
|
local empty_port = "''"
|
||||||
|
local port = state.settings.port or empty_port
|
||||||
|
local parsed_port = nil
|
||||||
|
local callback_called = false
|
||||||
local command = state.settings.bin
|
local command = state.settings.bin
|
||||||
.. " "
|
.. " "
|
||||||
.. state.settings.project_id
|
.. state.settings.project_id
|
||||||
.. " "
|
.. " "
|
||||||
.. state.settings.gitlab_url
|
.. state.settings.gitlab_url
|
||||||
.. " "
|
.. " "
|
||||||
.. state.settings.port
|
.. port
|
||||||
.. " "
|
.. " "
|
||||||
.. state.settings.auth_token
|
.. state.settings.auth_token
|
||||||
.. " "
|
.. " "
|
||||||
.. state.settings.log_path
|
.. state.settings.log_path
|
||||||
|
|
||||||
vim.fn.jobstart(command, {
|
local job_id = vim.fn.jobstart(command, {
|
||||||
on_stdout = function(job_id)
|
on_stdout = function(_, data)
|
||||||
if job_id <= 0 then
|
-- if port was not provided then we need to parse it from output of server
|
||||||
vim.notify("Could not start gitlab.nvim binary", vim.log.levels.ERROR)
|
if parsed_port == nil then
|
||||||
else
|
for _, line in ipairs(data) do
|
||||||
|
port = line:match("Server started on port:%s+(%d+)")
|
||||||
|
if port ~= nil then
|
||||||
|
parsed_port = port
|
||||||
|
state.settings.port = port
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- This assumes that first output of server will be parsable and port will be correctly set.
|
||||||
|
-- Make sure that this actually check if port was correctly parsed based on server output
|
||||||
|
-- because server outputs port only if it started successfully.
|
||||||
|
if parsed_port ~= nil and not callback_called then
|
||||||
callback()
|
callback()
|
||||||
|
callback_called = true
|
||||||
|
elseif not callback_called then
|
||||||
|
vim.notify("Failed to parse server port", vim.log.levels.ERROR)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
on_stderr = function(_, errors)
|
on_stderr = function(_, errors)
|
||||||
local err_msg = ''
|
local err_msg = ""
|
||||||
for _, err in ipairs(errors) do
|
for _, err in ipairs(errors) do
|
||||||
if err ~= "" and err ~= nil then
|
if err ~= "" and err ~= nil then
|
||||||
err_msg = err_msg .. err .. "\n"
|
err_msg = err_msg .. err .. "\n"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if err_msg ~= '' then vim.notify(err_msg, vim.log.levels.ERROR) end
|
if err_msg ~= "" then
|
||||||
|
vim.notify(err_msg, vim.log.levels.ERROR)
|
||||||
end
|
end
|
||||||
|
end,
|
||||||
|
on_exit = function(job_id, exit_code, ...)
|
||||||
|
vim.notify(
|
||||||
|
"Golang gitlab server exited: job_id: " .. job_id .. ", exit_code: " .. exit_code,
|
||||||
|
vim.log.levels.ERROR
|
||||||
|
)
|
||||||
|
end,
|
||||||
})
|
})
|
||||||
|
if job_id <= 0 then
|
||||||
|
vim.notify("Could not start gitlab.nvim binary", vim.log.levels.ERROR)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Builds the Go binary
|
-- Builds the Go binary
|
||||||
M.build = function(override)
|
M.build = function(override)
|
||||||
local file_path = u.current_file_path()
|
local file_path = u.current_file_path()
|
||||||
@@ -50,12 +80,13 @@ M.build = function(override)
|
|||||||
|
|
||||||
if not override then
|
if not override then
|
||||||
local binary_exists = vim.loop.fs_stat(state.settings.bin)
|
local binary_exists = vim.loop.fs_stat(state.settings.bin)
|
||||||
if binary_exists ~= nil then return end
|
if binary_exists ~= nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local cmd = u.is_windows() and
|
local cmd = u.is_windows() and "cd %s\\cmd && go build -o bin.exe && move bin.exe ..\\"
|
||||||
'cd %s\\cmd && go build -o bin.exe && move bin.exe ..\\' or
|
or "cd %s/cmd && go build -o bin && mv bin ../bin"
|
||||||
'cd %s/cmd && go build -o bin && mv bin ../bin'
|
|
||||||
|
|
||||||
local command = string.format(cmd, state.settings.bin_path)
|
local command = string.format(cmd, state.settings.bin_path)
|
||||||
local null = u.is_windows() and " >NUL" or " > /dev/null"
|
local null = u.is_windows() and " >NUL" or " > /dev/null"
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ local M = {}
|
|||||||
|
|
||||||
-- These are the default settings for the plugin
|
-- These are the default settings for the plugin
|
||||||
M.settings = {
|
M.settings = {
|
||||||
port = 21036,
|
port = nil, -- choose random port
|
||||||
log_path = (vim.fn.stdpath("cache") .. "/gitlab.nvim.log"),
|
log_path = (vim.fn.stdpath("cache") .. "/gitlab.nvim.log"),
|
||||||
reviewer = "delta",
|
reviewer = "delta",
|
||||||
attachment_dir = '',
|
attachment_dir = "",
|
||||||
popup = {
|
popup = {
|
||||||
exit = "<Esc>",
|
exit = "<Esc>",
|
||||||
perform_action = "<leader>s",
|
perform_action = "<leader>s",
|
||||||
@@ -29,15 +29,15 @@ M.settings = {
|
|||||||
relative = "editor",
|
relative = "editor",
|
||||||
position = "left",
|
position = "left",
|
||||||
size = "20%",
|
size = "20%",
|
||||||
resolved = '✓',
|
resolved = "✓",
|
||||||
unresolved = '',
|
unresolved = "",
|
||||||
},
|
},
|
||||||
review_pane = {
|
review_pane = {
|
||||||
delta = {
|
delta = {
|
||||||
added_file = "",
|
added_file = "",
|
||||||
modified_file = "",
|
modified_file = "",
|
||||||
removed_file = "",
|
removed_file = "",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
pipeline = {
|
pipeline = {
|
||||||
created = "",
|
created = "",
|
||||||
|
|||||||
@@ -126,20 +126,10 @@ M.create_popup_state = function(title, width, height)
|
|||||||
end
|
end
|
||||||
|
|
||||||
M.merge = function(defaults, overrides)
|
M.merge = function(defaults, overrides)
|
||||||
local result = {}
|
|
||||||
if type(defaults) == "table" and M.table_size(defaults) == 0 and type(overrides) == "table" then
|
if type(defaults) == "table" and M.table_size(defaults) == 0 and type(overrides) == "table" then
|
||||||
return overrides
|
return overrides
|
||||||
end
|
end
|
||||||
|
return vim.tbl_deep_extend("force", defaults, overrides)
|
||||||
for key, value in pairs(defaults) do
|
|
||||||
if type(value) == "table" then
|
|
||||||
result[key] = M.merge(value, overrides[key] or {})
|
|
||||||
else
|
|
||||||
result[key] = overrides[key] or value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
M.join = function(tbl, separator)
|
M.join = function(tbl, separator)
|
||||||
|
|||||||
Reference in New Issue
Block a user