defmodule Gogs do
@moduledoc """
Documentation for the main `Gogs` functions. <br />
This package is an `Elixir` interface to our `Gogs` Server.
It contains all functions we need to create repositories,
clone, add data to files, commit, push and diff.
Some of these functions use `Git` and others use the `REST API`.
We would _obviously_ prefer if everything was one or the other,
but sadly, some things cannot be done via `Git` or `REST`
so we have adopted a "hybrid" approach.
If anything is unclear, please open an issue:
https://github.com/dwyl/gogs/issues
"""
import GogsHelpers
@access_token Envar.get("GOGS_ACCESS_TOKEN")
@api_base_url GogsHelpers.api_base_url()
@git (Application.compile_env(:gogs, :mock) && Gogs.GitMock) || Git
@httpoison (Application.compile_env(:gogs, :mock) &&
Gogs.HTTPoisonMock) || HTTPoison
@doc """
`inject_poison/0` injects a TestDouble of HTTPoison in Test
so that we don't have duplicate mock in consuming apps.
see: github.com/dwyl/elixir-auth-google/issues/35
"""
def inject_git, do: @git
@doc """
`inject_poison/0` injects a TestDouble of HTTPoison in Test
so that we don't have duplicate mock in consuming apps.
see: github.com/dwyl/elixir-auth-google/issues/35
"""
def inject_poison, do: @httpoison
@doc """
`post/2` accepts two arguments: `url` and `params`.
Makes an `HTTP POST` request to the specified `url`
passing in the `params` as the request body.
Auth Headers and Content-Type are implicit.
"""
@spec post(String.t(), map) :: {:ok, map} | {:error, any}
def post(url, params \\ %{}) do
# IO.inspect(url, label: url)
body = Jason.encode!(params)
headers = [
{"Accept", "application/json"},
{"Authorization", "token #{@access_token}"},
{"Content-Type", "application/json"}
]
inject_poison().post(url, body, headers)
|> parse_body_response()
end
@doc """
`remote_repo_create/3` accepts 3 arguments: `org_name`, `repo_name` & `private`.
It creates a repo on the remote `Gogs` instance as defined
by the environment variable `GOGS_URL`.
For convenience it assumes that you only have _one_ `Gogs` instance.
If you have more or different requirements, please share!
"""
def remote_repo_create(org_name, repo_name, private \\ false) do
url = @api_base_url <> "org/#{org_name}/repos"
# IO.inspect(url, label: "remote_repo_create url")
params = %{
name: repo_name,
private: private,
description: repo_name,
readme: repo_name
}
post(url, params)
end
@doc """
`delete/1` accepts a single argument `url`;
the `url` for the repository to be deleted.
"""
@spec delete(String.t()) :: {:ok, map} | {:error, any}
def delete(url) do
inject_poison().delete(url <> "?token=#{@access_token}")
|> parse_body_response()
end
@doc """
`remote_repo_delete/2` accepts two arguments: `org_name` and `repo_name`.
It deletes the repo on the remote `Gogs` instance as defined
by the environment variable `GOGS_URL`.
"""
def remote_repo_delete(org_name, repo_name) do
url = @api_base_url <> "repos/#{org_name}/#{repo_name}"
# IO.inspect(url, label: "remote_repo_delete url")
delete(url)
end
@doc """
`clone/1` clones a remote git repository based on `git_repo_url`
returns the path of the _local_ copy of the repository.
"""
def clone(git_repo_url) do
# IO.inspect("git clone #{git_repo_url}")
case Git.clone(git_repo_url) do
{:ok, %Git.Repository{path: path}} ->
IO.inspect(path)
path
{:error, %Git.Error{message: _message}} ->
# IO.inspect("Attempted to clone #{git_repo_url}, got: #{message}")
get_repo_name_from_url(git_repo_url) |> local_repo_path()
end
end
def local_branch_create(repo_name, _branch_name \\ "draft") do
path = local_repo_path(repo_name)
repo = %Git.Repository{path: path}
inject_git().checkout(repo, ~w(-b draft)) # ["-b", branch_name])
end
# def commit do
# end
# def push do
# end
end