From c9b4eee4c589b8b40c02d0c96f887ec991580a24 Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Sun, 6 Apr 2025 09:33:11 +0800 Subject: Restructure static/templates into forged --- .golangci.yaml | 42 --- Makefile | 2 +- forged/.golangci.yaml | 42 +++ forged/cmd/forge/main.go | 1 + forged/internal/embed/.gitignore | 1 + forged/internal/embed/embed.go | 2 +- forged/internal/unsorted/resources.go | 2 +- forged/internal/unsorted/server.go | 2 +- forged/static/.gitignore | 2 + forged/static/chroma.css | 152 ++++++++ forged/static/style.css | 613 +++++++++++++++++++++++++++++++ forged/templates/400.tmpl | 25 ++ forged/templates/400_colon.tmpl | 26 ++ forged/templates/403.tmpl | 25 ++ forged/templates/404.tmpl | 24 ++ forged/templates/451.tmpl | 25 ++ forged/templates/500.tmpl | 25 ++ forged/templates/501.tmpl | 24 ++ forged/templates/_footer.tmpl | 12 + forged/templates/_group_path.tmpl | 8 + forged/templates/_group_view.tmpl | 56 +++ forged/templates/_head.tmpl | 9 + forged/templates/_header.tmpl | 35 ++ forged/templates/_ref_query.tmpl | 3 + forged/templates/group.tmpl | 80 ++++ forged/templates/index.tmpl | 63 ++++ forged/templates/login.tmpl | 59 +++ forged/templates/repo_branches.tmpl | 71 ++++ forged/templates/repo_commit.tmpl | 117 ++++++ forged/templates/repo_contrib_index.tmpl | 82 +++++ forged/templates/repo_contrib_one.tmpl | 123 +++++++ forged/templates/repo_index.tmpl | 94 +++++ forged/templates/repo_log.tmpl | 90 +++++ forged/templates/repo_raw_dir.tmpl | 88 +++++ forged/templates/repo_tree_dir.tmpl | 93 +++++ forged/templates/repo_tree_file.tmpl | 65 ++++ static/.gitignore | 2 - static/chroma.css | 152 -------- static/style.css | 613 ------------------------------- templates/400.tmpl | 25 -- templates/400_colon.tmpl | 26 -- templates/403.tmpl | 25 -- templates/404.tmpl | 24 -- templates/451.tmpl | 25 -- templates/500.tmpl | 25 -- templates/501.tmpl | 24 -- templates/_footer.tmpl | 12 - templates/_group_path.tmpl | 8 - templates/_group_view.tmpl | 56 --- templates/_head.tmpl | 9 - templates/_header.tmpl | 35 -- templates/_ref_query.tmpl | 3 - templates/group.tmpl | 80 ---- templates/index.tmpl | 63 ---- templates/login.tmpl | 59 --- templates/repo_branches.tmpl | 71 ---- templates/repo_commit.tmpl | 117 ------ templates/repo_contrib_index.tmpl | 82 ----- templates/repo_contrib_one.tmpl | 123 ------- templates/repo_index.tmpl | 94 ----- templates/repo_log.tmpl | 90 ----- templates/repo_raw_dir.tmpl | 88 ----- templates/repo_tree_dir.tmpl | 93 ----- templates/repo_tree_file.tmpl | 65 ---- 64 files changed, 2137 insertions(+), 2135 deletions(-) delete mode 100644 .golangci.yaml create mode 100644 forged/.golangci.yaml create mode 100644 forged/static/.gitignore create mode 100644 forged/static/chroma.css create mode 100644 forged/static/style.css create mode 100644 forged/templates/400.tmpl create mode 100644 forged/templates/400_colon.tmpl create mode 100644 forged/templates/403.tmpl create mode 100644 forged/templates/404.tmpl create mode 100644 forged/templates/451.tmpl create mode 100644 forged/templates/500.tmpl create mode 100644 forged/templates/501.tmpl create mode 100644 forged/templates/_footer.tmpl create mode 100644 forged/templates/_group_path.tmpl create mode 100644 forged/templates/_group_view.tmpl create mode 100644 forged/templates/_head.tmpl create mode 100644 forged/templates/_header.tmpl create mode 100644 forged/templates/_ref_query.tmpl create mode 100644 forged/templates/group.tmpl create mode 100644 forged/templates/index.tmpl create mode 100644 forged/templates/login.tmpl create mode 100644 forged/templates/repo_branches.tmpl create mode 100644 forged/templates/repo_commit.tmpl create mode 100644 forged/templates/repo_contrib_index.tmpl create mode 100644 forged/templates/repo_contrib_one.tmpl create mode 100644 forged/templates/repo_index.tmpl create mode 100644 forged/templates/repo_log.tmpl create mode 100644 forged/templates/repo_raw_dir.tmpl create mode 100644 forged/templates/repo_tree_dir.tmpl create mode 100644 forged/templates/repo_tree_file.tmpl delete mode 100644 static/.gitignore delete mode 100644 static/chroma.css delete mode 100644 static/style.css delete mode 100644 templates/400.tmpl delete mode 100644 templates/400_colon.tmpl delete mode 100644 templates/403.tmpl delete mode 100644 templates/404.tmpl delete mode 100644 templates/451.tmpl delete mode 100644 templates/500.tmpl delete mode 100644 templates/501.tmpl delete mode 100644 templates/_footer.tmpl delete mode 100644 templates/_group_path.tmpl delete mode 100644 templates/_group_view.tmpl delete mode 100644 templates/_head.tmpl delete mode 100644 templates/_header.tmpl delete mode 100644 templates/_ref_query.tmpl delete mode 100644 templates/group.tmpl delete mode 100644 templates/index.tmpl delete mode 100644 templates/login.tmpl delete mode 100644 templates/repo_branches.tmpl delete mode 100644 templates/repo_commit.tmpl delete mode 100644 templates/repo_contrib_index.tmpl delete mode 100644 templates/repo_contrib_one.tmpl delete mode 100644 templates/repo_index.tmpl delete mode 100644 templates/repo_log.tmpl delete mode 100644 templates/repo_raw_dir.tmpl delete mode 100644 templates/repo_tree_dir.tmpl delete mode 100644 templates/repo_tree_file.tmpl diff --git a/.golangci.yaml b/.golangci.yaml deleted file mode 100644 index 1c8c972..0000000 --- a/.golangci.yaml +++ /dev/null @@ -1,42 +0,0 @@ -linters: - enable-all: true - disable: - - tenv - - depguard - - err113 # dynamically defined errors are fine for our purposes - - forcetypeassert # type assertion failures are usually programming errors - - gochecknoinits # we use inits sparingly for good reasons - - godox # they're just used as markers for where needs improvements - - ireturn # doesn't work well with how we use generics - - lll # long lines are acceptable - - mnd # it's a bit ridiculous to replace all of them - - nakedret # patterns should be consistent - - nonamedreturns # i like named returns - - wrapcheck # wrapping all errors is just not necessary - - varnamelen # "from" and "to" are very valid - - stylecheck - - containedctx - - godot - - dogsled - - maintidx # e - - nestif # e - - gocognit # e - - gocyclo # e - - dupl # e - - cyclop # e - - goconst # e - - funlen # e - - wsl # e - - nlreturn # e - - unused # e - - exhaustruct # e - -linters-settings: - revive: - rules: - - name: error-strings - disabled: true - -issues: - max-issues-per-linter: 0 - max-same-issues: 0 diff --git a/Makefile b/Makefile index 98a2f14..990c1ce 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ CFLAGS = -Wall -Wextra -pedantic -std=c99 -D_GNU_SOURCE VERSION = $(shell git describe --tags --always --dirty) SOURCE_FILES = $(shell git ls-files) -EMBED = git2d/git2d hookc/hookc source.tar.gz $(wildcard LICENSE*) $(wildcard static/*) $(wildcard templates/*) +EMBED = git2d/git2d hookc/hookc source.tar.gz $(wildcard LICENSE*) $(wildcard forged/static/*) $(wildcard forged/templates/*) EMBED_ = $(EMBED:%=forged/internal/embed/%) forge: $(EMBED_) $(SOURCE_FILES) diff --git a/forged/.golangci.yaml b/forged/.golangci.yaml new file mode 100644 index 0000000..1c8c972 --- /dev/null +++ b/forged/.golangci.yaml @@ -0,0 +1,42 @@ +linters: + enable-all: true + disable: + - tenv + - depguard + - err113 # dynamically defined errors are fine for our purposes + - forcetypeassert # type assertion failures are usually programming errors + - gochecknoinits # we use inits sparingly for good reasons + - godox # they're just used as markers for where needs improvements + - ireturn # doesn't work well with how we use generics + - lll # long lines are acceptable + - mnd # it's a bit ridiculous to replace all of them + - nakedret # patterns should be consistent + - nonamedreturns # i like named returns + - wrapcheck # wrapping all errors is just not necessary + - varnamelen # "from" and "to" are very valid + - stylecheck + - containedctx + - godot + - dogsled + - maintidx # e + - nestif # e + - gocognit # e + - gocyclo # e + - dupl # e + - cyclop # e + - goconst # e + - funlen # e + - wsl # e + - nlreturn # e + - unused # e + - exhaustruct # e + +linters-settings: + revive: + rules: + - name: error-strings + disabled: true + +issues: + max-issues-per-linter: 0 + max-same-issues: 0 diff --git a/forged/cmd/forge/main.go b/forged/cmd/forge/main.go index 8785751..fde15d1 100644 --- a/forged/cmd/forge/main.go +++ b/forged/cmd/forge/main.go @@ -1,6 +1,7 @@ // SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +// The main entry point to the Lindenii Forge daemon. package main import ( diff --git a/forged/internal/embed/.gitignore b/forged/internal/embed/.gitignore index b4db111..e8708b1 100644 --- a/forged/internal/embed/.gitignore +++ b/forged/internal/embed/.gitignore @@ -4,3 +4,4 @@ /static /templates /LICENSE* +/forged diff --git a/forged/internal/embed/embed.go b/forged/internal/embed/embed.go index 68af51d..c9eeeb3 100644 --- a/forged/internal/embed/embed.go +++ b/forged/internal/embed/embed.go @@ -9,6 +9,6 @@ import "embed" //go:embed LICENSE* source.tar.gz var Source embed.FS -//go:embed templates/* static/* +//go:embed forged/templates/* forged/static/* //go:embed hookc/hookc git2d/git2d var Resources embed.FS diff --git a/forged/internal/unsorted/resources.go b/forged/internal/unsorted/resources.go index 9f3a5d0..692b454 100644 --- a/forged/internal/unsorted/resources.go +++ b/forged/internal/unsorted/resources.go @@ -30,7 +30,7 @@ func (s *Server) loadTemplates() (err error) { "minus": misc.Minus, }) - err = fs.WalkDir(embed.Resources, "templates", func(path string, d fs.DirEntry, err error) error { + err = fs.WalkDir(embed.Resources, "forged/templates", func(path string, d fs.DirEntry, err error) error { if err != nil { return err } diff --git a/forged/internal/unsorted/server.go b/forged/internal/unsorted/server.go index f8978a5..c7caa76 100644 --- a/forged/internal/unsorted/server.go +++ b/forged/internal/unsorted/server.go @@ -63,7 +63,7 @@ func NewServer(configPath string) (*Server, error) { "/-/source/", http.FileServer(http.FS(embed.Source)), ) - staticFS, err := fs.Sub(embed.Resources, "static") + staticFS, err := fs.Sub(embed.Resources, "forged/static") if err != nil { return s, err } diff --git a/forged/static/.gitignore b/forged/static/.gitignore new file mode 100644 index 0000000..812b75f --- /dev/null +++ b/forged/static/.gitignore @@ -0,0 +1,2 @@ +/index.html +# used for testing css without recompiling the server diff --git a/forged/static/chroma.css b/forged/static/chroma.css new file mode 100644 index 0000000..1f7219a --- /dev/null +++ b/forged/static/chroma.css @@ -0,0 +1,152 @@ +/* + * SPDX-License-Identifier: MIT AND BSD-2-Clause + * SPDX-FileCopyrightText: Copyright (c) 2018-2025 Pygments and Chroma authors + */ + +@media (prefers-color-scheme: light) { + /* Background */ .bg { ; } + /* PreWrapper */ .chroma { ; } + /* Error */ .chroma .err { } + /* LineLink */ .chroma .lnlinks { outline: none; text-decoration: none; color: inherit } + /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } + /* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; } + /* LineHighlight */ .chroma .hl { background-color: #e5e5e5 } + /* LineNumbersTable */ .chroma .lnt { white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } + /* LineNumbers */ .chroma .ln { white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } + /* Line */ .chroma .line { display: flex; } + /* Keyword */ .chroma .k { color: #008000; font-weight: bold } + /* KeywordConstant */ .chroma .kc { color: #008000; font-weight: bold } + /* KeywordDeclaration */ .chroma .kd { color: #008000; font-weight: bold } + /* KeywordNamespace */ .chroma .kn { color: #008000; font-weight: bold } + /* KeywordPseudo */ .chroma .kp { color: #008000 } + /* KeywordReserved */ .chroma .kr { color: #008000; font-weight: bold } + /* KeywordType */ .chroma .kt { color: #b00040 } + /* NameAttribute */ .chroma .na { color: #7d9029 } + /* NameBuiltin */ .chroma .nb { color: #008000 } + /* NameClass */ .chroma .nc { color: #0000ff; font-weight: bold } + /* NameConstant */ .chroma .no { color: #880000 } + /* NameDecorator */ .chroma .nd { color: #aa22ff } + /* NameEntity */ .chroma .ni { color: #999999; font-weight: bold } + /* NameException */ .chroma .ne { color: #d2413a; font-weight: bold } + /* NameFunction */ .chroma .nf { color: #0000ff } + /* NameLabel */ .chroma .nl { color: #a0a000 } + /* NameNamespace */ .chroma .nn { color: #0000ff; font-weight: bold } + /* NameTag */ .chroma .nt { color: #008000; font-weight: bold } + /* NameVariable */ .chroma .nv { color: #19177c } + /* LiteralString */ .chroma .s { color: #ba2121 } + /* LiteralStringAffix */ .chroma .sa { color: #ba2121 } + /* LiteralStringBacktick */ .chroma .sb { color: #ba2121 } + /* LiteralStringChar */ .chroma .sc { color: #ba2121 } + /* LiteralStringDelimiter */ .chroma .dl { color: #ba2121 } + /* LiteralStringDoc */ .chroma .sd { color: #ba2121; font-style: italic } + /* LiteralStringDouble */ .chroma .s2 { color: #ba2121 } + /* LiteralStringEscape */ .chroma .se { color: #bb6622; font-weight: bold } + /* LiteralStringHeredoc */ .chroma .sh { color: #ba2121 } + /* LiteralStringInterpol */ .chroma .si { color: #bb6688; font-weight: bold } + /* LiteralStringOther */ .chroma .sx { color: #008000 } + /* LiteralStringRegex */ .chroma .sr { color: #bb6688 } + /* LiteralStringSingle */ .chroma .s1 { color: #ba2121 } + /* LiteralStringSymbol */ .chroma .ss { color: #19177c } + /* LiteralNumber */ .chroma .m { color: #666666 } + /* LiteralNumberBin */ .chroma .mb { color: #666666 } + /* LiteralNumberFloat */ .chroma .mf { color: #666666 } + /* LiteralNumberHex */ .chroma .mh { color: #666666 } + /* LiteralNumberInteger */ .chroma .mi { color: #666666 } + /* LiteralNumberIntegerLong */ .chroma .il { color: #666666 } + /* LiteralNumberOct */ .chroma .mo { color: #666666 } + /* Operator */ .chroma .o { color: #666666 } + /* OperatorWord */ .chroma .ow { color: #aa22ff; font-weight: bold } + /* Comment */ .chroma .c { color: #408080; font-style: italic } + /* CommentHashbang */ .chroma .ch { color: #408080; font-style: italic } + /* CommentMultiline */ .chroma .cm { color: #408080; font-style: italic } + /* CommentSingle */ .chroma .c1 { color: #408080; font-style: italic } + /* CommentSpecial */ .chroma .cs { color: #408080; font-style: italic } + /* CommentPreproc */ .chroma .cp { color: #bc7a00 } + /* CommentPreprocFile */ .chroma .cpf { color: #bc7a00 } + /* GenericDeleted */ .chroma .gd { color: #a00000 } + /* GenericEmph */ .chroma .ge { font-style: italic } + /* GenericError */ .chroma .gr { color: #ff0000 } + /* GenericHeading */ .chroma .gh { color: #000080; font-weight: bold } + /* GenericInserted */ .chroma .gi { color: #00a000 } + /* GenericOutput */ .chroma .go { color: #888888 } + /* GenericPrompt */ .chroma .gp { color: #000080; font-weight: bold } + /* GenericStrong */ .chroma .gs { font-weight: bold } + /* GenericSubheading */ .chroma .gu { color: #800080; font-weight: bold } + /* GenericTraceback */ .chroma .gt { color: #0044dd } + /* GenericUnderline */ .chroma .gl { text-decoration: underline } + /* TextWhitespace */ .chroma .w { color: #bbbbbb } +} +@media (prefers-color-scheme: dark) { + /* Background */ .bg { color: #e6edf3; background-color: #000000; } + /* PreWrapper */ .chroma { color: #e6edf3; background-color: #000000; } + /* Error */ .chroma .err { color: #f85149 } + /* LineLink */ .chroma .lnlinks { outline: none; text-decoration: none; color: inherit } + /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } + /* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; } + /* LineHighlight */ .chroma .hl { background-color: #6e7681 } + /* LineNumbersTable */ .chroma .lnt { white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #737679 } + /* LineNumbers */ .chroma .ln { white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #6e7681 } + /* Line */ .chroma .line { display: flex; } + /* Keyword */ .chroma .k { color: #ff7b72 } + /* KeywordConstant */ .chroma .kc { color: #79c0ff } + /* KeywordDeclaration */ .chroma .kd { color: #ff7b72 } + /* KeywordNamespace */ .chroma .kn { color: #ff7b72 } + /* KeywordPseudo */ .chroma .kp { color: #79c0ff } + /* KeywordReserved */ .chroma .kr { color: #ff7b72 } + /* KeywordType */ .chroma .kt { color: #ff7b72 } + /* NameClass */ .chroma .nc { color: #f0883e; font-weight: bold } + /* NameConstant */ .chroma .no { color: #79c0ff; font-weight: bold } + /* NameDecorator */ .chroma .nd { color: #d2a8ff; font-weight: bold } + /* NameEntity */ .chroma .ni { color: #ffa657 } + /* NameException */ .chroma .ne { color: #f0883e; font-weight: bold } + /* NameFunction */ .chroma .nf { color: #d2a8ff; font-weight: bold } + /* NameLabel */ .chroma .nl { color: #79c0ff; font-weight: bold } + /* NameNamespace */ .chroma .nn { color: #ff7b72 } + /* NameProperty */ .chroma .py { color: #79c0ff } + /* NameTag */ .chroma .nt { color: #7ee787 } + /* NameVariable */ .chroma .nv { color: #79c0ff } + /* Literal */ .chroma .l { color: #a5d6ff } + /* LiteralDate */ .chroma .ld { color: #79c0ff } + /* LiteralString */ .chroma .s { color: #a5d6ff } + /* LiteralStringAffix */ .chroma .sa { color: #79c0ff } + /* LiteralStringBacktick */ .chroma .sb { color: #a5d6ff } + /* LiteralStringChar */ .chroma .sc { color: #a5d6ff } + /* LiteralStringDelimiter */ .chroma .dl { color: #79c0ff } + /* LiteralStringDoc */ .chroma .sd { color: #a5d6ff } + /* LiteralStringDouble */ .chroma .s2 { color: #a5d6ff } + /* LiteralStringEscape */ .chroma .se { color: #79c0ff } + /* LiteralStringHeredoc */ .chroma .sh { color: #79c0ff } + /* LiteralStringInterpol */ .chroma .si { color: #a5d6ff } + /* LiteralStringOther */ .chroma .sx { color: #a5d6ff } + /* LiteralStringRegex */ .chroma .sr { color: #79c0ff } + /* LiteralStringSingle */ .chroma .s1 { color: #a5d6ff } + /* LiteralStringSymbol */ .chroma .ss { color: #a5d6ff } + /* LiteralNumber */ .chroma .m { color: #a5d6ff } + /* LiteralNumberBin */ .chroma .mb { color: #a5d6ff } + /* LiteralNumberFloat */ .chroma .mf { color: #a5d6ff } + /* LiteralNumberHex */ .chroma .mh { color: #a5d6ff } + /* LiteralNumberInteger */ .chroma .mi { color: #a5d6ff } + /* LiteralNumberIntegerLong */ .chroma .il { color: #a5d6ff } + /* LiteralNumberOct */ .chroma .mo { color: #a5d6ff } + /* Operator */ .chroma .o { color: #ff7b72; font-weight: bold } + /* OperatorWord */ .chroma .ow { color: #ff7b72; font-weight: bold } + /* Comment */ .chroma .c { color: #8b949e; font-style: italic } + /* CommentHashbang */ .chroma .ch { color: #8b949e; font-style: italic } + /* CommentMultiline */ .chroma .cm { color: #8b949e; font-style: italic } + /* CommentSingle */ .chroma .c1 { color: #8b949e; font-style: italic } + /* CommentSpecial */ .chroma .cs { color: #8b949e; font-weight: bold; font-style: italic } + /* CommentPreproc */ .chroma .cp { color: #8b949e; font-weight: bold; font-style: italic } + /* CommentPreprocFile */ .chroma .cpf { color: #8b949e; font-weight: bold; font-style: italic } + /* GenericDeleted */ .chroma .gd { color: #ffa198; background-color: #490202 } + /* GenericEmph */ .chroma .ge { font-style: italic } + /* GenericError */ .chroma .gr { color: #ffa198 } + /* GenericHeading */ .chroma .gh { color: #79c0ff; font-weight: bold } + /* GenericInserted */ .chroma .gi { color: #56d364; background-color: #0f5323 } + /* GenericOutput */ .chroma .go { color: #8b949e } + /* GenericPrompt */ .chroma .gp { color: #8b949e } + /* GenericStrong */ .chroma .gs { font-weight: bold } + /* GenericSubheading */ .chroma .gu { color: #79c0ff } + /* GenericTraceback */ .chroma .gt { color: #ff7b72 } + /* GenericUnderline */ .chroma .gl { text-decoration: underline } + /* TextWhitespace */ .chroma .w { color: #6e7681 } +} diff --git a/forged/static/style.css b/forged/static/style.css new file mode 100644 index 0000000..b1e208f --- /dev/null +++ b/forged/static/style.css @@ -0,0 +1,613 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu + * SPDX-FileCopyrightText: Copyright (c) 2025 luk3yx + * SPDX-FileCopyrightText: Copyright (c) 2017-2025 Drew DeVault + * + * Drew did not directly contribute here but we took significant portions of + * SourceHut's CSS. + */ + +* { + box-sizing: border-box; +} + +/* Base styles and variables */ +html { + font-family: sans-serif; + background-color: var(--background-color); + color: var(--text-color); + font-size: 1rem; + --background-color: hsl(0, 0%, 100%); + --text-color: hsl(0, 0%, 0%); + --link-color: hsl(320, 50%, 36%); + --light-text-color: hsl(0, 0%, 45%); + --darker-border-color: hsl(0, 0%, 72%); + --lighter-border-color: hsl(0, 0%, 85%); + --text-decoration-color: hsl(0, 0%, 72%); + --darker-box-background-color: hsl(0, 0%, 92%); + --lighter-box-background-color: hsl(0, 0%, 95%); + --primary-color: hsl(320, 50%, 36%); + --primary-color-contrast: hsl(320, 0%, 100%); + --danger-color: #ff0000; + --danger-color-contrast: #ffffff; +} + +/* Dark mode overrides */ +@media (prefers-color-scheme: dark) { + html { + --background-color: hsl(0, 0%, 0%); + --text-color: hsl(0, 0%, 100%); + --link-color: hsl(320, 50%, 76%); + --light-text-color: hsl(0, 0%, 78%); + --darker-border-color: hsl(0, 0%, 35%); + --lighter-border-color: hsl(0, 0%, 25%); + --text-decoration-color: hsl(0, 0%, 30%); + --darker-box-background-color: hsl(0, 0%, 20%); + --lighter-box-background-color: hsl(0, 0%, 15%); + } +} + +/* Global layout */ +body { + margin: 0; +} +html, code, pre { + font-size: 0.96rem; /* TODO: Not always correct */ +} + +/* Toggle table controls */ +.toggle-table-off, .toggle-table-on { + opacity: 0; + position: absolute; +} +.toggle-table-off:focus-visible + table > thead > tr > th > label, +.toggle-table-on:focus-visible + table > thead > tr > th > label { + outline: 1.5px var(--primary-color) solid; +} +.toggle-table-off + table > thead > tr > th, .toggle-table-on + table > thead > tr > th { + padding: 0; +} +.toggle-table-off + table > thead > tr > th > label, .toggle-table-on + table > thead > tr > th > label { + width: 100%; + display: inline-block; + padding: 3px 0; + cursor: pointer; +} +.toggle-table-off:checked + table > tbody { + display: none; +} +.toggle-table-on + table > tbody { + display: none; +} +.toggle-table-on:checked + table > tbody { + display: table-row-group; +} + +/* Footer styles */ +footer { + margin-top: 1rem; + margin-left: auto; + margin-right: auto; + margin-bottom: 1rem; + display: block; + padding: 0 5px; + width: fit-content; + text-align: center; + color: var(--light-text-color); +} +footer a:link, footer a:visited { + color: inherit; +} + +.padding { + padding: 0 1rem; +} + +/* Link styles */ +a:link, a:visited { + text-decoration-color: var(--text-decoration-color); + color: var(--link-color); +} + +/* Readme inline code styling */ +#readme code:not(pre > code) { + background-color: var(--lighter-box-background-color); + border-radius: 2px; + padding: 2px; +} + +/* Readme word breaks to avoid overfull hboxes */ +#readme { + word-break: break-word; + line-height: 1.3; +} + +/* Table styles */ +table { + border: var(--lighter-border-color) solid 1px; + border-spacing: 0px; + border-collapse: collapse; +} +table.wide { + width: 100%; +} +td, th { + padding: 3px 5px; + border: var(--lighter-border-color) solid 1px; +} +.pad { + padding: 3px 5px; +} +th, thead, tfoot { + background-color: var(--lighter-box-background-color); +} +th[scope=row] { + text-align: left; +} +th { + font-weight: normal; +} +tr.title-row > th, th.title-row, .title-row { + background-color: var(--lighter-box-background-color); + font-weight: bold; +} +td > pre { + margin: 0; +} +#readme > *:last-child { + margin-bottom: 0; +} +#readme > *:first-child { + margin-top: 0; +} + +/* Table misc and scrolling */ +.commit-id { + font-family: monospace; + word-break: break-word; +} +.scroll { + overflow-x: auto; +} + +/* Diff/chunk styles */ +.chunk-unchanged { + color: grey; +} +.chunk-addition { + color: green; +} +@media (prefers-color-scheme: dark) { + .chunk-addition { + color: lime; + } +} +.chunk-deletion { + color: red; +} +.chunk-unknown { + color: yellow; +} +pre.chunk { + margin-top: 0; + margin-bottom: 0; +} +.centering { + text-align: center; +} + +/* Toggle content sections */ +.toggle-off-wrapper, .toggle-on-wrapper { + border: var(--lighter-border-color) solid 1px; +} +.toggle-off-toggle, .toggle-on-toggle { + opacity: 0; + position: absolute; +} +.toggle-off-header, .toggle-on-header { + font-weight: bold; + cursor: pointer; + display: block; + width: 100%; + background-color: var(--lighter-box-background-color); +} +.toggle-off-header > div, .toggle-on-header > div { + padding: 3px 5px; + display: block; +} +.toggle-on-content { + display: none; +} +.toggle-on-toggle:focus-visible + .toggle-on-header, .toggle-off-toggle:focus-visible + .toggle-off-header { + outline: 1.5px var(--primary-color) solid; +} +.toggle-on-toggle:checked + .toggle-on-header + .toggle-on-content { + display: block; +} +.toggle-off-content { + display: block; +} +.toggle-off-toggle:checked + .toggle-off-header + .toggle-off-content { + display: none; +} + +*:focus-visible { + outline: 1.5px var(--primary-color) solid; +} + +/* File display styles */ +.file-patch + .file-patch { + margin-top: 0.5rem; +} +.file-content { + padding: 3px 5px; +} +.file-header { + font-family: monospace; + display: flex; + flex-direction: row; + align-items: center; +} +.file-header::after { + content: "\25b6"; + font-family: sans-serif; + margin-left: auto; + line-height: 100%; + margin-right: 0.25em; +} +.file-toggle:checked + .file-header::after { + content: "\25bc"; +} + +/* Form elements */ +textarea { + box-sizing: border-box; + background-color: var(--lighter-box-background-color); + resize: vertical; +} +textarea, +input[type=text], +input[type=password] { + font-family: sans-serif; + background-color: var(--lighter-box-background-color); + color: var(--text-color); + border: none; + padding: 0.3rem; + width: 100%; + box-sizing: border-box; +} +td.tdinput, th.tdinput { + padding: 0; + position: relative; +} +td.tdinput textarea, +td.tdinput input[type=text], +td.tdinput input[type=password], +th.tdinput textarea, +th.tdinput input[type=text], +th.tdinput input[type=password] { + background-color: transparent; +} +td.tdinput select { + position: absolute; + background-color: var(--background-color); + border: none; + /* + width: 100%; + height: 100%; + */ + box-sizing: border-box; + top: 0; + left: 0; + right: 0; + bottom: 0; +} +select:active { + outline: 1.5px var(--primary-color) solid; +} + + +/* Button styles */ +.btn-primary, a.btn-primary { + background: var(--primary-color); + color: var(--primary-color-contrast); + border: var(--lighter-border-color) 1px solid; + font-weight: bold; +} +.btn-danger, a.btn-danger { + background: var(--danger-color); + color: var(--danger-color-contrast); + border: var(--lighter-border-color) 1px solid; + font-weight: bold; +} +.btn-white, a.btn-white { + background: var(--primary-color-contrast); + color: var(--primary-color); + border: var(--lighter-border-color) 1px solid; +} +.btn-normal, a.btn-normal, +input[type=file]::file-selector-button { + background: var(--lighter-box-background-color); + border: var(--lighter-border-color) 1px solid !important; + color: var(--text-color); +} +.btn, .btn-white, .btn-danger, .btn-normal, .btn-primary, +input[type=submit], +input[type=file]::file-selector-button { + display: inline-block; + width: auto; + min-width: fit-content; + padding: .1rem .75rem; + transition: background .1s linear; + cursor: pointer; +} +a.btn, a.btn-white, a.btn-danger, a.btn-normal, a.btn-primary { + text-decoration: none; +} + +/* Header layout */ +header#main-header { + /* background-color: var(--lighter-box-background-color); */ + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + flex-wrap: wrap; + padding-top: 1rem; + padding-bottom: 1rem; + gap: 0.5rem; +} +#main-header a, #main-header a:link, main-header a:visited { + text-decoration: none; + color: inherit; +} +#main-header-forge-title { + white-space: nowrap; +} +#breadcrumb-nav { + display: flex; + align-items: center; + flex: 1 1 auto; + min-width: 0; + overflow-x: auto; + gap: 0.25rem; + white-space: nowrap; +} +.breadcrumb-separator { + margin: 0 0.25rem; +} +#main-header-user { + display: flex; + align-items: center; + white-space: nowrap; +} +@media (max-width: 37.5rem) { + header#main-header { + flex-direction: column; + align-items: flex-start; + } + + #breadcrumb-nav { + width: 100%; + overflow-x: auto; + } +} + +/* Uncategorized */ +table + table { + margin-top: 1rem; +} + +td > ul { + padding-left: 1.5rem; + margin-top: 0; + margin-bottom: 0; +} + + + +.complete-error-page hr { + border: 0; + border-bottom: 1px dashed; +} + + + + + + +.key-val-grid { + display: grid; + grid-template-columns: auto 1fr; + gap: 0; + border: var(--lighter-border-color) 1px solid; + overflow: auto; +} + +.key-val-grid > .title-row { + grid-column: 1 / -1; + background-color: var(--lighter-box-background-color); + font-weight: bold; + padding: 3px 5px; + border-bottom: var(--lighter-border-color) 1px solid; +} + +.key-val-grid > .row-label { + background-color: var(--lighter-box-background-color); + padding: 3px 5px; + border-bottom: var(--lighter-border-color) 1px solid; + border-right: var(--lighter-border-color) 1px solid; + text-align: left; + font-weight: normal; +} + +.key-val-grid > .row-value { + padding: 3px 5px; + border-bottom: var(--lighter-border-color) 1px solid; + word-break: break-word; +} + +.key-val-grid code { + font-family: monospace; +} + +.key-val-grid ul { + margin: 0; + padding-left: 1.5rem; +} + +.key-val-grid > .row-label:nth-last-of-type(2), +.key-val-grid > .row-value:last-of-type { + border-bottom: none; +} + +@media (max-width: 37.5rem) { + .key-val-grid { + grid-template-columns: 1fr; + } + + .key-val-grid > .row-label { + border-right: none; + } +} +.key-val-grid > .title-row { + grid-column: 1 / -1; + background-color: var(--lighter-box-background-color); + font-weight: bold; + padding: 3px 5px; + border-bottom: var(--lighter-border-color) 1px solid; + margin: 0; + text-align: center; +} + +.key-val-grid-wrapper { + max-width: 100%; + width: fit-content; +} + +/* Tab navigation */ + +.nav-tabs-standalone { + border: none; + list-style: none; + margin: 0; + flex-grow: 1; + display: inline-flex; + flex-wrap: nowrap; + padding: 0; + border-bottom: 0.25rem var(--darker-box-background-color) solid; + width: 100%; + max-width: 100%; + min-width: 100%; +} + +.nav-tabs-standalone > li { + align-self: flex-end; +} +.nav-tabs-standalone > li > a { + padding: 0 1rem; +} + +.nav-item a.active { + background-color: var(--darker-box-background-color); +} + +.nav-item a, .nav-item a:link, .nav-item a:visited { + text-decoration: none; + color: inherit; +} + +.repo-header-extension { + margin-bottom: 1rem; + background-color: var(--darker-box-background-color); +} + +.repo-header > h2 { + display: inline; + margin: 0; + padding-right: 1rem; +} + +.repo-header > .nav-tabs-standalone { + border: none; + margin: 0; + flex-grow: 1; + display: inline-flex; + flex-wrap: nowrap; + padding: 0; +} + +.repo-header { + display: flex; + flex-wrap: nowrap; +} + +.repo-header-extension-content { + padding-top: 0.3rem; + padding-bottom: 0.2rem; +} + +.repo-header, .padding-wrapper, .repo-header-extension-content, #main-header, .readingwidth, .commit-list-small { + padding-left: 1rem; + padding-right: 1rem; + max-width: 60rem; + width: 100%; + margin-left: auto; + margin-right: auto; +} + +.padding-wrapper { + margin-bottom: 1rem; +} + +/* TODO */ + +.commit-list-small .event { + background-color: var(--lighter-box-background-color); + padding: 0.5rem; + margin-bottom: 1rem; + max-width: 30rem; +} + +.commit-list-small .event:last-child { + margin-bottom: 1rem; +} + +.commit-list-small a { + color: var(--link-color); + text-decoration: none; + font-weight: 500; +} + +.commit-list-small a:hover { + text-decoration: underline; + text-decoration-color: var(--text-decoration-color); +} + +.commit-list-small .event > div { + font-size: 0.95rem; + line-height: 1.4; +} + +.commit-list-small .pull-right { + float: right; + font-size: 0.85em; + color: var(--light-text-color); + margin-left: 1rem; +} + +.commit-list-small pre.commit { + margin: 0.25rem 0 0 0; + padding: 0; + font-family: inherit; + font-size: 0.95rem; + color: var(--text-color); + white-space: pre-wrap; +} + +.commit-list-small .commit-error { + color: var(--danger-color); + font-weight: bold; + margin-top: 1rem; +} diff --git a/forged/templates/400.tmpl b/forged/templates/400.tmpl new file mode 100644 index 0000000..58ce768 --- /dev/null +++ b/forged/templates/400.tmpl @@ -0,0 +1,25 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "400" -}} + + + + {{- template "head_common" . -}} + 400 Bad Request – {{ .global.forge_title }} + + + {{- template "header" . -}} +
+

