Commit 791ab51cf26032b4abc8946345c6eafbfd30ea5b

Thomas de Grivel 2021-12-07T12:02:49

fork with origin tracking

diff --git a/lib/kmxgit/repository_manager.ex b/lib/kmxgit/repository_manager.ex
index 74a807c..6748c96 100644
--- a/lib/kmxgit/repository_manager.ex
+++ b/lib/kmxgit/repository_manager.ex
@@ -53,7 +53,7 @@ defmodule Kmxgit.RepositoryManager do
     params = %{description: repo.description,
                slug: slug}
     %Repository{}
-    |> Repository.owner_changeset(params, owner)
+    |> Repository.owner_changeset(params, owner, repo)
     |> Repo.insert()
   end
 
@@ -120,7 +120,9 @@ defmodule Kmxgit.RepositoryManager do
       full_join: us in Slug,
       on: us.user_id == u.id,
       where: (fragment("lower(?)", os.slug) == ^downcase_owner or fragment("lower(?)", us.slug) == ^downcase_owner) and fragment("lower(?)", r.slug) == ^downcase_slug,
-      preload: [members: :slug,
+      preload: [forked_from: [organisation: :slug,
+                              user: :slug],
+                members: :slug,
                 organisation: [:slug, [users: :slug]],
                 user: :slug],
       limit: 1
diff --git a/lib/kmxgit/repository_manager/repository.ex b/lib/kmxgit/repository_manager/repository.ex
index 48bfc99..7979a4d 100644
--- a/lib/kmxgit/repository_manager/repository.ex
+++ b/lib/kmxgit/repository_manager/repository.ex
@@ -11,6 +11,7 @@ defmodule Kmxgit.RepositoryManager.Repository do
     field :deploy_keys, :string
     field :description, :string
     field :fork_to, :string, virtual: true
+    belongs_to :forked_from, __MODULE__
     belongs_to :organisation, Organisation, on_replace: :nilify
     field :owner_slug, :string, virtual: true
     field :slug, :string
@@ -25,25 +26,36 @@ defmodule Kmxgit.RepositoryManager.Repository do
     |> common_changeset()
   end
 
-  def owner_changeset(repository, attrs, owner = %Organisation{}) do
+  def owner_changeset(repository, attrs, owner, forked_from \\ nil)
+  def owner_changeset(repository, attrs, owner = %Organisation{}, forked_from) do
     repository
     |> cast(attrs, [:deploy_keys, :description, :slug])
     |> put_change(:organisation_id, owner.id)
     |> put_change(:user_id, nil)
     |> put_assoc(:organisation, owner)
     |> put_assoc(:user, nil)
+    |> put_forked_from(forked_from)
     |> common_changeset()
   end
-  def owner_changeset(repository, attrs, owner = %User{}) do
+  def owner_changeset(repository, attrs, owner = %User{}, forked_from) do
     repository
     |> cast(attrs, [:deploy_keys, :description, :slug])
     |> put_change(:organisation_id, nil)
     |> put_change(:user_id, owner.id)
     |> put_assoc(:organisation, nil)
     |> put_assoc(:user, owner)
+    |> put_forked_from(forked_from)
     |> common_changeset()
   end
 
+  defp put_forked_from(changeset, nil) do
+    changeset
+  end
+  defp put_forked_from(changeset, forked_from) do
+    changeset
+    |> put_change(:forked_from, forked_from)
+  end
+
   defp common_changeset(changeset) do
     changeset
     |> validate_required([:slug])
diff --git a/lib/kmxgit_web/templates/repository/show.html.heex b/lib/kmxgit_web/templates/repository/show.html.heex
index f495367..d329a66 100644
--- a/lib/kmxgit_web/templates/repository/show.html.heex
+++ b/lib/kmxgit_web/templates/repository/show.html.heex
@@ -2,7 +2,11 @@
 
   <div class="row">
     <div class="col col-12 col-sm-7">
-      <h1 id="repo_title"><%= link Repository.owner_slug(@repo), to: Routes.slug_path(@conn, :show, Repository.owner_slug(@repo)) %>/<%= link @repo.slug, to: Routes.repository_path(@conn, :show, Repository.owner_slug(@repo), String.split(@repo.slug, "/")) %></h1>
+      <h1 id="repo_title"><%= link Repository.owner_slug(@repo), to: Routes.slug_path(@conn, :show, Repository.owner_slug(@repo)) %>/<%= link @repo.slug, to: Routes.repository_path(@conn, :show, Repository.owner_slug(@repo), Repository.splat(@repo)) %></h1>
+      <%= if @repo.forked_from do %>
+        <%= gettext("Forked from") %>
+        <%= link Repository.full_slug(@repo.forked_from), to: Routes.repository_path(@conn, :show, Repository.owner_slug(@repo.forked_from), Repository.splat(@repo.forked_from)) %>
+      <% end %>
     </div>
     <div class="col col-12 col-sm-4">
       <%= if Repository.owner?(@repo, @current_user) do %>
diff --git a/priv/repo/migrations/20211207104515_add_forked_from_to_repositories.exs b/priv/repo/migrations/20211207104515_add_forked_from_to_repositories.exs
new file mode 100644
index 0000000..3808b2f
--- /dev/null
+++ b/priv/repo/migrations/20211207104515_add_forked_from_to_repositories.exs
@@ -0,0 +1,10 @@
+defmodule Kmxgit.Repo.Migrations.AddForkedFromToRepositories do
+  use Ecto.Migration
+
+  def change do
+    alter table(:repositories) do
+      add :forked_from_id, references(:repositories)
+    end
+    create index(:repositories, [:forked_from_id])
+  end
+end