From 9bf59bf7e304018f4590b3c54232d2a82038caa8 Mon Sep 17 00:00:00 2001
From: linrongbin16 git remote get-url origin
.
git remot
## API
-### `giturlparser.GitUrlPos`
+### Types
+
+#### `giturlparser.GitUrlPos`
The string index of a component.
@@ -35,7 +40,7 @@ It contains below fields:
- `start_pos`: Start string index.
- `end_pos`: End string index.
-### `giturlparser.GitUrlInfo`
+#### `giturlparser.GitUrlInfo`
Parsed information.
@@ -68,7 +73,9 @@ It contains below fields:
>
> If there's only 1 slash, the `org` component is omitted.
-### `parse`
+### Functions
+
+#### `parse`
Parse `url` and returns the parsed info (lua table).
@@ -90,7 +97,6 @@ Returns:
## References
1. [What are the supported git url formats?](https://stackoverflow.com/questions/31801271/what-are-the-supported-git-url-formats)
-2. [4.1 Git on the Server - The Protocols](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols)
## Development
diff --git a/giturlparser-1.0.3-1.rockspec b/giturlparser-scm-1.rockspec
similarity index 95%
rename from giturlparser-1.0.3-1.rockspec
rename to giturlparser-scm-1.rockspec
index bcc65c3..18b1e1a 100644
--- a/giturlparser-1.0.3-1.rockspec
+++ b/giturlparser-scm-1.rockspec
@@ -1,5 +1,5 @@
package = "giturlparser"
-version = "1.0.3-1"
+version = "scm-1"
source = {
url = "git+https://github.com/linrongbin16/giturlparser.lua.git",
}
From c86279f008639ee127d531c3b1f4b3b3f584beb8 Mon Sep 17 00:00:00 2001
From: linrongbin16
Date: Sun, 7 Jan 2024 16:57:14 +0800
Subject: [PATCH 2/7] chore(docs): wording (#25)
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 4ff22c2..fc80c29 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ Pure Lua implemented git URL parsing library, e.g. the output of git remot
#### `giturlparser.GitUrlPos`
-The string index of a component.
+The string position of a component.
```lua
--- @alias giturlparser.GitUrlPos {start_pos:integer?,end_pos:integer?}
From 2b6f1dad3c7f3cd8de156c2028038aa9ae9e393e Mon Sep 17 00:00:00 2001
From: linrongbin16
Date: Sun, 7 Jan 2024 17:07:18 +0800
Subject: [PATCH 3/7] chore(docs): wording (#26)
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index fc80c29..5896132 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
Pure Lua implemented git URL parsing library, e.g. the output of git remote get-url origin
.
-# Requirements
+## Requirements
- Lua >= 5.1, luajit >= 2.0.0.
@@ -23,7 +23,7 @@ Pure Lua implemented git URL parsing library, e.g. the output of git remot
`luarocks install giturlparser`
-## API
+## Documents
### Types
From 29c0994a31fb9b4ca392f21bb84f102f92706076 Mon Sep 17 00:00:00 2001
From: linrongbin16
Date: Sun, 7 Jan 2024 17:09:56 +0800
Subject: [PATCH 4/7] chore(make): update (#27)
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index 5f60bee..4a2cd3e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-install_dev:
+install_deps:
luarocks install --local luacov
luarocks install --local busted
From 454d7c3094669641c5e5dcc3060947f2364e7634 Mon Sep 17 00:00:00 2001
From: linrongbin16
Date: Mon, 8 Jan 2024 15:05:00 +0800
Subject: [PATCH 5/7] fix(parse): fix parse (#28)
---
.luacheckrc | 1 +
Makefile | 6 -
README.md | 90 ++-
giturlparser-scm-1.rockspec | 3 +
spec/giturlparser_spec.lua | 1432 ++++++++++++++++++++++++++++++++++-
src/giturlparser.lua | 643 ++++++++--------
6 files changed, 1835 insertions(+), 340 deletions(-)
delete mode 100644 Makefile
diff --git a/.luacheckrc b/.luacheckrc
index 56f2305..810574b 100644
--- a/.luacheckrc
+++ b/.luacheckrc
@@ -3,3 +3,4 @@ max_line_length = 500
unused = false
unused_args = false
exclude_files = {}
+ignore = { "542" }
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 4a2cd3e..0000000
--- a/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-install_deps:
- luarocks install --local luacov
- luarocks install --local busted
-
-test:
- busted --coverage
diff --git a/README.md b/README.md
index 5896132..11b3837 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
+
+
# giturlparser.lua
@@ -10,20 +12,69 @@
Pure Lua implemented git URL parsing library, e.g. the output of git remote get-url origin
.
+## Table of Contents
+
+- [Requirements](#requirements)
+- [Features](#features)
+- [Install](#install)
+- [API](#api)
+ - [Types](#types)
+ - [`giturlparser.GitUrlPos`](#giturlparsergiturlpos)
+ - [`giturlparser.GitUrlInfo`](#giturlparsergiturlinfo)
+ - [Functions](#functions)
+ - [`parse`](#parse)
+- [References](#references)
+- [Development](#development)
+- [Contribute](#contribute)
+
## Requirements
- Lua >= 5.1, luajit >= 2.0.0.
## Features
-- [x] Single file & zero dependency.
-- [x] Full [Git Protocols](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols) support.
+Single file & zero dependency.
+
+Full [Git Protocols](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols) support:
+
+> [!NOTE]
+>
+> Below pattern are (just easier to help explain the parsing algorithm) written in a regex-like syntax:
+>
+> 1. The `{}` contains parsed components returned from [`giturlparser.GitUrlInfo`](#giturlparsergiturlinfo).
+> 2. The `[]` contains optional (0 or 1) component.
+> 3. The `[]*` contains zero or more (≥ 0) component.
+> 4. The `[]+` contains 1 or more (≥ 1) component.
+> 5. The `|` inside `[]` is **_or_** operator.
+
+1. `{protocol}://[[{user}[:{password}]@]{host}[:{port}]]/[{org}/]*{repo}`, for example:
+ - `http://host.xyz/repo.git`
+ - `https://git@127.0.0.1:12345/repo.git`
+ - `ssh://username:password@host.xyz:port/path/to/the/repo.git`
+ - `ssh://host.xyz:port/path/to/the/repo.git`
+ - `file:///repo.git`
+ - `file://user:passwd@host.xyz:port/path/to/the/repo.git`
+ - `file://~/home/to/the/repo.git`
+2. `[{user}[:{password}]@]{host}:[{org}/]*{repo}`, for example:
+ - `git@host.xyz:repo.git`
+ - `user:passwd@host.xyz:path/to/the/repo.git`
+3. `[.|..|~][/{org}]*/{repo}`, for example:
+ - `repo.git`
+ - `./repo.git`
+ - `../path/to/the/repo.git`
+ - `~/home/to/the/repo.git`
+ - `/usr/home/to/the/repo.git`
+
+All of above can be written by:
+
+1. `[{protocol}://][[{user}[:{password}]@]host[:{port}]]/[{org}/]*{repo}`
+2. `[.|..|~][/{org}]*/{repo}`
## Install
`luarocks install giturlparser`
-## Documents
+## API
### Types
@@ -50,28 +101,23 @@ Parsed information.
It contains below fields:
-- `protocol`: Protocol, e.g. `http` (`http://`), `https` (`https://`), `ssh` (`ssh://`), `file` (`file://`).
-- `protocol_pos`: Protocol position.
-- `user`: User name, e.g. `username` in `ssh://username@githost.com`.
-- `user_pos`: User name position.
-- `password`: Password, e.g. `password` in `ssh://username:password@githost.com`.
-- `password_pos`: Password position.
-- `host`: Host name, e.g. `githost.com` in `ssh://githost.com`.
-- `host_pos`: Host name position.
-- `path`: All the left parts after `host/`, e.g. `linrongbin16/giturlparser.lua.git` in `https://github.com/linrongbin16/giturlparser.lua.git`.
-- `path_pos`: Path position.
-- `repo`: Repository (the left parts after the last slash `/`, if exists), e.g. `giturlparser.lua.git` in `https://github.com/linrongbin16/giturlparser.lua.git`.
-- `repo_pos`: Repository position.
-- `org`: , Organization (the parts after `host/` and before the last slash `/`, if exists), e.g. `linrongbin16` in `https://github.com/linrongbin16/giturlparser.lua.git`.
-- `org_pos`: Organization position.
+- `protocol`/`protocol_pos`: Protocol, e.g. `http` in `http://github.com`, and its position.
+- `user`/`user_pos`: User name, e.g. `username` in `ssh://username@githost.com`, and its position.
+- `password`/`password_pos`: Password, e.g. `password` in `ssh://username:password@githost.com`, and its position.
+- `host`/`host_pos`: Host name, e.g. `githost.com` in `ssh://githost.com`, and its position.
+- `port`/`port_pos`: Port, e.g. `12345` in `ssh://127.0.0.1:12345/org/repo.git`, and its position.
+- `path`/`path_pos`: All the left parts after host name (and optional port), e.g. `/linrongbin16/giturlparser.lua.git` in `https://github.com/linrongbin16/giturlparser.lua.git`, and its position.
-> [!NOTE]
->
-> The `{path}` component is equivalent to `{org}/{repo}`.
+There're 2 more sugar fields:
-> [!IMPORTANT]
+- `repo`/`repo_pos`: Repository (the last part after the last slash `/`), e.g. `giturlparser.lua.git` in `https://github.com/linrongbin16/giturlparser.lua.git`, and its position.
+- `org`/`org_pos`: , Organization (the parts after host name (and optional port), before the last slash `/`), e.g. `linrongbin16` in `https://github.com/linrongbin16/giturlparser.lua.git`, and its position.
+
+> [!NOTE]
>
-> If there's only 1 slash, the `org` component is omitted.
+> - The `{path}` component is (almost) equivalent to `/{org}/{repo}`.
+> - The `{org}` and `{repo}` component are trimmed from around slashes if there's any.
+> - If there's only 1 slash, the `org` component is omitted.
### Functions
diff --git a/giturlparser-scm-1.rockspec b/giturlparser-scm-1.rockspec
index 18b1e1a..a9b930a 100644
--- a/giturlparser-scm-1.rockspec
+++ b/giturlparser-scm-1.rockspec
@@ -11,6 +11,9 @@ description = {
dependencies = {
"lua >= 5.1, luajit >= 2.0.0",
}
+test_dependencies = {
+ "inspect",
+}
build = {
type = "builtin",
modules = {
diff --git a/spec/giturlparser_spec.lua b/spec/giturlparser_spec.lua
index 3d49659..d096cee 100644
--- a/spec/giturlparser_spec.lua
+++ b/spec/giturlparser_spec.lua
@@ -5,8 +5,857 @@ describe("giturlparser", function()
before_each(function() end)
+ -- local inspect = require("inspect")
local giturlparser = require("giturlparser")
- describe("[http(s)]", function()
+ describe("[_make_path]", function()
+ it("repo.git", function()
+ local actual = giturlparser._make_path("repo.git", 1)
+ assert_eq(actual.org, nil)
+ assert_eq(actual.org_pos, nil)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 1)
+ assert_eq(actual.repo_pos.end_pos, 8)
+ assert_eq(actual.path, "repo.git")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 8)
+ end)
+ it("repo.git/", function()
+ local actual = giturlparser._make_path("repo.git/", 1)
+ assert_eq(actual.org, nil)
+ assert_eq(actual.org_pos, nil)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 1)
+ assert_eq(actual.repo_pos.end_pos, 8)
+ assert_eq(actual.path, "repo.git/")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 9)
+ end)
+ it("/repo.git/", function()
+ local actual = giturlparser._make_path("/repo.git/", 1)
+ assert_eq(actual.org, nil)
+ assert_eq(actual.org_pos, nil)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 2)
+ assert_eq(actual.repo_pos.end_pos, 9)
+ assert_eq(actual.path, "/repo.git/")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 10)
+ end)
+ it("/repo.git", function()
+ local actual = giturlparser._make_path("/repo.git", 1)
+ assert_eq(actual.org, nil)
+ assert_eq(actual.org_pos, nil)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 2)
+ assert_eq(actual.repo_pos.end_pos, 9)
+ assert_eq(actual.path, "/repo.git")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 9)
+ end)
+ it("path/to/the/repo.git", function()
+ local actual = giturlparser._make_path("path/to/the/repo.git", 1)
+ assert_eq(actual.org, "path/to/the")
+ assert_eq(actual.org_pos.start_pos, 1)
+ assert_eq(actual.org_pos.end_pos, 11)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 13)
+ assert_eq(actual.repo_pos.end_pos, 20)
+ assert_eq(actual.path, "path/to/the/repo.git")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 20)
+ end)
+ it("path/to/the/repo.git/", function()
+ local actual = giturlparser._make_path("path/to/the/repo.git/", 1)
+ assert_eq(actual.org, "path/to/the")
+ assert_eq(actual.org_pos.start_pos, 1)
+ assert_eq(actual.org_pos.end_pos, 11)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 13)
+ assert_eq(actual.repo_pos.end_pos, 20)
+ assert_eq(actual.path, "path/to/the/repo.git/")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 21)
+ end)
+ it("/abspath/to/the/repo.git", function()
+ local actual = giturlparser._make_path("/abspath/to/the/repo.git", 1)
+ assert_eq(actual.org, "abspath/to/the")
+ assert_eq(actual.org_pos.start_pos, 2)
+ assert_eq(actual.org_pos.end_pos, 15)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 17)
+ assert_eq(actual.repo_pos.end_pos, 24)
+ assert_eq(actual.path, "/abspath/to/the/repo.git")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 24)
+ end)
+ it("/abspath/to/the/repo.git/", function()
+ local actual = giturlparser._make_path("/abspath/to/the/repo.git/", 1)
+ assert_eq(actual.org, "abspath/to/the")
+ assert_eq(actual.org_pos.start_pos, 2)
+ assert_eq(actual.org_pos.end_pos, 15)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 17)
+ assert_eq(actual.repo_pos.end_pos, 24)
+ assert_eq(actual.path, "/abspath/to/the/repo.git/")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 25)
+ end)
+ it("~/path/to/the/repo.git", function()
+ local actual = giturlparser._make_path("~/path/to/the/repo.git", 1)
+ assert_eq(actual.org, "~/path/to/the")
+ assert_eq(actual.org_pos.start_pos, 1)
+ assert_eq(actual.org_pos.end_pos, 13)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 15)
+ assert_eq(actual.repo_pos.end_pos, 22)
+ assert_eq(actual.path, "~/path/to/the/repo.git")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 22)
+ end)
+ it("~/path/to/the/repo.git/", function()
+ local actual = giturlparser._make_path("~/path/to/the/repo.git/", 1)
+ assert_eq(actual.org, "~/path/to/the")
+ assert_eq(actual.org_pos.start_pos, 1)
+ assert_eq(actual.org_pos.end_pos, 13)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 15)
+ assert_eq(actual.repo_pos.end_pos, 22)
+ assert_eq(actual.path, "~/path/to/the/repo.git/")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 23)
+ end)
+ it("./path/to/the/repo.git", function()
+ local actual = giturlparser._make_path("./path/to/the/repo.git", 1)
+ assert_eq(actual.org, "./path/to/the")
+ assert_eq(actual.org_pos.start_pos, 1)
+ assert_eq(actual.org_pos.end_pos, 13)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 15)
+ assert_eq(actual.repo_pos.end_pos, 22)
+ assert_eq(actual.path, "./path/to/the/repo.git")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 22)
+ end)
+ it("../path/to/the/repo.git/", function()
+ local actual = giturlparser._make_path("../path/to/the/repo.git/", 1)
+ assert_eq(actual.org, "../path/to/the")
+ assert_eq(actual.org_pos.start_pos, 1)
+ assert_eq(actual.org_pos.end_pos, 14)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 16)
+ assert_eq(actual.repo_pos.end_pos, 23)
+ assert_eq(actual.path, "../path/to/the/repo.git/")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 24)
+ end)
+ end)
+
+ describe("[_make_host]", function()
+ it("github.com/org/repo.git", function()
+ local actual = giturlparser._make_host("github.com/org/repo.git", 1)
+ -- print(string.format("_make_host-1:%s\n", inspect(actual)))
+ assert_eq(actual.host, "github.com")
+ assert_eq(actual.host_pos.start_pos, 1)
+ assert_eq(actual.host_pos.end_pos, 10)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ local path_obj = actual.path_obj
+ assert_eq(path_obj.org, "org")
+ assert_eq(path_obj.org_pos.start_pos, 12)
+ assert_eq(path_obj.org_pos.end_pos, 14)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 16)
+ assert_eq(path_obj.repo_pos.end_pos, 23)
+ assert_eq(path_obj.path, "/org/repo.git")
+ assert_eq(path_obj.path_pos.start_pos, 11)
+ assert_eq(path_obj.path_pos.end_pos, 23)
+ end)
+ it("github.com/org/repo.git/", function()
+ local actual = giturlparser._make_host("github.com/org/repo.git/", 1)
+ -- print(string.format("_make_host-2:%s\n", inspect(actual)))
+ assert_eq(actual.host, "github.com")
+ assert_eq(actual.host_pos.start_pos, 1)
+ assert_eq(actual.host_pos.end_pos, 10)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ local path_obj = actual.path_obj
+ assert_eq(path_obj.org, "org")
+ assert_eq(path_obj.org_pos.start_pos, 12)
+ assert_eq(path_obj.org_pos.end_pos, 14)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 16)
+ assert_eq(path_obj.repo_pos.end_pos, 23)
+ assert_eq(path_obj.path, "/org/repo.git/")
+ assert_eq(path_obj.path_pos.start_pos, 11)
+ assert_eq(path_obj.path_pos.end_pos, 24)
+ end)
+ it("github.com:port/org/repo.git", function()
+ local actual = giturlparser._make_host("github.com:port/org/repo.git", 1)
+ -- print(string.format("_make_host-3:%s\n", inspect(actual)))
+ assert_eq(actual.host, "github.com")
+ assert_eq(actual.host_pos.start_pos, 1)
+ assert_eq(actual.host_pos.end_pos, 10)
+ assert_eq(actual.port, "port")
+ assert_eq(actual.port_pos.start_pos, 12)
+ assert_eq(actual.port_pos.end_pos, 15)
+ local path_obj = actual.path_obj
+ assert_eq(path_obj.org, "org")
+ assert_eq(path_obj.org_pos.start_pos, 17)
+ assert_eq(path_obj.org_pos.end_pos, 19)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 21)
+ assert_eq(path_obj.repo_pos.end_pos, 28)
+ assert_eq(path_obj.path, "/org/repo.git")
+ assert_eq(path_obj.path_pos.start_pos, 16)
+ assert_eq(path_obj.path_pos.end_pos, 28)
+ end)
+ it("127.0.0.1:12345/org/repo.git/", function()
+ local actual = giturlparser._make_host("127.0.0.1:12345/org/repo.git/", 1)
+ -- print(string.format("_make_host-4:%s\n", inspect(actual)))
+ assert_eq(actual.host, "127.0.0.1")
+ assert_eq(actual.host_pos.start_pos, 1)
+ assert_eq(actual.host_pos.end_pos, 9)
+ assert_eq(actual.port, "12345")
+ assert_eq(actual.port_pos.start_pos, 11)
+ assert_eq(actual.port_pos.end_pos, 15)
+ local path_obj = actual.path_obj
+ assert_eq(path_obj.org, "org")
+ assert_eq(path_obj.org_pos.start_pos, 17)
+ assert_eq(path_obj.org_pos.end_pos, 19)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 21)
+ assert_eq(path_obj.repo_pos.end_pos, 28)
+ assert_eq(path_obj.path, "/org/repo.git/")
+ assert_eq(path_obj.path_pos.start_pos, 16)
+ assert_eq(path_obj.path_pos.end_pos, 29)
+ end)
+ it("github.com/repo.git", function()
+ local actual = giturlparser._make_host("github.com/repo.git", 1)
+ -- print(string.format("_make_host-3:%s\n", inspect(actual)))
+ assert_eq(actual.host, "github.com")
+ assert_eq(actual.host_pos.start_pos, 1)
+ assert_eq(actual.host_pos.end_pos, 10)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ local path_obj = actual.path_obj
+ assert_eq(path_obj.org, nil)
+ assert_eq(path_obj.org_pos, nil)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 12)
+ assert_eq(path_obj.repo_pos.end_pos, 19)
+ assert_eq(path_obj.path, "/repo.git")
+ assert_eq(path_obj.path_pos.start_pos, 11)
+ assert_eq(path_obj.path_pos.end_pos, 19)
+ end)
+ it("127.0.0.1:12345/repo.git/", function()
+ local actual = giturlparser._make_host("127.0.0.1:12345/repo.git/", 1)
+ -- print(string.format("_make_host-4:%s\n", inspect(actual)))
+ assert_eq(actual.host, "127.0.0.1")
+ assert_eq(actual.host_pos.start_pos, 1)
+ assert_eq(actual.host_pos.end_pos, 9)
+ assert_eq(actual.port, "12345")
+ assert_eq(actual.port_pos.start_pos, 11)
+ assert_eq(actual.port_pos.end_pos, 15)
+ local path_obj = actual.path_obj
+ assert_eq(path_obj.org, nil)
+ assert_eq(path_obj.org_pos, nil)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 17)
+ assert_eq(path_obj.repo_pos.end_pos, 24)
+ assert_eq(path_obj.path, "/repo.git/")
+ assert_eq(path_obj.path_pos.start_pos, 16)
+ assert_eq(path_obj.path_pos.end_pos, 25)
+ end)
+ end)
+
+ describe("[_make_host_with_omit_ssh]", function()
+ it("github.com:org/repo.git", function()
+ local actual =
+ giturlparser._make_host_with_omit_ssh("github.com:org/repo.git", 1)
+ -- print(string.format("_make_host_with_omit_ssh-1:%s\n", inspect(actual)))
+ assert_eq(actual.host, "github.com")
+ assert_eq(actual.host_pos.start_pos, 1)
+ assert_eq(actual.host_pos.end_pos, 10)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ local path_obj = actual.path_obj
+ assert_eq(path_obj.org, "org")
+ assert_eq(path_obj.org_pos.start_pos, 12)
+ assert_eq(path_obj.org_pos.end_pos, 14)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 16)
+ assert_eq(path_obj.repo_pos.end_pos, 23)
+ assert_eq(path_obj.path, "org/repo.git")
+ assert_eq(path_obj.path_pos.start_pos, 12)
+ assert_eq(path_obj.path_pos.end_pos, 23)
+ end)
+ it("github.com:org/repo.git/", function()
+ local actual =
+ giturlparser._make_host_with_omit_ssh("github.com:org/repo.git/", 1)
+ -- print(string.format("_make_host_with_omit_ssh-2:%s\n", inspect(actual)))
+ assert_eq(actual.host, "github.com")
+ assert_eq(actual.host_pos.start_pos, 1)
+ assert_eq(actual.host_pos.end_pos, 10)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ local path_obj = actual.path_obj
+ assert_eq(path_obj.org, "org")
+ assert_eq(path_obj.org_pos.start_pos, 12)
+ assert_eq(path_obj.org_pos.end_pos, 14)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 16)
+ assert_eq(path_obj.repo_pos.end_pos, 23)
+ assert_eq(path_obj.path, "org/repo.git/")
+ assert_eq(path_obj.path_pos.start_pos, 12)
+ assert_eq(path_obj.path_pos.end_pos, 24)
+ end)
+ it("github.com:repo.git", function()
+ local actual =
+ giturlparser._make_host_with_omit_ssh("github.com:repo.git", 1)
+ -- print(string.format("_make_host_with_omit_ssh-3:%s\n", inspect(actual)))
+ assert_eq(actual.host, "github.com")
+ assert_eq(actual.host_pos.start_pos, 1)
+ assert_eq(actual.host_pos.end_pos, 10)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ local path_obj = actual.path_obj
+ assert_eq(path_obj.org, nil)
+ assert_eq(path_obj.org_pos, nil)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 12)
+ assert_eq(path_obj.repo_pos.end_pos, 19)
+ assert_eq(path_obj.path, "repo.git")
+ assert_eq(path_obj.path_pos.start_pos, 12)
+ assert_eq(path_obj.path_pos.end_pos, 19)
+ end)
+ it("127.0.0.1:repo.git/", function()
+ local actual =
+ giturlparser._make_host_with_omit_ssh("127.0.0.1:repo.git/", 1)
+ -- print(string.format("_make_host_with_omit_ssh-4:%s\n", inspect(actual)))
+ assert_eq(actual.host, "127.0.0.1")
+ assert_eq(actual.host_pos.start_pos, 1)
+ assert_eq(actual.host_pos.end_pos, 9)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ local path_obj = actual.path_obj
+ assert_eq(path_obj.org, nil)
+ assert_eq(path_obj.org_pos, nil)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 11)
+ assert_eq(path_obj.repo_pos.end_pos, 18)
+ assert_eq(path_obj.path, "repo.git/")
+ assert_eq(path_obj.path_pos.start_pos, 11)
+ assert_eq(path_obj.path_pos.end_pos, 19)
+ end)
+ end)
+
+ describe("[_make_user]", function()
+ it("github.com/org/repo.git", function()
+ local actual = giturlparser._make_user("github.com/org/repo.git", 1)
+ -- print(string.format("_make_user-1:%s\n", inspect(actual)))
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "github.com")
+ assert_eq(host_obj.host_pos.start_pos, 1)
+ assert_eq(host_obj.host_pos.end_pos, 10)
+ assert_eq(host_obj.port, nil)
+ assert_eq(host_obj.port_pos, nil)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, "org")
+ assert_eq(path_obj.org_pos.start_pos, 12)
+ assert_eq(path_obj.org_pos.end_pos, 14)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 16)
+ assert_eq(path_obj.repo_pos.end_pos, 23)
+ assert_eq(path_obj.path, "/org/repo.git")
+ assert_eq(path_obj.path_pos.start_pos, 11)
+ assert_eq(path_obj.path_pos.end_pos, 23)
+ end)
+ it("github.com/org/repo.git/", function()
+ local actual = giturlparser._make_user("github.com/org/repo.git/", 1)
+ -- print(string.format("_make_user-2:%s\n", inspect(actual)))
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "github.com")
+ assert_eq(host_obj.host_pos.start_pos, 1)
+ assert_eq(host_obj.host_pos.end_pos, 10)
+ assert_eq(host_obj.port, nil)
+ assert_eq(host_obj.port_pos, nil)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, "org")
+ assert_eq(path_obj.org_pos.start_pos, 12)
+ assert_eq(path_obj.org_pos.end_pos, 14)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 16)
+ assert_eq(path_obj.repo_pos.end_pos, 23)
+ assert_eq(path_obj.path, "/org/repo.git/")
+ assert_eq(path_obj.path_pos.start_pos, 11)
+ assert_eq(path_obj.path_pos.end_pos, 24)
+ end)
+ it("user@github.com/org/repo.git", function()
+ local actual = giturlparser._make_user("user@github.com/org/repo.git", 1)
+ -- print(string.format("_make_user-3:%s\n", inspect(actual)))
+ assert_eq(actual.user, "user")
+ assert_eq(actual.user_pos.start_pos, 1)
+ assert_eq(actual.user_pos.end_pos, 4)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "github.com")
+ assert_eq(host_obj.host_pos.start_pos, 6)
+ assert_eq(host_obj.host_pos.end_pos, 15)
+ assert_eq(host_obj.port, nil)
+ assert_eq(host_obj.port_pos, nil)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, "org")
+ assert_eq(path_obj.org_pos.start_pos, 17)
+ assert_eq(path_obj.org_pos.end_pos, 19)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 21)
+ assert_eq(path_obj.repo_pos.end_pos, 28)
+ assert_eq(path_obj.path, "/org/repo.git")
+ assert_eq(path_obj.path_pos.start_pos, 16)
+ assert_eq(path_obj.path_pos.end_pos, 28)
+ end)
+ it("user:passwd@github.com/org/repo.git/", function()
+ local actual =
+ giturlparser._make_user("user:passwd@github.com/org/repo.git/", 1)
+ -- print(string.format("_make_user-4:%s\n", inspect(actual)))
+ assert_eq(actual.user, "user")
+ assert_eq(actual.user_pos.start_pos, 1)
+ assert_eq(actual.user_pos.end_pos, 4)
+ assert_eq(actual.password, "passwd")
+ assert_eq(actual.password_pos.start_pos, 6)
+ assert_eq(actual.password_pos.end_pos, 11)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "github.com")
+ assert_eq(host_obj.host_pos.start_pos, 13)
+ assert_eq(host_obj.host_pos.end_pos, 22)
+ assert_eq(host_obj.port, nil)
+ assert_eq(host_obj.port_pos, nil)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, "org")
+ assert_eq(path_obj.org_pos.start_pos, 24)
+ assert_eq(path_obj.org_pos.end_pos, 26)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 28)
+ assert_eq(path_obj.repo_pos.end_pos, 35)
+ assert_eq(path_obj.path, "/org/repo.git/")
+ assert_eq(path_obj.path_pos.start_pos, 23)
+ assert_eq(path_obj.path_pos.end_pos, 36)
+ end)
+ it("github.com:port/org/repo.git", function()
+ local actual = giturlparser._make_user("github.com:port/org/repo.git", 1)
+ -- print(string.format("_make_user-5:%s\n", inspect(actual)))
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "github.com")
+ assert_eq(host_obj.host_pos.start_pos, 1)
+ assert_eq(host_obj.host_pos.end_pos, 10)
+ assert_eq(host_obj.port, "port")
+ assert_eq(host_obj.port_pos.start_pos, 12)
+ assert_eq(host_obj.port_pos.end_pos, 15)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, "org")
+ assert_eq(path_obj.org_pos.start_pos, 17)
+ assert_eq(path_obj.org_pos.end_pos, 19)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 21)
+ assert_eq(path_obj.repo_pos.end_pos, 28)
+ assert_eq(path_obj.path, "/org/repo.git")
+ assert_eq(path_obj.path_pos.start_pos, 16)
+ assert_eq(path_obj.path_pos.end_pos, 28)
+ end)
+ it("127.0.0.1:12345/org/repo.git/", function()
+ local actual = giturlparser._make_user("127.0.0.1:12345/org/repo.git/", 1)
+ -- print(string.format("_make_user-6:%s\n", inspect(actual)))
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "127.0.0.1")
+ assert_eq(host_obj.host_pos.start_pos, 1)
+ assert_eq(host_obj.host_pos.end_pos, 9)
+ assert_eq(host_obj.port, "12345")
+ assert_eq(host_obj.port_pos.start_pos, 11)
+ assert_eq(host_obj.port_pos.end_pos, 15)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, "org")
+ assert_eq(path_obj.org_pos.start_pos, 17)
+ assert_eq(path_obj.org_pos.end_pos, 19)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 21)
+ assert_eq(path_obj.repo_pos.end_pos, 28)
+ assert_eq(path_obj.path, "/org/repo.git/")
+ assert_eq(path_obj.path_pos.start_pos, 16)
+ assert_eq(path_obj.path_pos.end_pos, 29)
+ end)
+ it("user2:passwd2@github.com:port/org/repo.git", function()
+ local actual =
+ giturlparser._make_user("user2:passwd2@github.com:port/org/repo.git", 1)
+ -- print(string.format("_make_user-7:%s\n", inspect(actual)))
+ assert_eq(actual.user, "user2")
+ assert_eq(actual.user_pos.start_pos, 1)
+ assert_eq(actual.user_pos.end_pos, 5)
+ assert_eq(actual.password, "passwd2")
+ assert_eq(actual.password_pos.start_pos, 7)
+ assert_eq(actual.password_pos.end_pos, 13)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "github.com")
+ assert_eq(host_obj.host_pos.start_pos, 15)
+ assert_eq(host_obj.host_pos.end_pos, 24)
+ assert_eq(host_obj.port, "port")
+ assert_eq(host_obj.port_pos.start_pos, 26)
+ assert_eq(host_obj.port_pos.end_pos, 29)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, "org")
+ assert_eq(path_obj.org_pos.start_pos, 31)
+ assert_eq(path_obj.org_pos.end_pos, 33)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 35)
+ assert_eq(path_obj.repo_pos.end_pos, 42)
+ assert_eq(path_obj.path, "/org/repo.git")
+ assert_eq(path_obj.path_pos.start_pos, 30)
+ assert_eq(path_obj.path_pos.end_pos, 42)
+ end)
+ it("git@127.0.0.1:12345/org/repo.git/", function()
+ local actual =
+ giturlparser._make_user("git@127.0.0.1:12345/org/repo.git/", 1)
+ -- print(string.format("_make_user-6:%s\n", inspect(actual)))
+ assert_eq(actual.user, "git")
+ assert_eq(actual.user_pos.start_pos, 1)
+ assert_eq(actual.user_pos.end_pos, 3)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "127.0.0.1")
+ assert_eq(host_obj.host_pos.start_pos, 5)
+ assert_eq(host_obj.host_pos.end_pos, 13)
+ assert_eq(host_obj.port, "12345")
+ assert_eq(host_obj.port_pos.start_pos, 15)
+ assert_eq(host_obj.port_pos.end_pos, 19)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, "org")
+ assert_eq(path_obj.org_pos.start_pos, 21)
+ assert_eq(path_obj.org_pos.end_pos, 23)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 25)
+ assert_eq(path_obj.repo_pos.end_pos, 32)
+ assert_eq(path_obj.path, "/org/repo.git/")
+ assert_eq(path_obj.path_pos.start_pos, 20)
+ assert_eq(path_obj.path_pos.end_pos, 33)
+ end)
+ it("github.com/repo.git", function()
+ local actual = giturlparser._make_user("github.com/repo.git", 1)
+ -- print(string.format("_make_user-7:%s\n", inspect(actual)))
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "github.com")
+ assert_eq(host_obj.host_pos.start_pos, 1)
+ assert_eq(host_obj.host_pos.end_pos, 10)
+ assert_eq(host_obj.port, nil)
+ assert_eq(host_obj.port_pos, nil)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, nil)
+ assert_eq(path_obj.org_pos, nil)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 12)
+ assert_eq(path_obj.repo_pos.end_pos, 19)
+ assert_eq(path_obj.path, "/repo.git")
+ assert_eq(path_obj.path_pos.start_pos, 11)
+ assert_eq(path_obj.path_pos.end_pos, 19)
+ end)
+ it("127.0.0.1:12345/repo.git/", function()
+ local actual = giturlparser._make_user("127.0.0.1:12345/repo.git/", 1)
+ -- print(string.format("_make_user-8:%s\n", inspect(actual)))
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "127.0.0.1")
+ assert_eq(host_obj.host_pos.start_pos, 1)
+ assert_eq(host_obj.host_pos.end_pos, 9)
+ assert_eq(host_obj.port, "12345")
+ assert_eq(host_obj.port_pos.start_pos, 11)
+ assert_eq(host_obj.port_pos.end_pos, 15)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, nil)
+ assert_eq(path_obj.org_pos, nil)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 17)
+ assert_eq(path_obj.repo_pos.end_pos, 24)
+ assert_eq(path_obj.path, "/repo.git/")
+ assert_eq(path_obj.path_pos.start_pos, 16)
+ assert_eq(path_obj.path_pos.end_pos, 25)
+ end)
+ it("git@github.com/repo.git", function()
+ local actual = giturlparser._make_user("git@github.com/repo.git", 1)
+ -- print(string.format("_make_user-9:%s\n", inspect(actual)))
+ assert_eq(actual.user, "git")
+ assert_eq(actual.user_pos.start_pos, 1)
+ assert_eq(actual.user_pos.end_pos, 3)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "github.com")
+ assert_eq(host_obj.host_pos.start_pos, 5)
+ assert_eq(host_obj.host_pos.end_pos, 14)
+ assert_eq(host_obj.port, nil)
+ assert_eq(host_obj.port_pos, nil)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, nil)
+ assert_eq(path_obj.org_pos, nil)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 16)
+ assert_eq(path_obj.repo_pos.end_pos, 23)
+ assert_eq(path_obj.path, "/repo.git")
+ assert_eq(path_obj.path_pos.start_pos, 15)
+ assert_eq(path_obj.path_pos.end_pos, 23)
+ end)
+ it("linrongbin:123456@127.0.0.1:12345/repo.git/", function()
+ local actual =
+ giturlparser._make_user("linrongbin:123@127.0.0.1:12345/repo.git/", 1)
+ -- print(string.format("_make_user-8:%s\n", inspect(actual)))
+ assert_eq(actual.user, "linrongbin")
+ assert_eq(actual.user_pos.start_pos, 1)
+ assert_eq(actual.user_pos.end_pos, 10)
+ assert_eq(actual.password, "123")
+ assert_eq(actual.password_pos.start_pos, 12)
+ assert_eq(actual.password_pos.end_pos, 14)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "127.0.0.1")
+ assert_eq(host_obj.host_pos.start_pos, 16)
+ assert_eq(host_obj.host_pos.end_pos, 24)
+ assert_eq(host_obj.port, "12345")
+ assert_eq(host_obj.port_pos.start_pos, 26)
+ assert_eq(host_obj.port_pos.end_pos, 30)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, nil)
+ assert_eq(path_obj.org_pos, nil)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 32)
+ assert_eq(path_obj.repo_pos.end_pos, 39)
+ assert_eq(path_obj.path, "/repo.git/")
+ assert_eq(path_obj.path_pos.start_pos, 31)
+ assert_eq(path_obj.path_pos.end_pos, 40)
+ end)
+ end)
+
+ describe("[_make_user with omitted ssh]", function()
+ it("github.com:org/repo.git", function()
+ local actual = giturlparser._make_user("github.com:org/repo.git", 1, true)
+ -- print(string.format("_make_user_omit-1:%s\n", inspect(actual)))
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "github.com")
+ assert_eq(host_obj.host_pos.start_pos, 1)
+ assert_eq(host_obj.host_pos.end_pos, 10)
+ assert_eq(host_obj.port, nil)
+ assert_eq(host_obj.port_pos, nil)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, "org")
+ assert_eq(path_obj.org_pos.start_pos, 12)
+ assert_eq(path_obj.org_pos.end_pos, 14)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 16)
+ assert_eq(path_obj.repo_pos.end_pos, 23)
+ assert_eq(path_obj.path, "org/repo.git")
+ assert_eq(path_obj.path_pos.start_pos, 12)
+ assert_eq(path_obj.path_pos.end_pos, 23)
+ end)
+ it("github.com:org/repo.git/", function()
+ local actual =
+ giturlparser._make_user("github.com:org/repo.git/", 1, true)
+ -- print(string.format("_make_user_omit-2:%s\n", inspect(actual)))
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "github.com")
+ assert_eq(host_obj.host_pos.start_pos, 1)
+ assert_eq(host_obj.host_pos.end_pos, 10)
+ assert_eq(host_obj.port, nil)
+ assert_eq(host_obj.port_pos, nil)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, "org")
+ assert_eq(path_obj.org_pos.start_pos, 12)
+ assert_eq(path_obj.org_pos.end_pos, 14)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 16)
+ assert_eq(path_obj.repo_pos.end_pos, 23)
+ assert_eq(path_obj.path, "org/repo.git/")
+ assert_eq(path_obj.path_pos.start_pos, 12)
+ assert_eq(path_obj.path_pos.end_pos, 24)
+ end)
+ it("user@github.com:repo.git", function()
+ local actual =
+ giturlparser._make_user("user@github.com:repo.git", 1, true)
+ -- print(string.format("_make_user_omit-3:%s\n", inspect(actual)))
+ assert_eq(actual.user, "user")
+ assert_eq(actual.user_pos.start_pos, 1)
+ assert_eq(actual.user_pos.end_pos, 4)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "github.com")
+ assert_eq(host_obj.host_pos.start_pos, 6)
+ assert_eq(host_obj.host_pos.end_pos, 15)
+ assert_eq(host_obj.port, nil)
+ assert_eq(host_obj.port_pos, nil)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, nil)
+ assert_eq(path_obj.org_pos, nil)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 17)
+ assert_eq(path_obj.repo_pos.end_pos, 24)
+ assert_eq(path_obj.path, "repo.git")
+ assert_eq(path_obj.path_pos.start_pos, 17)
+ assert_eq(path_obj.path_pos.end_pos, 24)
+ end)
+ it("user:passwd@127.0.0.1:repo.git/", function()
+ local actual =
+ giturlparser._make_user("user:passwd@127.0.0.1:repo.git/", 1, true)
+ -- print(string.format("_make_user_omit-4:%s\n", inspect(actual)))
+ assert_eq(actual.user, "user")
+ assert_eq(actual.user_pos.start_pos, 1)
+ assert_eq(actual.user_pos.end_pos, 4)
+ assert_eq(actual.password, "passwd")
+ assert_eq(actual.password_pos.start_pos, 6)
+ assert_eq(actual.password_pos.end_pos, 11)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "127.0.0.1")
+ assert_eq(host_obj.host_pos.start_pos, 13)
+ assert_eq(host_obj.host_pos.end_pos, 21)
+ assert_eq(host_obj.port, nil)
+ assert_eq(host_obj.port_pos, nil)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, nil)
+ assert_eq(path_obj.org_pos, nil)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 23)
+ assert_eq(path_obj.repo_pos.end_pos, 30)
+ assert_eq(path_obj.path, "repo.git/")
+ assert_eq(path_obj.path_pos.start_pos, 23)
+ assert_eq(path_obj.path_pos.end_pos, 31)
+ end)
+ it("github.com:repo.git", function()
+ local actual = giturlparser._make_user("github.com:repo.git", 1, true)
+ -- print(string.format("_make_user_omit-5:%s\n", inspect(actual)))
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "github.com")
+ assert_eq(host_obj.host_pos.start_pos, 1)
+ assert_eq(host_obj.host_pos.end_pos, 10)
+ assert_eq(host_obj.port, nil)
+ assert_eq(host_obj.port_pos, nil)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, nil)
+ assert_eq(path_obj.org_pos, nil)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 12)
+ assert_eq(path_obj.repo_pos.end_pos, 19)
+ assert_eq(path_obj.path, "repo.git")
+ assert_eq(path_obj.path_pos.start_pos, 12)
+ assert_eq(path_obj.path_pos.end_pos, 19)
+ end)
+ it("127.0.0.1:repo.git/", function()
+ local actual = giturlparser._make_user("127.0.0.1:repo.git/", 1, true)
+ -- print(string.format("_make_user_omit-6:%s\n", inspect(actual)))
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "127.0.0.1")
+ assert_eq(host_obj.host_pos.start_pos, 1)
+ assert_eq(host_obj.host_pos.end_pos, 9)
+ assert_eq(host_obj.port, nil)
+ assert_eq(host_obj.port_pos, nil)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, nil)
+ assert_eq(path_obj.org_pos, nil)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 11)
+ assert_eq(path_obj.repo_pos.end_pos, 18)
+ assert_eq(path_obj.path, "repo.git/")
+ assert_eq(path_obj.path_pos.start_pos, 11)
+ assert_eq(path_obj.path_pos.end_pos, 19)
+ end)
+ it("user@github.com:repo.git", function()
+ local actual =
+ giturlparser._make_user("user@github.com:repo.git", 1, true)
+ -- print(string.format("_make_user_omit-7:%s\n", inspect(actual)))
+ assert_eq(actual.user, "user")
+ assert_eq(actual.user_pos.start_pos, 1)
+ assert_eq(actual.user_pos.end_pos, 4)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "github.com")
+ assert_eq(host_obj.host_pos.start_pos, 6)
+ assert_eq(host_obj.host_pos.end_pos, 15)
+ assert_eq(host_obj.port, nil)
+ assert_eq(host_obj.port_pos, nil)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, nil)
+ assert_eq(path_obj.org_pos, nil)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 17)
+ assert_eq(path_obj.repo_pos.end_pos, 24)
+ assert_eq(path_obj.path, "repo.git")
+ assert_eq(path_obj.path_pos.start_pos, 17)
+ assert_eq(path_obj.path_pos.end_pos, 24)
+ end)
+ it("git:pass@127.0.0.1:repo.git/", function()
+ local actual =
+ giturlparser._make_user("git:pass@127.0.0.1:repo.git/", 1, true)
+ -- print(string.format("_make_user_omit-9:%s\n", inspect(actual)))
+ assert_eq(actual.user, "git")
+ assert_eq(actual.user_pos.start_pos, 1)
+ assert_eq(actual.user_pos.end_pos, 3)
+ assert_eq(actual.password, "pass")
+ assert_eq(actual.password_pos.start_pos, 5)
+ assert_eq(actual.password_pos.end_pos, 8)
+ local host_obj = actual.host_obj
+ assert_eq(host_obj.host, "127.0.0.1")
+ assert_eq(host_obj.host_pos.start_pos, 10)
+ assert_eq(host_obj.host_pos.end_pos, 18)
+ assert_eq(host_obj.port, nil)
+ assert_eq(host_obj.port_pos, nil)
+ local path_obj = host_obj.path_obj
+ assert_eq(path_obj.org, nil)
+ assert_eq(path_obj.org_pos, nil)
+ assert_eq(path_obj.repo, "repo.git")
+ assert_eq(path_obj.repo_pos.start_pos, 20)
+ assert_eq(path_obj.repo_pos.end_pos, 27)
+ assert_eq(path_obj.path, "repo.git/")
+ assert_eq(path_obj.path_pos.start_pos, 20)
+ assert_eq(path_obj.path_pos.end_pos, 28)
+ end)
+ end)
+
+ describe("[parse http(s)]", function()
it("http://host.xz/path/to/repo.git/", function()
local actual = giturlparser.parse("http://host.xz/path/to/repo.git/")
assert_eq(type(actual), "table")
@@ -26,6 +875,9 @@ describe("giturlparser", function()
assert_eq(actual.repo, "repo.git")
assert_eq(actual.repo_pos.start_pos, 24)
assert_eq(actual.repo_pos.end_pos, 31)
+ assert_eq(actual.path, "/path/to/repo.git/")
+ assert_eq(actual.path_pos.start_pos, 15)
+ assert_eq(actual.path_pos.end_pos, 32)
end)
it("http://host.xz/path/to/repo.git", function()
local actual = giturlparser.parse("http://host.xz/path/to/repo.git")
@@ -46,6 +898,9 @@ describe("giturlparser", function()
assert_eq(actual.repo, "repo.git")
assert_eq(actual.repo_pos.start_pos, 24)
assert_eq(actual.repo_pos.end_pos, 31)
+ assert_eq(actual.path, "/path/to/repo.git")
+ assert_eq(actual.path_pos.start_pos, 15)
+ assert_eq(actual.path_pos.end_pos, 31)
end)
it("https://host.xz/path/to/repo.git/", function()
local actual = giturlparser.parse("https://host.xz/path/to/repo.git/")
@@ -167,6 +1022,581 @@ describe("giturlparser", function()
assert_eq(actual.repo, "samba.git")
assert_eq(actual.repo_pos.start_pos, 41)
assert_eq(actual.repo_pos.end_pos, 49)
+ assert_eq(actual.path, "/samba.git")
+ assert_eq(actual.path_pos.start_pos, 40)
+ assert_eq(actual.path_pos.end_pos, 49)
+ end)
+ end)
+ describe("[parse ssh]", function()
+ it("ssh://user@host.xz/repo.git", function()
+ local actual = giturlparser.parse("ssh://user@host.xz/repo.git")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, "ssh")
+ assert_eq(actual.protocol_pos.start_pos, 1)
+ assert_eq(actual.protocol_pos.end_pos, 3)
+ assert_eq(actual.user, "user")
+ assert_eq(actual.user_pos.start_pos, 7)
+ assert_eq(actual.user_pos.end_pos, 10)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, "host.xz")
+ assert_eq(actual.host_pos.start_pos, 12)
+ assert_eq(actual.host_pos.end_pos, 18)
+ assert_eq(actual.org, nil)
+ assert_eq(actual.org_pos, nil)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 20)
+ assert_eq(actual.repo_pos.end_pos, 27)
+ assert_eq(actual.path, "/repo.git")
+ assert_eq(actual.path_pos.start_pos, 19)
+ assert_eq(actual.path_pos.end_pos, 27)
+ end)
+ it("ssh://git@github.com/linrongbin16/giturlparser.lua.git", function()
+ local actual = giturlparser.parse(
+ "ssh://git@github.com/linrongbin16/giturlparser.lua.git"
+ )
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, "ssh")
+ assert_eq(actual.protocol_pos.start_pos, 1)
+ assert_eq(actual.protocol_pos.end_pos, 3)
+ assert_eq(actual.user, "git")
+ assert_eq(actual.user_pos.start_pos, 7)
+ assert_eq(actual.user_pos.end_pos, 9)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, "github.com")
+ assert_eq(actual.host_pos.start_pos, 11)
+ assert_eq(actual.host_pos.end_pos, 20)
+ assert_eq(actual.org, "linrongbin16")
+ assert_eq(actual.org_pos.start_pos, 22)
+ assert_eq(actual.org_pos.end_pos, 33)
+ assert_eq(actual.repo, "giturlparser.lua.git")
+ assert_eq(actual.repo_pos.start_pos, 35)
+ assert_eq(actual.repo_pos.end_pos, 54)
+ assert_eq(actual.path, "/linrongbin16/giturlparser.lua.git")
+ assert_eq(actual.path_pos.start_pos, 21)
+ assert_eq(actual.path_pos.end_pos, 54)
+ end)
+ end)
+ describe("[parse ssh omit]", function()
+ it("git:pass@host.xz:repo.git", function()
+ local actual = giturlparser.parse("git:pass@host.xz:repo.git")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, nil)
+ assert_eq(actual.protocol_pos, nil)
+ assert_eq(actual.user, "git")
+ assert_eq(actual.user_pos.start_pos, 1)
+ assert_eq(actual.user_pos.end_pos, 3)
+ assert_eq(actual.password, "pass")
+ assert_eq(actual.password_pos.start_pos, 5)
+ assert_eq(actual.password_pos.end_pos, 8)
+ assert_eq(actual.host, "host.xz")
+ assert_eq(actual.host_pos.start_pos, 10)
+ assert_eq(actual.host_pos.end_pos, 16)
+ assert_eq(actual.org, nil)
+ assert_eq(actual.org_pos, nil)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 18)
+ assert_eq(actual.repo_pos.end_pos, 25)
+ assert_eq(actual.path, "repo.git")
+ assert_eq(actual.path_pos.start_pos, 18)
+ assert_eq(actual.path_pos.end_pos, 25)
+ end)
+ it("git@github.com:linrongbin16/giturlparser.lua.git", function()
+ local actual =
+ giturlparser.parse("git@github.com:linrongbin16/giturlparser.lua.git")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, nil)
+ assert_eq(actual.protocol_pos, nil)
+ assert_eq(actual.user, "git")
+ assert_eq(actual.user_pos.start_pos, 1)
+ assert_eq(actual.user_pos.end_pos, 3)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, "github.com")
+ assert_eq(actual.host_pos.start_pos, 5)
+ assert_eq(actual.host_pos.end_pos, 14)
+ assert_eq(actual.org, "linrongbin16")
+ assert_eq(actual.org_pos.start_pos, 16)
+ assert_eq(actual.org_pos.end_pos, 27)
+ assert_eq(actual.repo, "giturlparser.lua.git")
+ assert_eq(actual.repo_pos.start_pos, 29)
+ assert_eq(actual.repo_pos.end_pos, 48)
+ assert_eq(actual.path, "linrongbin16/giturlparser.lua.git")
+ assert_eq(actual.path_pos.start_pos, 16)
+ assert_eq(actual.path_pos.end_pos, 48)
+ end)
+ end)
+ describe("[parse git]", function()
+ it("git://user@host.xz/repo.git", function()
+ local actual = giturlparser.parse("git://user@host.xz/repo.git")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, "git")
+ assert_eq(actual.protocol_pos.start_pos, 1)
+ assert_eq(actual.protocol_pos.end_pos, 3)
+ assert_eq(actual.user, "user")
+ assert_eq(actual.user_pos.start_pos, 7)
+ assert_eq(actual.user_pos.end_pos, 10)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, "host.xz")
+ assert_eq(actual.host_pos.start_pos, 12)
+ assert_eq(actual.host_pos.end_pos, 18)
+ assert_eq(actual.org, nil)
+ assert_eq(actual.org_pos, nil)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 20)
+ assert_eq(actual.repo_pos.end_pos, 27)
+ assert_eq(actual.path, "/repo.git")
+ assert_eq(actual.path_pos.start_pos, 19)
+ assert_eq(actual.path_pos.end_pos, 27)
+ end)
+ it("git://git@github.com/linrongbin16/giturlparser.lua.git", function()
+ local actual = giturlparser.parse(
+ "git://git@github.com/linrongbin16/giturlparser.lua.git"
+ )
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, "git")
+ assert_eq(actual.protocol_pos.start_pos, 1)
+ assert_eq(actual.protocol_pos.end_pos, 3)
+ assert_eq(actual.user, "git")
+ assert_eq(actual.user_pos.start_pos, 7)
+ assert_eq(actual.user_pos.end_pos, 9)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, "github.com")
+ assert_eq(actual.host_pos.start_pos, 11)
+ assert_eq(actual.host_pos.end_pos, 20)
+ assert_eq(actual.org, "linrongbin16")
+ assert_eq(actual.org_pos.start_pos, 22)
+ assert_eq(actual.org_pos.end_pos, 33)
+ assert_eq(actual.repo, "giturlparser.lua.git")
+ assert_eq(actual.repo_pos.start_pos, 35)
+ assert_eq(actual.repo_pos.end_pos, 54)
+ assert_eq(actual.path, "/linrongbin16/giturlparser.lua.git")
+ assert_eq(actual.path_pos.start_pos, 21)
+ assert_eq(actual.path_pos.end_pos, 54)
+ end)
+ it("git://host.xz/repo.git", function()
+ local actual = giturlparser.parse("git://host.xz/repo.git")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, "git")
+ assert_eq(actual.protocol_pos.start_pos, 1)
+ assert_eq(actual.protocol_pos.end_pos, 3)
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, "host.xz")
+ assert_eq(actual.host_pos.start_pos, 7)
+ assert_eq(actual.host_pos.end_pos, 13)
+ assert_eq(actual.org, nil)
+ assert_eq(actual.org_pos, nil)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 15)
+ assert_eq(actual.repo_pos.end_pos, 22)
+ assert_eq(actual.path, "/repo.git")
+ assert_eq(actual.path_pos.start_pos, 14)
+ assert_eq(actual.path_pos.end_pos, 22)
+ end)
+ it("git://github.com/linrongbin16/giturlparser.lua.git", function()
+ local actual =
+ giturlparser.parse("git://github.com/linrongbin16/giturlparser.lua.git")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, "git")
+ assert_eq(actual.protocol_pos.start_pos, 1)
+ assert_eq(actual.protocol_pos.end_pos, 3)
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, "github.com")
+ assert_eq(actual.host_pos.start_pos, 7)
+ assert_eq(actual.host_pos.end_pos, 16)
+ assert_eq(actual.org, "linrongbin16")
+ assert_eq(actual.org_pos.start_pos, 18)
+ assert_eq(actual.org_pos.end_pos, 29)
+ assert_eq(actual.repo, "giturlparser.lua.git")
+ assert_eq(actual.repo_pos.start_pos, 31)
+ assert_eq(actual.repo_pos.end_pos, 50)
+ assert_eq(actual.path, "/linrongbin16/giturlparser.lua.git")
+ assert_eq(actual.path_pos.start_pos, 17)
+ assert_eq(actual.path_pos.end_pos, 50)
+ end)
+ end)
+ describe("[parse file remote]", function()
+ it("file://user@host.xz/repo.git", function()
+ local actual = giturlparser.parse("file://user@host.xz/repo.git")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, "file")
+ assert_eq(actual.protocol_pos.start_pos, 1)
+ assert_eq(actual.protocol_pos.end_pos, 4)
+ assert_eq(actual.user, "user")
+ assert_eq(actual.user_pos.start_pos, 8)
+ assert_eq(actual.user_pos.end_pos, 11)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, "host.xz")
+ assert_eq(actual.host_pos.start_pos, 13)
+ assert_eq(actual.host_pos.end_pos, 19)
+ assert_eq(actual.org, nil)
+ assert_eq(actual.org_pos, nil)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 21)
+ assert_eq(actual.repo_pos.end_pos, 28)
+ assert_eq(actual.path, "/repo.git")
+ assert_eq(actual.path_pos.start_pos, 20)
+ assert_eq(actual.path_pos.end_pos, 28)
+ end)
+ it("file://git@github.com/linrongbin16/giturlparser.lua.git", function()
+ local actual = giturlparser.parse(
+ "file://git@github.com/linrongbin16/giturlparser.lua.git"
+ )
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, "file")
+ assert_eq(actual.protocol_pos.start_pos, 1)
+ assert_eq(actual.protocol_pos.end_pos, 4)
+ assert_eq(actual.user, "git")
+ assert_eq(actual.user_pos.start_pos, 8)
+ assert_eq(actual.user_pos.end_pos, 10)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, "github.com")
+ assert_eq(actual.host_pos.start_pos, 12)
+ assert_eq(actual.host_pos.end_pos, 21)
+ assert_eq(actual.org, "linrongbin16")
+ assert_eq(actual.org_pos.start_pos, 23)
+ assert_eq(actual.org_pos.end_pos, 34)
+ assert_eq(actual.repo, "giturlparser.lua.git")
+ assert_eq(actual.repo_pos.start_pos, 36)
+ assert_eq(actual.repo_pos.end_pos, 55)
+ assert_eq(actual.path, "/linrongbin16/giturlparser.lua.git")
+ assert_eq(actual.path_pos.start_pos, 22)
+ assert_eq(actual.path_pos.end_pos, 55)
+ end)
+ it("file://host.xz/repo.git", function()
+ local actual = giturlparser.parse("file://host.xz/repo.git")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, "file")
+ assert_eq(actual.protocol_pos.start_pos, 1)
+ assert_eq(actual.protocol_pos.end_pos, 4)
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, "host.xz")
+ assert_eq(actual.host_pos.start_pos, 8)
+ assert_eq(actual.host_pos.end_pos, 14)
+ assert_eq(actual.org, nil)
+ assert_eq(actual.org_pos, nil)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 16)
+ assert_eq(actual.repo_pos.end_pos, 23)
+ assert_eq(actual.path, "/repo.git")
+ assert_eq(actual.path_pos.start_pos, 15)
+ assert_eq(actual.path_pos.end_pos, 23)
+ end)
+ it("file://github.com/linrongbin16/giturlparser.lua.git", function()
+ local actual = giturlparser.parse(
+ "file://github.com/linrongbin16/giturlparser.lua.git"
+ )
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, "file")
+ assert_eq(actual.protocol_pos.start_pos, 1)
+ assert_eq(actual.protocol_pos.end_pos, 4)
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, "github.com")
+ assert_eq(actual.host_pos.start_pos, 8)
+ assert_eq(actual.host_pos.end_pos, 17)
+ assert_eq(actual.org, "linrongbin16")
+ assert_eq(actual.org_pos.start_pos, 19)
+ assert_eq(actual.org_pos.end_pos, 30)
+ assert_eq(actual.repo, "giturlparser.lua.git")
+ assert_eq(actual.repo_pos.start_pos, 32)
+ assert_eq(actual.repo_pos.end_pos, 51)
+ assert_eq(actual.path, "/linrongbin16/giturlparser.lua.git")
+ assert_eq(actual.path_pos.start_pos, 18)
+ assert_eq(actual.path_pos.end_pos, 51)
+ end)
+ end)
+ describe("[parse file local]", function()
+ it("file:///path/to/repo.git", function()
+ local actual = giturlparser.parse("file:///path/to/repo.git")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, "file")
+ assert_eq(actual.protocol_pos.start_pos, 1)
+ assert_eq(actual.protocol_pos.end_pos, 4)
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, nil)
+ assert_eq(actual.host_pos, nil)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ assert_eq(actual.org, "path/to")
+ assert_eq(actual.org_pos.start_pos, 9)
+ assert_eq(actual.org_pos.end_pos, 15)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 17)
+ assert_eq(actual.repo_pos.end_pos, 24)
+ assert_eq(actual.path, "/path/to/repo.git")
+ assert_eq(actual.path_pos.start_pos, 8)
+ assert_eq(actual.path_pos.end_pos, 24)
+ end)
+ it("file:///repo.git", function()
+ local actual = giturlparser.parse("file:///repo.git")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, "file")
+ assert_eq(actual.protocol_pos.start_pos, 1)
+ assert_eq(actual.protocol_pos.end_pos, 4)
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, nil)
+ assert_eq(actual.host_pos, nil)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ assert_eq(actual.org, nil)
+ assert_eq(actual.org_pos, nil)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 9)
+ assert_eq(actual.repo_pos.end_pos, 16)
+ assert_eq(actual.path, "/repo.git")
+ assert_eq(actual.path_pos.start_pos, 8)
+ assert_eq(actual.path_pos.end_pos, 16)
+ end)
+ end)
+ describe("[parse local path]", function()
+ it("repo.git", function()
+ local actual = giturlparser.parse("repo.git")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, nil)
+ assert_eq(actual.protocol_pos, nil)
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, nil)
+ assert_eq(actual.host_pos, nil)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ assert_eq(actual.org, nil)
+ assert_eq(actual.org_pos, nil)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 1)
+ assert_eq(actual.repo_pos.end_pos, 8)
+ assert_eq(actual.path, "repo.git")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 8)
+ end)
+ it("repo.git/", function()
+ local actual = giturlparser.parse("repo.git/")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, nil)
+ assert_eq(actual.protocol_pos, nil)
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, nil)
+ assert_eq(actual.host_pos, nil)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ assert_eq(actual.org, nil)
+ assert_eq(actual.org_pos, nil)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 1)
+ assert_eq(actual.repo_pos.end_pos, 8)
+ assert_eq(actual.path, "repo.git/")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 9)
+ end)
+ it("/repo.git", function()
+ local actual = giturlparser.parse("/repo.git")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, nil)
+ assert_eq(actual.protocol_pos, nil)
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, nil)
+ assert_eq(actual.host_pos, nil)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ assert_eq(actual.org, nil)
+ assert_eq(actual.org_pos, nil)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 2)
+ assert_eq(actual.repo_pos.end_pos, 9)
+ assert_eq(actual.path, "/repo.git")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 9)
+ end)
+ it("/repo.git/", function()
+ local actual = giturlparser.parse("/repo.git/")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, nil)
+ assert_eq(actual.protocol_pos, nil)
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, nil)
+ assert_eq(actual.host_pos, nil)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ assert_eq(actual.org, nil)
+ assert_eq(actual.org_pos, nil)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 2)
+ assert_eq(actual.repo_pos.end_pos, 9)
+ assert_eq(actual.path, "/repo.git/")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 10)
+ end)
+ it("./repo.git", function()
+ local actual = giturlparser.parse("./repo.git")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, nil)
+ assert_eq(actual.protocol_pos, nil)
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, nil)
+ assert_eq(actual.host_pos, nil)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ assert_eq(actual.org, ".")
+ assert_eq(actual.org_pos.start_pos, 1)
+ assert_eq(actual.org_pos.end_pos, 1)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 3)
+ assert_eq(actual.repo_pos.end_pos, 10)
+ assert_eq(actual.path, "./repo.git")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 10)
+ end)
+ it("../repo.git/", function()
+ local actual = giturlparser.parse("../repo.git/")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, nil)
+ assert_eq(actual.protocol_pos, nil)
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, nil)
+ assert_eq(actual.host_pos, nil)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ assert_eq(actual.org, "..")
+ assert_eq(actual.org_pos.start_pos, 1)
+ assert_eq(actual.org_pos.end_pos, 2)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 4)
+ assert_eq(actual.repo_pos.end_pos, 11)
+ assert_eq(actual.path, "../repo.git/")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 12)
+ end)
+ it("~/path/to/repo.git", function()
+ local actual = giturlparser.parse("~/path/to/repo.git")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, nil)
+ assert_eq(actual.protocol_pos, nil)
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, nil)
+ assert_eq(actual.host_pos, nil)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ assert_eq(actual.org, "~/path/to")
+ assert_eq(actual.org_pos.start_pos, 1)
+ assert_eq(actual.org_pos.end_pos, 9)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 11)
+ assert_eq(actual.repo_pos.end_pos, 18)
+ assert_eq(actual.path, "~/path/to/repo.git")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 18)
+ end)
+ it("~/path/to/repo.git/", function()
+ local actual = giturlparser.parse("~/path/to/repo.git/")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, nil)
+ assert_eq(actual.protocol_pos, nil)
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, nil)
+ assert_eq(actual.host_pos, nil)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ assert_eq(actual.org, "~/path/to")
+ assert_eq(actual.org_pos.start_pos, 1)
+ assert_eq(actual.org_pos.end_pos, 9)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 11)
+ assert_eq(actual.repo_pos.end_pos, 18)
+ assert_eq(actual.path, "~/path/to/repo.git/")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 19)
+ end)
+ it("/absolute/path/to/repo.git", function()
+ local actual = giturlparser.parse("/absolute/path/to/repo.git")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, nil)
+ assert_eq(actual.protocol_pos, nil)
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, nil)
+ assert_eq(actual.host_pos, nil)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ assert_eq(actual.org, "absolute/path/to")
+ assert_eq(actual.org_pos.start_pos, 2)
+ assert_eq(actual.org_pos.end_pos, 17)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 19)
+ assert_eq(actual.repo_pos.end_pos, 26)
+ assert_eq(actual.path, "/absolute/path/to/repo.git")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 26)
+ end)
+ it("/absolute/path/to/repo.git/", function()
+ local actual = giturlparser.parse("/absolute/path/to/repo.git/")
+ assert_eq(type(actual), "table")
+ assert_eq(actual.protocol, nil)
+ assert_eq(actual.protocol_pos, nil)
+ assert_eq(actual.user, nil)
+ assert_eq(actual.user_pos, nil)
+ assert_eq(actual.password, nil)
+ assert_eq(actual.password_pos, nil)
+ assert_eq(actual.host, nil)
+ assert_eq(actual.host_pos, nil)
+ assert_eq(actual.port, nil)
+ assert_eq(actual.port_pos, nil)
+ assert_eq(actual.org, "absolute/path/to")
+ assert_eq(actual.org_pos.start_pos, 2)
+ assert_eq(actual.org_pos.end_pos, 17)
+ assert_eq(actual.repo, "repo.git")
+ assert_eq(actual.repo_pos.start_pos, 19)
+ assert_eq(actual.repo_pos.end_pos, 26)
+ assert_eq(actual.path, "/absolute/path/to/repo.git/")
+ assert_eq(actual.path_pos.start_pos, 1)
+ assert_eq(actual.path_pos.end_pos, 27)
end)
end)
end)
diff --git a/src/giturlparser.lua b/src/giturlparser.lua
index 3d0e6e6..639dd81 100644
--- a/src/giturlparser.lua
+++ b/src/giturlparser.lua
@@ -106,9 +106,8 @@ end
-- 'path' is all payload after 'host', e.g. 'org/repo'.
--
--- @alias giturlparser.GitUrlPos {start_pos:integer?,end_pos:integer?}
---- @alias giturlparser.GitUrlInfo {protocol:string?,protocol_pos:giturlparser.GitUrlPos?,user:string?,user_pos:giturlparser.GitUrlPos?,password:string?,password_pos:giturlparser.GitUrlPos?,host:string?,host_pos:giturlparser.GitUrlPos?,org:string?,org_pos:giturlparser.GitUrlPos?,repo:string,repo_pos:giturlparser.GitUrlPos,path:string,path_pos:giturlparser.GitUrlPos}
-local GitUrlInfo = {}
-
+--- @alias giturlparser.GitUrlInfo {protocol:string?,protocol_pos:giturlparser.GitUrlPos?,user:string?,user_pos:giturlparser.GitUrlPos?,password:string?,password_pos:giturlparser.GitUrlPos?,host:string?,host_pos:giturlparser.GitUrlPos?,port:string?,port_pos:giturlparser.GitUrlPos?,org:string?,org_pos:giturlparser.GitUrlPos?,repo:string?,repo_pos:giturlparser.GitUrlPos?,path:string?,path_pos:giturlparser.GitUrlPos?}
+--
--- @param url string
--- @param start_pos integer
--- @param end_pos integer
@@ -123,341 +122,363 @@ M._make = function(url, start_pos, end_pos)
return component, pos
end
---- @param url string
---- @return giturlparser.GitUrlInfo?, string?
-M.parse = function(url)
- if type(url) ~= "string" or string.len(url) == 0 then
- return nil, "empty string"
+--- @param val string
+--- @param pos giturlparser.GitUrlPos
+--- @return string, giturlparser.GitUrlPos
+M._trim_slash = function(val, pos)
+ assert(type(val) == "string")
+ if val and M._startswith(val, "/") then
+ val = string.sub(val, 2)
+ pos.start_pos = pos.start_pos + 1
end
-
- if M._endswith(url, "/") then
- url = string.sub(url, 1, #url - 1)
+ if val and M._endswith(val, "/") then
+ val = string.sub(val, 1, string.len(val) - 1)
+ pos.end_pos = pos.end_pos - 1
end
- local protocol = nil
- local protocol_pos = nil
- local user = nil
- local user_pos = nil
- local password = nil
- local password_pos = nil
- local host = nil
- local host_pos = nil
+ return val, pos
+end
+
+--- @alias giturlparser._GitUrlPath {org:string?,org_pos:giturlparser.GitUrlPos?,repo:string?,repo_pos:giturlparser.GitUrlPos?,path:string?,path_pos:giturlparser.GitUrlPos?}
+--
+--- @param p string
+--- @param start integer
+--- @return giturlparser._GitUrlPath
+M._make_path = function(p, start)
+ assert(type(start) == "number")
+
+ -- local inspect = require("inspect")
+
+ local endswith_slash = M._endswith(p, "/")
+
local org = nil
local org_pos = nil
local repo = nil
local repo_pos = nil
local path = nil
local path_pos = nil
+ local plen = string.len(p)
- local protocol_delimiter_pos = M._find(url, "://")
+ local last_slash_pos = M._rfind(p, "/", endswith_slash and plen - 1 or plen)
if
- type(protocol_delimiter_pos) == "number" and protocol_delimiter_pos > 1
+ type(last_slash_pos) == "number"
+ and last_slash_pos > start
+ and last_slash_pos < plen
then
- -- https, ssh, file, sftp, etc
- protocol, protocol_pos = M._make(url, 1, protocol_delimiter_pos - 1)
- local first_colon_pos = M._find(url, ":", protocol_delimiter_pos + 3)
+ org, org_pos = M._make(p, start, last_slash_pos - 1)
+ repo, repo_pos = M._make(p, last_slash_pos, plen)
+ else
+ -- no slash found, only 1 path component
+ repo, repo_pos = M._make(p, start, plen)
+ end
+
+ -- print(
+ -- string.format(
+ -- "|_make_path| p:%s, start:%s, plen:%s\n",
+ -- inspect(p),
+ -- inspect(start),
+ -- inspect(plen)
+ -- )
+ -- )
+ path, path_pos = M._make(p, start, plen)
+
+ if repo and repo_pos then
+ repo, repo_pos = M._trim_slash(repo, repo_pos)
+ end
+ if org and org_pos then
+ org, org_pos = M._trim_slash(org, org_pos)
+ end
+
+ return {
+ org = org,
+ org_pos = org_pos,
+ repo = repo,
+ repo_pos = repo_pos,
+ path = path,
+ path_pos = path_pos,
+ }
+end
+
+-- without omitted ssh protocol, host (and port end with ':') end with '/'
+--
+--- @alias giturlparser._GitUrlHost {host:string?,host_pos:giturlparser.GitUrlPos?,port:string?,port_pos:giturlparser.GitUrlPos?,path_obj:giturlparser._GitUrlPath}
+--
+--- @param p string
+--- @param start integer
+--- @return giturlparser._GitUrlHost
+M._make_host = function(p, start)
+ assert(type(start) == "number")
+ assert(not M._startswith(p, "/"))
+
+ local host = nil
+ local host_pos = nil
+ local port = nil
+ local port_pos = nil
+ --- @type giturlparser._GitUrlPath
+ local path_obj = {}
+
+ local plen = string.len(p)
+
+ -- find ':', the end position of host, start position of port
+ local first_colon_pos = M._find(p, ":", start)
+ if type(first_colon_pos) == "number" and first_colon_pos > start then
+ -- host end with ':', port start with ':'
+ host, host_pos = M._make(p, start, first_colon_pos - 1)
+
+ -- find first slash '/' (after second ':'), the end position of port, start position of path
+ local first_slash_pos = M._find(p, "/", first_colon_pos + 1)
if
- type(first_colon_pos) == "number"
- and first_colon_pos > protocol_delimiter_pos + 3
+ type(first_slash_pos) == "number"
+ and first_slash_pos > first_colon_pos + 1
then
- -- host end with ':', or user end with ':'
- local first_at_pos = M._find(url, "@", first_colon_pos + 1)
- if
- type(first_at_pos) == "number" and first_at_pos > first_colon_pos + 1
- then
- -- ssh password end pos
- local second_colon_pos = M._find(url, ":", first_at_pos + 1)
- if
- type(second_colon_pos) == "number"
- and second_colon_pos > first_at_pos + 1
- then
- -- host end with ':'
- host, host_pos = M._make(url, first_at_pos + 1, second_colon_pos - 1)
- password, password_pos =
- M._make(url, first_colon_pos + 1, first_at_pos - 1)
- user, user_pos =
- M._make(url, protocol_delimiter_pos + 3, first_colon_pos - 1)
-
- local last_slash_pos = M._rfind(url, "/")
- if
- type(last_slash_pos) == "number"
- and last_slash_pos > second_colon_pos + 1
- then
- repo, repo_pos = M._make(url, last_slash_pos + 1, string.len(url))
- org, org_pos =
- M._make(url, second_colon_pos + 1, last_slash_pos - 1)
- path, path_pos = M._make(url, second_colon_pos + 1, string.len(url))
- else
- repo, repo_pos = M._make(url, second_colon_pos + 1, string.len(url))
- path, path_pos = M._make(url, second_colon_pos + 1, string.len(url))
- -- missing org, org_pos
- end
- else
- local first_slash_pos = M._find(url, "/", first_at_pos + 1)
- if
- type(first_slash_pos) == "number"
- and first_slash_pos > first_at_pos + 1
- then
- -- host end with '/'
- host, host_pos = M._make(url, first_at_pos + 1, first_slash_pos - 1)
- password, password_pos =
- M._make(url, first_colon_pos + 1, first_at_pos - 1)
- user, user_pos =
- M._make(url, protocol_delimiter_pos + 3, first_colon_pos - 1)
-
- local last_slash_pos = M._rfind(url, "/")
- if
- type(last_slash_pos) == "number"
- and last_slash_pos > first_slash_pos + 1
- then
- repo, repo_pos = M._make(url, last_slash_pos + 1, string.len(url))
- org, org_pos =
- M._make(url, first_slash_pos + 1, last_slash_pos - 1)
- path, path_pos =
- M._make(url, first_slash_pos + 1, string.len(url))
- else
- repo, repo_pos =
- M._make(url, first_slash_pos + 1, string.len(url))
- path, path_pos =
- M._make(url, first_slash_pos + 1, string.len(url))
- -- missing org, org_pos
- end
- else
- return nil, "invalid url"
- end
- end
- else
- -- host end with ':'
- host, host_pos =
- M._make(url, protocol_delimiter_pos + 3, first_colon_pos - 1)
- -- missing user, password
-
- local last_slash_pos = M._rfind(url, "/")
- if
- type(last_slash_pos) == "number"
- and last_slash_pos > first_colon_pos + 1
- then
- repo, repo_pos = M._make(url, last_slash_pos + 1, string.len(url))
- org, org_pos = M._make(url, first_colon_pos + 1, last_slash_pos - 1)
- path, path_pos = M._make(url, first_colon_pos + 1, string.len(url))
- else
- repo, repo_pos = M._make(url, first_colon_pos + 1, string.len(url))
- path, path_pos = M._make(url, first_colon_pos + 1, string.len(url))
- -- missing org, org_pos
- end
- end
+ -- port end with '/'
+ port, port_pos = M._make(p, first_colon_pos + 1, first_slash_pos - 1)
+ path_obj = M._make_path(p, first_slash_pos)
else
- local first_slash_pos = M._find(url, "/", protocol_delimiter_pos + 3)
- if
- type(first_slash_pos) == "number"
- and first_slash_pos > protocol_delimiter_pos + 3
- then
- -- host end with '/'
- host, host_pos =
- M._make(url, protocol_delimiter_pos + 3, first_slash_pos - 1)
- local last_slash_pos = M._rfind(url, "/")
- if
- type(last_slash_pos) == "number"
- and last_slash_pos > first_slash_pos + 1
- then
- repo, repo_pos = M._make(url, last_slash_pos + 1, string.len(url))
- org, org_pos = M._make(url, first_slash_pos + 1, last_slash_pos - 1)
- path, path_pos = M._make(url, first_slash_pos + 1, string.len(url))
- else
- repo, repo_pos = M._make(url, first_slash_pos + 1, string.len(url))
- path, path_pos = M._make(url, first_slash_pos + 1, string.len(url))
- -- missing org
- end
- else
- return nil, "invalid url"
- end
+ -- path not found, port end until url end
+ port, port_pos = M._make(p, first_colon_pos + 1, plen)
end
else
- -- missing protocol, either ssh/local file path
- local first_at_pos = M._find(url, "@")
- if type(first_at_pos) == "number" and first_at_pos > 1 then
- local first_colon_pos = M._find(url, ":")
- if
- type(first_colon_pos) == "number"
- and first_colon_pos > 1
- and first_colon_pos < first_at_pos
- then
- -- user end with ':', password end with '@'
- user, user_pos = M._make(url, 1, first_colon_pos - 1)
- password, password_pos =
- M._make(url, first_colon_pos + 1, first_at_pos - 1)
-
- local second_colon_pos = M._find(url, ":", first_at_pos + 1)
- if
- type(second_colon_pos) == "number"
- and second_colon_pos > first_at_pos + 1
- then
- -- host end with ':'
- host, host_pos = M._make(url, first_at_pos + 1, second_colon_pos - 1)
-
- local last_slash_pos = M._rfind(url, "/")
- if
- type(last_slash_pos) == "number"
- and last_slash_pos > second_colon_pos + 1
- then
- repo, repo_pos = M._make(url, last_slash_pos + 1, string.len(url))
- org, org_pos =
- M._make(url, second_colon_pos + 1, last_slash_pos - 1)
- path, path_pos = M._make(url, second_colon_pos + 1, string.len(url))
- else
- repo, repo_pos = M._make(url, second_colon_pos + 1, string.len(url))
- path, path_pos = M._make(url, second_colon_pos + 1, string.len(url))
- -- missing org
- end
- else
- local first_slash_pos = M._find(url, "/", first_at_pos + 1)
- if
- type(first_slash_pos) == "number"
- and first_slash_pos > first_at_pos + 1
- then
- -- host end with '/'
- host, host_pos = M._make(url, first_at_pos + 1, first_slash_pos - 1)
-
- local last_slash_pos = M._rfind(url, "/")
- if
- type(last_slash_pos) == "number"
- and last_slash_pos > first_slash_pos + 1
- then
- repo, repo_pos = M._make(url, last_slash_pos + 1, string.len(url))
- org, org_pos =
- M._make(url, first_slash_pos + 1, last_slash_pos - 1)
- path, path_pos =
- M._make(url, first_slash_pos + 1, string.len(url))
- else
- repo, repo_pos =
- M._make(url, first_slash_pos + 1, string.len(url))
- path, path_pos =
- M._make(url, first_slash_pos + 1, string.len(url))
- -- missing org
- end
- else
- return nil, "invalid url"
- end
- end
- else
- -- user end with '@'
- user, user_pos = M._make(url, 1, first_at_pos - 1)
- -- missing password
-
- local second_colon_pos = M._find(url, ":", first_at_pos + 1)
- if
- type(second_colon_pos) == "number"
- and second_colon_pos > first_at_pos + 1
- then
- -- host end with ':'
- host, host_pos = M._make(url, first_at_pos + 1, second_colon_pos - 1)
-
- local last_slash_pos = M._rfind(url, "/")
- if
- type(last_slash_pos) == "number"
- and last_slash_pos > second_colon_pos + 1
- then
- repo, repo_pos = M._make(url, last_slash_pos + 1, string.len(url))
- org, org_pos =
- M._make(url, second_colon_pos + 1, last_slash_pos - 1)
- path, path_pos = M._make(url, second_colon_pos + 1, string.len(url))
- else
- repo, repo_pos = M._make(url, second_colon_pos + 1, string.len(url))
- path, path_pos = M._make(url, second_colon_pos + 1, string.len(url))
- -- missing org
- end
- else
- local first_slash_pos = M._find(url, "/", first_at_pos + 1)
- if
- type(first_slash_pos) == "number"
- and first_slash_pos > first_at_pos + 1
- then
- -- host end with '/'
- host, host_pos = M._make(url, first_at_pos + 1, first_slash_pos - 1)
-
- local last_slash_pos = M._rfind(url, "/")
- if
- type(last_slash_pos) == "number"
- and last_slash_pos > first_slash_pos + 1
- then
- repo, repo_pos = M._make(url, last_slash_pos + 1, string.len(url))
- org, org_pos =
- M._make(url, first_slash_pos + 1, last_slash_pos - 1)
- path, path_pos =
- M._make(url, first_slash_pos + 1, string.len(url))
- else
- repo, repo_pos =
- M._make(url, first_slash_pos + 1, string.len(url))
- path, path_pos =
- M._make(url, first_slash_pos + 1, string.len(url))
- -- missing org
- end
- else
- return nil, "invalid url"
- end
- end
- end
+ -- port not found, host (highly possibly) end with '/'
+
+ -- find first slash '/', the end position of host, start position of path
+ local first_slash_pos = M._find(p, "/", start)
+ if type(first_slash_pos) == "number" and first_slash_pos > start then
+ -- host end with '/'
+ host, host_pos = M._make(p, start, first_slash_pos - 1)
+ path_obj = M._make_path(p, first_slash_pos)
else
- local first_colon_pos = M._find(url, ":")
- if type(first_colon_pos) == "number" and first_colon_pos > 1 then
- -- host end with ':'
- host, host_pos = M._make(url, 1, first_colon_pos - 1)
-
- local last_slash_pos = M._rfind(url, "/")
- if
- type(last_slash_pos) == "number"
- and last_slash_pos > first_colon_pos + 1
- then
- repo, repo_pos = M._make(url, last_slash_pos + 1, string.len(url))
- org, org_pos = M._make(url, first_colon_pos + 1, last_slash_pos - 1)
- path, path_pos = M._make(url, first_colon_pos + 1, string.len(url))
- else
- repo, repo_pos = M._make(url, first_colon_pos + 1, string.len(url))
- path, path_pos = M._make(url, first_colon_pos + 1, string.len(url))
- -- missing org
- end
- else
- local first_slash_pos = M._find(url, "/")
- if type(first_slash_pos) == "number" and first_slash_pos > 1 then
- -- host end with '/'
- host, host_pos = M._make(url, 1, first_slash_pos - 1)
-
- local last_slash_pos = M._rfind(url, "/")
- if
- type(last_slash_pos) == "number"
- and last_slash_pos > first_colon_pos + 1
- then
- repo, repo_pos = M._make(url, last_slash_pos + 1, string.len(url))
- org, org_pos = M._make(url, first_colon_pos + 1, last_slash_pos - 1)
- path, path_pos = M._make(url, first_colon_pos + 1, string.len(url))
- else
- repo, repo_pos = M._make(url, first_colon_pos + 1, string.len(url))
- path, path_pos = M._make(url, first_colon_pos + 1, string.len(url))
- -- missing org
- end
- else
- return nil, "invalid url"
- end
- end
+ -- first slash not found, host is omitted, path end until url end
+ path_obj = M._make_path(p, start)
+ end
+ end
+
+ return {
+ host = host,
+ host_pos = host_pos,
+ port = port,
+ port_pos = port_pos,
+ path_obj = path_obj,
+ }
+end
+
+-- with omitted ssh protocol, host end with ':'
+--
+--- @param p string
+--- @param start integer
+--- @return giturlparser._GitUrlHost
+M._make_host_with_omit_ssh = function(p, start)
+ assert(type(start) == "number")
+ assert(not M._startswith(p, "/"))
+
+ local host = nil
+ local host_pos = nil
+ local port = nil
+ local port_pos = nil
+ --- @type giturlparser._GitUrlPath
+ local path_obj = {}
+
+ local plen = string.len(p)
+
+ -- find ':', the end position of host, start position of path
+ local first_colon_pos = M._find(p, ":", start)
+ if type(first_colon_pos) == "number" and first_colon_pos > start then
+ -- host end with ':', path start with ':'
+ host, host_pos = M._make(p, start, first_colon_pos - 1)
+ path_obj = M._make_path(p, first_colon_pos + 1)
+ else
+ -- host not found, path start from beginning
+ path_obj = M._make_path(p, start)
+ end
+
+ return {
+ host = host,
+ host_pos = host_pos,
+ port = port,
+ port_pos = port_pos,
+ path_obj = path_obj,
+ }
+end
+
+--- @alias giturlparser._GitUrlUser {user:string?,user_pos:giturlparser.GitUrlPos?,password:string?,password_pos:giturlparser.GitUrlPos?,host_obj:giturlparser._GitUrlHost}
+--
+--- @param p string
+--- @param start integer
+--- @param ssh_protocol_omitted boolean?
+--- @return giturlparser._GitUrlUser
+M._make_user = function(p, start, ssh_protocol_omitted)
+ assert(type(start) == "number")
+ assert(not M._startswith(p, "/"))
+
+ -- local inspect = require("inspect")
+
+ ssh_protocol_omitted = ssh_protocol_omitted or false
+
+ local user = nil
+ local user_pos = nil
+ local password = nil
+ local password_pos = nil
+ --- @type giturlparser._GitUrlHost
+ local host_obj = {}
+
+ local plen = string.len(p)
+
+ local host_start_pos = start
+
+ -- find first '@', the end position of user and password
+ local first_at_pos = M._find(p, "@", start)
+ -- print(
+ -- string.format(
+ -- "|_make_user-1| p:%s, start:%s, ssh_protocol_omitted:%s, first_at_pos:%s, host_start_pos:%s\n",
+ -- inspect(p),
+ -- inspect(start),
+ -- inspect(ssh_protocol_omitted),
+ -- inspect(first_at_pos),
+ -- inspect(host_start_pos)
+ -- )
+ -- )
+ if type(first_at_pos) == "number" and first_at_pos > start then
+ -- user (and password) end with '@'
+
+ -- find first ':' (before '@'), the end position of password
+ local first_colon_pos = M._find(p, ":", start)
+ if
+ type(first_colon_pos) == "number"
+ and first_colon_pos > start
+ and first_colon_pos < first_at_pos
+ then
+ -- password end with ':'
+ user, user_pos = M._make(p, start, first_colon_pos - 1)
+ password, password_pos = M._make(p, first_colon_pos + 1, first_at_pos - 1)
+ else
+ -- password not found, user end with '@'
+ user, user_pos = M._make(p, start, first_at_pos - 1)
end
+
+ -- host start from '@', user (and password) end position
+ host_start_pos = first_at_pos + 1
+ else
+ -- user (and password) not found
+ -- host start from beginning
end
+ -- print(
+ -- string.format(
+ -- "|_make_user-2| ssh_protocol_omitted:%s, host_start_pos:%s, first_at_pos:%s\n",
+ -- inspect(ssh_protocol_omitted),
+ -- inspect(host_start_pos),
+ -- inspect(first_at_pos)
+ -- )
+ -- )
+ host_obj = ssh_protocol_omitted
+ and M._make_host_with_omit_ssh(p, host_start_pos)
+ or M._make_host(p, host_start_pos)
+
return {
- protocol = protocol,
- protocol_pos = protocol_pos,
user = user,
user_pos = user_pos,
password = password,
password_pos = password_pos,
- host = host,
- host_pos = host_pos,
- org = org,
- org_pos = org_pos,
- repo = repo,
- repo_pos = repo_pos,
- path = path,
- path_pos = path_pos,
+ host_obj = host_obj,
}
end
+--- @param url string
+--- @return giturlparser.GitUrlInfo?, string?
+M.parse = function(url)
+ if type(url) ~= "string" or string.len(url) == 0 then
+ return nil, "empty string"
+ end
+
+ -- find first '://', the end position of protocol
+ local protocol_delimiter_pos = M._find(url, "://")
+ if
+ type(protocol_delimiter_pos) == "number" and protocol_delimiter_pos > 1
+ then
+ -- protocol end with '://'
+ local protocol, protocol_pos = M._make(url, 1, protocol_delimiter_pos - 1)
+
+ local user_obj = M._make_user(url, protocol_delimiter_pos + 3)
+ local host_obj = user_obj.host_obj
+ local path_obj = host_obj.path_obj
+
+ return {
+ protocol = protocol,
+ protocol_pos = protocol_pos,
+
+ -- user
+ user = user_obj.user,
+ user_pos = user_obj.user_pos,
+ password = user_obj.password,
+ password_pos = user_obj.password_pos,
+
+ -- host
+ host = host_obj.host,
+ host_pos = host_obj.host_pos,
+ port = host_obj.port,
+ port_pos = host_obj.port_pos,
+
+ -- path
+ org = path_obj.org,
+ org_pos = path_obj.org_pos,
+ repo = path_obj.repo,
+ repo_pos = path_obj.repo_pos,
+ path = path_obj.path,
+ path_pos = path_obj.path_pos,
+ }
+ else
+ -- protocol not found, either ssh/local file path
+
+ -- find first ':', host end position on omitted ssh protocol
+ local first_colon_pos = M._find(url, ":")
+ if type(first_colon_pos) == "number" and first_colon_pos > 1 then
+ local user_obj = M._make_user(url, 1, true)
+ local host_obj = user_obj.host_obj
+ local path_obj = host_obj.path_obj
+
+ return {
+ -- no protocol
+
+ -- user
+ user = user_obj.user,
+ user_pos = user_obj.user_pos,
+ password = user_obj.password,
+ password_pos = user_obj.password_pos,
+
+ -- host
+ host = host_obj.host,
+ host_pos = host_obj.host_pos,
+ port = host_obj.port,
+ port_pos = host_obj.port_pos,
+
+ -- path
+ org = path_obj.org,
+ org_pos = path_obj.org_pos,
+ repo = path_obj.repo,
+ repo_pos = path_obj.repo_pos,
+ path = path_obj.path,
+ path_pos = path_obj.path_pos,
+ }
+ else
+ -- host not found
+
+ -- treat as local file path, either absolute/relative
+ local path_obj = M._make_path(url, 1)
+ return {
+ -- no protocol
+ -- no user
+ -- no host
+
+ -- path
+ org = path_obj.org,
+ org_pos = path_obj.org_pos,
+ repo = path_obj.repo,
+ repo_pos = path_obj.repo_pos,
+ path = path_obj.path,
+ path_pos = path_obj.path_pos,
+ }
+ end
+ end
+end
+
return M
From 4838ccf14a0ff43c04a8448650b853944c42a1db Mon Sep 17 00:00:00 2001
From: linrongbin16
Date: Mon, 8 Jan 2024 15:10:20 +0800
Subject: [PATCH 6/7] chore(docs): writing (#30)
---
README.md | 58 +++++++++++++++++++++++++++++++++----------------------
1 file changed, 35 insertions(+), 23 deletions(-)
diff --git a/README.md b/README.md
index 11b3837..2b985c6 100644
--- a/README.md
+++ b/README.md
@@ -35,7 +35,7 @@ Pure Lua implemented git URL parsing library, e.g. the output of git remot
Single file & zero dependency.
-Full [Git Protocols](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols) support:
+Full [Git Protocols](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols) support (see below).
> [!NOTE]
>
@@ -47,28 +47,40 @@ Full [Git Protocols](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protoc
> 4. The `[]+` contains 1 or more (≥ 1) component.
> 5. The `|` inside `[]` is **_or_** operator.
-1. `{protocol}://[[{user}[:{password}]@]{host}[:{port}]]/[{org}/]*{repo}`, for example:
- - `http://host.xyz/repo.git`
- - `https://git@127.0.0.1:12345/repo.git`
- - `ssh://username:password@host.xyz:port/path/to/the/repo.git`
- - `ssh://host.xyz:port/path/to/the/repo.git`
- - `file:///repo.git`
- - `file://user:passwd@host.xyz:port/path/to/the/repo.git`
- - `file://~/home/to/the/repo.git`
-2. `[{user}[:{password}]@]{host}:[{org}/]*{repo}`, for example:
- - `git@host.xyz:repo.git`
- - `user:passwd@host.xyz:path/to/the/repo.git`
-3. `[.|..|~][/{org}]*/{repo}`, for example:
- - `repo.git`
- - `./repo.git`
- - `../path/to/the/repo.git`
- - `~/home/to/the/repo.git`
- - `/usr/home/to/the/repo.git`
-
-All of above can be written by:
-
-1. `[{protocol}://][[{user}[:{password}]@]host[:{port}]]/[{org}/]*{repo}`
-2. `[.|..|~][/{org}]*/{repo}`
+### Full Pattern
+
+`{protocol}://[[{user}[:{password}]@]{host}[:{port}]]/[{org}/]*{repo}`
+
+For example:
+
+- `http://host.xyz/repo.git`
+- `https://git@127.0.0.1:12345/repo.git`
+- `ssh://username:password@host.xyz:port/path/to/the/repo.git`
+- `ssh://host.xyz:port/path/to/the/repo.git`
+- `file:///repo.git`
+- `file://user:passwd@host.xyz:port/path/to/the/repo.git`
+- `file://~/home/to/the/repo.git`
+
+### Protocol Omitted Pattern
+
+`[{user}[:{password}]@]{host}:[{org}/]*{repo}`
+
+For example:
+
+- `git@host.xyz:repo.git`
+- `user:passwd@host.xyz:path/to/the/repo.git`
+
+### Local Pattern
+
+`[.|..|~][/{org}]*/{repo}`
+
+For example:
+
+- `repo.git`
+- `./repo.git`
+- `../path/to/the/repo.git`
+- `~/home/to/the/repo.git`
+- `/usr/home/to/the/repo.git`
## Install
From 77e2a62c041fc905724101086fa36bf2dcc10b6e Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Mon, 8 Jan 2024 15:12:12 +0800
Subject: [PATCH 7/7] chore(main): release 1.0.7 (#29)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
---
CHANGELOG.md | 7 +++++++
version.txt | 2 +-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 235cf61..a94e826 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
# Changelog
+## [1.0.7](https://github.com/linrongbin16/giturlparser.lua/compare/v1.0.6...v1.0.7) (2024-01-08)
+
+
+### Bug Fixes
+
+* **parse:** fix parse ([#28](https://github.com/linrongbin16/giturlparser.lua/issues/28)) ([454d7c3](https://github.com/linrongbin16/giturlparser.lua/commit/454d7c3094669641c5e5dcc3060947f2364e7634))
+
## [1.0.6](https://github.com/linrongbin16/giturlparser.lua/compare/v1.0.5...v1.0.6) (2024-01-07)
diff --git a/version.txt b/version.txt
index af0b7dd..238d6e8 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-1.0.6
+1.0.7