forked from a/repotool
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| abe56ca25a | |||
|
|
e286bb6189 | ||
| 47e632254f | |||
| ec647555b5 | |||
| 3883292bd6 | |||
| fddc3fbceb |
@ -11,7 +11,7 @@
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
"@semantic-release/git", {
|
"@semantic-release/git", {
|
||||||
"assets": ["dist/repotool", "repotool.plugin.zsh", "repotool.zsh"],
|
"assets": ["dist/repotool", "shell/zsh/repotool.plugin.zsh", "shell/zsh/repotool.zsh"],
|
||||||
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
|
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
9
Makefile
9
Makefile
@ -1,4 +1,4 @@
|
|||||||
.PHONY: all install
|
.PHONY: all install test
|
||||||
|
|
||||||
SOURCES_SRC:=$(shell find src -type f )
|
SOURCES_SRC:=$(shell find src -type f )
|
||||||
LIBS_SRC:=$(shell find lib -type f )
|
LIBS_SRC:=$(shell find lib -type f )
|
||||||
@ -7,14 +7,17 @@ REPOTOOL_PATH ?= ${HOME}/repo
|
|||||||
|
|
||||||
all: dist/repotool
|
all: dist/repotool
|
||||||
|
|
||||||
install: dist/repotool shell/zsh/repotool.zsh shell/zsh/repotool.plugin.zsh
|
install: dist/repotool shell/repotool.zsh shell/repotool.plugin.zsh
|
||||||
mkdir -p ${REPOTOOL_PATH}/.bin/
|
mkdir -p ${REPOTOOL_PATH}/.bin/
|
||||||
mkdir -p ${REPOTOOL_PATH}/.shell/
|
mkdir -p ${REPOTOOL_PATH}/.shell/
|
||||||
install dist/repotool ${REPOTOOL_PATH}/.bin/
|
install dist/repotool ${REPOTOOL_PATH}/.bin/
|
||||||
install shell/zsh/repotool.zsh shell/zsh/repotool.plugin.zsh ${REPOTOOL_PATH}/.shell/
|
install shell/repotool.zsh shell/repotool.plugin.zsh ${REPOTOOL_PATH}/.shell/
|
||||||
|
|
||||||
dist/repotool: $(SOURCES_SRC) $(LIBS_SRC) main.lua
|
dist/repotool: $(SOURCES_SRC) $(LIBS_SRC) main.lua
|
||||||
@mkdir -p dist
|
@mkdir -p dist
|
||||||
luabundler bundle main.lua -p "./src/?.lua" -p "./lib/?.lua" -o dist/repotool
|
luabundler bundle main.lua -p "./src/?.lua" -p "./lib/?.lua" -o dist/repotool
|
||||||
@sed -i "1i#!/usr/bin/env luajit" "dist/repotool"
|
@sed -i "1i#!/usr/bin/env luajit" "dist/repotool"
|
||||||
chmod +x dist/repotool
|
chmod +x dist/repotool
|
||||||
|
|
||||||
|
test:
|
||||||
|
@lua test.lua
|
||||||
|
|||||||
9
README.md
Normal file
9
README.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# repotool
|
||||||
|
|
||||||
|
this is a rediculous tool.
|
||||||
|
|
||||||
|
it returns json which is to be used by another wrapper for your shell that does directory movement.
|
||||||
|
|
||||||
|
i have no really other idea on how to implement this.
|
||||||
|
|
||||||
|
i did it in bashly originally, but i switched to lua.
|
||||||
59
fish-repotool/README.md
Normal file
59
fish-repotool/README.md
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# Fish Repotool Plugin
|
||||||
|
|
||||||
|
A Fish shell plugin for the repotool repository management system.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Using Fisher
|
||||||
|
|
||||||
|
```fish
|
||||||
|
fisher install path/to/fish-repotool
|
||||||
|
```
|
||||||
|
|
||||||
|
### Manual Installation
|
||||||
|
|
||||||
|
1. Copy the `conf.d/repotool.fish` file to your fish config directory:
|
||||||
|
```fish
|
||||||
|
cp conf.d/repotool.fish ~/.config/fish/conf.d/
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Copy the `functions/repotool.fish` file to your fish functions directory:
|
||||||
|
```fish
|
||||||
|
cp functions/repotool.fish ~/.config/fish/functions/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Set the `REPOTOOL_PATH` environment variable to specify where your repositories are stored:
|
||||||
|
|
||||||
|
```fish
|
||||||
|
set -gx REPOTOOL_PATH "$HOME/my-repos"
|
||||||
|
```
|
||||||
|
|
||||||
|
If not set, it defaults to `$HOME/repo`.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
The plugin provides a `repo` alias that sources the repotool function with the following commands:
|
||||||
|
|
||||||
|
- `repo get <url>` - Clone a repository if not found
|
||||||
|
- `repo worktree list` - List existing worktrees
|
||||||
|
- `repo worktree get <name>` - Create or go to a worktree
|
||||||
|
- `repo worktree root` - Return to the root directory
|
||||||
|
- `repo worktree remove <name>` - Remove a worktree
|
||||||
|
- `repo open` - Open the current repository in web browser
|
||||||
|
|
||||||
|
## Hooks
|
||||||
|
|
||||||
|
The plugin supports hooks that can be placed in `$REPOTOOL_PATH/.hooks/`:
|
||||||
|
|
||||||
|
- `before_<hook_name>_cd.fish` - Executed before changing directory
|
||||||
|
- `after_<hook_name>_cd.fish` - Executed after changing directory
|
||||||
|
|
||||||
|
Hooks can also have `.sh` extension or no extension at all.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Fish shell 4.0 or later
|
||||||
|
- `jq` for JSON parsing
|
||||||
|
- The repotool binary installed at `$REPOTOOL_PATH/.bin/repotool`
|
||||||
9
fish-repotool/conf.d/repotool.fish
Normal file
9
fish-repotool/conf.d/repotool.fish
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env fish
|
||||||
|
|
||||||
|
# Set default REPOTOOL_PATH if not already set
|
||||||
|
if not set -q REPOTOOL_PATH
|
||||||
|
set -gx REPOTOOL_PATH "$HOME/repo"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Create alias that sources the main repotool function
|
||||||
|
alias repo="source $REPOTOOL_PATH/.shell/repotool.fish"
|
||||||
79
fish-repotool/functions/repotool.fish
Normal file
79
fish-repotool/functions/repotool.fish
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env fish
|
||||||
|
|
||||||
|
# Set default REPOTOOL_PATH if not already set
|
||||||
|
if not set -q REPOTOOL_PATH
|
||||||
|
set -gx REPOTOOL_PATH "$HOME/repo"
|
||||||
|
end
|
||||||
|
|
||||||
|
function _activate_hook
|
||||||
|
set -l hook_name $argv[1]
|
||||||
|
set -l response $argv[2]
|
||||||
|
|
||||||
|
if test -f "$REPOTOOL_PATH/.hooks/$hook_name.fish"
|
||||||
|
source "$REPOTOOL_PATH/.hooks/$hook_name.fish" $response
|
||||||
|
return 0
|
||||||
|
else if test -f "$REPOTOOL_PATH/.hooks/$hook_name.sh"
|
||||||
|
source "$REPOTOOL_PATH/.hooks/$hook_name.sh" $response
|
||||||
|
return 0
|
||||||
|
else if test -f "$REPOTOOL_PATH/.hooks/$hook_name"
|
||||||
|
source "$REPOTOOL_PATH/.hooks/$hook_name" $response
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function _parse_json
|
||||||
|
set -l response $argv[1]
|
||||||
|
set -l key $argv[2]
|
||||||
|
echo "$response" | jq -r ".$key"
|
||||||
|
end
|
||||||
|
|
||||||
|
function _handle_response
|
||||||
|
set -l response $argv[1]
|
||||||
|
|
||||||
|
# Validate JSON
|
||||||
|
if not echo "$response" | jq . >/dev/null 2>&1
|
||||||
|
# Not valid JSON, write to stderr
|
||||||
|
echo "$response" >&2
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# Check if response has an echo field
|
||||||
|
set -l echo_msg (echo "$response" | jq -r '.echo // empty')
|
||||||
|
if test -n "$echo_msg"
|
||||||
|
echo "$echo_msg"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get hook name from response
|
||||||
|
set -l hook_name (echo "$response" | jq -r '.hook // empty')
|
||||||
|
|
||||||
|
# Handle before hook if hook name is provided
|
||||||
|
if test -n "$hook_name"
|
||||||
|
_activate_hook "before_{$hook_name}_cd" "$response"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Check if response has a cd field
|
||||||
|
set -l cd_path (echo "$response" | jq -r '.cd // empty')
|
||||||
|
if test -n "$cd_path"
|
||||||
|
cd "$cd_path"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Handle after hook if hook name is provided
|
||||||
|
if test -n "$hook_name"
|
||||||
|
_activate_hook "after_{$hook_name}_cd" "$response"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
set TOOL_BIN "$REPOTOOL_PATH/.bin/repotool"
|
||||||
|
|
||||||
|
# Pass all arguments to repotool and handle response
|
||||||
|
set -l response ($TOOL_BIN $argv)
|
||||||
|
set -l exit_code $status
|
||||||
|
|
||||||
|
if test $exit_code -ne 0
|
||||||
|
echo "Command failed with exit code $exit_code" >&2
|
||||||
|
return $exit_code
|
||||||
|
end
|
||||||
|
|
||||||
|
_handle_response "$response"
|
||||||
82
lib/git.sh
82
lib/git.sh
@ -1,82 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Parse a git URL into domain and path components
|
|
||||||
# Usage: parse_git_url <url> <perl_regex_command> <jq_command>
|
|
||||||
# Returns: JSON with domain and path fields
|
|
||||||
parse_git_url() {
|
|
||||||
local url="$1"
|
|
||||||
local regex="$2"
|
|
||||||
local jq="$3"
|
|
||||||
|
|
||||||
local domain=""
|
|
||||||
local path=""
|
|
||||||
local output
|
|
||||||
|
|
||||||
# Check if it's an HTTP(S) URL
|
|
||||||
if [[ "$url" =~ ^https?:// ]]; then
|
|
||||||
output=($(echo "$url" | $regex '/^https?:\/\/(?:.*?:)?(.*\..*?)\/(.*?)(\.git)?$/ && print "$1 $2" ' -))
|
|
||||||
if [[ ${#output[@]} -eq 2 ]]; then
|
|
||||||
domain=${output[0]}
|
|
||||||
path=${output[1]}
|
|
||||||
fi
|
|
||||||
# Check if it's an SSH URL
|
|
||||||
elif [[ "$url" =~ ^[^:]+@[^:]+: ]] || [[ "$url" =~ ^ssh:// ]]; then
|
|
||||||
output=($(echo "$url" | $regex '/^(?:.*?@)?(.*\..*?)(?::|\/)(.*?)(\.git)?$/ && print "$1 $2" ' -))
|
|
||||||
if [[ ${#output[@]} -eq 2 ]]; then
|
|
||||||
domain=${output[0]}
|
|
||||||
path=${output[1]}
|
|
||||||
fi
|
|
||||||
# Check if it's a bare domain path (e.g., gfx.cafe/oku/trade)
|
|
||||||
else
|
|
||||||
output=($(echo "$url" | $regex '/^(.*\..*?)\/(.*?)(\.git)?$/ && print "$1 $2" ' -))
|
|
||||||
if [[ ${#output[@]} -eq 2 ]]; then
|
|
||||||
domain=${output[0]}
|
|
||||||
path=${output[1]}
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Return JSON
|
|
||||||
$jq -n --arg domain "$domain" --arg path "$path" '{domain: $domain, path: $path}'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get domain and path from current git repository's origin
|
|
||||||
# Usage: parse_git_origin <perl_regex_command> <jq_command>
|
|
||||||
# Returns: JSON with domain and path fields
|
|
||||||
parse_git_origin() {
|
|
||||||
local regex="$1"
|
|
||||||
local jq="$2"
|
|
||||||
|
|
||||||
# Get origin URL
|
|
||||||
local origin_url
|
|
||||||
origin_url=$(git config --get remote.origin.url)
|
|
||||||
|
|
||||||
if [[ -z "$origin_url" ]]; then
|
|
||||||
$jq -n '{domain: "", path: ""}'
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Parse the URL
|
|
||||||
parse_git_url "$origin_url" "$regex" "$jq"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Validate if a URL is a valid git repository URL
|
|
||||||
# Usage: valid_url <url>
|
|
||||||
# Returns: 1 for HTTP(S), 2 for SSH, 3 for bare domain paths, -1 for invalid
|
|
||||||
valid_url() {
|
|
||||||
local url="$1"
|
|
||||||
|
|
||||||
if [[ "$url" =~ ^https?:// ]]; then
|
|
||||||
echo "1"
|
|
||||||
return 0
|
|
||||||
elif [[ "$url" =~ ^[^:]+@[^:]+: ]] || [[ "$url" =~ ^ssh:// ]]; then
|
|
||||||
echo "2"
|
|
||||||
return 0
|
|
||||||
elif [[ "$url" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]+/[^/]+ ]]; then
|
|
||||||
# Bare domain path like gfx.cafe/oku/trade
|
|
||||||
echo "3"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
echo "-1"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
3453
lib/luaunit.lua
Normal file
3453
lib/luaunit.lua
Normal file
File diff suppressed because it is too large
Load Diff
14
src/git.lua
14
src/git.lua
@ -7,9 +7,18 @@ function git.parse_url(url)
|
|||||||
local domain, path
|
local domain, path
|
||||||
|
|
||||||
-- Check if it's an HTTP(S) URL
|
-- Check if it's an HTTP(S) URL
|
||||||
domain, path = url:match("^https?://[^/]*@?([^/]+)/(.+)%.git$")
|
-- First try without authentication
|
||||||
|
domain, path = url:match("^https?://([^@/]+)/(.+)%.git$")
|
||||||
if not domain then
|
if not domain then
|
||||||
domain, path = url:match("^https?://[^/]*@?([^/]+)/(.+)$")
|
domain, path = url:match("^https?://([^@/]+)/(.+)$")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If that didn't match, try with authentication
|
||||||
|
if not domain then
|
||||||
|
domain, path = url:match("^https?://[^@]+@([^/]+)/(.+)%.git$")
|
||||||
|
end
|
||||||
|
if not domain then
|
||||||
|
domain, path = url:match("^https?://[^@]+@([^/]+)/(.+)$")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check if it's an SSH URL (git@host:path or ssh://...)
|
-- Check if it's an SSH URL (git@host:path or ssh://...)
|
||||||
@ -19,6 +28,7 @@ function git.parse_url(url)
|
|||||||
if not domain then
|
if not domain then
|
||||||
domain, path = url:match("^[^@]+@([^:]+):(.+)$")
|
domain, path = url:match("^[^@]+@([^:]+):(.+)$")
|
||||||
end
|
end
|
||||||
|
-- SSH URLs (ssh://...)
|
||||||
if not domain then
|
if not domain then
|
||||||
domain, path = url:match("^ssh://[^@]*@?([^/]+)/(.+)%.git$")
|
domain, path = url:match("^ssh://[^@]*@?([^/]+)/(.+)%.git$")
|
||||||
end
|
end
|
||||||
|
|||||||
111
test.lua
Normal file
111
test.lua
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
#!/usr/bin/env lua
|
||||||
|
|
||||||
|
-- Test runner for repotool
|
||||||
|
-- This script discovers and runs all test files in the test/ directory
|
||||||
|
|
||||||
|
-- Add src to package path
|
||||||
|
package.path = package.path .. ";./src/?.lua"
|
||||||
|
|
||||||
|
-- ANSI color codes
|
||||||
|
local colors = {
|
||||||
|
green = "\27[32m",
|
||||||
|
red = "\27[31m",
|
||||||
|
yellow = "\27[33m",
|
||||||
|
reset = "\27[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Test statistics
|
||||||
|
local stats = {
|
||||||
|
total = 0,
|
||||||
|
passed = 0,
|
||||||
|
failed = 0,
|
||||||
|
errors = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Simple test framework
|
||||||
|
_G.test = {}
|
||||||
|
_G.test.current_suite = nil
|
||||||
|
_G.test.current_test = nil
|
||||||
|
|
||||||
|
function _G.test.suite(name, fn)
|
||||||
|
_G.test.current_suite = name
|
||||||
|
print("\n" .. colors.yellow .. "Testing " .. name .. colors.reset)
|
||||||
|
fn()
|
||||||
|
_G.test.current_suite = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function _G.test.case(name, fn)
|
||||||
|
_G.test.current_test = name
|
||||||
|
stats.total = stats.total + 1
|
||||||
|
|
||||||
|
local status, err = pcall(fn)
|
||||||
|
if status then
|
||||||
|
stats.passed = stats.passed + 1
|
||||||
|
print(" " .. colors.green .. "✓" .. colors.reset .. " " .. name)
|
||||||
|
else
|
||||||
|
stats.failed = stats.failed + 1
|
||||||
|
print(" " .. colors.red .. "✗" .. colors.reset .. " " .. name)
|
||||||
|
table.insert(stats.errors, {
|
||||||
|
suite = _G.test.current_suite,
|
||||||
|
test = name,
|
||||||
|
error = err
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
_G.test.current_test = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function _G.assert_eq(actual, expected, message)
|
||||||
|
if actual ~= expected then
|
||||||
|
error((message or "Assertion failed") .. "\n Expected: " .. tostring(expected) .. "\n Actual: " .. tostring(actual))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function _G.assert_nil(value, message)
|
||||||
|
if value ~= nil then
|
||||||
|
error((message or "Expected nil") .. "\n Got: " .. tostring(value))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function _G.assert_not_nil(value, message)
|
||||||
|
if value == nil then
|
||||||
|
error(message or "Expected non-nil value")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Discover and run test files
|
||||||
|
local function run_tests()
|
||||||
|
local handle = io.popen("find test -name '*.lua' -type f | sort")
|
||||||
|
local test_files = handle:read("*a")
|
||||||
|
handle:close()
|
||||||
|
|
||||||
|
for file in test_files:gmatch("[^\n]+") do
|
||||||
|
-- Skip the test.lua file itself
|
||||||
|
if not file:match("test%.lua$") then
|
||||||
|
dofile(file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Main
|
||||||
|
print(colors.yellow .. "Running repotool tests..." .. colors.reset)
|
||||||
|
run_tests()
|
||||||
|
|
||||||
|
-- Print summary
|
||||||
|
print("\n" .. string.rep("-", 40))
|
||||||
|
print("Test Summary:")
|
||||||
|
print(" Total: " .. stats.total)
|
||||||
|
print(" " .. colors.green .. "Passed: " .. stats.passed .. colors.reset)
|
||||||
|
print(" " .. colors.red .. "Failed: " .. stats.failed .. colors.reset)
|
||||||
|
|
||||||
|
-- Print errors if any
|
||||||
|
if #stats.errors > 0 then
|
||||||
|
print("\n" .. colors.red .. "Failures:" .. colors.reset)
|
||||||
|
for _, err in ipairs(stats.errors) do
|
||||||
|
print("\n " .. err.suite .. " > " .. err.test)
|
||||||
|
print(" " .. err.error:gsub("\n", "\n "))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Exit with appropriate code
|
||||||
|
os.exit(stats.failed > 0 and 1 or 0)
|
||||||
99
test/test_git_parser.lua
Normal file
99
test/test_git_parser.lua
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
local git = require("git")
|
||||||
|
|
||||||
|
test.suite("git.parse_url", function()
|
||||||
|
test.case("parses HTTPS URL without .git", function()
|
||||||
|
local domain, path = git.parse_url("https://gitlab.freedesktop.org/xorg/proto")
|
||||||
|
assert_eq(domain, "gitlab.freedesktop.org", "Domain should be gitlab.freedesktop.org")
|
||||||
|
assert_eq(path, "xorg/proto", "Path should be xorg/proto")
|
||||||
|
end)
|
||||||
|
|
||||||
|
test.case("parses HTTPS URL without .git", function()
|
||||||
|
local domain, path = git.parse_url("https://gitlab.freedesktop.org/xorg/proto/xcbproto")
|
||||||
|
assert_eq(domain, "gitlab.freedesktop.org", "Domain should be gitlab.freedesktop.org")
|
||||||
|
assert_eq(path, "xorg/proto/xcbproto", "Path should be xorg/proto/xcbproto")
|
||||||
|
end)
|
||||||
|
|
||||||
|
test.case("parses HTTPS URL with .git", function()
|
||||||
|
local domain, path = git.parse_url("https://github.com/user/repo.git")
|
||||||
|
assert_eq(domain, "github.com", "Domain should be github.com")
|
||||||
|
assert_eq(path, "user/repo", "Path should be user/repo")
|
||||||
|
end)
|
||||||
|
|
||||||
|
test.case("parses HTTPS URL with authentication", function()
|
||||||
|
local domain, path = git.parse_url("https://user@gitlab.freedesktop.org/xorg/proto")
|
||||||
|
assert_eq(domain, "gitlab.freedesktop.org", "Domain should be gitlab.freedesktop.org")
|
||||||
|
assert_eq(path, "xorg/proto", "Path should be xorg/proto")
|
||||||
|
end)
|
||||||
|
|
||||||
|
test.case("parses HTTPS URL with authentication and .git", function()
|
||||||
|
local domain, path = git.parse_url("https://user:token@github.com/user/repo.git")
|
||||||
|
assert_eq(domain, "github.com", "Domain should be github.com")
|
||||||
|
assert_eq(path, "user/repo", "Path should be user/repo")
|
||||||
|
end)
|
||||||
|
|
||||||
|
test.case("parses SSH URL", function()
|
||||||
|
local domain, path = git.parse_url("git@github.com:user/repo.git")
|
||||||
|
assert_eq(domain, "github.com", "Domain should be github.com")
|
||||||
|
assert_eq(path, "user/repo", "Path should be user/repo")
|
||||||
|
end)
|
||||||
|
|
||||||
|
test.case("parses SSH URL without .git", function()
|
||||||
|
local domain, path = git.parse_url("git@gitlab.com:group/project")
|
||||||
|
assert_eq(domain, "gitlab.com", "Domain should be gitlab.com")
|
||||||
|
assert_eq(path, "group/project", "Path should be group/project")
|
||||||
|
end)
|
||||||
|
|
||||||
|
test.case("parses SSH URL with port", function()
|
||||||
|
local domain, path = git.parse_url("ssh://git@github.com/user/repo.git")
|
||||||
|
assert_eq(domain, "github.com", "Domain should be github.com")
|
||||||
|
assert_eq(path, "user/repo", "Path should be user/repo")
|
||||||
|
end)
|
||||||
|
|
||||||
|
test.case("parses bare domain path", function()
|
||||||
|
local domain, path = git.parse_url("gfx.cafe/oku/trade")
|
||||||
|
assert_eq(domain, "gfx.cafe", "Domain should be gfx.cafe")
|
||||||
|
assert_eq(path, "oku/trade", "Path should be oku/trade")
|
||||||
|
end)
|
||||||
|
|
||||||
|
test.case("returns nil for invalid URLs", function()
|
||||||
|
local domain, path = git.parse_url("not-a-url")
|
||||||
|
assert_nil(domain, "Domain should be nil for invalid URL")
|
||||||
|
assert_nil(path, "Path should be nil for invalid URL")
|
||||||
|
end)
|
||||||
|
|
||||||
|
test.case("handles complex paths", function()
|
||||||
|
local domain, path = git.parse_url("https://gitlab.com/group/subgroup/project.git")
|
||||||
|
assert_eq(domain, "gitlab.com", "Domain should be gitlab.com")
|
||||||
|
assert_eq(path, "group/subgroup/project", "Path should preserve subgroups")
|
||||||
|
end)
|
||||||
|
|
||||||
|
test.case("does not parse short SSH syntax as regular domain", function()
|
||||||
|
-- This ensures git@g:xorg/proto is treated as SSH, not misinterpreted
|
||||||
|
local domain, path = git.parse_url("git@g:xorg/proto")
|
||||||
|
assert_eq(domain, "g", "Domain should be g for SSH URL")
|
||||||
|
assert_eq(path, "xorg/proto", "Path should be xorg/proto")
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
test.suite("git.valid_url", function()
|
||||||
|
test.case("identifies HTTPS URLs", function()
|
||||||
|
assert_eq(git.valid_url("https://github.com/user/repo"), 1)
|
||||||
|
assert_eq(git.valid_url("http://example.com/path"), 1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
test.case("identifies SSH URLs", function()
|
||||||
|
assert_eq(git.valid_url("git@github.com:user/repo"), 2)
|
||||||
|
assert_eq(git.valid_url("ssh://git@github.com/user/repo"), 2)
|
||||||
|
end)
|
||||||
|
|
||||||
|
test.case("identifies bare domain paths", function()
|
||||||
|
assert_eq(git.valid_url("example.com/user/repo"), 3)
|
||||||
|
assert_eq(git.valid_url("sub.example.org/path/to/repo"), 3)
|
||||||
|
end)
|
||||||
|
|
||||||
|
test.case("returns -1 for invalid URLs", function()
|
||||||
|
assert_eq(git.valid_url("not-a-url"), -1)
|
||||||
|
assert_eq(git.valid_url("/local/path"), -1)
|
||||||
|
assert_eq(git.valid_url("file:///path"), -1)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
Loading…
Reference in New Issue
Block a user