neiam
/gitgud
Git Gud
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
1
Log in to mark this repository.
Show the detected licence on the stats page
fd8f955 · Gabriel Morell · 2026-09-22 13:46
Message
{commit_body(@commit)}
Files changed
modified
lib/git_gud_web/live/repo_live/languages.ex
+33
−0
@@ -80,6 +80,8 @@ defmodule GitGudWeb.RepoLive.Languages do
| 80 | 80 | <% end %> |
| 81 | 81 | </p> |
| 82 | 82 | |
| 83 | + <.license repo={@repo} handle={@handle} /> | |
| 84 | + | |
| 83 | 85 | <%= case @status do %> |
| 84 | 86 | <% :empty -> %> |
| 85 | 87 | <p class="text-sm opacity-70">This branch or repository is empty.</p> |
@@ -136,6 +138,37 @@ defmodule GitGudWeb.RepoLive.Languages do
| 136 | 138 | """ |
| 137 | 139 | end |
| 138 | 140 | |
| 141 | + attr :repo, :map, required: true | |
| 142 | + attr :handle, :string, required: true | |
| 143 | + | |
| 144 | + # Detected from the licence file at the default branch's tip, so it is | |
| 145 | + # labelled with that branch rather than with whichever ref the stats | |
| 146 | + # on this page are for — the two can differ, and quietly showing one | |
| 147 | + # branch's licence under another's name would be a lie. | |
| 148 | + defp license(assigns) do | |
| 149 | + ~H""" | |
| 150 | + <p class="text-sm flex items-center gap-2"> | |
| 151 | + <%= if @repo.license do %> | |
| 152 | + <span class="badge badge-sm badge-outline">{@repo.license}</span> | |
| 153 | + <.link | |
| 154 | + :if={@repo.license_file} | |
| 155 | + navigate={ | |
| 156 | + ~p"/r/#{@handle}/#{@repo.name}/blob/#{@repo.default_branch}/#{@repo.license_file}" | |
| 157 | + } | |
| 158 | + class="link link-hover text-xs opacity-70 font-mono" | |
| 159 | + > | |
| 160 | + {@repo.license_file} | |
| 161 | + </.link> | |
| 162 | + <span class="text-xs opacity-50">on {@repo.default_branch}</span> | |
| 163 | + <% else %> | |
| 164 | + <span class="text-xs opacity-60"> | |
| 165 | + No licence detected on {@repo.default_branch}. | |
| 166 | + </span> | |
| 167 | + <% end %> | |
| 168 | + </p> | |
| 169 | + """ | |
| 170 | + end | |
| 171 | + | |
| 139 | 172 | attr :stats, :map, required: true |
| 140 | 173 | |
| 141 | 174 | defp bar(assigns) do |
added
test/git_gud_web/live/stats_license_test.exs
+75
−0
@@ -0,0 +1,75 @@
| 1 | +defmodule GitGudWeb.StatsLicenseTest do | |
| 2 | + @moduledoc """ | |
| 3 | + The detected licence on `/r/:owner/:name/stats/languages`. | |
| 4 | + | |
| 5 | + It is labelled with the default branch rather than with whichever ref | |
| 6 | + the stats are for: detection follows the default branch's tip, and | |
| 7 | + the two can differ. | |
| 8 | + """ | |
| 9 | + use GitGudWeb.ConnCase, async: false | |
| 10 | + | |
| 11 | + import Ecto.Query, only: [from: 2] | |
| 12 | + import Phoenix.LiveViewTest | |
| 13 | + import GitGud.ForgeFixtures | |
| 14 | + | |
| 15 | + alias GitGud.Repositories | |
| 16 | + alias GitGud.Repositories.Repository | |
| 17 | + | |
| 18 | + setup %{conn: conn} do | |
| 19 | + {user, repo} = repository_fixture(%{visibility: "public"}) | |
| 20 | + seed_main_branch(repo, user) | |
| 21 | + %{conn: log_in_user(conn, user), user: user, repo: repo, handle: user.handle} | |
| 22 | + end | |
| 23 | + | |
| 24 | + test "shows the licence and links to the file it came from", %{ | |
| 25 | + conn: conn, | |
| 26 | + user: user, | |
| 27 | + repo: repo, | |
| 28 | + handle: handle | |
| 29 | + } do | |
| 30 | + sha = seed_file(repo, "main", "LICENSE.md", File.read!("LICENSE.md"), user) | |
| 31 | + assert {:ok, "AGPL-3.0"} = Repositories.detect_and_store_license(repo, sha) | |
| 32 | + | |
| 33 | + {:ok, _view, html} = live(conn, ~p"/r/#{handle}/#{repo.name}/stats/languages") | |
| 34 | + | |
| 35 | + assert html =~ "AGPL-3.0" | |
| 36 | + assert html =~ "LICENSE.md" | |
| 37 | + assert html =~ "/r/#{handle}/#{repo.name}/blob/main/LICENSE.md" | |
| 38 | + end | |
| 39 | + | |
| 40 | + test "says so when nothing was detected", %{conn: conn, repo: repo, handle: handle} do | |
| 41 | + {:ok, _view, html} = live(conn, ~p"/r/#{handle}/#{repo.name}/stats/languages") | |
| 42 | + | |
| 43 | + assert html =~ "No licence detected" | |
| 44 | + refute html =~ "badge-outline\">AGPL" | |
| 45 | + end | |
| 46 | + | |
| 47 | + test "an unrecognised licence file reads as undetected, not as a guess", %{ | |
| 48 | + conn: conn, | |
| 49 | + user: user, | |
| 50 | + repo: repo, | |
| 51 | + handle: handle | |
| 52 | + } do | |
| 53 | + sha = seed_file(repo, "main", "LICENSE", "Be excellent to each other.\n", user) | |
| 54 | + assert {:ok, nil} = Repositories.detect_and_store_license(repo, sha) | |
| 55 | + | |
| 56 | + {:ok, _view, html} = live(conn, ~p"/r/#{handle}/#{repo.name}/stats/languages") | |
| 57 | + | |
| 58 | + assert html =~ "No licence detected" | |
| 59 | + end | |
| 60 | + | |
| 61 | + test "renders a licence with no recorded file", %{conn: conn, repo: repo, handle: handle} do | |
| 62 | + # Possible for a row written before `license_file` existed: the | |
| 63 | + # badge still shows, with nothing to link to. | |
| 64 | + {1, _} = | |
| 65 | + GitGud.Repo.update_all( | |
| 66 | + from(r in Repository, where: r.id == ^repo.id), | |
| 67 | + set: [license: "MIT", license_file: nil] | |
| 68 | + ) | |
| 69 | + | |
| 70 | + {:ok, _view, html} = live(conn, ~p"/r/#{handle}/#{repo.name}/stats/languages") | |
| 71 | + | |
| 72 | + assert html =~ "MIT" | |
| 73 | + refute html =~ "/blob/main/" | |
| 74 | + end | |
| 75 | +end |
Parents: 53f3a6c