400 Bad Request

+

{{- .complete_error_msg -}}

+
+
Lindenii Forge
+
+
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/forged/templates/400_colon.tmpl b/forged/templates/400_colon.tmpl new file mode 100644 index 0000000..470a685 --- /dev/null +++ b/forged/templates/400_colon.tmpl @@ -0,0 +1,26 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "400_colon" -}} + + + + {{- template "head_common" . -}} + 400 Bad Request – {{ .global.forge_title }} + + + {{- template "header" . -}} +
+

400 Bad Request

+

We recently switched URL schemes. Previously “:” was used as our URL group separator, but because OpenSMTPD does not implement local-part address quoting properly, we’re unable to include “:” in URLs properly, hence we use “-” now.

+

As a precaution in case visitors get confused, this page was set up. You should probably replace the “:”s with “-”s in the URL bar. If there are colons in the URL that is not the group separator—that’s an edge case that we’ll fix later.

+
+
Lindenii Forge
+
+
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/forged/templates/403.tmpl b/forged/templates/403.tmpl new file mode 100644 index 0000000..86d5518 --- /dev/null +++ b/forged/templates/403.tmpl @@ -0,0 +1,25 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "403" -}} + + + + {{- template "head_common" . -}} + 403 Forbidden – {{ .global.forge_title }} + + + {{- template "header" . -}} +
+

