Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(parser): support ssh://git@ protocol #124

Merged
merged 4 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@
--- @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(

Check warning on line 39 in lua/gitlinker/linker.lua

View check run for this annotation

Codecov / codecov/patch

lua/gitlinker/linker.lua#L38-L39

Added lines #L38 - L39 were not covered by tests
"failed to parse remote url protocol:%s",
vim.inspect(remote_url)

Check warning on line 41 in lua/gitlinker/linker.lua

View check run for this annotation

Codecov / codecov/patch

lua/gitlinker/linker.lua#L41

Added line #L41 was not covered by tests
)
)
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(

Check warning on line 67 in lua/gitlinker/linker.lua

View check run for this annotation

Codecov / codecov/patch

lua/gitlinker/linker.lua#L66-L67

Added lines #L66 - L67 were not covered by tests
"failed to parse remote url host:%s",
vim.inspect(remote_url)

Check warning on line 69 in lua/gitlinker/linker.lua

View check run for this annotation

Codecov / codecov/patch

lua/gitlinker/linker.lua#L69

Added line #L69 was not covered by tests
)
)
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 @@
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
Loading