diff options
author | EuAndreh <eu@euandre.org> | 2025-05-02 18:25:16 -0300 |
---|---|---|
committer | EuAndreh <eu@euandre.org> | 2025-05-02 18:25:16 -0300 |
commit | 7b9c475de4d30a909a0f4da4c0a2f754498f7f0e (patch) | |
tree | fdf96d022b4d9c213c2de5e8d26168cbe93faa37 | |
parent | Makefile: Clean-up old stuff (diff) | |
download | gistatic-7b9c475de4d30a909a0f4da4c0a2f754498f7f0e.tar.gz gistatic-7b9c475de4d30a909a0f4da4c0a2f754498f7f0e.tar.xz |
WIP: Commit sh code as-is
-rw-r--r-- | Makefile | 18 | ||||
-rwxr-xr-x | src/gistatic | 1861 | ||||
-rw-r--r-- | tests/resources/repositories/repo-1/.gitdir/description | 2 |
3 files changed, 620 insertions, 1261 deletions
@@ -41,6 +41,20 @@ side-assets = \ ## and installation. all: $(derived-assets) +tests/resources/repositories/repo-1/.git \ +tests/resources/repositories/repo-2/.git: + ln -s .gitdir $@ + +emit-index: src/gistatic + @rm -rf tmp/index/ + @./src/gistatic -i -o tmp/index/ ~/dev/published/git-permalink/ ../capim/ ../libedn/ ../listatic/ ../lisp-cli/ + @ln -rfs tmp/git-permalink tmp/index/git-permalink + +emit-repo: src/gistatic + @rm -rf tmp/git-permalink/ + @time ./src/gistatic -o tmp/git-permalink/ -u FIXME-url-1 ~/dev/published/git-permalink/ + +run: shellcheck emit-index emit-repo check-unit: @@ -53,6 +67,10 @@ check-integration: ## build can run tests at the same time. The required artifacts ## are created if missing. check: check-unit check-integration +# tests/resources/repositories/repo-1/.git +# tests/resources/repositories/repo-2/.git +# sh tests/build-sample.sh +# sh tests/integration.sh diff --git a/src/gistatic b/src/gistatic index fec517a..a7ad6fe 100755 --- a/src/gistatic +++ b/src/gistatic @@ -1,467 +1,390 @@ #!/bin/sh -# shellcheck disable=2034 disable=2059 -# FIXME: remove these ^^^ set -eu -MSG_USAGE_EN='Usage: - gistatic -i -o DIRECTORY REPOSITORY... - gistatic -o DIRECTORY -u CLONE_URL [-b MAIN_BRANCH] REPOSITORY - gistatic [-hV]' - -MSG_HELP_EN=' -Options: - -i build the index page of the repositories - -u CLONE_URL address to be shown alongside "git clone" - -o DIRECTORY output where to place the generated files - -b MAIN_BRANCH the default branch of the repository (default: main) - -h, --help show this help - -V, --version print the version information - -See "man gistatic" for more information.' - -MSG_MISSING_CLIARG_EN='Missing %s' -MSG_INCOMPATIBLE_OPTIONS_EN='Incompatible options: ' -MSG_MISSING_ARGS_EN='REPOSITORY' -MSG_LANGNAME_EN='en' -MSG_INDEX_DESCRIPTION_EN='Index of repositories' -MSG_DEFAULT_TITLE_EN='Repositories' -MSG_LOGO_ALT_INDEX_EN='Logo image of the repository list' -MSG_LOGO_ALT_REPOSITORY_EN='Logo image of the repository' -MSG_NAME_EN='Name' -MSG_DESCRIPTION_EN='Description' -MSG_LAST_COMMIT_EN='Last commit' -MSG_COMMIT_FEED_EN='commit feed' -MSG_TAGS_FEED_EN='tags feed' -MSG_NAV_FILES_EN='files' -MSG_NAV_LOG_EN='log' -MSG_NAV_REFS_EN='refs' -MSG_THEAD_BRANCH_EN='Branch' -MSG_THEAD_COMMITMSG_EN='Commit message' -MSG_THEAD_AUTHOR_EN='Author' -MSG_THEAD_DATE_EN='Date' -MSG_THEAD_TAG_EN='Tag' -MSG_TITLE_REFS_EN='refs' -MSG_GENERATING_LOG_EN='Generating %s...' -# HTML escaped messages -MSG_ESCAPED_FOOTER_TEMPLATE_EN='Generated with <a href="https://euandreh.xyz/gistatic/">gistatic</a>.' - -set_lang() { - lang="$1" - eval " - MSG_USAGE=\$MSG_USAGE_$lang - MSG_HELP=\$MSG_HELP_$lang - MSG_MISSING_CLIARG=\$MSG_MISSING_CLIARG_$lang - MSG_INCOMPATIBLE_OPTIONS=\$MSG_INCOMPATIBLE_OPTIONS_$lang - MSG_MISSING_ARGS=\$MSG_MISSING_ARGS_$lang - MSG_LANGNAME=\$MSG_LANGNAME_$lang - MSG_INDEX_DESCRIPTION=\$MSG_INDEX_DESCRIPTION_$lang - MSG_DEFAULT_TITLE=\$MSG_DEFAULT_TITLE_$lang - MSG_LOGO_ALT_INDEX=\$MSG_LOGO_ALT_INDEX_$lang - MSG_LOGO_ALT_REPOSITORY=\$MSG_LOGO_ALT_REPOSITORY_$lang - MSG_NAME=\$MSG_NAME_$lang - MSG_DESCRIPTION=\$MSG_DESCRIPTION_$lang - MSG_LAST_COMMIT=\$MSG_LAST_COMMIT_$lang - MSG_COMMIT_FEED=\$MSG_COMMIT_FEED_$lang - MSG_TAGS_FEED=\$MSG_TAGS_FEED_$lang - MSG_NAV_FILES=\$MSG_NAV_FILES_$lang - MSG_NAV_LOG=\$MSG_NAV_LOG_$lang - MSG_NAV_REFS=\$MSG_NAV_REFS_$lang - MSG_THEAD_BRANCH=\$MSG_THEAD_BRANCH_$lang - MSG_THEAD_COMMITMSG=\$MSG_THEAD_COMMITMSG_$lang - MSG_THEAD_AUTHOR=\$MSG_THEAD_AUTHOR_$lang - MSG_THEAD_DATE=\$MSG_THEAD_DATE_$lang - MSG_THEAD_TAG=\$MSG_THEAD_TAG_$lang - MSG_TITLE_REFS=\$MSG_TITLE_REFS_$lang - MSG_GENERATING_LOG=\$MSG_GENERATING_LOG_$lang - - MSG_ESCAPED_FOOTER_TEMPLATE=\$MSG_ESCAPED_FOOTER_TEMPLATE_$lang -" +usage() { + cat <<-'EOF' + Usage: + gistatic -i -o DIRECTORY REPOSITORY... + gistatic -o DIRECTORY -u CLONE_URL [-b MAIN_BRANCH] REPOSITORY' + EOF } -get_lang() { - # LC_MESSAGES="ll_CC.CODESET@modifier" -> ll_CC, where quotes - # are optional - locale 2>/dev/null | - grep ^LC_MESSAGES | - cut -d. -f1 | - cut -d\" -f2 | - cut -d= -f2 -} -case "$(get_lang)" in - *) - set_lang EN - ;; -esac +LANGNAME="$(printf '%s' "${LANG:-en}" | cut -d_ -f1)" +LANGNAME='en' + +MSG_MISSING_CLIARG='Missing %s' +MSG_INCOMPATIBLE_OPTIONS='Incompatible options: ' +MSG_MISSING_ARGS='REPOSITORY' +MSG_INDEX_DESCRIPTION='Index of repositories' +MSG_TITLE_INDEX='Repositories' +MSG_LOGO_ALT_INDEX='Logo image of the repository list' +MSG_LOGO_ALT_REPOSITORY='Logo image of the repository' +MSG_NAME='Name' +MSG_DESCRIPTION='Description' +MSG_LAST_COMMIT='Last commit' +MSG_COMMIT_FEED='commit feed' +MSG_TAGS_FEED='tags feed' +MSG_NAV_FILES='files' +MSG_NAV_LOG='log' +MSG_NAV_REFS='refs' +MSG_THEAD_BRANCH='Branch' +MSG_THEAD_COMMITMSG='Commit message' +MSG_THEAD_AUTHOR='Author' +MSG_THEAD_DATE='Date' +MSG_THEAD_TAG='Tag' +MSG_TITLE_REFS='refs' +MSG_GENERATING_LOG='Generating %s...' + +# HTML escaped messages +MSG_ESCAPED_FOOTER_TEMPLATE='Generated with <a href="https://euandreh.xyz/gistatic/">gistatic</a>.' + +t() { + gettext 'gistatic' "$1" +} + # -# Utilities +# Template strings # -tac() { - sed '1!G;h;$!d' +print_logo() { + color="$1" + cat <<EOF +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> + <path fill="$color" d="M 0 8 L 1 8 L 1 9 L 0 9 L 0 8 Z" /> + <path fill="$color" d="M 0 13 L 1 13 L 1 14 L 0 14 L 0 13 Z" /> + <path fill="$color" d="M 1 8 L 2 8 L 2 9 L 1 9 L 1 8 Z" /> + <path fill="$color" d="M 1 13 L 2 13 L 2 14 L 1 14 L 1 13 Z" /> + <path fill="$color" d="M 2 8 L 3 8 L 3 9 L 2 9 L 2 8 Z" /> + <path fill="$color" d="M 2 13 L 3 13 L 3 14 L 2 14 L 2 13 Z" /> + <path fill="$color" d="M 3 8 L 4 8 L 4 9 L 3 9 L 3 8 Z" /> + <path fill="$color" d="M 3 13 L 4 13 L 4 14 L 3 14 L 3 13 Z" /> + <path fill="$color" d="M 4 7 L 5 7 L 5 8 L 4 8 L 4 7 Z" /> + <path fill="$color" d="M 4 8 L 5 8 L 5 9 L 4 9 L 4 8 Z" /> + <path fill="$color" d="M 4 13 L 5 13 L 5 14 L 4 14 L 4 13 Z" /> + <path fill="$color" d="M 5 6 L 6 6 L 6 7 L 5 7 L 5 6 Z" /> + <path fill="$color" d="M 5 7 L 6 7 L 6 8 L 5 8 L 5 7 Z" /> + <path fill="$color" d="M 5 13 L 6 13 L 6 14 L 5 14 L 5 13 Z" /> + <path fill="$color" d="M 6 5 L 7 5 L 7 6 L 6 6 L 6 5 Z" /> + <path fill="$color" d="M 6 6 L 7 6 L 7 7 L 6 7 L 6 6 Z" /> + <path fill="$color" d="M 6 14 L 7 14 L 7 15 L 6 15 L 6 14 Z" /> + <path fill="$color" d="M 7 1 L 8 1 L 8 2 L 7 2 L 7 1 Z" /> + <path fill="$color" d="M 7 14 L 8 14 L 8 15 L 7 15 L 7 14 Z" /> + <path fill="$color" d="M 7 15 L 8 15 L 8 16 L 7 16 L 7 15 Z" /> + <path fill="$color" d="M 7 2 L 8 2 L 8 3 L 7 3 L 7 2 Z" /> + <path fill="$color" d="M 7 3 L 8 3 L 8 4 L 7 4 L 7 3 Z" /> + <path fill="$color" d="M 7 4 L 8 4 L 8 5 L 7 5 L 7 4 Z" /> + <path fill="$color" d="M 7 5 L 8 5 L 8 6 L 7 6 L 7 5 Z" /> + <path fill="$color" d="M 8 1 L 9 1 L 9 2 L 8 2 L 8 1 Z" /> + <path fill="$color" d="M 8 15 L 9 15 L 9 16 L 8 16 L 8 15 Z" /> + <path fill="$color" d="M 9 1 L 10 1 L 10 2 L 9 2 L 9 1 Z" /> + <path fill="$color" d="M 9 2 L 10 2 L 10 3 L 9 3 L 9 2 Z" /> + <path fill="$color" d="M 9 6 L 10 6 L 10 7 L 9 7 L 9 6 Z" /> + <path fill="$color" d="M 9 15 L 10 15 L 10 16 L 9 16 L 9 15 Z" /> + <path fill="$color" d="M 10 2 L 11 2 L 11 3 L 10 3 L 10 2 Z" /> + <path fill="$color" d="M 10 3 L 11 3 L 11 4 L 10 4 L 10 3 Z" /> + <path fill="$color" d="M 10 4 L 11 4 L 11 5 L 10 5 L 10 4 Z" /> + <path fill="$color" d="M 10 5 L 11 5 L 11 6 L 10 6 L 10 5 Z" /> + <path fill="$color" d="M 10 6 L 11 6 L 11 7 L 10 7 L 10 6 Z" /> + <path fill="$color" d="M 11 6 L 12 6 L 12 7 L 11 7 L 11 6 Z" /> + <path fill="$color" d="M 11 8 L 12 8 L 12 9 L 11 9 L 11 8 Z" /> + <path fill="$color" d="M 10 15 L 11 15 L 11 16 L 10 16 L 10 15 Z" /> + <path fill="$color" d="M 11 10 L 12 10 L 12 11 L 11 11 L 11 10 Z" /> + <path fill="$color" d="M 11 12 L 12 12 L 12 13 L 11 13 L 11 12 Z" /> + <path fill="$color" d="M 11 14 L 12 14 L 12 15 L 11 15 L 11 14 Z" /> + <path fill="$color" d="M 11 15 L 12 15 L 12 16 L 11 16 L 11 15 Z" /> + <path fill="$color" d="M 12 6 L 13 6 L 13 7 L 12 7 L 12 6 Z" /> + <path fill="$color" d="M 12 8 L 13 8 L 13 9 L 12 9 L 12 8 Z" /> + <path fill="$color" d="M 12 10 L 13 10 L 13 11 L 12 11 L 12 10 Z" /> + <path fill="$color" d="M 12 12 L 13 12 L 13 13 L 12 13 L 12 12 Z" /> + <path fill="$color" d="M 12 14 L 13 14 L 13 15 L 12 15 L 12 14 Z" /> + <path fill="$color" d="M 13 6 L 14 6 L 14 7 L 13 7 L 13 6 Z" /> + <path fill="$color" d="M 13 8 L 14 8 L 14 9 L 13 9 L 13 8 Z" /> + <path fill="$color" d="M 13 10 L 14 10 L 14 11 L 13 11 L 13 10 Z" /> + <path fill="$color" d="M 13 12 L 14 12 L 14 13 L 13 13 L 13 12 Z" /> + <path fill="$color" d="M 13 13 L 14 13 L 14 14 L 13 14 L 13 13 Z" /> + <path fill="$color" d="M 13 14 L 14 14 L 14 15 L 13 15 L 13 14 Z" /> + <path fill="$color" d="M 14 7 L 15 7 L 15 8 L 14 8 L 14 7 Z" /> + <path fill="$color" d="M 14 8 L 15 8 L 15 9 L 14 9 L 14 8 Z" /> + <path fill="$color" d="M 14 9 L 15 9 L 15 10 L 14 10 L 14 9 Z" /> + <path fill="$color" d="M 14 10 L 15 10 L 15 11 L 14 11 L 14 10 Z" /> + <path fill="$color" d="M 14 11 L 15 11 L 15 12 L 14 12 L 14 11 Z" /> + <path fill="$color" d="M 14 12 L 15 12 L 15 13 L 14 13 L 14 12 Z" /> +</svg> +EOF } -escape() { - printf '%s' "$1" | - sed \ - -e 's|&|\&|g' \ - -e 's|<|\<|g' \ - -e 's|>|\>|g' \ - -e 's|"|\"|g' \ - -e "s|'|\'|g" +print_style() { + cat <<'EOF' +:root { + --color: black; + --background-color: white; + --background-contrast-color: hsl(0, 0%, 98%); + --hover-color: hsl(0, 0%, 93%); + --nav-color: hsl(0, 0%, 87%); + --selected-color: hsl(0, 0%, 80%); + --diff-added-color: hsl(120, 100%, 23%); + --diff-removed-color: hsl(0, 100%, 47%); } -realpath() { - mkdir -p "$1" - cd "$1" - pwd +@media(prefers-color-scheme: dark) { + :root { + --color: white; + --background-color: black; + --background-contrast-color: hsl(0, 0%, 2%); + --hover-color: hsl(0, 0%, 7%); + --nav-color: hsl(0, 0%, 13%); + --selected-color: hsl(0, 0%, 20%); + } + + body { + color: var(--color); + background-color: var(--background-color); + } + + a { + color: hsl(211, 100%, 60%); + } + + a:visited { + color: hsl(242, 100%, 80%); + } } +body { + font-family: monospace; + max-width: 1100px; + margin: 0 auto 0 auto; +} -# -# Documentation functions -# +.logo { + height: 6em; + width: 6em; +} -usage() { - printf '%s\n' "$MSG_USAGE" +.header-horizontal-grouping { + display: flex; + align-items: center; + margin-top: 1em; + margin-bottom: 1em; } -help() { - printf '%s\n' "$MSG_HELP" +.header-description { + margin-left: 2em; } -version() { - printf 'gistatic-0.1.0 1970-01-01\n' +nav { + margin-top: 2em; } +nav ul { + display: flex; + list-style-type: none; + margin-bottom: 0; +} -# -# Template strings -# +nav li { + margin-left: 10px; +} -print_logo() { - cat <<-'EOF' - <?xml version="1.0" encoding="UTF-8" standalone="no"?> - <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> - <path d="M 0 8 L 1 8 L 1 9 L 0 9 L 0 8 Z" /> - <path d="M 0 13 L 1 13 L 1 14 L 0 14 L 0 13 Z" /> - <path d="M 1 8 L 2 8 L 2 9 L 1 9 L 1 8 Z" /> - <path d="M 1 13 L 2 13 L 2 14 L 1 14 L 1 13 Z" /> - <path d="M 2 8 L 3 8 L 3 9 L 2 9 L 2 8 Z" /> - <path d="M 2 13 L 3 13 L 3 14 L 2 14 L 2 13 Z" /> - <path d="M 3 8 L 4 8 L 4 9 L 3 9 L 3 8 Z" /> - <path d="M 3 13 L 4 13 L 4 14 L 3 14 L 3 13 Z" /> - <path d="M 4 7 L 5 7 L 5 8 L 4 8 L 4 7 Z" /> - <path d="M 4 8 L 5 8 L 5 9 L 4 9 L 4 8 Z" /> - <path d="M 4 13 L 5 13 L 5 14 L 4 14 L 4 13 Z" /> - <path d="M 5 6 L 6 6 L 6 7 L 5 7 L 5 6 Z" /> - <path d="M 5 7 L 6 7 L 6 8 L 5 8 L 5 7 Z" /> - <path d="M 5 13 L 6 13 L 6 14 L 5 14 L 5 13 Z" /> - <path d="M 6 5 L 7 5 L 7 6 L 6 6 L 6 5 Z" /> - <path d="M 6 6 L 7 6 L 7 7 L 6 7 L 6 6 Z" /> - <path d="M 6 14 L 7 14 L 7 15 L 6 15 L 6 14 Z" /> - <path d="M 7 1 L 8 1 L 8 2 L 7 2 L 7 1 Z" /> - <path d="M 7 14 L 8 14 L 8 15 L 7 15 L 7 14 Z" /> - <path d="M 7 15 L 8 15 L 8 16 L 7 16 L 7 15 Z" /> - <path d="M 7 2 L 8 2 L 8 3 L 7 3 L 7 2 Z" /> - <path d="M 7 3 L 8 3 L 8 4 L 7 4 L 7 3 Z" /> - <path d="M 7 4 L 8 4 L 8 5 L 7 5 L 7 4 Z" /> - <path d="M 7 5 L 8 5 L 8 6 L 7 6 L 7 5 Z" /> - <path d="M 8 1 L 9 1 L 9 2 L 8 2 L 8 1 Z" /> - <path d="M 8 15 L 9 15 L 9 16 L 8 16 L 8 15 Z" /> - <path d="M 9 1 L 10 1 L 10 2 L 9 2 L 9 1 Z" /> - <path d="M 9 2 L 10 2 L 10 3 L 9 3 L 9 2 Z" /> - <path d="M 9 6 L 10 6 L 10 7 L 9 7 L 9 6 Z" /> - <path d="M 9 15 L 10 15 L 10 16 L 9 16 L 9 15 Z" /> - <path d="M 10 2 L 11 2 L 11 3 L 10 3 L 10 2 Z" /> - <path d="M 10 3 L 11 3 L 11 4 L 10 4 L 10 3 Z" /> - <path d="M 10 4 L 11 4 L 11 5 L 10 5 L 10 4 Z" /> - <path d="M 10 5 L 11 5 L 11 6 L 10 6 L 10 5 Z" /> - <path d="M 10 6 L 11 6 L 11 7 L 10 7 L 10 6 Z" /> - <path d="M 11 6 L 12 6 L 12 7 L 11 7 L 11 6 Z" /> - <path d="M 11 8 L 12 8 L 12 9 L 11 9 L 11 8 Z" /> - <path d="M 10 15 L 11 15 L 11 16 L 10 16 L 10 15 Z" /> - <path d="M 11 10 L 12 10 L 12 11 L 11 11 L 11 10 Z" /> - <path d="M 11 12 L 12 12 L 12 13 L 11 13 L 11 12 Z" /> - <path d="M 11 14 L 12 14 L 12 15 L 11 15 L 11 14 Z" /> - <path d="M 11 15 L 12 15 L 12 16 L 11 16 L 11 15 Z" /> - <path d="M 12 6 L 13 6 L 13 7 L 12 7 L 12 6 Z" /> - <path d="M 12 8 L 13 8 L 13 9 L 12 9 L 12 8 Z" /> - <path d="M 12 10 L 13 10 L 13 11 L 12 11 L 12 10 Z" /> - <path d="M 12 12 L 13 12 L 13 13 L 12 13 L 12 12 Z" /> - <path d="M 12 14 L 13 14 L 13 15 L 12 15 L 12 14 Z" /> - <path d="M 13 6 L 14 6 L 14 7 L 13 7 L 13 6 Z" /> - <path d="M 13 8 L 14 8 L 14 9 L 13 9 L 13 8 Z" /> - <path d="M 13 10 L 14 10 L 14 11 L 13 11 L 13 10 Z" /> - <path d="M 13 12 L 14 12 L 14 13 L 13 13 L 13 12 Z" /> - <path d="M 13 13 L 14 13 L 14 14 L 13 14 L 13 13 Z" /> - <path d="M 13 14 L 14 14 L 14 15 L 13 15 L 13 14 Z" /> - <path d="M 14 7 L 15 7 L 15 8 L 14 8 L 14 7 Z" /> - <path d="M 14 8 L 15 8 L 15 9 L 14 9 L 14 8 Z" /> - <path d="M 14 9 L 15 9 L 15 10 L 14 10 L 14 9 Z" /> - <path d="M 14 10 L 15 10 L 15 11 L 14 11 L 14 10 Z" /> - <path d="M 14 11 L 15 11 L 15 12 L 14 12 L 14 11 Z" /> - <path d="M 14 12 L 15 12 L 15 13 L 14 13 L 14 12 Z" /> - </svg> - EOF +nav a, nav a:visited { + padding: 2px 8px 0px 8px; + color: var(--color); } -print_style() { - cat <<-'EOF' - :root { - --color: black; - --background-color: white; - --background-contrast-color: hsl(0, 0%, 98%); - --hover-color: hsl(0, 0%, 93%); - --nav-color: hsl(0, 0%, 87%); - --selected-color: hsl(0, 0%, 80%); - --diff-added-color: hsl(120, 100%, 23%); - --diff-removed-color: hsl(0, 100%, 47%); - } - - @media(prefers-color-scheme: dark) { - :root { - --color: white; - --background-color: black; - --background-contrast-color: hsl(0, 0%, 2%); - --hover-color: hsl(0, 0%, 7%); - --nav-color: hsl(0, 0%, 13%); - --selected-color: hsl(0, 0%, 20%); - } - - body { - color: var(--color); - background-color: var(--background-color); - } - - a { - color: hsl(211, 100%, 60%); - } - - a:visited { - color: hsl(242, 100%, 80%); - } - } - - body { - font-family: monospace; - max-width: 1100px; - margin: 0 auto 0 auto; - } - - .logo { - height: 6em; - width: 6em; - } - - .header-horizontal-grouping { - display: flex; - align-items: center; - margin-top: 1em; - margin-bottom: 1em; - } - - .header-description { - margin-left: 2em; - } - - nav { - margin-top: 2em; - } - - nav ul { - display: flex; - list-style-type: none; - margin-bottom: 0; - } - - nav li { - margin-left: 10px; - } - - nav a, nav a:visited { - padding: 2px 8px 0px 8px; - color: var(--color); - } - - .selected-nav-item { - background-color: var(--nav-color); - } - - hr { - margin-top: 0; - border: 0; - border-top: 3px solid var(--nav-color); - } - - table { - margin: 2em auto; - } - - th { - padding-bottom: 1em; - } - - tbody tr:hover { - background-color: var(--hover-color); - } - - td { - padding-left: 1em; - padding-right: 1em; - } - - - /* commit page */ - - .diff-added, .diff-removed { - text-decoration: none; - } - - .diff-added:target, .diff-removed:target { - background-color: var(--selected-color); - } - - .diff-added, .diff-added:visited { - color: var(--diff-added-color); - } - - .diff-removed, .diff-removed:visited { - color: var(--diff-removed-color); - } - - - /* log page */ - - .log-commit-box { - padding: 1em; - margin: 1em; - background-color: var(--background-contrast-color); - } - - .log-commit-tag { - padding: 2px; - border: 1px solid; - color: var(--color); - } - - .log-head-highlight { - background-color: #ff8888; /* FIXME: hsl + dark-mode */ - } - - .log-branch-highlight { - background-color: #88ff88; /* FIXME: hsl + dark-mode */ - } - - .log-tag-highlight { - background-color: #ffff88; /* FIXME: hsl + dark-mode */ - } - - .pre-wrapping { - overflow: auto; - margin: 1em; - } - - .log-notes { - /* FIXME: yellow box goes until the end of the screen */ - padding: 1em; - background-color: #ffd; /* FIXME: hsl + dark-mode */ - } - - .log-pagination { - text-align: center; - margin: 2em; - } - - - footer { - text-align: center; - } - EOF +.selected-nav-item { + background-color: var(--nav-color); +} + +hr { + margin-top: 0; + border: 0; + border-top: 3px solid var(--nav-color); +} + +table { + margin: 2em auto; +} + +th { + padding-bottom: 1em; +} + +tbody tr:hover { + background-color: var(--hover-color); +} + +td { + padding-left: 1em; + padding-right: 1em; +} + + +/* commit page */ + +.diff-added, .diff-removed { + text-decoration: none; +} + +.diff-added:target, .diff-removed:target { + background-color: var(--selected-color); +} + +.diff-added, .diff-added:visited { + color: var(--diff-added-color); +} + +.diff-removed, .diff-removed:visited { + color: var(--diff-removed-color); +} + + +/* log page */ + +.log-commit-box { + padding: 1em; + margin: 1em; + background-color: var(--background-contrast-color); +} + +.log-commit-tag { + padding: 2px; + border: 1px solid; + color: var(--color); +} + +.log-head-highlight { + background-color: #ff8888; /* FIXME: hsl + dark-mode */ +} + +.log-branch-highlight { + background-color: #88ff88; /* FIXME: hsl + dark-mode */ +} + +.log-tag-highlight { + background-color: #ffff88; /* FIXME: hsl + dark-mode */ +} + +.pre-wrapping { + overflow: auto; + margin: 1em; +} + +.log-notes { + /* FIXME: yellow box goes until the end of the screen */ + padding: 1em; + background-color: #ffd; /* FIXME: hsl + dark-mode */ +} + +.log-pagination { + text-align: center; + margin: 2em; +} + + +footer { + text-align: center; +} +EOF } print_index_header() { - cat <<-EOF - <!DOCTYPE html> - <html lang="$(escape "$MSG_LANGNAME")"> - <head> - <meta charset="UTF-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1" /> - <meta name="description" content="$(escape "$MSG_INDEX_DESCRIPTION")" /> - <link rel="icon" type="image/svg+xml" href="logo.svg" /> - <link rel="stylesheet" type="text/css" href="style.css" /> - <title>$(escape "$TITLE")</title> - </head> - <body> - <header> - <div class="header-horizontal-grouping"> - <img alt="$(escape "$MSG_LOGO_ALT_INDEX")" src="logo.svg" /> - <h1 class="header-description"> - $(escape "$TITLE") - </h1> - </div> - <hr /> - </header> - <main> - <table> - <thead> - <tr> - <th> - $(escape "$MSG_NAME") - </th> - <th> - $(escape "$MSG_DESCRIPTION") - </th> - <th> - $(escape "$MSG_LAST_COMMIT") - </th> - </tr> - </thead> - <tbody> + cat <<EOF +<!DOCTYPE html> +<html lang="$LANGNAME"> + <head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="description" content="$(t "$MSG_INDEX_DESCRIPTION")" /> + <link rel="icon" type="image/svg+xml" href="img/favicon.svg" /> + <link rel="stylesheet" type="text/css" href="style.css" /> + <title>$(t "$MSG_TITLE_INDEX")</title> + </head> + <body> + <header> + <div class="header-horizontal-grouping"> + <picture> + <source srcset="img/logo/dark.svg" media="(prefers-color-scheme: dark)" /> + <img src="img/logo/light.svg" alt="$(t "$MSG_LOGO_ALT_INDEX")" /> + </picture> + <h1 class="header-description"> + $(t "$MSG_TITLE_INDEX") + </h1> + </div> + <hr /> + </header> + <main> + <table> + <thead> + <tr> + <th> + $(t "$MSG_NAME") + </th> + <th> + $(t "$MSG_DESCRIPTION") + </th> + <th> + $(t "$MSG_LAST_COMMIT") + </th> + </tr> + </thead> + <tbody> EOF } print_index_row() { - repo="$(basename "$(realpath "${1%.git}")")" - description="$(cat "$1/description" 2>/dev/null ||:)" - last_commit_date="$(git -C "$1" log -1 --format=%cd --date='format:%Y-%m:%d %H:%M' 2>/dev/null ||:)" - cat <<-EOF - <tr> - <td> - <a href="$(escape "$repo")"> - $(escape "$repo") - </a> - </td> - <td> - $(escape "$description") - </td> - <td> - $(escape "$last_commit_date") - </td> - </tr> - EOF + path="$1" + repo_vars "$path" + + last_commit_date="$(git log -1 --format=%cd --date='format:%Y-%m:%d %H:%M' 2>/dev/null ||:)" + cat <<EOF + <tr> + <td> + <a href="$(printf '%s' "$FULLNAME" | htmlesc)"> + $(printf '%s' "$FULLNAME" | htmlesc) + </a> + </td> + <td> + $(printf '%s' "$DESCRIPTION" | htmlesc) + </td> + <td> + $(printf '%s' "$last_commit_date" | htmlesc) + </td> + </tr> +EOF } print_index_footer() { - cat <<-EOF - </tbody> - </table> - </main> - <footer> - <hr /> - <p> - $MSG_ESCAPED_FOOTER_TEMPLATE - </p> - </footer> - </body> - </html> - EOF + cat <<EOF + </tbody> + </table> + </main> + <footer> + <hr /> + <p> + $(t "$MSG_ESCAPED_FOOTER_TEMPLATE") + </p> + </footer> + </body> +</html> +EOF +} + +imgs() { + DIR="$1" + mkdir -p "$DIR"/img/logo + print_logo black > "$DIR"/img/favicon.svg + print_logo black > "$DIR"/img/logo/light.svg + print_logo white > "$DIR"/img/logo/dark.svg + print_style > "$DIR"/style.css } index_write() { + mkdir -p "$OUTDIR" { print_index_header for r in "$@"; do @@ -469,40 +392,12 @@ index_write() { done print_index_footer } > "$OUTDIR/index.html" - - print_logo > "$OUTDIR/logo.svg" - print_style > "$OUTDIR/style.css" + imgs "$OUTDIR" } genlog() { if [ "$VERBOSE" = true ]; then - printf "$MSG_GENERATING_LOG\n" "$1" >&2 - fi -} - -parallel_n=0 -cached_run() { - TARGET_PATH="$1" - shift # drop $TARGET_PATH - shift # drop -- - - if [ -e "$OUTDIR/$TARGET_PATH" ]; then - return - fi - - if [ -e "$CACHE_DIR/$TARGET_PATH" ]; then - $CMD "$CACHE_DIR/$TARGET_PATH" "$OUTDIR/$TARGET_PATH" - else - { - genlog "$OUTDIR/$TARGET_PATH" - "$@" - $CMD "$CACHE_DIR/$TARGET_PATH" "$OUTDIR/$TARGET_PATH" - } & - parallel_n=$((parallel_n + 1)) - if [ "$parallel_n" = "$MAX_JOBS" ]; then - wait - parallel_n=0 - fi + : # printf "$MSXG_GENERATING_LOG\n" "$1" >&2 # FIXME fi } @@ -510,177 +405,159 @@ cached_run() { # exts() { } # FIXME: emit signatures code -TAB="$(printf '\t')" -repo_tarballs_write2() { +repo_tarballs_mk() { git branch --format '%(refname:lstrip=2)' | while read -r branch; do - cat <<-EOF - all: $OUTDIR/tarballs/$NAME-$branch.$EXT - - $OUTDIR/tarballs/$NAME-$branch.$EXT: $CACHE_DIR/tarballs/$NAME-$branch.$EXT - ${TAB}\$(LN) \$? \$@ - - $CACHE_DIR/tarballs/$NAME-$branch.$EXT: $CACHE_DIR/branch-revisions/$branch - ${TAB}git -C "$REPO" archive --prefix $NAME-$branch/ -o \$@ $branch + cat <<EOF +all: $OUTDIR/$FULLNAME/tarball/$NAME-$branch.$EXT - $CACHE_DIR/branch-revisions/$branch: ALWAYS - ${TAB}@git -C "$REPO" rev-parse $branch | ifnew \$@ +$OUTDIR/$FULLNAME/tarball/$NAME-$branch.$EXT: $REPO/refs/heads/$branch + env GIT_DIR="$REPO" git archive --prefix $NAME-$branch/ -o \$@ $branch - EOF +EOF done git tag | while read -r tag; do - cat <<-EOF - all: $OUTDIR/tarballs/$NAME-$tag.$EXT - - $OUTDIR/tarballs/$NAME-$tag.$EXT: $CACHE_DIR/tarballs/$NAME-$tag.$EXT - ${TAB}\$(LN) \$? \$@ + cat <<EOF +all: $OUTDIR/$FULLNAME/tarball/$NAME-$tag.$EXT - $CACHE_DIR/tarballs/$NAME-$tag.$EXT: - ${TAB}git -C "$REPO" archive --prefix $NAME-$tag/ -o \$@ $tag +$OUTDIR/$FULLNAME/tarball/$NAME-$tag.$EXT: $REPO/refs/tags/$tag + env GIT_DIR="$REPO" git archive --prefix $NAME-$tag/ -o \$@ $tag - EOF +EOF done } -repo_tarballs_write() { - repo="$1" - mkdir -p "$OUTDIR/tarballs" "$CACHE_DIR/tarballs" - local_parallel_n=0 - for branch in $(git branch --format '%(refname:lstrip=2)'); do - TARBALL_PATH="$OUTDIR/tarballs/$repo-$branch.tar.gz" - genlog "$TARBALL_PATH" - git archive --prefix "$repo-$branch/" "$branch" \ - -o "$TARBALL_PATH" & - local_parallel_n=$((local_parallel_n + 1)) - if [ "$local_parallel_n" = "$MAX_JOBS" ]; then - wait - local_parallel_n=0 - fi - done - wait - - for tag in $(git tag); do - TARBALL_PATH="tarballs/$repo-$tag.tar.gz" - cached_run "$TARBALL_PATH" -- \ - git archive --prefix "$repo-$tag/" "$tag" \ - -o "$CACHE_DIR/$TARBALL_PATH" - - SIGNATURE_PATH="tarballs/$repo-$tag.tar.gz.asc" - if git notes --ref=refs/notes/signatures/tar.gz show "$tag" \ - 1>/dev/null 2>&1; then - git notes --ref=refs/notes/signatures/tar.gz \ - show "$tag" > "$OUTDIR/$SIGNATURE_PATH" - fi - done +repo_commits_mk() { + git log --format='format:%H' | while read -r commit; do + cat <<EOF +all: $OUTDIR/$FULLNAME/commit/$commit.html - wait +$OUTDIR/$FULLNAME/commit/$commit.html: + $0 -u "$CLONE_URL" -x commit "$REPO" $commit > \$@ +EOF + done } -print_repo_refs2() { - cat <<-EOF - all: $OUTDIR/refs.html +repo_refs_mk() { + cat <<EOF +all: $OUTDIR/$FULLNAME/refs.html - $OUTDIR/refs.html: ALWAYS - ${TAB}$0 -x refs "$REPO" > \$@ +$OUTDIR/$FULLNAME/refs.html: $REPO/refs/heads/ $REPO/refs/tags/ + $0 -u "$CLONE_URL" -x refs "$REPO" > \$@ - EOF +EOF } +# FIXME: translate commits.xml and tags.xml + +print_clone_url() { + if [ -z "$CLONE_URL" ]; then + return + fi + + cat <<EOF + <code> + git clone $(printf '%s/%s' "$CLONE_URL" "$FULLNAME"/ | htmlesc) + </code> +EOF +} + exec_refs() { repo_vars "$1" - cat <<-EOF - <!DOCTYPE html> - <html lang="$(escape "$MSG_LANGNAME")"> - <head> - <meta charset="UTF-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1" /> - <meta name="description" content="$(escape "$DESCRIPTION")" /> - <link rel="icon" type="image/svg+xml" href="logo.svg" /> - <link rel="stylesheet" type="text/css" href="style.css" /> - <link rel="alternate" type="application/atom+xml" href="commits.xml" title="$(escape "$NAME") - $(escape "$MSG_COMMIT_FEED")" hreflang="$(escape "$MSG_LANGNAME")" /> - <link rel="alternate" type="application/atom+xml" href="tags.xml" title="$(escape "$NAME") - $(escape "$MSG_TAGS_FEED")" hreflang="$(escape "$MSG_LANGNAME")" /> - <title>$(escape "$NAME") - $(escape "$MSG_TITLE_REFS")</title> - </head> - <body> - <header> - <div class="header-horizontal-grouping"> - <a href="../"> - <img alt="$(escape "$MSG_LOGO_ALT_INDEX")" class="logo" src="logo.svg" /> - </a> - <div class="header-description"> - <h1> - <a href="./"> - $(escape "$NAME") - </a> - </h1> - <h2> - $(escape "$DESCRIPTION") - </h2> - <code> - git clone $(escape "$CLONE_URL") - </code> - </div> - </div> - <nav> - <ul> - <li> - <a href="./"> - $(escape "$MSG_NAV_FILES") - </a> - </li> - <li> - <a href="log/$(escape "$MAIN_BRANCH").html"> - $(escape "$MSG_NAV_LOG") - </a> - </li> - <li class="selected-nav-item"> - <a href="refs.html"> - $(escape "$MSG_NAV_REFS") - </a> - </li> - </ul> - </nav> - <hr /> - </header> - <main> - <table> - <thead> - <tr> - <th> - $(escape "$MSG_THEAD_BRANCH") - </th> - <th> - $(escape "$MSG_THEAD_COMMITMSG") - </th> - <th> - $(escape "$MSG_THEAD_AUTHOR") - </th> - <th> - $(escape "$MSG_THEAD_DATE") - </th> - </tr> - </thead> - <tbody> - EOF + cat <<EOF | sed '/^$/d' +<!DOCTYPE html> +<html lang="$LANGNAME"> + <head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="description" content="$(printf '%s' "$DESCRIPTION" | htmlesc)" /> + <link rel="icon" type="image/svg+xml" href="img/favicon.svg" /> + <link rel="stylesheet" type="text/css" href="style.css" /> + <link rel="alternate" type="application/atom+xml" href="commits.xml" title="$(printf '%s' "$NAME" | htmlesc) - $(t "$MSG_COMMIT_FEED")" hreflang="$LANGNAME" /> + <link rel="alternate" type="application/atom+xml" href="tags.xml" title="$(printf '%s' "$NAME" | htmlesc) - $(t "$MSG_TAGS_FEED")" hreflang="$LANGNAME" /> + <title>$(printf '%s' "$NAME" | htmlesc) - $(t "$MSG_TITLE_REFS")</title> + </head> + <body> + <header> + <div class="header-horizontal-grouping"> + <a href="../"> + <picture> + <source srcset="img/logo/dark.svg" media="(prefers-color-scheme: dark)" /> + <img src="img/logo/light.svg" alt="$(t "$MSG_LOGO_ALT_INDEX")" /> + </picture> + </a> + <div class="header-description"> + <h1> + <a href="./"> + $(printf '%s' "$NAME" | htmlesc) + </a> + </h1> + <h2> + $DESCRIPTION + </h2> +$(print_clone_url) + </div> + </div> + <nav> + <ul> + <li> + <a href="./"> + $(t "$MSG_NAV_FILES") + </a> + </li> + <li> + <a href="log/$(printf '%s' "$MAIN_BRANCH" | htmlesc).html"> + $(t "$MSG_NAV_LOG") + </a> + </li> + <li class="selected-nav-item"> + <a href="refs.html"> + $(t "$MSG_NAV_REFS") + </a> + </li> + </ul> + </nav> + <hr /> + </header> + <main> + <table> + <thead> + <tr> + <th> + $(t "$MSG_THEAD_BRANCH") + </th> + <th> + $(t "$MSG_THEAD_COMMITMSG") + </th> + <th> + $(t "$MSG_THEAD_AUTHOR") + </th> + <th> + $(t "$MSG_THEAD_DATE") + </th> + </tr> + </thead> + <tbody> +EOF for branch in $(git branch --format '%(refname:lstrip=2)'); do - sha="$(git rev-parse "$branch")" + commit="$(git rev-parse "$branch")" cat <<EOF <tr> <td> - <a href="log/$(escape "$branch").html"> - $(escape "$branch") + <a href="log/$(printf '%s' "$branch" | htmlesc).html"> + $(printf '%s' "$branch" | htmlesc) </a> </td> <td> - <a href="commit/$(escape "$sha").html"> - $(escape "$(git log -1 --format=%s "$sha")") + <a href="commit/$(printf '%s' "$commit" | htmlesc).html"> + $(printf '%s\n' "$(git log -1 --format=%s "$commit")" | htmlesc) </a> </td> <td> - $(escape "$(git log -1 --format=%an "$sha")") + $(printf '%s\n' "$(git log -1 --format=%an "$commit")" | htmlesc) </td> <td> - $(escape "$(git log -1 --format=%cd --date='format:%Y-%m:%d %H:%M' "$sha")") + $(printf '%s\n' "$(git log -1 --format=%cd --date='format:%Y-%m:%d %H:%M' "$commit")" | htmlesc) </td> </tr> EOF @@ -693,6 +570,7 @@ EOF PRINTED_TABLE_OPEN=false for tag in $(git tag | tac); do + commit="$(git rev-parse "$tag")" if [ "$PRINTED_TABLE_OPEN" = false ]; then PRINTED_TABLE_OPEN=true cat <<EOF @@ -700,13 +578,16 @@ EOF <thead> <tr> <th> - $(escape "$MSG_THEAD_TAG") + $(t "$MSG_THEAD_TAG") </th> + <th> + $(t "$MSG_THEAD_COMMITMSG") + </th> <th> - $(escape "$MSG_THEAD_AUTHOR") + $(t "$MSG_THEAD_AUTHOR") </th> <th> - $(escape "$MSG_THEAD_DATE") + $(t "$MSG_THEAD_DATE") </th> </tr> </thead> @@ -714,26 +595,32 @@ EOF EOF fi - if [ -e "$CACHE_DIR/tarballs/$repo-$tag.tar.gz.asc" ]; then - tarball_link="(<a href=\"tarballs/$(escape "$repo")-$(escape "$tag").tar.gz\">tarball</a>, - <a href=\"tarballs/$(escape "$repo")-$(escape "$tag").tar.gz.asc\">sig</a>)" + if false && [ -e "$CACHE_DIR/tarball/$repo-$tag.$EXT.asc" ]; then + tarball_link="(<a href=\"tarballs/$(printf '%s' "$repo" | htmlesc)-$(printf '%s' "$tag" | htmlesc).$EXT\">tarball</a>, + <a href=\"tarballs/$(printf '%s' "$repo" | htmlesc)-$(printf '%s' "$tag" | htmlesc).$EXT.asc\">sig</a>)" else - tarball_link="(<a href=\"tarballs/$(escape "$repo")-$(escape "$tag").tar.gz\">tarball</a>)" + tarball_link="(<a href=\"tarballs/$(printf '%s' "$FULLNAME" | htmlesc)-$(printf '%s' "$tag" | htmlesc).$EXT\">tarball</a>)" fi + # FIXME: translate tag/ cat <<EOF <tr> <td> - <a href="tag/$(escape "$tag").html"> - $(escape "$tag") + <a href="tag/$(printf '%s' "$tag" | htmlesc).html"> + $(printf '%s' "$tag" | htmlesc) </a> $tarball_link </td> <td> - $(escape "$(git log -1 --format=%an "$tag")") + <a href="commit/$(printf '%s' "$commit" | htmlesc).html"> + $(printf '%s\n' "$(git log -1 --format=%s "$commit")" | htmlesc) + </a> + </td> + <td> + $(printf '%s\n' "$(git log -1 --format=%an "$tag")" | htmlesc) </td> <td> - $(escape "$(git log -1 --format=%cd --date='format:%Y-%m:%d %H:%M' "$tag")") + $(printf '%s\n' "$(git log -1 --format=%cd --date='format:%Y-%m:%d %H:%M' "$tag")" | htmlesc) </td> </tr> EOF @@ -751,7 +638,7 @@ EOF <footer> <hr /> <p> - $MSG_ESCAPED_FOOTER_TEMPLATE + $(t "$MSG_ESCAPED_FOOTER_TEMPLATE") </p> </footer> </body> @@ -759,174 +646,77 @@ EOF EOF } -print_repo_refs() { - repo="$1" - description="$2" - cat <<EOF +exec_commit() { + repo_vars "$1" + commit="$2" + previous_commit="$(git rev-parse "$commit^" 2>/dev/null ||:)" + subject="$(git log -1 --format='%s')" + cat <<EOF | sed '/^$/d' <!DOCTYPE html> -<html lang="$(escape "$MSG_LANGNAME")"> +<html lang="$LANGNAME"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <meta name="description" content="$(escape "$description")" /> - <link rel="icon" type="image/svg+xml" href="logo.svg" /> - <link rel="stylesheet" type="text/css" href="style.css" /> - <link rel="alternate" type="application/atom+xml" href="commits.xml" title="$(escape "$repo") - $(escape "$MSG_COMMIT_FEED")" hreflang="$(escape "$MSG_LANGNAME")" /> - <link rel="alternate" type="application/atom+xml" href="tags.xml" title="$(escape "$repo") - $(escape "$MSG_TAGS_FEED")" hreflang="$(escape "$MSG_LANGNAME")" /> - <title>$(escape "$repo") - $(escape "$MSG_TITLE_REFS")</title> + <meta name="description" content="$(printf '%s' "$DESCRIPTION" | htmlesc)" /> + <link rel="icon" type="image/svg+xml" href="../img/favicon.svg" /> + <link rel="stylesheet" type="text/css" href="../style.css" /> + <link rel="alternate" type="application/atom+xml" href="../commits.xml" title="$(printf '%s' "$NAME" | htmlesc) - $(t "$MSG_COMMIT_FEED")" hreflang="$LANGNAME" /> + <link rel="alternate" type="application/atom+xml" href="../tags.xml" title="$(printf '%s' "$NAME" | htmlesc) - $(t "$MSG_TAGS_FEED")" hreflang="$LANGNAME" /> + <title>$(printf '%s@%s - %s' "$NAME" "$commit" "$subject" | htmlesc)</title> </head> <body> <header> <div class="header-horizontal-grouping"> - <a href="../"> - <img alt="$(escape "$MSG_LOGO_ALT_INDEX")" class="logo" src="logo.svg" /> - </a> - <div class="header-description"> - <h1> - <a href="./"> - $(escape "$repo") - </a> - </h1> - <h2> - $(escape "$description") - </h2> - <code> - git clone $(escape "$CLONE_URL") - </code> - </div> + <a href="../../"> + <picture> + <source srcset="../img/logo/dark.svg" media="(prefers-color-scheme: dark)" /> + <img src="../img/logo/light.svg" alt="$(t "$MSG_LOGO_ALT_INDEX")" /> + </picture> + </a> + <div class="header-description"> + <h1> + <a href="../"> + $(printf '%s' "$NAME" | htmlesc) + </a> + </h1> + <h2> + $(printf '%s' "$DESCRIPTION" | htmlesc) + </h2> +$(print_clone_url) + </div> </div> <nav> - <ul> - <li> - <a href="./"> - $(escape "$MSG_NAV_FILES") - </a> - </li> - <li> - <a href="log/$(escape "$MAIN_BRANCH").html"> - $(escape "$MSG_NAV_LOG") - </a> - </li> - <li class="selected-nav-item"> - <a href="refs.html"> - $(escape "$MSG_NAV_REFS") - </a> - </li> - </ul> + <ul> + <li> + <a href="./"> + $(t "$MSG_NAV_FILES") + </a> + </li> + <li> + <a href="log/$(printf '%s' "$MAIN_BRANCH" | htmlesc).html"> + $(t "$MSG_NAV_LOG") + </a> + </li> + <li> + <a href="refs.html"> + $(t "$MSG_NAV_REFS") + </a> + </li> + </ul> </nav> <hr /> </header> <main> - <table> - <thead> - <tr> - <th> - $(escape "$MSG_THEAD_BRANCH") - </th> - <th> - $(escape "$MSG_THEAD_COMMITMSG") - </th> - <th> - $(escape "$MSG_THEAD_AUTHOR") - </th> - <th> - $(escape "$MSG_THEAD_DATE") - </th> - </tr> - </thead> - <tbody> EOF - for branch in $(git branch --format '%(refname:lstrip=2)'); do - sha="$(git rev-parse "$branch")" - cat <<EOF - <tr> - <td> - <a href="log/$(escape "$branch").html"> - $(escape "$branch") - </a> - </td> - <td> - <a href="commit/$(escape "$sha").html"> - $(escape "$(git log -1 --format=%s "$sha")") - </a> - </td> - <td> - $(escape "$(git log -1 --format=%an "$sha")") - </td> - <td> - $(escape "$(git log -1 --format=%cd --date='format:%Y-%m:%d %H:%M' "$sha")") - </td> - </tr> -EOF - done - - cat <<EOF - </tbody> - </table> -EOF - PRINTED_TABLE_OPEN=false - - for tag in $(git tag | tac); do - if [ "$PRINTED_TABLE_OPEN" = false ]; then - PRINTED_TABLE_OPEN=true - cat <<EOF - <table> - <thead> - <tr> - <th> - $(escape "$MSG_THEAD_TAG") - </th> - <th> - $(escape "$MSG_THEAD_AUTHOR") - </th> - <th> - $(escape "$MSG_THEAD_DATE") - </th> - </tr> - </thead> - <tbody> -EOF - fi - - if [ -e "$CACHE_DIR/tarballs/$repo-$tag.tar.gz.asc" ]; then - tarball_link="(<a href=\"tarballs/$(escape "$repo")-$(escape "$tag").tar.gz\">tarball</a>, - <a href=\"tarballs/$(escape "$repo")-$(escape "$tag").tar.gz.asc\">sig</a>)" - else - tarball_link="(<a href=\"tarballs/$(escape "$repo")-$(escape "$tag").tar.gz\">tarball</a>)" - fi - - cat <<EOF - <tr> - <td> - <a href="tag/$(escape "$tag").html"> - $(escape "$tag") - </a> - $tarball_link - </td> - <td> - $(escape "$(git log -1 --format=%an "$tag")") - </td> - <td> - $(escape "$(git log -1 --format=%cd --date='format:%Y-%m:%d %H:%M' "$tag")") - </td> - </tr> -EOF - done - - if [ "$PRINTED_TABLE_OPEN" = true ]; then - cat <<EOF - </tbody> - </table> -EOF - fi + print_formatted_diff "$commit" "$previous_commit" cat <<EOF </main> <footer> <hr /> <p> - $MSG_ESCAPED_FOOTER_TEMPLATE + $(t "$MSG_ESCAPED_FOOTER_TEMPLATE") </p> </footer> </body> @@ -935,12 +725,13 @@ EOF } print_formatted_diff() { - sha="$1" - previous_sha="$2" + commit="$1" + previous_commit="$2" printf '<pre class="pre-wrapping">' # git show -p --stat "$sha" - escape "$(git show -p "$sha")" | awk \ - -v SHA="$sha" -v PREVIOUS_SHA="$previous_sha" ' + # FIXME: translate tree/ + git show -p --full-index "$commit" | htmlesc | awk \ + -v COMMIT="$commit" -v PREVIOUS_COMMIT="$previous_commit" ' BEGIN { diff_init = 0 diffl = 0 @@ -955,14 +746,14 @@ print_formatted_diff() { diff_init == 1 && /^--- a\// { fname = substr($0, 7) printf "--- a/<a href=\"../tree/%s/%s.html\">%s</a>\n", - PREVIOUS_SHA, fname, fname + PREVIOUS_COMMIT, fname, fname next } diff_init == 1 && /^\+\+\+ b\// { fname = substr($0, 7) printf "--- b/<a href=\"../tree/%s/%s.html\">%s</a>\n", - SHA, fname, fname + COMMIT, fname, fname next } @@ -982,501 +773,66 @@ print_formatted_diff() { next } - { - print $0 - } + { print $0 } ' printf '</pre>\n' } -print_repo_commit_page() { - repo="$1" - description="$2" - sha="$3" - previous_sha="$(git rev-parse "$sha^" 2>/dev/null ||:)" - summary="$(git log -1 --format=%B "$sha")" +preamble_mk() { cat <<EOF -<!DOCTYPE html> -<html lang="$(escape "$MSG_LANGNAME")"> - <head> - <meta charset="UTF-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1" /> - <meta name="description" content="$(escape "$description")" /> - <link rel="icon" type="image/svg+xml" href="../logo.svg" /> - <link rel="stylesheet" type="text/css" href="../style.css" /> - <link rel="alternate" type="application/atom+xml" href="../commits.xml" title="$(escape "$repo") - $(escape "$MSG_COMMIT_FEED")" hreflang="$(escape "$MSG_LANGNAME")" /> - <link rel="alternate" type="application/atom+xml" href="../tags.xml" title="$(escape "$repo") - $(escape "$MSG_TAGS_FEED")" hreflang="$(escape "$MSG_LANGNAME")" /> - <title>$(escape "$repo")@$(escape "$sha") - $(escape "$summary")</title> - </head> - <body> - <header> - <div class="header-horizontal-grouping"> - <a href="../../"> - <img alt="$(escape "$MSG_LOGO_ALT_REPOSITORY")" class="logo" src="../logo.svg" /> - </a> - <div class="header-description"> - <h1> - <a href="../"> - $(escape "$repo") - </a> - </h1> - <h2> - $(escape "$description") - </h2> - <code> - git clone $(escape "$CLONE_URL") - </code> - </div> - </div> - <nav> - <ul> - <li> - <a href="../"> - $(escape "$MSG_NAV_FILES") - </a> - </li> - <li> - <a href="../log/$(escape "$MAIN_BRANCH").html"> - $(escape "$MSG_NAV_LOG") - </a> - </li> - <li> - <a href="../refs.html"> - $(escape "$MSG_NAV_REFS") - </a> - </li> - </ul> - </nav> - <hr /> - </header> - <main> -$(print_formatted_diff "$sha" "$previous_sha") - </main> - <footer> - <hr /> - <p> - $MSG_ESCAPED_FOOTER_TEMPLATE - </p> - </footer> - </body> -</html> -EOF -} +.POSIX: -repo_commits_write() { - repo="$1" - description="$2" - mkdir -p "$OUTDIR/commit" "$CACHE_DIR/commit" - for branch in $(git branch --format '%(refname:lstrip=2)'); do - for commit in $(git rev-list "$branch"); do - COMMIT_PATH="commit/$commit.html" +all: +ALWAYS: - if [ -e "$OUTDIR/$COMMIT_PATH" ]; then - # Assume all previous history exists, too - break - fi - cached_run "$COMMIT_PATH" -- \ - eval "print_repo_commit_page '$repo' '$description' '$commit' \ - > '$CACHE_DIR/$COMMIT_PATH'" - done - done - - wait +EOF } -NEWLINE="$(printf '\n')" -print_repo_log_page() { - repo="$1" - description="$2" - newer_page_name="$3" - older_page_name="$4" - shift - shift - shift - shift - - title='FIXME' - - if [ -z "$newer_page_name" ]; then - escaped_newer_page_link='' - else - escaped_newer_page_link=" <a href=\"$(escape "$newer_page_name")\">newer FIXME i18n</a>"' -' - fi +repo_vars() { + REPO="$1" - if [ -z "$older_page_name" ]; then - escaped_older_page_link='' - else - escaped_older_page_link=" <a href=\"$(escape "$older_page_name")\">older FIXME i18n</a>"' -' - fi + unset GIT_DIR + GIT_DIR="$REPO"/"$(git -C "$REPO" rev-parse --git-dir)" + GIT_DIR="$(realpath --relative-to=. "$GIT_DIR")" + export GIT_DIR - if [ -n "$newer_page_name" ] || [ -n "$older_page_name" ]; then - escaped_pagination_open=' <section class="log-pagination"> -' - escaped_pagination_close=' </section> -' - else - escaped_pagination_open='' - escaped_pagination_close='' - fi + is_bare="$(git rev-parse --is-bare-repository)" - if [ -n "$newer_page_name" ] && [ -n "$older_page_name" ]; then - escaped_pagination_separator=' | -' + NAME="$(realpath --relative-to=. "$REPO")" + if [ "$is_bare" = false ] && [ "$NAME" = "$GIT_DIR" ]; then + NAME="$(dirname -- "$NAME")" else - escaped_pagination_separator='' + NAME="${NAME%.git}" fi + FULLNAME="$NAME" + NAME="$(basename -- "$NAME")" - cat <<EOF -<!DOCTYPE html> -<html lang="$(escape "$MSG_LANGNAME")"> - <head> - <meta charset="UTF-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1" /> - <meta name="description" content="$(escape "$description")" /> - <link rel="icon" type="image/svg+xml" href="../logo.svg" /> - <link rel="stylesheet" type="text/css" href="../style.css" /> - <link rel="alternate" type="application/atom+xml" href="../commits.xml" title="$(escape "$repo") - $(escape "$MSG_COMMIT_FEED")" hreflang="$(escape "$MSG_LANGNAME")" /> - <link rel="alternate" type="application/atom+xml" href="../tags.xml" title="$(escape "$repo") - $(escape "$MSG_TAGS_FEED")" hreflang="$(escape "$MSG_LANGNAME")" /> - <title>$(escape "$repo") - $(escape "$title")</title> - </head> - <body> - <header> - <div class="header-horizontal-grouping"> - <a href="../../"> - <img alt="$(escape "$MSG_LOGO_ALT_INDEX")" class="logo" src="../logo.svg" /> - </a> - <div class="header-description"> - <h1> - <a href="../"> - $(escape "$repo") - </a> - </h1> - <h2> - $(escape "$description") - </h2> - <code> - git clone $(escape "$CLONE_URL") - </code> - </div> - </div> - <nav> - <ul> - <li> - <a href="../"> - $(escape "$MSG_NAV_FILES") - </a> - </li> - <li class="selected-nav-item"> - <a href="../log/$(escape "$MAIN_BRANCH").html"> - $(escape "$MSG_NAV_LOG") - </a> - </li> - <li> - <a href="../refs.html"> - $(escape "$MSG_NAV_REFS") - </a> - </li> - </ul> - </nav> - <hr /> - </header> - <main> -EOF - - for commit in "$@"; do - body_txt="$(git log -1 --format=%b "$commit")" - if [ "$body_txt" = "$NEWLINE" ]; then - body='' - else - body=" - -$body_txt" - fi - - notes_txt="$(git log -1 --format=%N "$commit")" - - if [ "$notes_txt" = "$NEWLINE" ]; then - escaped_notes='' - else - escaped_notes=" - <pre class=\"pre-wrapping log-notes\">$(escape "$notes_txt")</pre>" - fi - - # FIXME: show if commit is in branch, tag or HEAD - # <a href="#" class="log-commit-tag log-head-highlight">HEAD</a> - # <a href="#" class="log-commit-tag log-branch-highlight">main</a> - # <a href="#" class="log-commit-tag log-tag-highlight">v0.2.1</a> - - cat <<EOF - <section class="log-commit-box"> - <p> - <a href="../commit/$(escape "$commit").html">$(escape "$commit")</a> - | - $(escape "$(git log -1 --format=%an "$commit")") - </p> - <pre class="pre-wrapping"><strong>$(escape "$(git log -1 --format=%s "$commit")")</strong>$(escape "$body")</pre>$escaped_notes - </section> -EOF - done - - cat <<EOF -$escaped_pagination_open$escaped_newer_page_link$escaped_pagination_separator$escaped_older_page_link$escaped_pagination_close </main> - <footer> - <hr /> - <p> - $MSG_ESCAPED_FOOTER_TEMPLATE - </p> - </footer> - </body> -</html> -EOF -} - -# FIXME: use log/main/1.html over diffs? -LOG_PAGE_MAX=50 -repo_log_write() { - repo="$1" - description="$2" - mkdir -p "$OUTDIR/log" "$CACHE_DIR/log" - for ref in $(git branch --format '%(refname:lstrip=2)') $(git tag); do - # FIXME: add bail out of loop when the first page already - # exists, so nothing after that needs to be ran - - mkdir -p "$CACHE_DIR/log_tmp/$ref" - PAGE_SIZE=0 - PAGE_INDEX=0 - for commit in $(git rev-list "$ref" | tac); do - if [ "$PAGE_SIZE" = 0 ]; then - FIRST="$commit" - fi - LAST="$commit" - PAGE_NAME="$FIRST..$LAST.html" - PAGE_SIZE=$((PAGE_SIZE + 1)) - - if [ "$PAGE_SIZE" != "$LOG_PAGE_MAX" ]; then - continue - fi - - echo "$PAGE_NAME" > "$CACHE_DIR/log_tmp/$ref/$PAGE_INDEX" - - PAGE_INDEX=$((PAGE_INDEX + 1)) - PAGE_SIZE=0 - done - if [ "$PAGE_SIZE" != 0 ]; then - echo "$PAGE_NAME" > "$CACHE_DIR/log_tmp/$ref/$PAGE_INDEX" - fi - - PAGE_COMMITS='' - PAGE_SIZE=0 - PAGE_INDEX=0 - for commit in $(git rev-list "$ref" | tac); do - PAGE_COMMITS="$commit $PAGE_COMMITS" - PAGE_SIZE=$((PAGE_SIZE + 1)) - - if [ "$PAGE_SIZE" != "$LOG_PAGE_MAX" ]; then - continue - fi - - # FIXME: 80 columns - NEWER_PAGE_NAME="$(cat "$CACHE_DIR/log_tmp/$ref/$((PAGE_INDEX + 1))" 2>/dev/null ||:)" - CURRT_PAGE_NAME="$(cat "$CACHE_DIR/log_tmp/$ref/$((PAGE_INDEX + 0))" 2>/dev/null ||:)" - OLDER_PAGE_NAME="$(cat "$CACHE_DIR/log_tmp/$ref/$((PAGE_INDEX - 1))" 2>/dev/null ||:)" - PAGE_PATH="log/$CURRT_PAGE_NAME" - - cached_run "$PAGE_PATH" -- eval "print_repo_log_page \ - '$repo' '$description' \ - '$NEWER_PAGE_NAME' '$OLDER_PAGE_NAME' \ - $PAGE_COMMITS \ - > '$CACHE_DIR/$PAGE_PATH'" - PAGE_COMMITS='' - PAGE_SIZE=0 - PAGE_INDEX=$((PAGE_INDEX + 1)) - done - if [ "$PAGE_SIZE" != 0 ]; then - # FIXME: 80 columns - NEWER_PAGE_NAME="$(cat "$CACHE_DIR/log_tmp/$ref/$((PAGE_INDEX + 1))" 2>/dev/null ||:)" - CURRT_PAGE_NAME="$(cat "$CACHE_DIR/log_tmp/$ref/$((PAGE_INDEX + 0))" 2>/dev/null ||:)" - OLDER_PAGE_NAME="$(cat "$CACHE_DIR/log_tmp/$ref/$((PAGE_INDEX - 1))" 2>/dev/null ||:)" - PAGE_PATH="log/$CURRT_PAGE_NAME" - - cached_run "$PAGE_PATH" -- eval "print_repo_log_page \ - '$repo' '$description' \ - '$NEWER_PAGE_NAME' '$OLDER_PAGE_NAME' \ - $PAGE_COMMITS \ - > '$CACHE_DIR/$PAGE_PATH'" - fi - ln -fs "$CURRT_PAGE_NAME" "$OUTDIR/log/$ref.html" - done - rm -rf "$CACHE_DIR/log_tmp" - - wait -} - -print_repo_index_page() { - repo="$1" - description="$2" - - cat <<EOF -<!DOCTYPE html> -<html lang="$(escape "$MSG_LANGNAME")"> - <head> - <meta charset="UTF-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1" /> - <meta name="description" content="$(escape "$description")" /> - <link rel="icon" type="image/svg+xml" href="log.svg" /> - <link rel="stylesheet" type="text/css" href="style.css" /> - <link rel="alternate" type="application/atom+xml" href="commits.xml" title="$(escape "$repo") - $(escape "$MSG_COMMIT_FEED")" hreflang="$(escape "$MSG_LANGNAME")" /> - <link rel="alternate" type="application/atom+xml" href="tags.xml" title="$(escape "$repo") - $(escape "$MSG_TAGS_FEED")" hreflang="$(escape "$MSG_LANGNAME")" /> - <title>$(escape "$repo") - FIXME</title> - </head> - <body> - <header> - <div class="header-horizontal-grouping"> - <a href="../"> - <img alt="$(escape "$MSG_LOGO_ALT_INDEX")" class="logo" src="logo.svg" /> - </a> - <div class="header-description"> - <h1> - <a href="./"> - $(escape "$repo") - </a> - </h1> - <h2> - $(escape "$description") - </h2> - <code> - git clone <a href="$(escape "$CLONE_URL")">$(escape "$CLONE_URL")</a> - </code> - </div> - </div> - <nav> - <ul> - <li class="selected-nav-item"> - <a href="./"> - $(escape "$MSG_NAV_FILES") - </a> - </li> - <li> - <a href="log/$(escape "$MAIN_BRANCH").html"> - $(escape "$MSG_NAV_LOG") - </a> - </li> - <li> - <a href="refs.html"> - $(escape "$MSG_NAV_REFS") - </a> - </li> - </ul> - </nav> - <hr /> - </header> - <main> - <section> - Os arquivos vão aqui. - </section> - <section> - O README vai aqui. - </section> - </main> - <footer> - <hr /> - <p> - $MSG_ESCAPED_FOOTER_TEMPLATE - </p> - </footer> - </body> -</html> -EOF -} - -repo_trees_write() { - echo -} - -preamble() { - cat <<-EOF - .POSIX: - - LN = $CMD - - default: all - - ALWAYS: - - - EOF -} - -repo_vars() { - EXT=tar.xz - REPO_DIR="${1%/}" - REPO="${1%/}" # FIXME: shesc - NAME="$(basename "$REPO" .git)" - CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/gistatic/$NAME" - GIT_DIR="$REPO/$(git -C "$REPO" rev-parse --git-dir)" - export GIT_DIR + EXT=tar.gz DESCRIPTION="$(cat "$GIT_DIR"/description 2>/dev/null ||:)" } -repo_write2() { - repo_vars "$1" +repo_write() { + path="$1" + repo_vars "$path" mkdir -p \ - "$OUTDIR"/tarballs \ - "$CACHE_DIR"/tarballs \ - "$CACHE_DIR"/branch-revisions - { - preamble - repo_tarballs_write2 - print_repo_refs2 - } | tee f | make -f- -} + "$OUTDIR"/"$FULLNAME"/commit \ + "$OUTDIR"/"$FULLNAME"/tarball \ -repo_write() { - cd "$1" - # FIXME: use $REPO and $DESCRIPTION - repo="$(basename "$(realpath "${1%.git}")")" - description="$(cat "$1/description" 2>/dev/null ||:)" - CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/gistatic/$repo" - - repo_tarballs_write "$repo" - print_repo_refs "$repo" "$description" > "$OUTDIR/refs.html" - repo_commits_write "$repo" "$description" - repo_log_write "$repo" "$description" - print_repo_index_page "$repo" "$description" > "$OUTDIR/index.html" - repo_trees_write "$repo" "$description" - - cd - > /dev/null + { + preamble_mk + repo_tarballs_mk + repo_commits_mk + repo_refs_mk + } | tee f | (unset GIT_DIR; make -f- -j`nproc`) + imgs "$OUTDIR"/"$FULLNAME" } -for flag in "$@"; do - case "$flag" in - --) - break - ;; - --help) - usage - help - exit - ;; - --version) - version - exit - ;; - *) - ;; - esac -done - VERBOSE=true INDEX=false -TITLE="$MSG_DEFAULT_TITLE" -OUTDIR= +OUTDIR=. CLONE_URL= -CACHE_DIR= MAX_JOBS=1 MAIN_BRANCH='main' MAIN_BRANCH_SET=false @@ -1484,46 +840,34 @@ REPO= DESCRIPTION= CMD='ln' EXEC= -while getopts 'b:o:t:u:j:isqx:hV' flag; do +while getopts 'b:o:u:j:isqx:' flag; do case "$flag" in - b) + (b) MAIN_BRANCH="$OPTARG" MAIN_BRANCH_SET=true ;; - o) - OUTDIR="$(realpath "$OPTARG")" - ;; - t) - TITLE="$OPTARG" + (o) + OUTDIR="$OPTARG" ;; - u) + (u) CLONE_URL="$OPTARG" ;; - j) + (j) MAX_JOBS="$OPTARG" ;; - i) + (i) INDEX=true ;; - q) + (q) VERBOSE=false ;; - s) + (s) CMD='ln -s' ;; - x) + (x) EXEC="$OPTARG" ;; - h) - usage - help - exit - ;; - V) - version - exit - ;; - *) + (*) usage >&2 exit 2 ;; @@ -1531,25 +875,17 @@ while getopts 'b:o:t:u:j:isqx:hV' flag; do done shift $((OPTIND - 1)) -assert_arg() { - if [ -z "$1" ]; then - printf "$MSG_MISSING_CLIARG\n\n" "$2" >&2 - usage >&2 - exit 2 - fi -} - if [ -n "$EXEC" ]; then "exec_$EXEC" "$@" exit fi -assert_arg "$OUTDIR" '-o DIRECTORY' +if false; then if [ "$INDEX" = false ]; then assert_arg "$CLONE_URL" '-u CLONE_URL' elif [ -n "$CLONE_URL" ] || [ "$MAIN_BRANCH_SET" = true ]; then { - printf '%s' "$MSG_INCOMPATIBLE_OPTIONS" + printf '%s' "$MSG_INCOMPATIBLE_OPTIONS" # FIXME printf -- '-i' if [ -n "$CLONE_URL" ]; then printf -- ' -u' @@ -1563,14 +899,19 @@ elif [ -n "$CLONE_URL" ] || [ "$MAIN_BRANCH_SET" = true ]; then } >&2 exit 2 fi +fi -assert_arg "${1:-}" "$MSG_MISSING_ARGS" - -mkdir -p "$OUTDIR" +eval "$(assert-arg "${1:-}" "$MSG_MISSING_ARGS")" # FIXME +if false; then if [ "$INDEX" = true ]; then index_write "$@" else - # repo_write "$1" - repo_write2 "$1" + repo_write "$1" fi +fi + +index_write "$@" +for path in "$@"; do + repo_write "$path" +done diff --git a/tests/resources/repositories/repo-1/.gitdir/description b/tests/resources/repositories/repo-1/.gitdir/description index 498b267..fcb0f49 100644 --- a/tests/resources/repositories/repo-1/.gitdir/description +++ b/tests/resources/repositories/repo-1/.gitdir/description @@ -1 +1 @@ -Unnamed repository; edit this file 'description' to name the repository. +The first example repository. |