403 Forbidden

+

{{- .complete_error_msg -}}

+
+
Lindenii Forge
+
+
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/forged/templates/404.tmpl b/forged/templates/404.tmpl new file mode 100644 index 0000000..2eabb06 --- /dev/null +++ b/forged/templates/404.tmpl @@ -0,0 +1,24 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "404" -}} + + + + {{- template "head_common" . -}} + 404 Not Found – {{ .global.forge_title }} + + + {{- template "header" . -}} +
+

404 Not Found

+
+
Lindenii Forge
+
+
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/forged/templates/451.tmpl b/forged/templates/451.tmpl new file mode 100644 index 0000000..ed6343c --- /dev/null +++ b/forged/templates/451.tmpl @@ -0,0 +1,25 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "451" -}} + + + + {{- template "head_common" . -}} + 451 Unavailable For Legal Reasons – {{ .global.forge_title }} + + + {{- template "header" . -}} +
+

451 Unavailable For Legal Reasons

+

{{- .complete_error_msg -}}

+
+
Lindenii Forge
+
+
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/forged/templates/500.tmpl b/forged/templates/500.tmpl new file mode 100644 index 0000000..3a540e6 --- /dev/null +++ b/forged/templates/500.tmpl @@ -0,0 +1,25 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "500" -}} + + + + {{- template "head_common" . -}} + 500 Internal Server Error – {{ .global.forge_title }} + + + {{- template "header" . -}} +
+

