Skip to content

Commit

Permalink
fix(parser): support ssh://git@ protocol (#124)
Browse files Browse the repository at this point in the history
  • Loading branch information
linrongbin16 authored Nov 17, 2023
1 parent 1236865 commit 53c4efc
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 68 deletions.
2 changes: 1 addition & 1 deletion lua/gitlinker.lua
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ local function setup(opts)
end
vim.keymap.set({ "n", "v" }, k, function()
deprecation.notify(
"'mapping' option is deprecated! please migrate to 'GitLink' command."
"'mapping' option is deprecated! please set 'mapping=false' and migrate to 'GitLink' command."
)
logger.debug("|setup| keymap v:%s", vim.inspect(v))
link({ action = v.action, router = v.router })
Expand Down
94 changes: 60 additions & 34 deletions lua/gitlinker/linker.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,49 +11,75 @@ local utils = require("gitlinker.utils")
--- @param remote_url string
--- @return {protocol:string?,host:string?,user:string?,repo:string?}
local function _parse_remote_url(remote_url)
local GIT = "git"
local HTTP = "http"
local HTTPS = "https"
local GIT_PROTO = "git@"
local HTTP_PROTO = "http://"
local HTTPS_PROTO = "https://"
local PROTOS = { ["git@"] = ":", ["https://"] = "/", ["http://"] = "/" }

local protocol = nil
local protocol_end_pos = nil
local host = nil
local host_end_pos = nil
local user = nil
local repo = nil
if utils.string_startswith(remote_url, GIT_PROTO) then
protocol = GIT
protocol_end_pos = string.len(GIT_PROTO)
host_end_pos = utils.string_find(remote_url, ":", protocol_end_pos + 1)
logger.ensure(
type(host_end_pos) == "number" and host_end_pos > protocol_end_pos + 1,
"failed to parse remote url host:%s",
vim.inspect(remote_url)

--- @type string
local proto = nil
--- @type string
local proto_delimiter = nil
--- @type integer?
local proto_pos = nil
for p, d in pairs(PROTOS) do
proto_pos = utils.string_find(remote_url, p)
if type(proto_pos) == "number" and proto_pos > 0 then
proto = p
proto_delimiter = d
break
end
end
if not proto_pos then
error(
string.format(
"failed to parse remote url protocol:%s",
vim.inspect(remote_url)
)
)
host = remote_url:sub(protocol_end_pos + 1, host_end_pos - 1)
elseif
utils.string_startswith(remote_url, HTTP_PROTO)
or utils.string_startswith(remote_url, HTTPS_PROTO)
then
protocol = utils.string_startswith(remote_url, HTTP_PROTO) and HTTP or HTTPS
protocol_end_pos = utils.string_startswith(remote_url, HTTP_PROTO)
and string.len(HTTP_PROTO)
or string.len(HTTPS_PROTO)
host_end_pos = utils.string_find(remote_url, "/", protocol_end_pos + 1)
logger.ensure(
type(host_end_pos) == "number" and host_end_pos > protocol_end_pos + 1,
"failed to parse remote url host:%s",
vim.inspect(remote_url)
end

logger.debug(
"|gitlinker.linker - _parse_remote_url| 1. remote_url:%s, proto_pos:%s (%s)",
vim.inspect(remote_url),
vim.inspect(proto_pos),
vim.inspect(proto)
)
if type(proto_pos) == "number" and proto_pos > 0 then
protocol_end_pos = proto_pos + string.len(proto) - 1
protocol = remote_url:sub(1, protocol_end_pos)
logger.debug(
"|gitlinker.linker - _parse_remote_url| 2. remote_url:%s, proto_pos:%s (%s), protocol_end_pos:%s (%s)",
vim.inspect(remote_url),
vim.inspect(proto_pos),
vim.inspect(proto),
vim.inspect(protocol_end_pos),
vim.inspect(protocol)
)
host_end_pos =
utils.string_find(remote_url, proto_delimiter, protocol_end_pos + 1)
if not host_end_pos then
error(
string.format(
"failed to parse remote url host:%s",
vim.inspect(remote_url)
)
)
end
host = remote_url:sub(protocol_end_pos + 1, host_end_pos - 1)
else
logger.ensure(
false,
"failed to parse remote url:%s",
vim.inspect(remote_url)
logger.debug(
"|gitlinker.linker - _parse_remote_url| last. remote_url:%s, proto_pos:%s (%s), protocol_end_pos:%s (%s), host_end_pos:%s (%s)",
vim.inspect(remote_url),
vim.inspect(proto_pos),
vim.inspect(proto),
vim.inspect(protocol_end_pos),
vim.inspect(protocol),
vim.inspect(host_end_pos),
vim.inspect(host)
)
end

Expand All @@ -68,7 +94,7 @@ local function _parse_remote_url(remote_url)
return result
end

--- @alias gitlinker.Linker {remote_url:string,protocol:"git"|"http"|"https",host:string,user:string,repo:string,rev:string,file:string,lstart:integer,lend:integer,file_changed:boolean}
--- @alias gitlinker.Linker {remote_url:string,protocol:string,host:string,user:string,repo:string,rev:string,file:string,lstart:integer,lend:integer,file_changed:boolean}
--- @return gitlinker.Linker?
local function make_linker()
local root = git.get_root()
Expand Down
28 changes: 11 additions & 17 deletions lua/gitlinker/routers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function Builder:new(lk, range_maker)
local o = {
domain = string.format(
"%s%s",
lk.protocol == "git" and "https://" or (lk.protocol .. "://"),
utils.string_endswith(lk.protocol, "git@") and "https://" or lk.protocol,
lk.host
),
user = lk.user,
Expand Down Expand Up @@ -125,7 +125,7 @@ local function browse(lk, _placeholder)
assert(
type(_placeholder) == "boolean" and _placeholder,
string.format(
"%s must be true, make sure you didn't set this function in 'router_binding'",
"%s must be true, make sure you didn't set this function in 'router'",
vim.inspect(_placeholder)
)
)
Expand All @@ -142,7 +142,7 @@ local function browse(lk, _placeholder)
assert(
false,
string.format(
"%s not support, please bind it in 'router_binding'!",
"%s not support, please bind it in 'router'!",
vim.inspect(lk.host)
)
)
Expand Down Expand Up @@ -180,7 +180,7 @@ local function blame(lk, _placeholder)
assert(
type(_placeholder) == "boolean" and _placeholder,
string.format(
"%s must be true, make sure you didn't set this function in 'router_binding'",
"%s must be true, make sure you didn't set this function in 'router'",
vim.inspect(_placeholder)
)
)
Expand All @@ -197,25 +197,19 @@ local function blame(lk, _placeholder)
assert(
false,
string.format(
"%s not support, please bind it in 'router_binding'!",
"%s not support, please bind it in 'router'!",
vim.inspect(lk.host)
)
)
return nil
end

--- @param router_binding gitlinker.Options
local function setup(router_binding)
BROWSE_BINDING = vim.tbl_extend(
"force",
vim.deepcopy(BROWSE_BINDING),
router_binding.browse or {}
)
BLAME_BINDING = vim.tbl_extend(
"force",
vim.deepcopy(BLAME_BINDING),
router_binding.blame or {}
)
--- @param bindings gitlinker.Options
local function setup(bindings)
BROWSE_BINDING =
vim.tbl_extend("force", vim.deepcopy(BROWSE_BINDING), bindings.browse or {})
BLAME_BINDING =
vim.tbl_extend("force", vim.deepcopy(BLAME_BINDING), bindings.blame or {})
end

local M = {
Expand Down
22 changes: 16 additions & 6 deletions test/linker_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,17 @@ describe("linker", function()
"git@github.com:linrongbin16/gitlinker.nvim.git"
)
assert_eq(type(parsed), "table")
assert_eq(parsed.protocol, "git")
assert_eq(parsed.protocol, "git@")
assert_eq(parsed.host, "github.com")
assert_eq(parsed.user, "linrongbin16")
assert_eq(parsed.repo, "gitlinker.nvim.git")
end)
it("parse ssh://git@", function()
local parsed = linker._parse_remote_url(
"ssh://git@github.com:linrongbin16/gitlinker.nvim.git"
)
assert_eq(type(parsed), "table")
assert_eq(parsed.protocol, "ssh://git@")
assert_eq(parsed.host, "github.com")
assert_eq(parsed.user, "linrongbin16")
assert_eq(parsed.repo, "gitlinker.nvim.git")
Expand All @@ -31,7 +41,7 @@ describe("linker", function()
"http://github.com/linrongbin16/gitlinker.nvim.git"
)
assert_eq(type(parsed), "table")
assert_eq(parsed.protocol, "http")
assert_eq(parsed.protocol, "http://")
assert_eq(parsed.host, "github.com")
assert_eq(parsed.user, "linrongbin16")
assert_eq(parsed.repo, "gitlinker.nvim.git")
Expand All @@ -41,7 +51,7 @@ describe("linker", function()
"https://github.com/linrongbin16/gitlinker.nvim.git"
)
assert_eq(type(parsed), "table")
assert_eq(parsed.protocol, "https")
assert_eq(parsed.protocol, "https://")
assert_eq(parsed.host, "github.com")
assert_eq(parsed.user, "linrongbin16")
assert_eq(parsed.repo, "gitlinker.nvim.git")
Expand All @@ -68,15 +78,15 @@ describe("linker", function()
end
end)
it("make with range", function()
local lk = linker.make_linker({ lstart = 10, lend = 20 }) --[[@as gitlinker.Linker]]
local lk = linker.make_linker() --[[@as gitlinker.Linker]]
print(string.format("linker:%s", vim.inspect(lk)))
if github_actions then
assert_true(type(lk) == "table" or lk == nil)
else
assert_eq(type(lk), "table")
assert_eq(lk.file, "lua/gitlinker.lua")
assert_eq(lk.lstart, 10)
assert_eq(lk.lend, 20)
assert_true(type(lk.lstart) == "number" and lk.lstart > 0)
assert_true(type(lk.lend) == "number" and lk.lend > 0)
assert_eq(type(lk.rev), "string")
assert_true(string.len(lk.rev) > 0)
assert_eq(type(lk.remote_url), "string")
Expand Down
20 changes: 10 additions & 10 deletions test/routers_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe("routers", function()
it("without line numbers", function()
local actual = routers.browse({
remote_url = "git@github.com:linrongbin16/gitlinker.nvim.git",
protocol = "git",
protocol = "git@",
host = "github.com",
user = "linrongbin16",
repo = "gitlinker.nvim.git",
Expand All @@ -37,7 +37,7 @@ describe("routers", function()
it("with line start", function()
local actual = routers.browse({
remote_url = "git@github.com:linrongbin16/gitlinker.nvim.git",
protocol = "git",
protocol = "git@",
host = "github.com",
user = "linrongbin16",
repo = "gitlinker.nvim.git",
Expand All @@ -55,7 +55,7 @@ describe("routers", function()
it("with same line start and line end", function()
local actual = routers.browse({
remote_url = "git@github.com:linrongbin16/gitlinker.nvim.git",
protocol = "git",
protocol = "git@",
host = "github.com",
user = "linrongbin16",
repo = "gitlinker.nvim.git",
Expand All @@ -73,7 +73,7 @@ describe("routers", function()
it("with different line start and line end", function()
local actual = routers.browse({
remote_url = "git@github.com:linrongbin16/gitlinker.nvim.git",
protocol = "git",
protocol = "git@",
host = "github.com",
user = "linrongbin16",
repo = "gitlinker.nvim.git",
Expand All @@ -91,7 +91,7 @@ describe("routers", function()
it("bitbucket without line numbers", function()
local actual = routers.bitbucket_browse({
remote_url = "git@bitbucket.org:linrongbin16/gitlinker.nvim.git",
protocol = "git",
protocol = "git@",
host = "bitbucket.org",
user = "linrongbin16",
repo = "gitlinker.nvim.git",
Expand All @@ -107,7 +107,7 @@ describe("routers", function()
it("bitbucket with line start", function()
local actual = routers.bitbucket_browse({
remote_url = "git@bitbucket.org:linrongbin16/gitlinker.nvim.git",
protocol = "git",
protocol = "git@",
host = "bitbucket.org",
user = "linrongbin16",
repo = "gitlinker.nvim.git",
Expand All @@ -127,7 +127,7 @@ describe("routers", function()
it("without line numbers", function()
local actual = routers.blame({
remote_url = "git@github.com:linrongbin16/gitlinker.nvim.git",
protocol = "git",
protocol = "git@",
host = "github.com",
user = "linrongbin16",
repo = "gitlinker.nvim.git",
Expand All @@ -143,7 +143,7 @@ describe("routers", function()
it("with line start", function()
local actual = routers.blame({
remote_url = "git@github.com:linrongbin16/gitlinker.nvim.git",
protocol = "git",
protocol = "git@",
host = "github.com",
user = "linrongbin16",
repo = "gitlinker.nvim.git",
Expand All @@ -161,7 +161,7 @@ describe("routers", function()
it("bitbucket without line numbers", function()
local actual = routers.bitbucket_blame({
remote_url = "git@github.com:linrongbin16/gitlinker.nvim.git",
protocol = "git",
protocol = "git@",
host = "github.com",
user = "linrongbin16",
repo = "gitlinker.nvim.git",
Expand All @@ -177,7 +177,7 @@ describe("routers", function()
it("bitbucket with line start", function()
local actual = routers.bitbucket_blame({
remote_url = "git@github.com:linrongbin16/gitlinker.nvim.git",
protocol = "git",
protocol = "git@",
host = "github.com",
user = "linrongbin16",
repo = "gitlinker.nvim.git",
Expand Down

0 comments on commit 53c4efc

Please sign in to comment.