Fresh repository history for elektrine/tarakan hosted at https://git.elektrine.com/elektrine/tarakan.
83 lines
2.7 KiB
Elixir
83 lines
2.7 KiB
Elixir
defmodule TarakanWeb.RepositoryPaths do
|
|
@moduledoc """
|
|
Builds repository-scoped paths from a repository's stored host, so no view
|
|
or controller hardcodes a single source host into its links.
|
|
|
|
Remote repositories live under their host domain (`/github.com/owner/name`),
|
|
so a source URL pastes directly onto Tarakan. Hosted repositories live at
|
|
GitHub-style bare paths (`/handle/name`); `TarakanWeb.Plugs.HostedRoutes`
|
|
maps that form onto the internal `/hosted` route scope.
|
|
"""
|
|
|
|
use TarakanWeb, :verified_routes
|
|
|
|
alias Tarakan.Repositories.Repository
|
|
|
|
def repository_path(repository) do
|
|
repository_root(repository)
|
|
end
|
|
|
|
def repository_security_path(repository) do
|
|
repository_root(repository) <> "/security"
|
|
end
|
|
|
|
def repository_commits_path(repository) do
|
|
repository_root(repository) <> "/commits"
|
|
end
|
|
|
|
def repository_commit_path(repository, commit_sha) do
|
|
repository_commits_path(repository) <> "/" <> encode_path_segment(commit_sha)
|
|
end
|
|
|
|
def repository_code_path(repository, commit_sha, path_segments \\ []) do
|
|
root = repository_root(repository) <> "/code/" <> encode_path_segment(commit_sha)
|
|
|
|
case path_segments do
|
|
[] -> root
|
|
segments -> root <> "/" <> Enum.map_join(segments, "/", &encode_path_segment/1)
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Clone URLs for a Tarakan-hosted repository, or nil for external hosts.
|
|
|
|
The HTTPS URL derives from the endpoint's public URL; the SSH URL is
|
|
included only while the SSH daemon is enabled.
|
|
"""
|
|
def clone_urls(repository) do
|
|
if Repository.hosted?(repository) do
|
|
base = TarakanWeb.Endpoint.url()
|
|
path = "#{repository.owner}/#{repository.name}.git"
|
|
|
|
%{https: "#{base}/#{path}", ssh: ssh_clone_url(URI.parse(base).host, path)}
|
|
end
|
|
end
|
|
|
|
defp ssh_clone_url(host, path) do
|
|
config = Application.get_env(:tarakan, Tarakan.GitSSH, [])
|
|
|
|
if Keyword.get(config, :enabled, false) do
|
|
case Keyword.get(config, :port, 22) do
|
|
22 -> "ssh://git@#{host}/#{path}"
|
|
port -> "ssh://git@#{host}:#{port}/#{path}"
|
|
end
|
|
end
|
|
end
|
|
|
|
defp repository_root(%{owner: owner, name: name} = repository) do
|
|
if hosted?(repository) do
|
|
"/" <> encode_path_segment(owner) <> "/" <> encode_path_segment(name)
|
|
else
|
|
"/" <>
|
|
encode_path_segment(repository.host) <>
|
|
"/" <> encode_path_segment(owner) <> "/" <> encode_path_segment(name)
|
|
end
|
|
end
|
|
|
|
# Projection rows (infestation graph, instance ledger) carry host/owner/name as
|
|
# plain maps rather than loaded structs.
|
|
defp hosted?(%Repository{} = repository), do: Repository.hosted?(repository)
|
|
defp hosted?(%{host: host}), do: host == Repository.hosted_host()
|
|
|
|
defp encode_path_segment(segment), do: URI.encode(segment, &URI.char_unreserved?/1)
|
|
end
|