500 Internal Server Error

+

{{- .complete_error_msg -}}

+
+
Lindenii Forge
+
+
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/forged/templates/501.tmpl b/forged/templates/501.tmpl new file mode 100644 index 0000000..b6ab2f0 --- /dev/null +++ b/forged/templates/501.tmpl @@ -0,0 +1,24 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "501" -}} + + + + {{- template "head_common" . -}} + 501 Not Implemented – {{ .global.forge_title }} + + + {{- template "header" . -}} +
+

501 Not Implemented

+
+
Lindenii Forge
+
+
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/forged/templates/_footer.tmpl b/forged/templates/_footer.tmpl new file mode 100644 index 0000000..f71ea3e --- /dev/null +++ b/forged/templates/_footer.tmpl @@ -0,0 +1,12 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "footer" -}} +Lindenii Forge +{{ .global.forge_version }} +(source, +upstream, +license, +support) +{{- end -}} diff --git a/forged/templates/_group_path.tmpl b/forged/templates/_group_path.tmpl new file mode 100644 index 0000000..f5d3bf8 --- /dev/null +++ b/forged/templates/_group_path.tmpl @@ -0,0 +1,8 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "group_path_plain" -}} +{{- $p := . -}} +{{- range $i, $s := . -}}{{- $s -}}{{- if ne $i (minus (len $p) 1) -}}/{{- end -}}{{- end -}} +{{- end -}} diff --git a/forged/templates/_group_view.tmpl b/forged/templates/_group_view.tmpl new file mode 100644 index 0000000..92b6639 --- /dev/null +++ b/forged/templates/_group_view.tmpl @@ -0,0 +1,56 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "group_view" -}} +{{- if .subgroups -}} + + + + + + + + + + + + {{- range .subgroups -}} + + + + + {{- end -}} + +
Subgroups
NameDescription
+ {{- .Name -}} + + {{- .Description -}} +
+{{- end -}} +{{- if .repos -}} + + + + + + + + + + + + {{- range .repos -}} + + + + + {{- end -}} + +
Repos
NameDescription
+ {{- .Name -}} + + {{- .Description -}} +
+{{- end -}} +{{- end -}} diff --git a/forged/templates/_head.tmpl b/forged/templates/_head.tmpl new file mode 100644 index 0000000..d6d6571 --- /dev/null +++ b/forged/templates/_head.tmpl @@ -0,0 +1,9 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "head_common" -}} + + + +{{- end -}} diff --git a/forged/templates/_header.tmpl b/forged/templates/_header.tmpl new file mode 100644 index 0000000..340a2ac --- /dev/null +++ b/forged/templates/_header.tmpl @@ -0,0 +1,35 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "header" -}} +
+ + +
+ {{- if ne .user_id_string "" -}} + {{- .username -}} + {{- else -}} + Login + {{- end -}} +
+
+{{- end -}} diff --git a/forged/templates/_ref_query.tmpl b/forged/templates/_ref_query.tmpl new file mode 100644 index 0000000..2f78955 --- /dev/null +++ b/forged/templates/_ref_query.tmpl @@ -0,0 +1,3 @@ +{{- define "ref_query" -}} +{{- if .ref_type -}}?{{- .ref_type -}}={{- .ref_name -}}{{- end -}} +{{- end -}} diff --git a/forged/templates/group.tmpl b/forged/templates/group.tmpl new file mode 100644 index 0000000..b15c316 --- /dev/null +++ b/forged/templates/group.tmpl @@ -0,0 +1,80 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "group" -}} +{{- $group_path := .group_path -}} + + + + {{- template "head_common" . -}} + {{- range $i, $s := .group_path -}}{{- $s -}}{{- if ne $i (len $group_path) -}}/{{- end -}}{{- end }} – {{ .global.forge_title -}} + + + {{- template "header" . -}} +
+ {{- if .description -}} +

{{- .description -}}

+ {{- end -}} + {{- template "group_view" . -}} +
+ {{- if .direct_access -}} +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ Create repo +
Name + +
Description + +
Contrib + +
+
+
+
+
+ +
+
+
+
+
+ {{- end -}} +
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/forged/templates/index.tmpl b/forged/templates/index.tmpl new file mode 100644 index 0000000..ff7c127 --- /dev/null +++ b/forged/templates/index.tmpl @@ -0,0 +1,63 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "index" -}} + + + + {{- template "head_common" . -}} + Index – {{ .global.forge_title -}} + + + {{- template "header" . -}} +
+ + + + + + + + + + + + {{- range .groups -}} + + + + + {{- end -}} + +
Groups
NameDescription
+ {{- .Name -}} + + {{- .Description -}} +
+ + + + + + + + + + + + + + + + +
+ Info +
SSH public key{{- .global.server_public_key_string -}}
SSH fingerprint{{- .global.server_public_key_fingerprint -}}
+
+
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/forged/templates/login.tmpl b/forged/templates/login.tmpl new file mode 100644 index 0000000..1e26c82 --- /dev/null +++ b/forged/templates/login.tmpl @@ -0,0 +1,59 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "login" -}} + + + + {{- template "head_common" . -}} + Login – {{ .global.forge_title -}} + + + {{- .login_error -}} +
+
+ + + + + + + + + + + + + + + + + + + + + +
+ Password authentication +
Username + +
Password + +
+
+
+
+
+ +
+
+
+
+
+
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/forged/templates/repo_branches.tmpl b/forged/templates/repo_branches.tmpl new file mode 100644 index 0000000..55ea0a6 --- /dev/null +++ b/forged/templates/repo_branches.tmpl @@ -0,0 +1,71 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "repo_branches" -}} +{{- $root := . -}} + + + + {{- template "head_common" . -}} + {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} + + + {{- template "header" . -}} +
+

{{- .repo_name -}}

+ +
+
+
+ {{- .repo_description -}} +
+
+
+

+ + Warning: Due to various recent migrations, viewing non-HEAD refs may be broken. + +

+ + + + + + + + {{- range .branches -}} + + + + {{- end -}} + +
Branches
+ {{ . }} +
+
+ + +{{- end -}} diff --git a/forged/templates/repo_commit.tmpl b/forged/templates/repo_commit.tmpl new file mode 100644 index 0000000..470bba9 --- /dev/null +++ b/forged/templates/repo_commit.tmpl @@ -0,0 +1,117 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "repo_commit" -}} +{{- $root := . -}} + + + + {{- template "head_common" . -}} + Commit {{ .commit_id }} – {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} + + + {{- template "header" . -}} +
+

{{- .repo_name -}}

+ +
+
+
+ {{- .repo_description -}} +
+
+
+
+
+
Commit info
+
ID
+
{{- .commit_id -}}
+
Author
+
+ {{- .commit_object.Author.Name -}} <{{- .commit_object.Author.Email -}}> +
+
Author date
+
{{- .commit_object.Author.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" -}}
+
Committer
+
+ {{- .commit_object.Committer.Name -}} <{{- .commit_object.Committer.Email -}}> +
+
Committer date
+
{{- .commit_object.Committer.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" -}}
+
Actions
+
+ Get patch +
+
+
+
+ +
+
{{- .commit_object.Message -}}
+
+
+ {{- $parent_commit_hash := .parent_commit_hash -}} + {{- $commit_object := .commit_object -}} + {{- range .file_patches -}} +
+ + +
+ {{- range .Chunks -}} + {{- if eq .Operation 0 -}} +
{{ .Content }}
+ {{- else if eq .Operation 1 -}} +
{{ .Content }}
+ {{- else if eq .Operation 2 -}} +
{{ .Content }}
+ {{- else -}} +
{{ .Content }}
+ {{- end -}} + {{- end -}} +
+
+ {{- end -}} +
+
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/forged/templates/repo_contrib_index.tmpl b/forged/templates/repo_contrib_index.tmpl new file mode 100644 index 0000000..172a079 --- /dev/null +++ b/forged/templates/repo_contrib_index.tmpl @@ -0,0 +1,82 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "repo_contrib_index" -}} +{{- $root := . -}} + + + + {{- template "head_common" . -}} + Merge requests – {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} + + + {{- template "header" . -}} +
+

{{- .repo_name -}}

+ +
+
+
+ {{- .repo_description -}} +
+
+
+

How to submit a merge request

+
git clone {{ .ssh_clone_url }}
+cd {{ .repo_name }}
+git checkout -b contrib/name_of_your_contribution
+# edit and commit stuff
+git push -u origin HEAD
+

Pushes that update branches in other namespaces, or pushes to existing contribution branches belonging to other SSH keys, will be automatically +rejected, unless you are an authenticated maintainer. Otherwise, a merge request is automatically opened, and the maintainers are notified via IRC.

+

Alternatively, you may email patches to {{ .repo_patch_mailing_list }}.

+
+
+ + + + + + + + + + {{- range .merge_requests -}} + + + + + + {{- end -}} + +
IDTitleStatus
{{- .ID -}}{{- .Title -}}{{- .Status -}}
+
+
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/forged/templates/repo_contrib_one.tmpl b/forged/templates/repo_contrib_one.tmpl new file mode 100644 index 0000000..a5f35d3 --- /dev/null +++ b/forged/templates/repo_contrib_one.tmpl @@ -0,0 +1,123 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "repo_contrib_one" -}} +{{- $root := . -}} + + + + {{- template "head_common" . -}} + Merge requests – {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} + + + {{- template "header" . -}} +
+

{{- .repo_name -}}

+ +
+
+
+ {{- .repo_description -}} +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Merge request info
ID{{- .mr_id -}}
Status{{- .mr_status -}}
Title{{- .mr_title -}}
Source ref{{- .mr_source_ref -}}
Destination branch{{- .mr_destination_branch -}}
Merge base{{- .merge_base.Hash.String -}}
+
+
+ {{- $merge_base := .merge_base -}} + {{- $source_commit := .source_commit -}} + {{- range .file_patches -}} +
+ + +
+ {{- range .Chunks -}} + {{- if eq .Operation 0 -}} +
{{ .Content }}
+ {{- else if eq .Operation 1 -}} +
{{ .Content }}
+ {{- else if eq .Operation 2 -}} +
{{ .Content }}
+ {{- else -}} +
{{ .Content }}
+ {{- end -}} + {{- end -}} +
+
+ {{- end -}} +
+
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/forged/templates/repo_index.tmpl b/forged/templates/repo_index.tmpl new file mode 100644 index 0000000..d040f3a --- /dev/null +++ b/forged/templates/repo_index.tmpl @@ -0,0 +1,94 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "repo_index" -}} +{{- $root := . -}} + + + + {{- template "head_common" . -}} + {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} + + + {{- template "header" . -}} +
+

