diff --git a/.gitignore b/.gitignore
index a91e699..b2e22f0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,5 +39,5 @@ npm-debug.log
/priv/repo/dumps/
/priv/static/
-/size
-/size.o
+/bin/size
+*.o
diff --git a/Makefile b/Makefile
index 21d2b17..90c84be 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
-PROG = size
-SRC = size.c
-SRC_O = size.o
+PROG = bin/size
+SRC = c_src/size.c
+SRC_O = c_src/size.o
all: ${PROG}
diff --git a/README.md b/README.md
index 17737b0..b7b2a4d 100644
--- a/README.md
+++ b/README.md
@@ -63,6 +63,36 @@ location ~ ^(.*/info/refs|.*/git-upload-pack)$ {
```
+<h1><a id="todo" href="#todo">TODO</a></h1>
+
+## kmxgit 0.4
+
+ - slugs without joins
+ - Markdown refactor
+ - git port / bindings
+ - pygmentize port
+ - shell commands -> elixir (mkdir mv rm)
+ - Shared deploy SSH keys.
+ - For now deploy keys must be unique (cannot be shared between repos).
+ - Releases
+ - infos
+ - static files
+ - Pull requests
+ - Comments in diff
+ - Issues / tickets
+ - fields
+ - trac: reported_by, owner, priority, milestone, component, version, severity, keywords, carbon_copy, branch
+ - github:
+ - gitlab:
+ - discussion
+ - status change
+ - Static site generator
+ - OAuth2
+ - Google
+ - Github
+ - Gitlab
+
+
<h1><a id="ChangeLog" href="#ChangeLog">ChangeLog</a></h1>
<h2><a id="v0.3" href="#v0.3">Added in kmxgit 0.3</a></h2>
@@ -159,28 +189,6 @@ location ~ ^(.*/info/refs|.*/git-upload-pack)$ {
- user auth using Guardian
-<h1><a id="todo" href="#todo">TODO</a></h1>
-
-## kmxgit 0.4
-
- - Shared deploy SSH keys.
- - For now deploy keys must be unique (cannot be shared between repos).
- - Releases
- - infos
- - static files
- - Pull requests
- - Comments in diff
- - Issues / tickets
- - fields: reported_by, owner, priority, milestone, component, version, severity, keywords, carbon_copy, branch
- - discussion
- - status change
- - Static site generator
- - OAuth2
- - Google
- - Github
- - Gitlab
-
-
<h1><a href="#copyright" id="copyright">Copyright</a></h1>
kmxgit - git server administration
diff --git a/c_src/size.c b/c_src/size.c
new file mode 100644
index 0000000..bdd49f2
--- /dev/null
+++ b/c_src/size.c
@@ -0,0 +1,51 @@
+/* size - truncate standard input by size */
+
+#include <err.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define BUFSIZE 8192
+
+int usage(char *argv0)
+{
+ fprintf(stderr, "Usage: %s SIZE COMMAND [ARGS ...]\n", argv0);
+ return 1;
+}
+
+int main (int argc, char **argv)
+{
+ char *a;
+ char cmd[BUFSIZE];
+ char *c = cmd;
+ char buf[BUFSIZE];
+ int i = 0;
+ size_t pos = 0;
+ ssize_t r;
+ unsigned long size;
+ FILE *pipe;
+ size_t len;
+ if (argc < 3)
+ return usage(argv[0]);
+ size = strtoul(argv[1], NULL, 10);
+ for (i = 2; i < argc; i++) {
+ a = argv[i];
+ while ((*c++ = *a++))
+ ;
+ c--;
+ *c++ = ' ';
+ }
+ *c = 0;
+ pipe = popen(cmd, "w");
+ len = pos + BUFSIZE < size ? BUFSIZE : size - pos;
+ while (pos < size && (r = fread(buf, 1, len, stdin)) > 0) {
+ if (fwrite(buf, r, 1, pipe) != 1)
+ err(1, "fwrite");
+ pos += r;
+ len = pos + BUFSIZE < size ? BUFSIZE : size - pos;
+ }
+ if (r < 0)
+ err(1, "fread");
+ pclose(pipe);
+ return 0;
+}
diff --git a/cli/kmxgit.rb b/cli/kmxgit.rb
deleted file mode 100755
index 089183f..0000000
--- a/cli/kmxgit.rb
+++ /dev/null
@@ -1,183 +0,0 @@
-#!/usr/bin/env ruby
-
-require 'capybara'
-require 'io/console'
-require 'json'
-require 'open-uri'
-require 'optparse'
-
-Options = Struct.new(:cmd, :user)
-
-def usage()
- puts """Usage :
-$ kmxgit (-h | --help)
- Display this help message and exit.
-$ kmxgit [OPTIONS] (-m | --mirror)
- Mirror website
-Available options :
- -u USER | --user=USER Login as USER.
-"""
-end
-
-def main(argv)
- @options = Options.new(nil, nil)
- OptionParser.new do |opts|
- opts.on("-h", "--help") do
- @options.cmd = :help
- end
- opts.on("-m", "--mirror") do
- @options.cmd = :mirror
- end
- opts.on("-uUSER", "--user=USER") do |user|
- @options.user = user
- end
- end.parse!
- case @options.cmd
- when :help
- usage()
- return 0
- when :mirror
- FileUtils.mkdir_p "git.kmx.io"
- Capybara.configure do |config|
- config.save_path = "git.kmx.io"
- end
- @session = Capybara::Session.new(:selenium)
- if @options.user
- login()
- end
- return mirror()
- else
- usage()
- return 1
- end
-end
-
-def login()
- @session.visit("https://git.kmx.io/_log_in")
- while @session.has_selector?('form #user_password')
- password = IO::console.getpass("Password: ")
- @session.fill_in 'Login', with: @options.user
- @session.fill_in 'Password', with: password
- @session.click_button 'Submit'
- end
- while @session.has_selector?('form #user_totp')
- totp = IO::console.getpass("TOTP: ")
- @session.fill_in 'TOTP', with: totp
- @session.click_button 'Submit'
- end
- if @session.current_path == "/_log_in"
- raise "Failed to login"
- end
-end
-
-def get_links
- local = []
- external = []
- local_img = []
- external_img = []
- links = []
- scripts = []
- @session.all("a").each do |elt|
- href = elt[:href].split("#")[0]
- if href.start_with?("https://git.kmx.io/")
- local << href.slice(18..)
- else
- external << href
- end
- end
- local = local.uniq.compact
- external = external.uniq.compact
- @session.all("img").each do |elt|
- href = elt[:src].split("#")[0]
- if href.start_with?("https://git.kmx.io/")
- local_img << href.slice(18..)
- else
- external_img << href
- end
- end
- local_img = local_img.uniq.compact
- external_img = external_img.uniq.compact
- @session.all("link", visible: false).each do |elt|
- links << elt[:href]
- end
- @session.all("script", visible: false).each do |elt|
- scripts << elt[:src]
- end
- {local: local,
- external: external,
- links: links,
- scripts: scripts}
-end
-
-def visited?(path)
- @visited[path]
-end
-
-def visited!(path)
- @visited[path] = true
-end
-
-def save_visited
- File.write("git.kmx.io/.visited.json", @visited.to_json)
-end
-
-def mirror_asset(path)
- p = path
- p = p.sub(/[#].*$/, "")
- p = p.sub(/[?].*$/, "")
- if !visited?(p)
- visited!(p)
- @visited << p
- url = "https://git.kmx.io" + path
- io = open(url)
- IO.copy_stream(io, "git.kmx.io" + p)
- save_visited()
- end
- p
-end
-
-def mirror_page(path)
- p = path
- p = p.sub(/[#].*$/, "")
- if p.end_with?("/")
- p = p + "index.html"
- end
- if File.directory?("git.kmx.io" + p)
- p = p + "/index.html"
- end
- if !visited?(p)
- visited!(p)
- url = "https://git.kmx.io" + path
- @session.visit(url)
- dir = "git.kmx.io"
- File.dirname(p).split("/").each do |item|
- dir = "#{dir}/#{item}"
- File.unlink(dir) if File.file?(dir)
- end
- @session.save_page("." + p)
- links = get_links()
- puts links.inspect
- links[:local_img].each do |local_img|
- mirror_asset(local_img)
- end
- links[:links].each do |link|
- mirror_asset(link)
- end
- links[:scripts].each do |script|
- mirror_asset(script)
- end
- links[:local].each do |local|
- mirror_page(local)
- end
- save_visited()
- end
- p
-end
-
-def mirror
- @visited = []
- mirror_page("/")
- 1
-end
-
-main ARGV
diff --git a/lib/kmxgit/organisation_manager.ex b/lib/kmxgit/organisation_manager.ex
index 3de5b61..56098ab 100644
--- a/lib/kmxgit/organisation_manager.ex
+++ b/lib/kmxgit/organisation_manager.ex
@@ -35,9 +35,6 @@ defmodule Kmxgit.OrganisationManager do
def index_order_by(query, %{column: "id", reverse: true}) do
order_by(query, [desc: :id])
end
- def index_order_by(query, %{column: "id"}) do
- order_by(query, :id)
- end
def index_order_by(query, %{column: "name", reverse: true}) do
order_by(query, [org, s], [desc_nulls_last: fragment("lower(?)", org.name)])
end
@@ -56,6 +53,9 @@ defmodule Kmxgit.OrganisationManager do
def index_order_by(query, %{column: "du"}) do
order_by(query, :disk_usage)
end
+ def index_order_by(query, _) do
+ order_by(query, :id)
+ end
def update_disk_usage() do
Repo.all(from org in Organisation, preload: :slug)
diff --git a/lib/kmxgit/repository_manager.ex b/lib/kmxgit/repository_manager.ex
index 285efb8..a5105fa 100644
--- a/lib/kmxgit/repository_manager.ex
+++ b/lib/kmxgit/repository_manager.ex
@@ -12,6 +12,8 @@ defmodule Kmxgit.RepositoryManager do
alias Kmxgit.UserManager
alias Kmxgit.UserManager.User
+ # Do you want to refactor this code ?
+
def list_all_repositories() do
from(r in Repository)
|> join(:full, [r], o in Organisation, on: o.id == r.organisation_id)
@@ -209,11 +211,15 @@ defmodule Kmxgit.RepositoryManager do
def add_member(%Repository{} = repo, login) do
user = UserManager.get_user_by_login(login)
if user do
- members = [user | repo.members]
- repo
- |> Repository.changeset(%{})
- |> Ecto.Changeset.put_assoc(:members, members)
- |> Repo.update()
+ if ! Enum.find(repo.members, & &1.id == user.id) do
+ members = [user | repo.members]
+ repo
+ |> Repository.changeset(%{})
+ |> Ecto.Changeset.put_assoc(:members, members)
+ |> Repo.update()
+ else
+ {:error, :already_a_member}
+ end
else
{:error, :not_found}
end
@@ -222,11 +228,15 @@ defmodule Kmxgit.RepositoryManager do
def remove_member(%Repository{} = repo, login) do
user = UserManager.get_user_by_login(login)
if user do
- members = Enum.reject(repo.members, &(&1.id == user.id))
- repo
- |> Repository.changeset(%{})
- |> Ecto.Changeset.put_assoc(:members, members)
- |> Repo.update()
+ if Enum.find(repo.members, & &1.id == user.id) do
+ members = Enum.reject(repo.members, &(&1.id == user.id))
+ repo
+ |> Repository.changeset(%{})
+ |> Ecto.Changeset.put_assoc(:members, members)
+ |> Repo.update()
+ else
+ {:error, :already_a_member}
+ end
else
{:error, :not_found}
end
diff --git a/lib/kmxgit/repository_manager/repository.ex b/lib/kmxgit/repository_manager/repository.ex
index c80475e..8df055b 100644
--- a/lib/kmxgit/repository_manager/repository.ex
+++ b/lib/kmxgit/repository_manager/repository.ex
@@ -192,7 +192,7 @@ defmodule Kmxgit.RepositoryManager.Repository do
end
def deploy_user(repo) do
- slug = repo |> full_slug() |> String.replace(~r(.+/), "__")
+ slug = repo |> full_slug() |> String.replace(~r(\.\+/), "__")
"_deploy_#{slug}"
end
diff --git a/lib/kmxgit/user_manager.ex b/lib/kmxgit/user_manager.ex
index 999671e..f45110f 100644
--- a/lib/kmxgit/user_manager.ex
+++ b/lib/kmxgit/user_manager.ex
@@ -16,6 +16,7 @@ defmodule Kmxgit.UserManager do
owned_repositories: [members: :slug,
organisation: :slug,
user: :slug]]
+
def list_all_users() do
from(u in User)
|> join(:inner, [u], s in Slug, on: s.user_id == u.id)
diff --git a/lib/kmxgit_web/controllers/repository_controller.ex b/lib/kmxgit_web/controllers/repository_controller.ex
index bb91838..b83582a 100644
--- a/lib/kmxgit_web/controllers/repository_controller.ex
+++ b/lib/kmxgit_web/controllers/repository_controller.ex
@@ -491,22 +491,23 @@ defmodule KmxgitWeb.RepositoryController do
slug = Enum.join(params["slug"], "/")
repo = RepositoryManager.get_repository_by_owner_and_slug(params["owner"], slug)
if repo && Repository.owner?(repo, current_user) do
- case Repo.transaction(fn ->
- case RepositoryManager.update_repository(repo, params["repository"]) do
- {:ok, repo1} ->
- s = Repository.full_slug(repo)
- s1 = Repository.full_slug(repo1)
- if s != s1 do
- case GitManager.rename(s, s1) do
- :ok -> repo1
- {:error, err} -> Repo.rollback(err)
- end
- else
- repo1
- end
- {:error, changeset} -> Repo.rollback(changeset)
+ tr = Repo.transaction(fn ->
+ case RepositoryManager.update_repository(repo, params["repository"]) do
+ {:ok, repo1} ->
+ s = Repository.full_slug(repo)
+ s1 = Repository.full_slug(repo1)
+ if s != s1 do
+ case GitManager.rename(s, s1) do
+ :ok -> repo1
+ {:error, err} -> Repo.rollback(err)
+ end
+ else
+ repo1
end
- end) do
+ {:error, changeset} -> Repo.rollback(changeset)
+ end
+ end)
+ case tr do
{:ok, repo1} ->
case GitManager.update_auth() do
:ok -> :ok = GitManager.public_access(Repository.full_slug(repo1), repo1.public_access)
diff --git a/lib/kmxgit_web/templates/admin/user/show.html.heex b/lib/kmxgit_web/templates/admin/user/show.html.heex
index 47c426c..7f62197 100644
--- a/lib/kmxgit_web/templates/admin/user/show.html.heex
+++ b/lib/kmxgit_web/templates/admin/user/show.html.heex
@@ -22,7 +22,7 @@
<th><%= gettext "Description" %></th>
<td>
<%= if @user.description do %>
- <%= raw Earmark.as_html!(@user.description) %>
+ <%= raw Markdown.to_html!(@user.description) %>
<% end %>
</td>
</tr>
diff --git a/lib/kmxgit_web/templates/layout/nav.html.heex b/lib/kmxgit_web/templates/layout/nav.html.heex
index 4424c7c..387c0a2 100644
--- a/lib/kmxgit_web/templates/layout/nav.html.heex
+++ b/lib/kmxgit_web/templates/layout/nav.html.heex
@@ -5,7 +5,7 @@
<span><i class="fas fa-square"></i></span> kmx git
</div>
</a>
- <%= if !@conn.assigns[:no_navbar_links] do %>
+ <%= if ! @conn.assigns[:no_navbar_links] do %>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
diff --git a/lib/kmxgit_web/templates/organisation/show.html.heex b/lib/kmxgit_web/templates/organisation/show.html.heex
index 2def63c..862975e 100644
--- a/lib/kmxgit_web/templates/organisation/show.html.heex
+++ b/lib/kmxgit_web/templates/organisation/show.html.heex
@@ -39,7 +39,7 @@
<th><%= gettext "Description" %></th>
<td>
<%= if @org.description do %>
- <%= raw Earmark.as_html!(@org.description) %>
+ <%= raw Markdown.to_html!(@org.description) %>
<% end %>
</td>
</tr>
diff --git a/lib/kmxgit_web/templates/page/ssh_keys_fingerprint.txt.eex b/lib/kmxgit_web/templates/page/ssh_keys_fingerprint.txt.eex
index 85f5218..abb859a 100644
--- a/lib/kmxgit_web/templates/page/ssh_keys_fingerprint.txt.eex
+++ b/lib/kmxgit_web/templates/page/ssh_keys_fingerprint.txt.eex
@@ -1,4 +1,5 @@
-1024 SHA256:r57ekxPcF9yJ0WpHOUpAFjm07xTpPjRSGlogZ0rYUCw root@git.kmx.io (DSA)
- 256 SHA256:18YiaGgFCjxudAXYNqwgTsc18+8VJKhANWY/z1M9QII root@git.kmx.io (ECDSA)
- 256 SHA256:YIvGEjpZv0WTbi82w9YcWlD0wjrNehdEW/Fm8VGysxI root@git.kmx.io (ED25519)
-3072 SHA256:nCIvnd0P1WO6UktpUlW1txA74kmIojRSn22OUh1uiNs root@git.kmx.io (RSA)
+/!\ Warning /!\ SSH keys have changed, here are the new ones :
+1024 SHA256:O7NLic6YcSMZAeZUIM4xwzE6dL9uyiIcLUrxBl9sQ3I root@git.kmx.io (DSA)
+ 256 SHA256:Nxh+WtteSkSNc98RRtQTjoKUUrLVLFwe51eztgRirFA root@git.kmx.io (ECDSA)
+ 256 SHA256:LvKPy9BCcR2/TdRDB03NqYftphKu4jCcOq6bESFXtLs root@git.kmx.io (ED25519)
+3072 SHA256:FilNI547qCbcy01f7IJiDsdUfjECMsO5caN7xXUI7DM root@git.kmx.io (RSA)
diff --git a/lib/kmxgit_web/templates/user/show.html.heex b/lib/kmxgit_web/templates/user/show.html.heex
index 04f430e..f2c83ae 100644
--- a/lib/kmxgit_web/templates/user/show.html.heex
+++ b/lib/kmxgit_web/templates/user/show.html.heex
@@ -5,7 +5,7 @@
<h1><%= @user.name %> (<%= @user.slug.slug %>)</h1>
<div class="col col-12 col-md-8">
<%= if @user.description do %>
- <%= raw Earmark.as_html!(@user.description) %>
+ <%= raw Markdown.to_html!(@user.description) %>
<% end %>
</div>
<%= if @current_user && @user.id == @current_user.id do %>
@@ -53,7 +53,7 @@
</th>
<td>
<ul>
- <%= for org <- Enum.sort_by(@user.organisations, fn o -> o.slug.slug end) do %>
+ <%= for org <- Enum.sort_by(@user.organisations, & &1.slug.slug) do %>
<li>
<%= link(org.name || org.slug.slug,
to: Routes.slug_path(@conn, :show, org.slug.slug),
diff --git a/lib/kmxgit_web/views/layout_view.ex b/lib/kmxgit_web/views/layout_view.ex
index 73e0a36..aaab1d5 100644
--- a/lib/kmxgit_web/views/layout_view.ex
+++ b/lib/kmxgit_web/views/layout_view.ex
@@ -3,11 +3,6 @@ defmodule KmxgitWeb.LayoutView do
alias Kmxgit.RepositoryManager.Repository
- def flash_json(conn) do
- {:ok, result} = Jason.encode(get_flash(conn))
- %{"data-flash": result}
- end
-
# Phoenix LiveDashboard is available only in development by default,
# so we instruct Elixir to not warn if the dashboard route is missing.
@compile {:no_warn_undefined, {Routes, :live_dashboard_path, 2}}
diff --git a/lib/markdown.ex b/lib/markdown.ex
index 869d50b..b0f40d1 100644
--- a/lib/markdown.ex
+++ b/lib/markdown.ex
@@ -14,4 +14,8 @@ defmodule Markdown do
changeset
end
end
+
+ def to_html!(md) do
+ Earmark.as_html!(md)
+ end
end
diff --git a/lib/pygmentize.ex b/lib/pygmentize.ex
index 5585a96..caf60ac 100644
--- a/lib/pygmentize.ex
+++ b/lib/pygmentize.ex
@@ -15,7 +15,7 @@ defmodule Pygmentize do
def html(content, filename) do
lexer = lexer(filename)
- cmd = "./size #{byte_size(content)} pygmentize -l #{lexer} -f html"
+ cmd = "./bin/size #{byte_size(content)} pygmentize -l #{lexer} -f html"
IO.inspect(cmd)
port = Port.open({:spawn, cmd}, [:binary, :use_stdio, :exit_status, :stderr_to_stdout])
Port.monitor(port)
diff --git a/size.c b/size.c
deleted file mode 100644
index bdd49f2..0000000
--- a/size.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/* size - truncate standard input by size */
-
-#include <err.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#define BUFSIZE 8192
-
-int usage(char *argv0)
-{
- fprintf(stderr, "Usage: %s SIZE COMMAND [ARGS ...]\n", argv0);
- return 1;
-}
-
-int main (int argc, char **argv)
-{
- char *a;
- char cmd[BUFSIZE];
- char *c = cmd;
- char buf[BUFSIZE];
- int i = 0;
- size_t pos = 0;
- ssize_t r;
- unsigned long size;
- FILE *pipe;
- size_t len;
- if (argc < 3)
- return usage(argv[0]);
- size = strtoul(argv[1], NULL, 10);
- for (i = 2; i < argc; i++) {
- a = argv[i];
- while ((*c++ = *a++))
- ;
- c--;
- *c++ = ' ';
- }
- *c = 0;
- pipe = popen(cmd, "w");
- len = pos + BUFSIZE < size ? BUFSIZE : size - pos;
- while (pos < size && (r = fread(buf, 1, len, stdin)) > 0) {
- if (fwrite(buf, r, 1, pipe) != 1)
- err(1, "fwrite");
- pos += r;
- len = pos + BUFSIZE < size ? BUFSIZE : size - pos;
- }
- if (r < 0)
- err(1, "fread");
- pclose(pipe);
- return 0;
-}