#!/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 gistatic .'
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
"
}
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
#
# Utilities
#
tac() {
sed '1!G;h;$!d'
}
escape() {
printf '%s' "$1" |
sed \
-e 's|&|\&|g' \
-e 's|<|\<|g' \
-e 's|>|\>|g' \
-e 's|"|\"|g' \
-e "s|'|\'|g"
}
realpath() {
mkdir -p "$1"
cd "$1"
pwd
}
#
# Documentation functions
#
usage() {
printf '%s\n' "$MSG_USAGE"
}
help() {
printf '%s\n' "$MSG_HELP"
}
version() {
printf 'gistatic-0.1.0 1970-01-01\n'
}
#
# Template strings
#
print_logo() {
cat <<-'EOF'
EOF
}
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
}
print_index_header() {
cat <<-EOF
$(escape "$TITLE")
$(escape "$MSG_NAME")
$(escape "$MSG_DESCRIPTION")
$(escape "$MSG_LAST_COMMIT")
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
$(escape "$repo")
$(escape "$description")
$(escape "$last_commit_date")
EOF
}
print_index_footer() {
cat <<-EOF
EOF
}
index_write() {
{
print_index_header
for r in "$@"; do
print_index_row "$r"
done
print_index_footer
} > "$OUTDIR/index.html"
print_logo > "$OUTDIR/logo.svg"
print_style > "$OUTDIR/style.css"
}
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
fi
}
# FIXME: get from config?
# exts() { }
# FIXME: emit signatures code
TAB="$(printf '\t')"
repo_tarballs_write2() {
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
$CACHE_DIR/branch-revisions/$branch: ALWAYS
${TAB}@git -C "$REPO" rev-parse $branch | ifnew \$@
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) \$? \$@
$CACHE_DIR/tarballs/$NAME-$tag.$EXT:
${TAB}git -C "$REPO" archive --prefix $NAME-$tag/ -o \$@ $tag
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
wait
}
print_repo_refs2() {
cat <<-EOF
all: $OUTDIR/refs.html
$OUTDIR/refs.html: ALWAYS
${TAB}$0 -x refs "$REPO" > \$@
EOF
}
exec_refs() {
repo_vars "$1"
cat <<-EOF
$(escape "$NAME") - $(escape "$MSG_TITLE_REFS")
$(escape "$MSG_THEAD_BRANCH")
$(escape "$MSG_THEAD_COMMITMSG")
$(escape "$MSG_THEAD_AUTHOR")
$(escape "$MSG_THEAD_DATE")
EOF
for branch in $(git branch --format '%(refname:lstrip=2)'); do
sha="$(git rev-parse "$branch")"
cat <
$(escape "$branch")
$(escape "$(git log -1 --format=%s "$sha")")
$(escape "$(git log -1 --format=%an "$sha")")
$(escape "$(git log -1 --format=%cd --date='format:%Y-%m:%d %H:%M' "$sha")")
EOF
done
cat <
EOF
PRINTED_TABLE_OPEN=false
for tag in $(git tag | tac); do
if [ "$PRINTED_TABLE_OPEN" = false ]; then
PRINTED_TABLE_OPEN=true
cat <
$(escape "$MSG_THEAD_TAG")
$(escape "$MSG_THEAD_AUTHOR")
$(escape "$MSG_THEAD_DATE")
EOF
fi
if [ -e "$CACHE_DIR/tarballs/$repo-$tag.tar.gz.asc" ]; then
tarball_link="(tarball ,
sig )"
else
tarball_link="(tarball )"
fi
cat <
$(escape "$tag")
$tarball_link
$(escape "$(git log -1 --format=%an "$tag")")
$(escape "$(git log -1 --format=%cd --date='format:%Y-%m:%d %H:%M' "$tag")")
EOF
done
if [ "$PRINTED_TABLE_OPEN" = true ]; then
cat <
EOF
fi
cat <
EOF
}
print_repo_refs() {
repo="$1"
description="$2"
cat <
$(escape "$repo") - $(escape "$MSG_TITLE_REFS")
$(escape "$MSG_THEAD_BRANCH")
$(escape "$MSG_THEAD_COMMITMSG")
$(escape "$MSG_THEAD_AUTHOR")
$(escape "$MSG_THEAD_DATE")
EOF
for branch in $(git branch --format '%(refname:lstrip=2)'); do
sha="$(git rev-parse "$branch")"
cat <
$(escape "$branch")
$(escape "$(git log -1 --format=%s "$sha")")
$(escape "$(git log -1 --format=%an "$sha")")
$(escape "$(git log -1 --format=%cd --date='format:%Y-%m:%d %H:%M' "$sha")")
EOF
done
cat <
EOF
PRINTED_TABLE_OPEN=false
for tag in $(git tag | tac); do
if [ "$PRINTED_TABLE_OPEN" = false ]; then
PRINTED_TABLE_OPEN=true
cat <
$(escape "$MSG_THEAD_TAG")
$(escape "$MSG_THEAD_AUTHOR")
$(escape "$MSG_THEAD_DATE")
EOF
fi
if [ -e "$CACHE_DIR/tarballs/$repo-$tag.tar.gz.asc" ]; then
tarball_link="(tarball ,
sig )"
else
tarball_link="(tarball )"
fi
cat <
$(escape "$tag")
$tarball_link
$(escape "$(git log -1 --format=%an "$tag")")
$(escape "$(git log -1 --format=%cd --date='format:%Y-%m:%d %H:%M' "$tag")")
EOF
done
if [ "$PRINTED_TABLE_OPEN" = true ]; then
cat <
EOF
fi
cat <
EOF
}
print_formatted_diff() {
sha="$1"
previous_sha="$2"
printf ''
# git show -p --stat "$sha"
escape "$(git show -p "$sha")" | awk \
-v SHA="$sha" -v PREVIOUS_SHA="$previous_sha" '
BEGIN {
diff_init = 0
diffl = 0
}
/^(diff|index) / {
diff_init = 1
print $0
next
}
diff_init == 1 && /^--- a\// {
fname = substr($0, 7)
printf "--- a/%s \n",
PREVIOUS_SHA, fname, fname
next
}
diff_init == 1 && /^\+\+\+ b\// {
fname = substr($0, 7)
printf "--- b/%s \n",
SHA, fname, fname
next
}
{ diff_init = 0 }
/^-/ {
diffl++
printf "%s \n",
diffl, diffl, $0
next
}
/^\+/ {
diffl++
printf "%s \n",
diffl, diffl, $0
next
}
{
print $0
}
'
printf ' \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")"
cat <
$(escape "$repo")@$(escape "$sha") - $(escape "$summary")
$(print_formatted_diff "$sha" "$previous_sha")
EOF
}
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"
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
}
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=" newer FIXME i18n "'
'
fi
if [ -z "$older_page_name" ]; then
escaped_older_page_link=''
else
escaped_older_page_link=" older FIXME i18n "'
'
fi
if [ -n "$newer_page_name" ] || [ -n "$older_page_name" ]; then
escaped_pagination_open='
'
else
escaped_pagination_open=''
escaped_pagination_close=''
fi
if [ -n "$newer_page_name" ] && [ -n "$older_page_name" ]; then
escaped_pagination_separator=' |
'
else
escaped_pagination_separator=''
fi
cat <
$(escape "$repo") - $(escape "$title")
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="
$(escape "$notes_txt") "
fi
# FIXME: show if commit is in branch, tag or HEAD
# HEAD
# main
# v0.2.1
cat <
$(escape "$commit")
|
$(escape "$(git log -1 --format=%an "$commit")")
$(escape "$(git log -1 --format=%s "$commit")") $(escape "$body") $escaped_notes
EOF
done
cat <
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 <
$(escape "$repo") - FIXME
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
DESCRIPTION="$(cat "$GIT_DIR"/description 2>/dev/null ||:)"
}
repo_write2() {
repo_vars "$1"
mkdir -p \
"$OUTDIR"/tarballs \
"$CACHE_DIR"/tarballs \
"$CACHE_DIR"/branch-revisions
{
preamble
repo_tarballs_write2
print_repo_refs2
} | tee f | make -f-
}
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
}
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=
CLONE_URL=
CACHE_DIR=
MAX_JOBS=1
MAIN_BRANCH='main'
MAIN_BRANCH_SET=false
REPO=
DESCRIPTION=
CMD='ln'
EXEC=
while getopts 'b:o:t:u:j:isqx:hV' flag; do
case "$flag" in
b)
MAIN_BRANCH="$OPTARG"
MAIN_BRANCH_SET=true
;;
o)
OUTDIR="$(realpath "$OPTARG")"
;;
t)
TITLE="$OPTARG"
;;
u)
CLONE_URL="$OPTARG"
;;
j)
MAX_JOBS="$OPTARG"
;;
i)
INDEX=true
;;
q)
VERBOSE=false
;;
s)
CMD='ln -s'
;;
x)
EXEC="$OPTARG"
;;
h)
usage
help
exit
;;
V)
version
exit
;;
*)
usage >&2
exit 2
;;
esac
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 [ "$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 -- '-i'
if [ -n "$CLONE_URL" ]; then
printf -- ' -u'
fi
if [ "$MAIN_BRANCH_SET" = true ]; then
printf -- ' -b'
fi
printf '\n\n'
usage
} >&2
exit 2
fi
assert_arg "${1:-}" "$MSG_MISSING_ARGS"
mkdir -p "$OUTDIR"
if [ "$INDEX" = true ]; then
index_write "$@"
else
# repo_write "$1"
repo_write2 "$1"
fi