{{- .repo_name -}}

+ +
+
+
+ {{- .repo_description -}} +
+
+ {{- if .notes -}} +
Notes
+
    + {{- range .notes -}}
  • {{- . -}}
  • {{- end -}} +
+ + {{- end -}} +

{{- .ssh_clone_url -}}

+ {{- if .ref_name -}} +

+ + Warning: Due to various recent migrations, viewing non-HEAD refs may be broken. + +

+ {{- end -}} + {{- if .commits -}} +
+ {{- range .commits -}} +
+
+ + {{- .Hash | printf "%.8s" -}} + +  — {{- .Author -}} + + {{- .Date -}} + +
+
{{- .Message | first_line -}}
+
+ {{- end -}} + {{- if dereference_error .commits_err -}} +
+ Error while obtaining commit log: {{ .commits_err }} +
+ {{- end -}} +
+ {{- end -}} + {{- if .readme -}} +
+ {{- .readme -}} +
+ {{- end -}} +
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/forged/templates/repo_log.tmpl b/forged/templates/repo_log.tmpl new file mode 100644 index 0000000..2262902 --- /dev/null +++ b/forged/templates/repo_log.tmpl @@ -0,0 +1,90 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "repo_log" -}} +{{- $root := . -}} + + + + {{- template "head_common" . -}} + Log – {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} + + + {{- template "header" . -}} +
+

{{- .repo_name -}}

+ +
+
+
+ {{- .repo_description -}} +
+
+
+ {{- if .ref_name -}} +

+ + Warning: Due to various recent migrations, viewing non-HEAD refs may be broken. + +

+ {{- end -}} + + + + + + + + + + + + + + {{- range .commits -}} + + + + + + + {{- end -}} + {{- if dereference_error .commits_err -}} + Error while obtaining commit log: {{ .commits_err }} + {{- end -}} + +
Commits {{ if .ref_name }} on {{ .ref_name }}{{ end -}}
IDTitleAuthorAuthor date
{{- .Hash -}}{{- .Message | first_line -}} + + + {{- .Author.When.Format "2006-01-02 15:04:05 -0700" -}} +
+
+
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/forged/templates/repo_raw_dir.tmpl b/forged/templates/repo_raw_dir.tmpl new file mode 100644 index 0000000..a33da4a --- /dev/null +++ b/forged/templates/repo_raw_dir.tmpl @@ -0,0 +1,88 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "repo_raw_dir" -}} +{{- $root := . -}} + + + + {{- template "head_common" . -}} + /{{ .path_spec }}{{ if ne .path_spec "" }}/{{ end }} – {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} + + + {{- template "header" . -}} +
+

{{- .repo_name -}}

+ +
+
+
+ {{- .repo_description -}} +
+
+
+ {{- if .ref_name -}} +

+ + Warning: Due to various recent migrations, viewing non-HEAD refs may be broken. + +

+ {{- end -}} + + + + + + + + + + + + + {{- $path_spec := .path_spec -}} + {{- range .files -}} + + + + + + {{- end -}} + +
+ (Raw) /{{ .path_spec }}{{ if ne .path_spec "" }}/{{ end }}{{ if .ref_name }} on {{ .ref_name }}{{ end -}} +
ModeFilenameSize
{{- .Mode -}}{{- .Name -}}{{- if not .IsFile -}}/{{- end -}}{{- .Size -}}
+
+
+
+
+
+
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/forged/templates/repo_tree_dir.tmpl b/forged/templates/repo_tree_dir.tmpl new file mode 100644 index 0000000..fc06646 --- /dev/null +++ b/forged/templates/repo_tree_dir.tmpl @@ -0,0 +1,93 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "repo_tree_dir" -}} +{{- $root := . -}} + + + + {{- template "head_common" . -}} + /{{ .path_spec }}{{ if ne .path_spec "" }}/{{ end }} – {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} + + + {{- template "header" . -}} +
+

{{- .repo_name -}}

+ +
+
+
+ {{- .repo_description -}} +
+
+
+ {{- if .ref_name -}} +

+ + Warning: Due to various recent migrations, viewing non-HEAD refs may be broken. + +

+ {{- end -}} + + + + + + + + + + + + + {{- $path_spec := .path_spec -}} + {{- range .files -}} + + + + + + {{- end -}} + +
+ /{{ .path_spec }}{{ if ne .path_spec "" }}/{{ end }}{{ if .ref_name }} on {{ .ref_name }}{{ end -}} +
ModeFilenameSize
{{- .Mode -}}{{- .Name -}}{{- if not .IsFile -}}/{{- end -}}{{- .Size -}}
+
+
+
+
+
+ {{- if .readme -}} +
+ {{- .readme -}} +
+ {{- end -}} +
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/forged/templates/repo_tree_file.tmpl b/forged/templates/repo_tree_file.tmpl new file mode 100644 index 0000000..76404a9 --- /dev/null +++ b/forged/templates/repo_tree_file.tmpl @@ -0,0 +1,65 @@ +{{/* + SPDX-License-Identifier: AGPL-3.0-only + SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu +*/}} +{{- define "repo_tree_file" -}} +{{- $root := . -}} + + + + {{- template "head_common" . -}} + + /{{ .path_spec }} – {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} + + + {{- template "header" . -}} +
+

{{- .repo_name -}}

+ +
+
+
+ {{- .repo_description -}} +
+
+
+ {{- if .ref_name -}} +

+ + Warning: Due to various recent migrations, viewing non-HEAD refs may be broken. + +

+ {{- end -}} +

+ /{{ .path_spec }} (raw) +

+ {{- .file_contents -}} +
+
+ {{- template "footer" . -}} +
+ + +{{- end -}} diff --git a/static/.gitignore b/static/.gitignore deleted file mode 100644 index 812b75f..0000000 --- a/static/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/index.html -# used for testing css without recompiling the server diff --git a/static/chroma.css b/static/chroma.css deleted file mode 100644 index 1f7219a..0000000 --- a/static/chroma.css +++ /dev/null @@ -1,152 +0,0 @@ -/* - * SPDX-License-Identifier: MIT AND BSD-2-Clause - * SPDX-FileCopyrightText: Copyright (c) 2018-2025 Pygments and Chroma authors - */ - -@media (prefers-color-scheme: light) { - /* Background */ .bg { ; } - /* PreWrapper */ .chroma { ; } - /* Error */ .chroma .err { } - /* LineLink */ .chroma .lnlinks { outline: none; text-decoration: none; color: inherit } - /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } - /* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; } - /* LineHighlight */ .chroma .hl { background-color: #e5e5e5 } - /* LineNumbersTable */ .chroma .lnt { white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } - /* LineNumbers */ .chroma .ln { white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } - /* Line */ .chroma .line { display: flex; } - /* Keyword */ .chroma .k { color: #008000; font-weight: bold } - /* KeywordConstant */ .chroma .kc { color: #008000; font-weight: bold } - /* KeywordDeclaration */ .chroma .kd { color: #008000; font-weight: bold } - /* KeywordNamespace */ .chroma .kn { color: #008000; font-weight: bold } - /* KeywordPseudo */ .chroma .kp { color: #008000 } - /* KeywordReserved */ .chroma .kr { color: #008000; font-weight: bold } - /* KeywordType */ .chroma .kt { color: #b00040 } - /* NameAttribute */ .chroma .na { color: #7d9029 } - /* NameBuiltin */ .chroma .nb { color: #008000 } - /* NameClass */ .chroma .nc { color: #0000ff; font-weight: bold } - /* NameConstant */ .chroma .no { color: #880000 } - /* NameDecorator */ .chroma .nd { color: #aa22ff } - /* NameEntity */ .chroma .ni { color: #999999; font-weight: bold } - /* NameException */ .chroma .ne { color: #d2413a; font-weight: bold } - /* NameFunction */ .chroma .nf { color: #0000ff } - /* NameLabel */ .chroma .nl { color: #a0a000 } - /* NameNamespace */ .chroma .nn { color: #0000ff; font-weight: bold } - /* NameTag */ .chroma .nt { color: #008000; font-weight: bold } - /* NameVariable */ .chroma .nv { color: #19177c } - /* LiteralString */ .chroma .s { color: #ba2121 } - /* LiteralStringAffix */ .chroma .sa { color: #ba2121 } - /* LiteralStringBacktick */ .chroma .sb { color: #ba2121 } - /* LiteralStringChar */ .chroma .sc { color: #ba2121 } - /* LiteralStringDelimiter */ .chroma .dl { color: #ba2121 } - /* LiteralStringDoc */ .chroma .sd { color: #ba2121; font-style: italic } - /* LiteralStringDouble */ .chroma .s2 { color: #ba2121 } - /* LiteralStringEscape */ .chroma .se { color: #bb6622; font-weight: bold } - /* LiteralStringHeredoc */ .chroma .sh { color: #ba2121 } - /* LiteralStringInterpol */ .chroma .si { color: #bb6688; font-weight: bold } - /* LiteralStringOther */ .chroma .sx { color: #008000 } - /* LiteralStringRegex */ .chroma .sr { color: #bb6688 } - /* LiteralStringSingle */ .chroma .s1 { color: #ba2121 } - /* LiteralStringSymbol */ .chroma .ss { color: #19177c } - /* LiteralNumber */ .chroma .m { color: #666666 } - /* LiteralNumberBin */ .chroma .mb { color: #666666 } - /* LiteralNumberFloat */ .chroma .mf { color: #666666 } - /* LiteralNumberHex */ .chroma .mh { color: #666666 } - /* LiteralNumberInteger */ .chroma .mi { color: #666666 } - /* LiteralNumberIntegerLong */ .chroma .il { color: #666666 } - /* LiteralNumberOct */ .chroma .mo { color: #666666 } - /* Operator */ .chroma .o { color: #666666 } - /* OperatorWord */ .chroma .ow { color: #aa22ff; font-weight: bold } - /* Comment */ .chroma .c { color: #408080; font-style: italic } - /* CommentHashbang */ .chroma .ch { color: #408080; font-style: italic } - /* CommentMultiline */ .chroma .cm { color: #408080; font-style: italic } - /* CommentSingle */ .chroma .c1 { color: #408080; font-style: italic } - /* CommentSpecial */ .chroma .cs { color: #408080; font-style: italic } - /* CommentPreproc */ .chroma .cp { color: #bc7a00 } - /* CommentPreprocFile */ .chroma .cpf { color: #bc7a00 } - /* GenericDeleted */ .chroma .gd { color: #a00000 } - /* GenericEmph */ .chroma .ge { font-style: italic } - /* GenericError */ .chroma .gr { color: #ff0000 } - /* GenericHeading */ .chroma .gh { color: #000080; font-weight: bold } - /* GenericInserted */ .chroma .gi { color: #00a000 } - /* GenericOutput */ .chroma .go { color: #888888 } - /* GenericPrompt */ .chroma .gp { color: #000080; font-weight: bold } - /* GenericStrong */ .chroma .gs { font-weight: bold } - /* GenericSubheading */ .chroma .gu { color: #800080; font-weight: bold } - /* GenericTraceback */ .chroma .gt { color: #0044dd } - /* GenericUnderline */ .chroma .gl { text-decoration: underline } - /* TextWhitespace */ .chroma .w { color: #bbbbbb } -} -@media (prefers-color-scheme: dark) { - /* Background */ .bg { color: #e6edf3; background-color: #000000; } - /* PreWrapper */ .chroma { color: #e6edf3; background-color: #000000; } - /* Error */ .chroma .err { color: #f85149 } - /* LineLink */ .chroma .lnlinks { outline: none; text-decoration: none; color: inherit } - /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } - /* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; } - /* LineHighlight */ .chroma .hl { background-color: #6e7681 } - /* LineNumbersTable */ .chroma .lnt { white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #737679 } - /* LineNumbers */ .chroma .ln { white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #6e7681 } - /* Line */ .chroma .line { display: flex; } - /* Keyword */ .chroma .k { color: #ff7b72 } - /* KeywordConstant */ .chroma .kc { color: #79c0ff } - /* KeywordDeclaration */ .chroma .kd { color: #ff7b72 } - /* KeywordNamespace */ .chroma .kn { color: #ff7b72 } - /* KeywordPseudo */ .chroma .kp { color: #79c0ff } - /* KeywordReserved */ .chroma .kr { color: #ff7b72 } - /* KeywordType */ .chroma .kt { color: #ff7b72 } - /* NameClass */ .chroma .nc { color: #f0883e; font-weight: bold } - /* NameConstant */ .chroma .no { color: #79c0ff; font-weight: bold } - /* NameDecorator */ .chroma .nd { color: #d2a8ff; font-weight: bold } - /* NameEntity */ .chroma .ni { color: #ffa657 } - /* NameException */ .chroma .ne { color: #f0883e; font-weight: bold } - /* NameFunction */ .chroma .nf { color: #d2a8ff; font-weight: bold } - /* NameLabel */ .chroma .nl { color: #79c0ff; font-weight: bold } - /* NameNamespace */ .chroma .nn { color: #ff7b72 } - /* NameProperty */ .chroma .py { color: #79c0ff } - /* NameTag */ .chroma .nt { color: #7ee787 } - /* NameVariable */ .chroma .nv { color: #79c0ff } - /* Literal */ .chroma .l { color: #a5d6ff } - /* LiteralDate */ .chroma .ld { color: #79c0ff } - /* LiteralString */ .chroma .s { color: #a5d6ff } - /* LiteralStringAffix */ .chroma .sa { color: #79c0ff } - /* LiteralStringBacktick */ .chroma .sb { color: #a5d6ff } - /* LiteralStringChar */ .chroma .sc { color: #a5d6ff } - /* LiteralStringDelimiter */ .chroma .dl { color: #79c0ff } - /* LiteralStringDoc */ .chroma .sd { color: #a5d6ff } - /* LiteralStringDouble */ .chroma .s2 { color: #a5d6ff } - /* LiteralStringEscape */ .chroma .se { color: #79c0ff } - /* LiteralStringHeredoc */ .chroma .sh { color: #79c0ff } - /* LiteralStringInterpol */ .chroma .si { color: #a5d6ff } - /* LiteralStringOther */ .chroma .sx { color: #a5d6ff } - /* LiteralStringRegex */ .chroma .sr { color: #79c0ff } - /* LiteralStringSingle */ .chroma .s1 { color: #a5d6ff } - /* LiteralStringSymbol */ .chroma .ss { color: #a5d6ff } - /* LiteralNumber */ .chroma .m { color: #a5d6ff } - /* LiteralNumberBin */ .chroma .mb { color: #a5d6ff } - /* LiteralNumberFloat */ .chroma .mf { color: #a5d6ff } - /* LiteralNumberHex */ .chroma .mh { color: #a5d6ff } - /* LiteralNumberInteger */ .chroma .mi { color: #a5d6ff } - /* LiteralNumberIntegerLong */ .chroma .il { color: #a5d6ff } - /* LiteralNumberOct */ .chroma .mo { color: #a5d6ff } - /* Operator */ .chroma .o { color: #ff7b72; font-weight: bold } - /* OperatorWord */ .chroma .ow { color: #ff7b72; font-weight: bold } - /* Comment */ .chroma .c { color: #8b949e; font-style: italic } - /* CommentHashbang */ .chroma .ch { color: #8b949e; font-style: italic } - /* CommentMultiline */ .chroma .cm { color: #8b949e; font-style: italic } - /* CommentSingle */ .chroma .c1 { color: #8b949e; font-style: italic } - /* CommentSpecial */ .chroma .cs { color: #8b949e; font-weight: bold; font-style: italic } - /* CommentPreproc */ .chroma .cp { color: #8b949e; font-weight: bold; font-style: italic } - /* CommentPreprocFile */ .chroma .cpf { color: #8b949e; font-weight: bold; font-style: italic } - /* GenericDeleted */ .chroma .gd { color: #ffa198; background-color: #490202 } - /* GenericEmph */ .chroma .ge { font-style: italic } - /* GenericError */ .chroma .gr { color: #ffa198 } - /* GenericHeading */ .chroma .gh { color: #79c0ff; font-weight: bold } - /* GenericInserted */ .chroma .gi { color: #56d364; background-color: #0f5323 } - /* GenericOutput */ .chroma .go { color: #8b949e } - /* GenericPrompt */ .chroma .gp { color: #8b949e } - /* GenericStrong */ .chroma .gs { font-weight: bold } - /* GenericSubheading */ .chroma .gu { color: #79c0ff } - /* GenericTraceback */ .chroma .gt { color: #ff7b72 } - /* GenericUnderline */ .chroma .gl { text-decoration: underline } - /* TextWhitespace */ .chroma .w { color: #6e7681 } -} diff --git a/static/style.css b/static/style.css deleted file mode 100644 index b1e208f..0000000 --- a/static/style.css +++ /dev/null @@ -1,613 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu - * SPDX-FileCopyrightText: Copyright (c) 2025 luk3yx - * SPDX-FileCopyrightText: Copyright (c) 2017-2025 Drew DeVault - * - * Drew did not directly contribute here but we took significant portions of - * SourceHut's CSS. - */ - -* { - box-sizing: border-box; -} - -/* Base styles and variables */ -html { - font-family: sans-serif; - background-color: var(--background-color); - color: var(--text-color); - font-size: 1rem; - --background-color: hsl(0, 0%, 100%); - --text-color: hsl(0, 0%, 0%); - --link-color: hsl(320, 50%, 36%); - --light-text-color: hsl(0, 0%, 45%); - --darker-border-color: hsl(0, 0%, 72%); - --lighter-border-color: hsl(0, 0%, 85%); - --text-decoration-color: hsl(0, 0%, 72%); - --darker-box-background-color: hsl(0, 0%, 92%); - --lighter-box-background-color: hsl(0, 0%, 95%); - --primary-color: hsl(320, 50%, 36%); - --primary-color-contrast: hsl(320, 0%, 100%); - --danger-color: #ff0000; - --danger-color-contrast: #ffffff; -} - -/* Dark mode overrides */ -@media (prefers-color-scheme: dark) { - html { - --background-color: hsl(0, 0%, 0%); - --text-color: hsl(0, 0%, 100%); - --link-color: hsl(320, 50%, 76%); - --light-text-color: hsl(0, 0%, 78%); - --darker-border-color: hsl(0, 0%, 35%); - --lighter-border-color: hsl(0, 0%, 25%); - --text-decoration-color: hsl(0, 0%, 30%); - --darker-box-background-color: hsl(0, 0%, 20%); - --lighter-box-background-color: hsl(0, 0%, 15%); - } -} - -/* Global layout */ -body { - margin: 0; -} -html, code, pre { - font-size: 0.96rem; /* TODO: Not always correct */ -} - -/* Toggle table controls */ -.toggle-table-off, .toggle-table-on { - opacity: 0; - position: absolute; -} -.toggle-table-off:focus-visible + table > thead > tr > th > label, -.toggle-table-on:focus-visible + table > thead > tr > th > label { - outline: 1.5px var(--primary-color) solid; -} -.toggle-table-off + table > thead > tr > th, .toggle-table-on + table > thead > tr > th { - padding: 0; -} -.toggle-table-off + table > thead > tr > th > label, .toggle-table-on + table > thead > tr > th > label { - width: 100%; - display: inline-block; - padding: 3px 0; - cursor: pointer; -} -.toggle-table-off:checked + table > tbody { - display: none; -} -.toggle-table-on + table > tbody { - display: none; -} -.toggle-table-on:checked + table > tbody { - display: table-row-group; -} - -/* Footer styles */ -footer { - margin-top: 1rem; - margin-left: auto; - margin-right: auto; - margin-bottom: 1rem; - display: block; - padding: 0 5px; - width: fit-content; - text-align: center; - color: var(--light-text-color); -} -footer a:link, footer a:visited { - color: inherit; -} - -.padding { - padding: 0 1rem; -} - -/* Link styles */ -a:link, a:visited { - text-decoration-color: var(--text-decoration-color); - color: var(--link-color); -} - -/* Readme inline code styling */ -#readme code:not(pre > code) { - background-color: var(--lighter-box-background-color); - border-radius: 2px; - padding: 2px; -} - -/* Readme word breaks to avoid overfull hboxes */ -#readme { - word-break: break-word; - line-height: 1.3; -} - -/* Table styles */ -table { - border: var(--lighter-border-color) solid 1px; - border-spacing: 0px; - border-collapse: collapse; -} -table.wide { - width: 100%; -} -td, th { - padding: 3px 5px; - border: var(--lighter-border-color) solid 1px; -} -.pad { - padding: 3px 5px; -} -th, thead, tfoot { - background-color: var(--lighter-box-background-color); -} -th[scope=row] { - text-align: left; -} -th { - font-weight: normal; -} -tr.title-row > th, th.title-row, .title-row { - background-color: var(--lighter-box-background-color); - font-weight: bold; -} -td > pre { - margin: 0; -} -#readme > *:last-child { - margin-bottom: 0; -} -#readme > *:first-child { - margin-top: 0; -} - -/* Table misc and scrolling */ -.commit-id { - font-family: monospace; - word-break: break-word; -} -.scroll { - overflow-x: auto; -} - -/* Diff/chunk styles */ -.chunk-unchanged { - color: grey; -} -.chunk-addition { - color: green; -} -@media (prefers-color-scheme: dark) { - .chunk-addition { - color: lime; - } -} -.chunk-deletion { - color: red; -} -.chunk-unknown { - color: yellow; -} -pre.chunk { - margin-top: 0; - margin-bottom: 0; -} -.centering { - text-align: center; -} - -/* Toggle content sections */ -.toggle-off-wrapper, .toggle-on-wrapper { - border: var(--lighter-border-color) solid 1px; -} -.toggle-off-toggle, .toggle-on-toggle { - opacity: 0; - position: absolute; -} -.toggle-off-header, .toggle-on-header { - font-weight: bold; - cursor: pointer; - display: block; - width: 100%; - background-color: var(--lighter-box-background-color); -} -.toggle-off-header > div, .toggle-on-header > div { - padding: 3px 5px; - display: block; -} -.toggle-on-content { - display: none; -} -.toggle-on-toggle:focus-visible + .toggle-on-header, .toggle-off-toggle:focus-visible + .toggle-off-header { - outline: 1.5px var(--primary-color) solid; -} -.toggle-on-toggle:checked + .toggle-on-header + .toggle-on-content { - display: block; -} -.toggle-off-content { - display: block; -} -.toggle-off-toggle:checked + .toggle-off-header + .toggle-off-content { - display: none; -} - -*:focus-visible { - outline: 1.5px var(--primary-color) solid; -} - -/* File display styles */ -.file-patch + .file-patch { - margin-top: 0.5rem; -} -.file-content { - padding: 3px 5px; -} -.file-header { - font-family: monospace; - display: flex; - flex-direction: row; - align-items: center; -} -.file-header::after { - content: "\25b6"; - font-family: sans-serif; - margin-left: auto; - line-height: 100%; - margin-right: 0.25em; -} -.file-toggle:checked + .file-header::after { - content: "\25bc"; -} - -/* Form elements */ -textarea { - box-sizing: border-box; - background-color: var(--lighter-box-background-color); - resize: vertical; -} -textarea, -input[type=text], -input[type=password] { - font-family: sans-serif; - background-color: var(--lighter-box-background-color); - color: var(--text-color); - border: none; - padding: 0.3rem; - width: 100%; - box-sizing: border-box; -} -td.tdinput, th.tdinput { - padding: 0; - position: relative; -} -td.tdinput textarea, -td.tdinput input[type=text], -td.tdinput input[type=password], -th.tdinput textarea, -th.tdinput input[type=text], -th.tdinput input[type=password] { - background-color: transparent; -} -td.tdinput select { - position: absolute; - background-color: var(--background-color); - border: none; - /* - width: 100%; - height: 100%; - */ - box-sizing: border-box; - top: 0; - left: 0; - right: 0; - bottom: 0; -} -select:active { - outline: 1.5px var(--primary-color) solid; -} - - -/* Button styles */ -.btn-primary, a.btn-primary { - background: var(--primary-color); - color: var(--primary-color-contrast); - border: var(--lighter-border-color) 1px solid; - font-weight: bold; -} -.btn-danger, a.btn-danger { - background: var(--danger-color); - color: var(--danger-color-contrast); - border: var(--lighter-border-color) 1px solid; - font-weight: bold; -} -.btn-white, a.btn-white { - background: var(--primary-color-contrast); - color: var(--primary-color); - border: var(--lighter-border-color) 1px solid; -} -.btn-normal, a.btn-normal, -input[type=file]::file-selector-button { - background: var(--lighter-box-background-color); - border: var(--lighter-border-color) 1px solid !important; - color: var(--text-color); -} -.btn, .btn-white, .btn-danger, .btn-normal, .btn-primary, -input[type=submit], -input[type=file]::file-selector-button { - display: inline-block; - width: auto; - min-width: fit-content; - padding: .1rem .75rem; - transition: background .1s linear; - cursor: pointer; -} -a.btn, a.btn-white, a.btn-danger, a.btn-normal, a.btn-primary { - text-decoration: none; -} - -/* Header layout */ -header#main-header { - /* background-color: var(--lighter-box-background-color); */ - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - flex-wrap: wrap; - padding-top: 1rem; - padding-bottom: 1rem; - gap: 0.5rem; -} -#main-header a, #main-header a:link, main-header a:visited { - text-decoration: none; - color: inherit; -} -#main-header-forge-title { - white-space: nowrap; -} -#breadcrumb-nav { - display: flex; - align-items: center; - flex: 1 1 auto; - min-width: 0; - overflow-x: auto; - gap: 0.25rem; - white-space: nowrap; -} -.breadcrumb-separator { - margin: 0 0.25rem; -} -#main-header-user { - display: flex; - align-items: center; - white-space: nowrap; -} -@media (max-width: 37.5rem) { - header#main-header { - flex-direction: column; - align-items: flex-start; - } - - #breadcrumb-nav { - width: 100%; - overflow-x: auto; - } -} - -/* Uncategorized */ -table + table { - margin-top: 1rem; -} - -td > ul { - padding-left: 1.5rem; - margin-top: 0; - margin-bottom: 0; -} - - - -.complete-error-page hr { - border: 0; - border-bottom: 1px dashed; -} - - - - - - -.key-val-grid { - display: grid; - grid-template-columns: auto 1fr; - gap: 0; - border: var(--lighter-border-color) 1px solid; - overflow: auto; -} - -.key-val-grid > .title-row { - grid-column: 1 / -1; - background-color: var(--lighter-box-background-color); - font-weight: bold; - padding: 3px 5px; - border-bottom: var(--lighter-border-color) 1px solid; -} - -.key-val-grid > .row-label { - background-color: var(--lighter-box-background-color); - padding: 3px 5px; - border-bottom: var(--lighter-border-color) 1px solid; - border-right: var(--lighter-border-color) 1px solid; - text-align: left; - font-weight: normal; -} - -.key-val-grid > .row-value { - padding: 3px 5px; - border-bottom: var(--lighter-border-color) 1px solid; - word-break: break-word; -} - -.key-val-grid code { - font-family: monospace; -} - -.key-val-grid ul { - margin: 0; - padding-left: 1.5rem; -} - -.key-val-grid > .row-label:nth-last-of-type(2), -.key-val-grid > .row-value:last-of-type { - border-bottom: none; -} - -@media (max-width: 37.5rem) { - .key-val-grid { - grid-template-columns: 1fr; - } - - .key-val-grid > .row-label { - border-right: none; - } -} -.key-val-grid > .title-row { - grid-column: 1 / -1; - background-color: var(--lighter-box-background-color); - font-weight: bold; - padding: 3px 5px; - border-bottom: var(--lighter-border-color) 1px solid; - margin: 0; - text-align: center; -} - -.key-val-grid-wrapper { - max-width: 100%; - width: fit-content; -} - -/* Tab navigation */ - -.nav-tabs-standalone { - border: none; - list-style: none; - margin: 0; - flex-grow: 1; - display: inline-flex; - flex-wrap: nowrap; - padding: 0; - border-bottom: 0.25rem var(--darker-box-background-color) solid; - width: 100%; - max-width: 100%; - min-width: 100%; -} - -.nav-tabs-standalone > li { - align-self: flex-end; -} -.nav-tabs-standalone > li > a { - padding: 0 1rem; -} - -.nav-item a.active { - background-color: var(--darker-box-background-color); -} - -.nav-item a, .nav-item a:link, .nav-item a:visited { - text-decoration: none; - color: inherit; -} - -.repo-header-extension { - margin-bottom: 1rem; - background-color: var(--darker-box-background-color); -} - -.repo-header > h2 { - display: inline; - margin: 0; - padding-right: 1rem; -} - -.repo-header > .nav-tabs-standalone { - border: none; - margin: 0; - flex-grow: 1; - display: inline-flex; - flex-wrap: nowrap; - padding: 0; -} - -.repo-header { - display: flex; - flex-wrap: nowrap; -} - -.repo-header-extension-content { - padding-top: 0.3rem; - padding-bottom: 0.2rem; -} - -.repo-header, .padding-wrapper, .repo-header-extension-content, #main-header, .readingwidth, .commit-list-small { - padding-left: 1rem; - padding-right: 1rem; - max-width: 60rem; - width: 100%; - margin-left: auto; - margin-right: auto; -} - -.padding-wrapper { - margin-bottom: 1rem; -} - -/* TODO */ - -.commit-list-small .event { - background-color: var(--lighter-box-background-color); - padding: 0.5rem; - margin-bottom: 1rem; - max-width: 30rem; -} - -.commit-list-small .event:last-child { - margin-bottom: 1rem; -} - -.commit-list-small a { - color: var(--link-color); - text-decoration: none; - font-weight: 500; -} - -.commit-list-small a:hover { - text-decoration: underline; - text-decoration-color: var(--text-decoration-color); -} - -.commit-list-small .event > div { - font-size: 0.95rem; - line-height: 1.4; -} - -.commit-list-small .pull-right { - float: right; - font-size: 0.85em; - color: var(--light-text-color); - margin-left: 1rem; -} - -.commit-list-small pre.commit { - margin: 0.25rem 0 0 0; - padding: 0; - font-family: inherit; - font-size: 0.95rem; - color: var(--text-color); - white-space: pre-wrap; -} - -.commit-list-small .commit-error { - color: var(--danger-color); - font-weight: bold; - margin-top: 1rem; -} diff --git a/templates/400.tmpl b/templates/400.tmpl deleted file mode 100644 index 58ce768..0000000 --- a/templates/400.tmpl +++ /dev/null @@ -1,25 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "400" -}} - - - - {{- template "head_common" . -}} - 400 Bad Request – {{ .global.forge_title }} - - - {{- template "header" . -}} -
-

400 Bad Request

-

{{- .complete_error_msg -}}

-
-
Lindenii Forge
-
-
- {{- template "footer" . -}} -
- - -{{- end -}} diff --git a/templates/400_colon.tmpl b/templates/400_colon.tmpl deleted file mode 100644 index 470a685..0000000 --- a/templates/400_colon.tmpl +++ /dev/null @@ -1,26 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "400_colon" -}} - - - - {{- template "head_common" . -}} - 400 Bad Request – {{ .global.forge_title }} - - - {{- template "header" . -}} -
-

400 Bad Request

-

We recently switched URL schemes. Previously “:” was used as our URL group separator, but because OpenSMTPD does not implement local-part address quoting properly, we’re unable to include “:” in URLs properly, hence we use “-” now.

-

As a precaution in case visitors get confused, this page was set up. You should probably replace the “:”s with “-”s in the URL bar. If there are colons in the URL that is not the group separator—that’s an edge case that we’ll fix later.

-
-
Lindenii Forge
-
-
- {{- template "footer" . -}} -
- - -{{- end -}} diff --git a/templates/403.tmpl b/templates/403.tmpl deleted file mode 100644 index 86d5518..0000000 --- a/templates/403.tmpl +++ /dev/null @@ -1,25 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "403" -}} - - - - {{- template "head_common" . -}} - 403 Forbidden – {{ .global.forge_title }} - - - {{- template "header" . -}} -
-

403 Forbidden

-

{{- .complete_error_msg -}}

-
-
Lindenii Forge
-
-
- {{- template "footer" . -}} -
- - -{{- end -}} diff --git a/templates/404.tmpl b/templates/404.tmpl deleted file mode 100644 index 2eabb06..0000000 --- a/templates/404.tmpl +++ /dev/null @@ -1,24 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "404" -}} - - - - {{- template "head_common" . -}} - 404 Not Found – {{ .global.forge_title }} - - - {{- template "header" . -}} -
-

404 Not Found

-
-
Lindenii Forge
-
-
- {{- template "footer" . -}} -
- - -{{- end -}} diff --git a/templates/451.tmpl b/templates/451.tmpl deleted file mode 100644 index ed6343c..0000000 --- a/templates/451.tmpl +++ /dev/null @@ -1,25 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "451" -}} - - - - {{- template "head_common" . -}} - 451 Unavailable For Legal Reasons – {{ .global.forge_title }} - - - {{- template "header" . -}} -
-

451 Unavailable For Legal Reasons

-

{{- .complete_error_msg -}}

-
-
Lindenii Forge
-
-
- {{- template "footer" . -}} -
- - -{{- end -}} diff --git a/templates/500.tmpl b/templates/500.tmpl deleted file mode 100644 index 3a540e6..0000000 --- a/templates/500.tmpl +++ /dev/null @@ -1,25 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "500" -}} - - - - {{- template "head_common" . -}} - 500 Internal Server Error – {{ .global.forge_title }} - - - {{- template "header" . -}} -
-

500 Internal Server Error

-

{{- .complete_error_msg -}}

-
-
Lindenii Forge
-
-
- {{- template "footer" . -}} -
- - -{{- end -}} diff --git a/templates/501.tmpl b/templates/501.tmpl deleted file mode 100644 index b6ab2f0..0000000 --- a/templates/501.tmpl +++ /dev/null @@ -1,24 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "501" -}} - - - - {{- template "head_common" . -}} - 501 Not Implemented – {{ .global.forge_title }} - - - {{- template "header" . -}} -
-

501 Not Implemented

-
-
Lindenii Forge
-
-
- {{- template "footer" . -}} -
- - -{{- end -}} diff --git a/templates/_footer.tmpl b/templates/_footer.tmpl deleted file mode 100644 index f71ea3e..0000000 --- a/templates/_footer.tmpl +++ /dev/null @@ -1,12 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "footer" -}} -Lindenii Forge -{{ .global.forge_version }} -(source, -upstream, -license, -support) -{{- end -}} diff --git a/templates/_group_path.tmpl b/templates/_group_path.tmpl deleted file mode 100644 index f5d3bf8..0000000 --- a/templates/_group_path.tmpl +++ /dev/null @@ -1,8 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "group_path_plain" -}} -{{- $p := . -}} -{{- range $i, $s := . -}}{{- $s -}}{{- if ne $i (minus (len $p) 1) -}}/{{- end -}}{{- end -}} -{{- end -}} diff --git a/templates/_group_view.tmpl b/templates/_group_view.tmpl deleted file mode 100644 index 92b6639..0000000 --- a/templates/_group_view.tmpl +++ /dev/null @@ -1,56 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "group_view" -}} -{{- if .subgroups -}} - - - - - - - - - - - - {{- range .subgroups -}} - - - - - {{- end -}} - -
Subgroups
NameDescription
- {{- .Name -}} - - {{- .Description -}} -
-{{- end -}} -{{- if .repos -}} - - - - - - - - - - - - {{- range .repos -}} - - - - - {{- end -}} - -
Repos
NameDescription
- {{- .Name -}} - - {{- .Description -}} -
-{{- end -}} -{{- end -}} diff --git a/templates/_head.tmpl b/templates/_head.tmpl deleted file mode 100644 index d6d6571..0000000 --- a/templates/_head.tmpl +++ /dev/null @@ -1,9 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "head_common" -}} - - - -{{- end -}} diff --git a/templates/_header.tmpl b/templates/_header.tmpl deleted file mode 100644 index 340a2ac..0000000 --- a/templates/_header.tmpl +++ /dev/null @@ -1,35 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "header" -}} -
- - -
- {{- if ne .user_id_string "" -}} - {{- .username -}} - {{- else -}} - Login - {{- end -}} -
-
-{{- end -}} diff --git a/templates/_ref_query.tmpl b/templates/_ref_query.tmpl deleted file mode 100644 index 2f78955..0000000 --- a/templates/_ref_query.tmpl +++ /dev/null @@ -1,3 +0,0 @@ -{{- define "ref_query" -}} -{{- if .ref_type -}}?{{- .ref_type -}}={{- .ref_name -}}{{- end -}} -{{- end -}} diff --git a/templates/group.tmpl b/templates/group.tmpl deleted file mode 100644 index b15c316..0000000 --- a/templates/group.tmpl +++ /dev/null @@ -1,80 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "group" -}} -{{- $group_path := .group_path -}} - - - - {{- template "head_common" . -}} - {{- range $i, $s := .group_path -}}{{- $s -}}{{- if ne $i (len $group_path) -}}/{{- end -}}{{- end }} – {{ .global.forge_title -}} - - - {{- template "header" . -}} -
- {{- if .description -}} -

{{- .description -}}

- {{- end -}} - {{- template "group_view" . -}} -
- {{- if .direct_access -}} -
-
- - - - - - - - - - - - - - - - - - - - - - - - - -
- Create repo -
Name - -
Description - -
Contrib - -
-
-
-
-
- -
-
-
-
-
- {{- end -}} -
- {{- template "footer" . -}} -
- - -{{- end -}} diff --git a/templates/index.tmpl b/templates/index.tmpl deleted file mode 100644 index ff7c127..0000000 --- a/templates/index.tmpl +++ /dev/null @@ -1,63 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "index" -}} - - - - {{- template "head_common" . -}} - Index – {{ .global.forge_title -}} - - - {{- template "header" . -}} -
- - - - - - - - - - - - {{- range .groups -}} - - - - - {{- end -}} - -
Groups
NameDescription
- {{- .Name -}} - - {{- .Description -}} -
- - - - - - - - - - - - - - - - -
- Info -
SSH public key{{- .global.server_public_key_string -}}
SSH fingerprint{{- .global.server_public_key_fingerprint -}}
-
-
- {{- template "footer" . -}} -
- - -{{- end -}} diff --git a/templates/login.tmpl b/templates/login.tmpl deleted file mode 100644 index 1e26c82..0000000 --- a/templates/login.tmpl +++ /dev/null @@ -1,59 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "login" -}} - - - - {{- template "head_common" . -}} - Login – {{ .global.forge_title -}} - - - {{- .login_error -}} -
-
- - - - - - - - - - - - - - - - - - - - - -
- Password authentication -
Username - -
Password - -
-
-
-
-
- -
-
-
-
-
-
- {{- template "footer" . -}} -
- - -{{- end -}} diff --git a/templates/repo_branches.tmpl b/templates/repo_branches.tmpl deleted file mode 100644 index 55ea0a6..0000000 --- a/templates/repo_branches.tmpl +++ /dev/null @@ -1,71 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "repo_branches" -}} -{{- $root := . -}} - - - - {{- template "head_common" . -}} - {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} - - - {{- template "header" . -}} -
-

{{- .repo_name -}}

- -
-
-
- {{- .repo_description -}} -
-
-
-

- - Warning: Due to various recent migrations, viewing non-HEAD refs may be broken. - -

- - - - - - - - {{- range .branches -}} - - - - {{- end -}} - -
Branches
- {{ . }} -
-
- - -{{- end -}} diff --git a/templates/repo_commit.tmpl b/templates/repo_commit.tmpl deleted file mode 100644 index 470bba9..0000000 --- a/templates/repo_commit.tmpl +++ /dev/null @@ -1,117 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "repo_commit" -}} -{{- $root := . -}} - - - - {{- template "head_common" . -}} - Commit {{ .commit_id }} – {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} - - - {{- template "header" . -}} -
-

{{- .repo_name -}}

- -
-
-
- {{- .repo_description -}} -
-
-
-
-
-
Commit info
-
ID
-
{{- .commit_id -}}
-
Author
-
- {{- .commit_object.Author.Name -}} <{{- .commit_object.Author.Email -}}> -
-
Author date
-
{{- .commit_object.Author.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" -}}
-
Committer
-
- {{- .commit_object.Committer.Name -}} <{{- .commit_object.Committer.Email -}}> -
-
Committer date
-
{{- .commit_object.Committer.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" -}}
-
Actions
-
- Get patch -
-
-
-
- -
-
{{- .commit_object.Message -}}
-
-
- {{- $parent_commit_hash := .parent_commit_hash -}} - {{- $commit_object := .commit_object -}} - {{- range .file_patches -}} -
- - -
- {{- range .Chunks -}} - {{- if eq .Operation 0 -}} -
{{ .Content }}
- {{- else if eq .Operation 1 -}} -
{{ .Content }}
- {{- else if eq .Operation 2 -}} -
{{ .Content }}
- {{- else -}} -
{{ .Content }}
- {{- end -}} - {{- end -}} -
-
- {{- end -}} -
-
- {{- template "footer" . -}} -
- - -{{- end -}} diff --git a/templates/repo_contrib_index.tmpl b/templates/repo_contrib_index.tmpl deleted file mode 100644 index 172a079..0000000 --- a/templates/repo_contrib_index.tmpl +++ /dev/null @@ -1,82 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "repo_contrib_index" -}} -{{- $root := . -}} - - - - {{- template "head_common" . -}} - Merge requests – {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} - - - {{- template "header" . -}} -
-

{{- .repo_name -}}

- -
-
-
- {{- .repo_description -}} -
-
-
-

How to submit a merge request

-
git clone {{ .ssh_clone_url }}
-cd {{ .repo_name }}
-git checkout -b contrib/name_of_your_contribution
-# edit and commit stuff
-git push -u origin HEAD
-

Pushes that update branches in other namespaces, or pushes to existing contribution branches belonging to other SSH keys, will be automatically -rejected, unless you are an authenticated maintainer. Otherwise, a merge request is automatically opened, and the maintainers are notified via IRC.

-

Alternatively, you may email patches to {{ .repo_patch_mailing_list }}.

-
-
- - - - - - - - - - {{- range .merge_requests -}} - - - - - - {{- end -}} - -
IDTitleStatus
{{- .ID -}}{{- .Title -}}{{- .Status -}}
-
-
- {{- template "footer" . -}} -
- - -{{- end -}} diff --git a/templates/repo_contrib_one.tmpl b/templates/repo_contrib_one.tmpl deleted file mode 100644 index a5f35d3..0000000 --- a/templates/repo_contrib_one.tmpl +++ /dev/null @@ -1,123 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "repo_contrib_one" -}} -{{- $root := . -}} - - - - {{- template "head_common" . -}} - Merge requests – {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} - - - {{- template "header" . -}} -
-

{{- .repo_name -}}

- -
-
-
- {{- .repo_description -}} -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Merge request info
ID{{- .mr_id -}}
Status{{- .mr_status -}}
Title{{- .mr_title -}}
Source ref{{- .mr_source_ref -}}
Destination branch{{- .mr_destination_branch -}}
Merge base{{- .merge_base.Hash.String -}}
-
-
- {{- $merge_base := .merge_base -}} - {{- $source_commit := .source_commit -}} - {{- range .file_patches -}} -
- - -
- {{- range .Chunks -}} - {{- if eq .Operation 0 -}} -
{{ .Content }}
- {{- else if eq .Operation 1 -}} -
{{ .Content }}
- {{- else if eq .Operation 2 -}} -
{{ .Content }}
- {{- else -}} -
{{ .Content }}
- {{- end -}} - {{- end -}} -
-
- {{- end -}} -
-
- {{- template "footer" . -}} -
- - -{{- end -}} diff --git a/templates/repo_index.tmpl b/templates/repo_index.tmpl deleted file mode 100644 index d040f3a..0000000 --- a/templates/repo_index.tmpl +++ /dev/null @@ -1,94 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "repo_index" -}} -{{- $root := . -}} - - - - {{- template "head_common" . -}} - {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} - - - {{- template "header" . -}} -
-

{{- .repo_name -}}

- -
-
-
- {{- .repo_description -}} -
-
- {{- if .notes -}} -
Notes
-
    - {{- range .notes -}}
  • {{- . -}}
  • {{- end -}} -
- - {{- end -}} -

{{- .ssh_clone_url -}}

- {{- if .ref_name -}} -

- - Warning: Due to various recent migrations, viewing non-HEAD refs may be broken. - -

- {{- end -}} - {{- if .commits -}} -
- {{- range .commits -}} -
-
- - {{- .Hash | printf "%.8s" -}} - -  — {{- .Author -}} - - {{- .Date -}} - -
-
{{- .Message | first_line -}}
-
- {{- end -}} - {{- if dereference_error .commits_err -}} -
- Error while obtaining commit log: {{ .commits_err }} -
- {{- end -}} -
- {{- end -}} - {{- if .readme -}} -
- {{- .readme -}} -
- {{- end -}} -
- {{- template "footer" . -}} -
- - -{{- end -}} diff --git a/templates/repo_log.tmpl b/templates/repo_log.tmpl deleted file mode 100644 index 2262902..0000000 --- a/templates/repo_log.tmpl +++ /dev/null @@ -1,90 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "repo_log" -}} -{{- $root := . -}} - - - - {{- template "head_common" . -}} - Log – {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} - - - {{- template "header" . -}} -
-

{{- .repo_name -}}

- -
-
-
- {{- .repo_description -}} -
-
-
- {{- if .ref_name -}} -

- - Warning: Due to various recent migrations, viewing non-HEAD refs may be broken. - -

- {{- end -}} - - - - - - - - - - - - - - {{- range .commits -}} - - - - - - - {{- end -}} - {{- if dereference_error .commits_err -}} - Error while obtaining commit log: {{ .commits_err }} - {{- end -}} - -
Commits {{ if .ref_name }} on {{ .ref_name }}{{ end -}}
IDTitleAuthorAuthor date
{{- .Hash -}}{{- .Message | first_line -}} - - - {{- .Author.When.Format "2006-01-02 15:04:05 -0700" -}} -
-
-
- {{- template "footer" . -}} -
- - -{{- end -}} diff --git a/templates/repo_raw_dir.tmpl b/templates/repo_raw_dir.tmpl deleted file mode 100644 index a33da4a..0000000 --- a/templates/repo_raw_dir.tmpl +++ /dev/null @@ -1,88 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "repo_raw_dir" -}} -{{- $root := . -}} - - - - {{- template "head_common" . -}} - /{{ .path_spec }}{{ if ne .path_spec "" }}/{{ end }} – {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} - - - {{- template "header" . -}} -
-

{{- .repo_name -}}

- -
-
-
- {{- .repo_description -}} -
-
-
- {{- if .ref_name -}} -

- - Warning: Due to various recent migrations, viewing non-HEAD refs may be broken. - -

- {{- end -}} - - - - - - - - - - - - - {{- $path_spec := .path_spec -}} - {{- range .files -}} - - - - - - {{- end -}} - -
- (Raw) /{{ .path_spec }}{{ if ne .path_spec "" }}/{{ end }}{{ if .ref_name }} on {{ .ref_name }}{{ end -}} -
ModeFilenameSize
{{- .Mode -}}{{- .Name -}}{{- if not .IsFile -}}/{{- end -}}{{- .Size -}}
-
-
-
-
-
-
- {{- template "footer" . -}} -
- - -{{- end -}} diff --git a/templates/repo_tree_dir.tmpl b/templates/repo_tree_dir.tmpl deleted file mode 100644 index fc06646..0000000 --- a/templates/repo_tree_dir.tmpl +++ /dev/null @@ -1,93 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "repo_tree_dir" -}} -{{- $root := . -}} - - - - {{- template "head_common" . -}} - /{{ .path_spec }}{{ if ne .path_spec "" }}/{{ end }} – {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} - - - {{- template "header" . -}} -
-

{{- .repo_name -}}

- -
-
-
- {{- .repo_description -}} -
-
-
- {{- if .ref_name -}} -

- - Warning: Due to various recent migrations, viewing non-HEAD refs may be broken. - -

- {{- end -}} - - - - - - - - - - - - - {{- $path_spec := .path_spec -}} - {{- range .files -}} - - - - - - {{- end -}} - -
- /{{ .path_spec }}{{ if ne .path_spec "" }}/{{ end }}{{ if .ref_name }} on {{ .ref_name }}{{ end -}} -
ModeFilenameSize
{{- .Mode -}}{{- .Name -}}{{- if not .IsFile -}}/{{- end -}}{{- .Size -}}
-
-
-
-
-
- {{- if .readme -}} -
- {{- .readme -}} -
- {{- end -}} -
- {{- template "footer" . -}} -
- - -{{- end -}} diff --git a/templates/repo_tree_file.tmpl b/templates/repo_tree_file.tmpl deleted file mode 100644 index 76404a9..0000000 --- a/templates/repo_tree_file.tmpl +++ /dev/null @@ -1,65 +0,0 @@ -{{/* - SPDX-License-Identifier: AGPL-3.0-only - SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu -*/}} -{{- define "repo_tree_file" -}} -{{- $root := . -}} - - - - {{- template "head_common" . -}} - - /{{ .path_spec }} – {{ .repo_name }} – {{ template "group_path_plain" .group_path }} – {{ .global.forge_title -}} - - - {{- template "header" . -}} -
-

{{- .repo_name -}}

- -
-
-
- {{- .repo_description -}} -
-
-
- {{- if .ref_name -}} -

- - Warning: Due to various recent migrations, viewing non-HEAD refs may be broken. - -

- {{- end -}} -

- /{{ .path_spec }} (raw) -

- {{- .file_contents -}} -
- - - -{{- end -}} -- cgit v1.2.3