Fedora packaging (hopefully)
Some checks failed
Deploy Website / deploy-website (push) Successful in 39s
Publish kewt-git to AUR / publish-aur-git (push) Successful in 21s
Release Standalone Builder / build (release) Successful in 27s
Release Standalone Builder / publish-fedora (release) Failing after 15s
Release Standalone Builder / publish-aur (release) Successful in 22s
Release Standalone Builder / publish-homebrew (release) Successful in 7s
Some checks failed
Deploy Website / deploy-website (push) Successful in 39s
Publish kewt-git to AUR / publish-aur-git (push) Successful in 21s
Release Standalone Builder / build (release) Successful in 27s
Release Standalone Builder / publish-fedora (release) Failing after 15s
Release Standalone Builder / publish-aur (release) Successful in 22s
Release Standalone Builder / publish-homebrew (release) Successful in 7s
This commit is contained in:
@@ -20,51 +20,80 @@ jobs:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.21'
|
||||
go-version: "1.21"
|
||||
|
||||
- name: Upload Release Asset
|
||||
uses: https://gitea.com/actions/release-action@main
|
||||
with:
|
||||
files: |-
|
||||
kewt
|
||||
api_key: '${{secrets.GITEA_TOKEN}}'
|
||||
packaging/bash/kewt.bash
|
||||
api_key: "${{secrets.GITEA_TOKEN}}"
|
||||
|
||||
- name: Push to GitHub Release
|
||||
run: |
|
||||
TAG="${GITHUB_REF#refs/tags/}"
|
||||
|
||||
# Fetch release body from Gitea
|
||||
|
||||
RELEASE_BODY=$(curl -sL \
|
||||
"https://git.krzak.org/api/v1/repos/N0VA/kewt/releases/tags/${TAG}" \
|
||||
| jq -r '.body // ""')
|
||||
|
||||
# Build JSON payload
|
||||
|
||||
PAYLOAD=$(jq -n \
|
||||
--arg tag "$TAG" \
|
||||
--arg name "Release $TAG" \
|
||||
--arg body "$RELEASE_BODY" \
|
||||
'{tag_name: $tag, name: $name, body: $body, draft: false, prerelease: false}')
|
||||
|
||||
# Create the release on GitHub
|
||||
|
||||
curl -sL -X POST \
|
||||
-H "Authorization: token ${{ secrets.GH_RELEASE_TOKEN }}" \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
"https://api.github.com/repos/n0va-bot/kewt/releases" \
|
||||
-d "$PAYLOAD" || true
|
||||
|
||||
# Get the release ID
|
||||
|
||||
RELEASE_ID=$(curl -sL \
|
||||
-H "Authorization: token ${{ secrets.GH_RELEASE_TOKEN }}" \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
"https://api.github.com/repos/n0va-bot/kewt/releases/tags/${TAG}" | jq -r '.id')
|
||||
|
||||
# Upload the asset
|
||||
|
||||
curl -sL -X POST \
|
||||
-H "Authorization: token ${{ secrets.GH_RELEASE_TOKEN }}" \
|
||||
-H "Content-Type: application/octet-stream" \
|
||||
"https://uploads.github.com/repos/n0va-bot/kewt/releases/${RELEASE_ID}/assets?name=kewt" \
|
||||
--data-binary @kewt
|
||||
|
||||
publish-fedora:
|
||||
runs-on: local
|
||||
needs: build
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update || true
|
||||
sudo apt-get install -y rpm || true
|
||||
|
||||
- name: Build Fedora Assets
|
||||
run: |
|
||||
if command -v rpmbuild >/dev/null; then
|
||||
make srpm
|
||||
else
|
||||
echo "rpmbuild not found, generating spec file only"
|
||||
TAG="${GITHUB_REF#refs/tags/}"
|
||||
VERSION="${TAG#v}"
|
||||
sed -e "s/VERSION_PLACEHOLDER/${VERSION}/g" packaging/fedora/kewt.spec.template > packaging/fedora/kewt.spec
|
||||
fi
|
||||
|
||||
- name: Upload Fedora Assets
|
||||
uses: https://gitea.com/actions/release-action@main
|
||||
with:
|
||||
files: |-
|
||||
kewt-*.src.rpm
|
||||
packaging/fedora/kewt.spec
|
||||
api_key: "${{secrets.GITEA_TOKEN}}"
|
||||
|
||||
publish-aur:
|
||||
runs-on: local
|
||||
needs: build
|
||||
@@ -76,21 +105,21 @@ jobs:
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y openssh-client curl jq
|
||||
|
||||
|
||||
- name: Render PKGBUILD and SRCINFO
|
||||
run: |
|
||||
VERSION=${GITHUB_REF#refs/tags/v}
|
||||
VERSION=${VERSION#refs/tags/}
|
||||
|
||||
|
||||
curl -sL -o kewt https://git.krzak.org/N0VA/kewt/releases/download/v${VERSION}/kewt
|
||||
|
||||
|
||||
CHECKSUM=$(sha256sum kewt | awk '{print $1}')
|
||||
|
||||
|
||||
mkdir -p aur-work
|
||||
sed -e "s/VERSION_PLACEHOLDER/${VERSION}/g" \
|
||||
-e "s/SHA256SUM_PLACEHOLDER/${CHECKSUM}/g" \
|
||||
packaging/AUR/PKGBUILD.template > aur-work/PKGBUILD
|
||||
|
||||
|
||||
sed -e "s/VERSION_PLACEHOLDER/${VERSION}/g" \
|
||||
-e "s/SHA256SUM_PLACEHOLDER/${CHECKSUM}/g" \
|
||||
packaging/AUR/.SRCINFO.template > aur-work/.SRCINFO
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,2 +1,2 @@
|
||||
out/
|
||||
kewt
|
||||
kewt
|
||||
|
||||
15
Makefile
15
Makefile
@@ -1,6 +1,7 @@
|
||||
PREFIX ?= /usr/local
|
||||
BINDIR = $(PREFIX)/bin
|
||||
ZSHCOMPDIR ?= $(PREFIX)/share/zsh/site-functions
|
||||
BASHCOMPDIR ?= $(PREFIX)/share/bash-completion/completions
|
||||
|
||||
all: kewt
|
||||
|
||||
@@ -12,13 +13,25 @@ install: kewt
|
||||
install -m 755 kewt $(DESTDIR)$(BINDIR)/kewt
|
||||
install -d $(DESTDIR)$(ZSHCOMPDIR)
|
||||
install -m 644 packaging/zsh/_kewt $(DESTDIR)$(ZSHCOMPDIR)/_kewt
|
||||
install -d $(DESTDIR)$(BASHCOMPDIR)
|
||||
install -m 644 packaging/bash/kewt.bash $(DESTDIR)$(BASHCOMPDIR)/kewt
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(BINDIR)/kewt
|
||||
rm -f $(DESTDIR)$(ZSHCOMPDIR)/_kewt
|
||||
rm -f $(DESTDIR)$(BASHCOMPDIR)/kewt
|
||||
|
||||
clean:
|
||||
rm -f kewt
|
||||
rm -f kewt kewt-*.tar.gz
|
||||
|
||||
dist:
|
||||
$(eval VERSION := $(shell git describe --tags --always | sed 's/^v//;s/-/./g'))
|
||||
tar -czf kewt-$(VERSION).tar.gz --exclude-vcs --exclude=kewt --exclude=kewt-$(VERSION).tar.gz --transform "s|^|kewt-$(VERSION)/|" *
|
||||
|
||||
srpm: dist
|
||||
$(eval VERSION := $(shell git describe --tags --always | sed 's/^v//;s/-/./g'))
|
||||
sed -e "s/VERSION_PLACEHOLDER/$(VERSION)/g" packaging/fedora/kewt.spec.template > packaging/fedora/kewt.spec
|
||||
rpmbuild -bs --define "_sourcedir $(PWD)" --define "_srcrpmdir $(PWD)" packaging/fedora/kewt.spec
|
||||
|
||||
test:
|
||||
sh tests/test_runner.sh
|
||||
|
||||
24
kewt.sh
24
kewt.sh
@@ -45,6 +45,8 @@ positional_count=0
|
||||
watch_mode="false"
|
||||
serve_mode="false"
|
||||
serve_port=""
|
||||
draft_mode="false"
|
||||
dry_run_mode="false"
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
@@ -89,6 +91,8 @@ _kewt() {
|
||||
'--to[Output directory]:directory:_directories'
|
||||
'(-w --watch)'{-w,--watch}'[Watch for file changes and rebuild automatically]'
|
||||
'(-s --serve)'{-s,--serve}'[Start a local HTTP server after building]::port:'
|
||||
'(-d --draft)'{-d,--draft}'[Include draft pages in the build]'
|
||||
'(-)--dry-run[Show what would be built without writing any files]'
|
||||
)
|
||||
|
||||
_arguments -S -C $args '*: :_directories'
|
||||
@@ -141,6 +145,12 @@ EOFCOMPS
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
--draft|-d)
|
||||
draft_mode="true"
|
||||
;;
|
||||
--dry-run)
|
||||
dry_run_mode="true"
|
||||
;;
|
||||
--*)
|
||||
die "Unknown option: $1"
|
||||
;;
|
||||
@@ -201,10 +211,24 @@ refresh_build_context
|
||||
if [ "$clean_mode" = "true" ]; then
|
||||
[ -d "$out" ] && rm -rf "$out"
|
||||
fi
|
||||
|
||||
if [ "$dry_run_mode" = "true" ]; then
|
||||
dry_run_out="$KEWT_TMPDIR/dry_run_out"
|
||||
mkdir -p "$dry_run_out"
|
||||
out="$dry_run_out"
|
||||
fi
|
||||
|
||||
mkdir -p "$out"
|
||||
|
||||
build_site
|
||||
|
||||
if [ "$dry_run_mode" = "true" ]; then
|
||||
echo ""
|
||||
echo "Dry run complete. Files that would be generated:"
|
||||
find "$dry_run_out" -type f | sed "s|^$dry_run_out/||" | sort
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$serve_mode" = "true" ]; then
|
||||
port="${serve_port:-8000}"
|
||||
if command -v python3 >/dev/null 2>&1; then
|
||||
|
||||
@@ -48,8 +48,10 @@ build_dir_entries_list() {
|
||||
elif [ "${entry%.md}" != "$entry" ]; then
|
||||
entry_rel_path="${entry#"$src"/}"
|
||||
load_manifest_entry "$entry_rel_path" || continue
|
||||
if [ "${draft_mode:-false}" != "true" ]; then
|
||||
[ "$manifest_draft" = "true" ] && continue
|
||||
fi
|
||||
label="${name%.md}"
|
||||
[ "$manifest_draft" = "true" ] && continue
|
||||
|
||||
post_h="$manifest_title"
|
||||
|
||||
@@ -373,7 +375,9 @@ build_files() {
|
||||
|
||||
if [ "${file%.md}" != "$file" ] && [ "$is_preserved" -eq 0 ]; then
|
||||
load_manifest_entry "$rel_path" || continue
|
||||
[ "$manifest_draft" = "true" ] && continue
|
||||
if [ "${draft_mode:-false}" != "true" ]; then
|
||||
[ "$manifest_draft" = "true" ] && continue
|
||||
fi
|
||||
is_home="false"; [ "$file" = "$src/index.md" ] && is_home="true"
|
||||
out_file="$out/${rel_path%.md}.html"
|
||||
if needs_rebuild "$file" "$out_file"; then
|
||||
@@ -476,8 +480,15 @@ build_feed() {
|
||||
post_url="$base_url_feed$manifest_url"
|
||||
pub_date=$(format_rfc2822_utc "$post_date" "$post_time")
|
||||
|
||||
printf ' <item>\n <title>%s</title>\n <link>%s</link>\n <guid>%s</guid>\n <pubDate>%s</pubDate>\n </item>\n' \
|
||||
"$feed_post_title" "$post_url" "$post_url" "$pub_date" >> "$feed_path"
|
||||
if [ "$feed_full_content" = "true" ]; then
|
||||
feed_content_file="$src/$post_rel_path"
|
||||
feed_content_html=$(ENABLE_HEADER_LINKS="false" CUSTOM_ADMONITIONS="" MARKDOWN_SITE_ROOT="$src" MARKDOWN_FALLBACK_FILE="$script_dir/styles/$style.css" sh "$script_dir/markdown.sh" "$feed_content_file" | sed 's/</\</g; s/>/\>/g')
|
||||
printf ' <item>\n <title>%s</title>\n <link>%s</link>\n <guid>%s</guid>\n <pubDate>%s</pubDate>\n <description>%s</description>\n </item>\n' \
|
||||
"$feed_post_title" "$post_url" "$post_url" "$pub_date" "$feed_content_html" >> "$feed_path"
|
||||
else
|
||||
printf ' <item>\n <title>%s</title>\n <link>%s</link>\n <guid>%s</guid>\n <pubDate>%s</pubDate>\n </item>\n' \
|
||||
"$feed_post_title" "$post_url" "$post_url" "$pub_date" >> "$feed_path"
|
||||
fi
|
||||
done
|
||||
|
||||
printf ' </channel>\n</rss>\n' >> "$feed_path"
|
||||
@@ -606,12 +617,24 @@ build_tags() {
|
||||
}
|
||||
|
||||
build_error_page() {
|
||||
[ -n "$error_page" ] && [ ! -f "$out/$error_page" ] || return
|
||||
[ -n "$error_page" ] || return
|
||||
|
||||
temp_404="$KEWT_TMPDIR/404_gen.md"
|
||||
printf '# 404 - Not Found\n\nThe requested page could not be found.\n' > "$temp_404"
|
||||
render_markdown "$temp_404" "false" "/$error_page" > "$out/$error_page"
|
||||
rm -f "$temp_404"
|
||||
error_base="${error_page%.html}"
|
||||
error_md="$src/${error_base}.md"
|
||||
|
||||
if [ -f "$error_md" ]; then
|
||||
if needs_rebuild "$error_md" "$out/$error_page"; then
|
||||
is_home="false"
|
||||
current_url="/$error_page"
|
||||
parse_frontmatter "$error_md"
|
||||
render_markdown "$error_md" "$is_home" "/$error_page" > "$out/$error_page"
|
||||
fi
|
||||
elif [ ! -f "$out/$error_page" ]; then
|
||||
temp_404="$KEWT_TMPDIR/404_gen.md"
|
||||
printf '# 404 - Not Found\n\nThe requested page could not be found.\n' > "$temp_404"
|
||||
render_markdown "$temp_404" "false" "/$error_page" > "$out/$error_page"
|
||||
rm -f "$temp_404"
|
||||
fi
|
||||
}
|
||||
|
||||
build_site() {
|
||||
|
||||
@@ -22,6 +22,8 @@ Options:
|
||||
--post Create a new empty post file in the configured posts_dir with current date and time as name
|
||||
--generate-template [path] Generate a new template file at <path> (default: template.html)
|
||||
--version Show version information.
|
||||
--draft, -d Include draft pages in the build.
|
||||
--dry-run Show what would be built without writing any files.
|
||||
--from <src> Source directory (default: site)
|
||||
--to <out> Output directory (default: out)
|
||||
--watch, -w Watch for file changes and rebuild automatically.
|
||||
|
||||
@@ -34,7 +34,8 @@ tags_dir = "tags"
|
||||
generate_search = false
|
||||
search_in_footer = false
|
||||
search_in_header = false
|
||||
include_cw_pages_in_search = false'
|
||||
include_cw_pages_in_search = false
|
||||
feed_full_content = false'
|
||||
|
||||
DEFAULT_TMPL='<!doctype html>
|
||||
<html lang="{{LANG}}">
|
||||
@@ -129,6 +130,7 @@ _load_conf_line() {
|
||||
search_in_footer) search_in_footer="$_lc_val" ;;
|
||||
search_in_header) search_in_header="$_lc_val" ;;
|
||||
include_cw_pages_in_search) include_cw_pages_in_search="$_lc_val" ;;
|
||||
feed_full_content) feed_full_content="$_lc_val" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
@@ -187,8 +187,10 @@ build_markdown_manifest() {
|
||||
eval "find \"$src\" \( $IGNORE_ARGS -o $HIDE_ARGS -o $PRESERVE_ARGS \) -prune -o -name \"*.md\" -print" | sort | while IFS= read -r visible_file; do
|
||||
visible_rel_path="${visible_file#"$src"/}"
|
||||
load_manifest_entry "$visible_rel_path" || continue
|
||||
[ "$manifest_draft" = "true" ] && continue
|
||||
manifest_dir_hidden_by_draft_index "$manifest_dir_rel" && continue
|
||||
if [ "${draft_mode:-false}" != "true" ]; then
|
||||
[ "$manifest_draft" = "true" ] && continue
|
||||
manifest_dir_hidden_by_draft_index "$manifest_dir_rel" && continue
|
||||
fi
|
||||
printf '%s\n' "$visible_rel_path" >> "$manifest_visible_list"
|
||||
done
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
pkgbase = kewt-git
|
||||
pkgdesc = A minimalist, 100% POSIX, static site generator inspired by werc and kew
|
||||
pkgver = r0.0000001
|
||||
pkgver = r0.0000002
|
||||
pkgrel = 1
|
||||
url = https://kewt.krzak.org
|
||||
arch = any
|
||||
license = ISC
|
||||
makedepends = git
|
||||
depends = sh
|
||||
optdepends = bash-completion: bash shell completions
|
||||
provides = kewt
|
||||
conflicts = kewt
|
||||
conflicts = kewt-bin
|
||||
|
||||
@@ -6,10 +6,13 @@ pkgbase = kewt-bin
|
||||
arch = any
|
||||
license = ISC
|
||||
depends = sh
|
||||
optdepends = bash-completion: bash shell completions
|
||||
provides = kewt
|
||||
conflicts = kewt
|
||||
conflicts = kewt-git
|
||||
source = kewt-bin-VERSION_PLACEHOLDER.sh::https://git.krzak.org/N0VA/kewt/releases/download/vVERSION_PLACEHOLDER/kewt
|
||||
source = kewt-bin-VERSION_PLACEHOLDER.bash::https://git.krzak.org/N0VA/kewt/releases/download/vVERSION_PLACEHOLDER/kewt.bash
|
||||
sha256sums = SHA256SUM_PLACEHOLDER
|
||||
sha256sums = SKIP
|
||||
|
||||
pkgname = kewt-bin
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Maintainer: n0va <n0va@krzak.org>
|
||||
pkgname=kewt-git
|
||||
pkgver=r0.0000001
|
||||
pkgver=r0.0000002
|
||||
pkgrel=1
|
||||
pkgdesc="A minimalist, 100% POSIX, static site generator inspired by werc and kew"
|
||||
arch=('any')
|
||||
@@ -28,4 +28,5 @@ package() {
|
||||
install -Dm755 kewt "${pkgdir}/usr/bin/kewt"
|
||||
install -d "${pkgdir}/usr/share/zsh/site-functions"
|
||||
"${pkgdir}/usr/bin/kewt" --dump-zsh-completions > "${pkgdir}/usr/share/zsh/site-functions/_kewt"
|
||||
install -Dm644 packaging/bash/kewt.bash "${pkgdir}/usr/share/bash-completion/completions/kewt"
|
||||
}
|
||||
|
||||
@@ -9,8 +9,9 @@ license=('ISC')
|
||||
depends=('sh')
|
||||
provides=('kewt')
|
||||
conflicts=('kewt' 'kewt-git')
|
||||
source=("${pkgname}-${pkgver}.sh::https://git.krzak.org/N0VA/kewt/releases/download/v${pkgver}/kewt")
|
||||
sha256sums=('SHA256SUM_PLACEHOLDER')
|
||||
source=("${pkgname}-${pkgver}.sh::https://git.krzak.org/N0VA/kewt/releases/download/v${pkgver}/kewt"
|
||||
"${pkgname}-${pkgver}.bash::https://git.krzak.org/N0VA/kewt/releases/download/v${pkgver}/kewt.bash")
|
||||
sha256sums=('SHA256SUM_PLACEHOLDER' 'SKIP')
|
||||
|
||||
build() {
|
||||
chmod +x "${srcdir}/${pkgname}-${pkgver}.sh"
|
||||
@@ -20,4 +21,5 @@ package() {
|
||||
install -Dm755 "${srcdir}/${pkgname}-${pkgver}.sh" "${pkgdir}/usr/bin/kewt"
|
||||
install -d "${pkgdir}/usr/share/zsh/site-functions"
|
||||
"${pkgdir}/usr/bin/kewt" --dump-zsh-completions > "${pkgdir}/usr/share/zsh/site-functions/_kewt"
|
||||
install -Dm644 "${srcdir}/${pkgname}-${pkgver}.bash" "${pkgdir}/usr/share/bash-completion/completions/kewt"
|
||||
}
|
||||
|
||||
37
packaging/bash/kewt.bash
Normal file
37
packaging/bash/kewt.bash
Normal file
@@ -0,0 +1,37 @@
|
||||
_kewt() {
|
||||
local cur prev opts
|
||||
COMPREPLY=()
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
|
||||
opts="--help --new --init --clean --no-clean --update --post --generate-template --version --from --to --watch -w --serve -s --draft --dry-run"
|
||||
|
||||
case "$prev" in
|
||||
--from|--to)
|
||||
COMPREPLY=$(compgen -d -- "$cur")
|
||||
return 0
|
||||
;;
|
||||
--serve|-s)
|
||||
COMPREPLY=()
|
||||
return 0
|
||||
;;
|
||||
--new|--init|--update)
|
||||
COMPREPLY=$(compgen -d -- "$cur")
|
||||
return 0
|
||||
;;
|
||||
--generate-template)
|
||||
COMPREPLY=$(compgen -f -- "$cur")
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ "$cur" == -* ]]; then
|
||||
COMPREPLY=$(compgen -W "$opts" -- "$cur")
|
||||
return 0
|
||||
fi
|
||||
|
||||
COMPREPLY=$(compgen -d -- "$cur")
|
||||
return 0
|
||||
}
|
||||
|
||||
complete -F _kewt kewt
|
||||
41
packaging/fedora/kewt.spec.template
Normal file
41
packaging/fedora/kewt.spec.template
Normal file
@@ -0,0 +1,41 @@
|
||||
Name: kewt
|
||||
Version: VERSION_PLACEHOLDER
|
||||
Release: 1%{?dist}
|
||||
Summary: A minimalist, 100% POSIX, static site generator inspired by werc
|
||||
|
||||
License: ISC
|
||||
URL: https://kewt.krzak.org
|
||||
Source0: https://git.krzak.org/N0VA/kewt/archive/v%{version}.tar.gz
|
||||
|
||||
BuildArch: noarch
|
||||
BuildRequires: make
|
||||
Requires: sh
|
||||
Requires: findutils
|
||||
Requires: grep
|
||||
Requires: sed
|
||||
Requires: gawk
|
||||
Recommends: python3
|
||||
Recommends: bash-completion
|
||||
|
||||
%description
|
||||
A minimalist, 100% POSIX, static site generator inspired by werc and kew
|
||||
|
||||
%prep
|
||||
%autosetup
|
||||
|
||||
%build
|
||||
%make_build
|
||||
|
||||
%install
|
||||
%make_install PREFIX=%{_prefix} BINDIR=%{_bindir} ZSHCOMPDIR=%{_datadir}/zsh/site-functions BASHCOMPDIR=%{_datadir}/bash-completion/completions
|
||||
|
||||
%files
|
||||
%license LICENSE
|
||||
%doc README.md
|
||||
%{_bindir}/kewt
|
||||
%{_datadir}/zsh/site-functions/_kewt
|
||||
%{_datadir}/bash-completion/completions/kewt
|
||||
|
||||
%changelog
|
||||
* Mon May 20 2024 n0va <n0va@krzak.org> - VERSION_PLACEHOLDER-1
|
||||
- Initial package for Fedora
|
||||
@@ -9,7 +9,7 @@ class Kewt < Formula
|
||||
def install
|
||||
bin.install "kewt"
|
||||
chmod 0755, bin/"kewt"
|
||||
generate_completions_from_executable(bin/"kewt", "--dump-zsh-completions", shells: [:zsh])
|
||||
generate_completions_from_executable(bin/"kewt", "--dump-zsh-completions", shells: [:zsh, :bash])
|
||||
end
|
||||
|
||||
test do
|
||||
|
||||
@@ -17,6 +17,8 @@ _kewt() {
|
||||
'--to[Output directory]:directory:_directories'
|
||||
'(-w --watch)'{-w,--watch}'[Watch for file changes and rebuild automatically]'
|
||||
'(-s --serve)'{-s,--serve}'[Start a local HTTP server after building]::port:'
|
||||
'(-d --draft)'{-d,--draft}'[Include draft pages in the build]'
|
||||
'(-)--dry-run[Show what would be built without writing any files]'
|
||||
)
|
||||
|
||||
_arguments -S -C $args '*: :_directories'
|
||||
|
||||
@@ -38,6 +38,14 @@ sudo make install
|
||||
brew tap n0va-bot/tap
|
||||
brew install kewt
|
||||
```
|
||||
|
||||
### Fedora
|
||||
|
||||
```sh
|
||||
sudo dnf copr enable n0va-bot/kewt
|
||||
sudo dnf install kewt
|
||||
```
|
||||
|
||||
### bpkg
|
||||
|
||||
```sh
|
||||
|
||||
185
tests/test_builder.sh
Normal file
185
tests/test_builder.sh
Normal file
@@ -0,0 +1,185 @@
|
||||
test_needs_rebuild_no_output() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
. "$project_dir/lib/builder.sh"
|
||||
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
echo "test" > "$tmpdir/src.md"
|
||||
|
||||
needs_rebuild "$tmpdir/src.md" "$tmpdir/out.html"
|
||||
result=$?
|
||||
assert_eq "0" "$result" "rebuild when output missing"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_needs_rebuild_output_newer() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
. "$project_dir/lib/builder.sh"
|
||||
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
echo "test" > "$tmpdir/src.md"
|
||||
sleep 1
|
||||
echo "test" > "$tmpdir/out.html"
|
||||
|
||||
needs_rebuild "$tmpdir/src.md" "$tmpdir/out.html"
|
||||
result=$?
|
||||
assert_eq "1" "$result" "no rebuild when output newer"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_needs_rebuild_source_newer() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
. "$project_dir/lib/builder.sh"
|
||||
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
echo "old" > "$tmpdir/out.html"
|
||||
sleep 1
|
||||
echo "new" > "$tmpdir/src.md"
|
||||
|
||||
needs_rebuild "$tmpdir/src.md" "$tmpdir/out.html"
|
||||
result=$?
|
||||
assert_eq "0" "$result" "rebuild when source newer"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_escape_html_text() {
|
||||
. "$project_dir/lib/generator.sh"
|
||||
|
||||
result=$(escape_html_text "<script>&test>")
|
||||
assert_eq "<script>&test>" "$result" "escape html text"
|
||||
}
|
||||
|
||||
test_escape_html_attr() {
|
||||
. "$project_dir/lib/generator.sh"
|
||||
|
||||
result=$(escape_html_attr 'value with "quotes" & <tags>')
|
||||
assert_eq "value with "quotes" & <tags>" "$result" "escape html attr"
|
||||
}
|
||||
|
||||
test_nav_links_empty() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
. "$project_dir/lib/generator.sh"
|
||||
|
||||
nav_links=""
|
||||
result=$(nav_links_html)
|
||||
assert_eq "" "$result" "empty nav links"
|
||||
}
|
||||
|
||||
test_nav_links_markdown() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
. "$project_dir/lib/generator.sh"
|
||||
|
||||
nav_links="[Docs](/docs), [About](/about)"
|
||||
result=$(nav_links_html)
|
||||
assert_contains '<li><a href="/docs">Docs</a></li>' "$result" "nav links markdown docs"
|
||||
assert_contains '<li><a href="/about">About</a></li>' "$result" "nav links markdown about"
|
||||
}
|
||||
|
||||
test_nav_links_plain() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
. "$project_dir/lib/generator.sh"
|
||||
|
||||
nav_links="https://example.com"
|
||||
result=$(nav_links_html)
|
||||
assert_contains '<li><a href="https://example.com">' "$result" "nav links plain url"
|
||||
}
|
||||
|
||||
test_find_closest() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
. "$project_dir/lib/generator.sh"
|
||||
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir/sub/deep"
|
||||
echo "root" > "$tmpdir/template.html"
|
||||
echo "sub" > "$tmpdir/sub/template.html"
|
||||
|
||||
src="$tmpdir"
|
||||
result=$(find_closest "template.html" "$tmpdir/sub/deep")
|
||||
assert_eq "$tmpdir/sub/template.html" "$result" "find closest in parent"
|
||||
|
||||
result=$(find_closest "template.html" "$tmpdir")
|
||||
assert_eq "$tmpdir/template.html" "$result" "find closest in current"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_find_closest_fallback_to_src() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
. "$project_dir/lib/generator.sh"
|
||||
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir/sub"
|
||||
echo "root" > "$tmpdir/template.html"
|
||||
|
||||
src="$tmpdir"
|
||||
result=$(find_closest "template.html" "$tmpdir/sub")
|
||||
assert_eq "$tmpdir/template.html" "$result" "find closest falls back to src"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_custom_404_md() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
. "$project_dir/lib/metadata.sh"
|
||||
. "$project_dir/lib/manifest.sh"
|
||||
. "$project_dir/lib/generator.sh"
|
||||
. "$project_dir/lib/builder.sh"
|
||||
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
|
||||
cat > "$tmpdir/site.conf" <<EOF
|
||||
title = "Test"
|
||||
error_page = "not_found.html"
|
||||
EOF
|
||||
|
||||
printf '# Custom 404\n\nPage not found, sorry.\n' > "$tmpdir/not_found.md"
|
||||
|
||||
src="$tmpdir"
|
||||
out="$tmpdir/out"
|
||||
KEWT_TMPDIR="$tmpdir/tmp"
|
||||
mkdir -p "$out" "$KEWT_TMPDIR"
|
||||
|
||||
awk_dir="$project_dir/awk"
|
||||
script_dir="$project_dir"
|
||||
style="kewt"
|
||||
template="$KEWT_TMPDIR/default_template.html"
|
||||
printf '%s\n' "$DEFAULT_TMPL" > "$template"
|
||||
nav=""
|
||||
footer=""
|
||||
header_brand=""
|
||||
head_extra=""
|
||||
asset_version=""
|
||||
lang="en"
|
||||
current_url=""
|
||||
fm_title=""
|
||||
fm_content_warning=""
|
||||
fm_description=""
|
||||
generate_page_title="true"
|
||||
logo_as_favicon="false"
|
||||
favicon=""
|
||||
display_logo="false"
|
||||
display_title="true"
|
||||
logo=""
|
||||
search_in_header="false"
|
||||
search_in_footer="false"
|
||||
cw_hide_url="true"
|
||||
enable_header_links="false"
|
||||
custom_admonitions=""
|
||||
|
||||
build_error_page
|
||||
|
||||
assert_file_exists "$out/not_found.html" "custom 404 html generated"
|
||||
assert_contains "Custom 404" "$(cat "$out/not_found.html")" "custom 404 has custom content"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
@@ -104,3 +104,26 @@ test_config_load_missing_file() {
|
||||
|
||||
assert_eq "kewt" "$title" "missing file keeps defaults"
|
||||
}
|
||||
|
||||
test_config_feed_full_content_default() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
|
||||
assert_eq "false" "$feed_full_content" "default feed_full_content"
|
||||
}
|
||||
|
||||
test_config_feed_full_content_load() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
cat > "$tmpdir/test.conf" <<EOF
|
||||
feed_full_content = true
|
||||
EOF
|
||||
|
||||
reset_config
|
||||
load_config "$tmpdir/test.conf"
|
||||
|
||||
assert_eq "true" "$feed_full_content" "load feed_full_content"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
43
tests/test_manifest.sh
Normal file
43
tests/test_manifest.sh
Normal file
@@ -0,0 +1,43 @@
|
||||
test_draft_mode_includes_drafts_in_manifest() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
. "$project_dir/lib/metadata.sh"
|
||||
. "$project_dir/lib/manifest.sh"
|
||||
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
|
||||
cat > "$tmpdir/site.conf" <<EOF
|
||||
title = "Test"
|
||||
dir_indexes = true
|
||||
EOF
|
||||
|
||||
printf '# Normal Page\n' > "$tmpdir/normal.md"
|
||||
printf -- '---\ndraft = true\n---\n# Draft Page\n' > "$tmpdir/draft.md"
|
||||
|
||||
src="$tmpdir"
|
||||
out="$tmpdir/out"
|
||||
KEWT_TMPDIR="$tmpdir/tmp"
|
||||
mkdir -p "$KEWT_TMPDIR"
|
||||
|
||||
awk_dir="$project_dir/awk"
|
||||
script_dir="$project_dir"
|
||||
|
||||
reset_config
|
||||
load_config "$tmpdir/site.conf"
|
||||
IGNORE_ARGS="-name '.kewtignore' -o -path '$src/.*'"
|
||||
HIDE_ARGS="-name '.kewtignore' -o -name '.kewthide' -o -name '.kewtpreserve' -o -path '$src/.*'"
|
||||
PRESERVE_ARGS="-false"
|
||||
|
||||
draft_mode="false"
|
||||
build_markdown_manifest
|
||||
visible_count=$(wc -l < "$manifest_visible_list")
|
||||
assert_eq "1" "$visible_count" "without draft mode only normal page visible"
|
||||
|
||||
draft_mode="true"
|
||||
build_markdown_manifest
|
||||
visible_count=$(wc -l < "$manifest_visible_list")
|
||||
assert_eq "2" "$visible_count" "with draft mode both pages visible"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
146
tests/test_markdown.sh
Normal file
146
tests/test_markdown.sh
Normal file
@@ -0,0 +1,146 @@
|
||||
test_markdown_heading() {
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
printf '# Hello World\n\nSome content.\n' > "$tmpdir/test.md"
|
||||
|
||||
result=$(ENABLE_HEADER_LINKS="false" CUSTOM_ADMONITIONS="" MARKDOWN_SITE_ROOT="$tmpdir" MARKDOWN_FALLBACK_FILE="" sh "$project_dir/markdown.sh" "$tmpdir/test.md")
|
||||
assert_contains "<h1" "$result" "markdown heading tag"
|
||||
assert_contains "Hello World" "$result" "markdown heading text"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_markdown_paragraph() {
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
printf 'This is a paragraph.\n' > "$tmpdir/test.md"
|
||||
|
||||
result=$(ENABLE_HEADER_LINKS="false" CUSTOM_ADMONITIONS="" MARKDOWN_SITE_ROOT="$tmpdir" MARKDOWN_FALLBACK_FILE="" sh "$project_dir/markdown.sh" "$tmpdir/test.md")
|
||||
assert_contains "<p>" "$result" "markdown paragraph open"
|
||||
assert_contains "This is a paragraph." "$result" "markdown paragraph text"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_markdown_bold() {
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
printf 'This is **bold** text.\n' > "$tmpdir/test.md"
|
||||
|
||||
result=$(ENABLE_HEADER_LINKS="false" CUSTOM_ADMONITIONS="" MARKDOWN_SITE_ROOT="$tmpdir" MARKDOWN_FALLBACK_FILE="" sh "$project_dir/markdown.sh" "$tmpdir/test.md")
|
||||
assert_contains "<strong>bold</strong>" "$result" "markdown bold"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_markdown_italic() {
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
printf 'This is *italic* text.\n' > "$tmpdir/test.md"
|
||||
|
||||
result=$(ENABLE_HEADER_LINKS="false" CUSTOM_ADMONITIONS="" MARKDOWN_SITE_ROOT="$tmpdir" MARKDOWN_FALLBACK_FILE="" sh "$project_dir/markdown.sh" "$tmpdir/test.md")
|
||||
assert_contains "<em>italic</em>" "$result" "markdown italic"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_markdown_link() {
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
printf '[click here](https://example.com)\n' > "$tmpdir/test.md"
|
||||
|
||||
result=$(ENABLE_HEADER_LINKS="false" CUSTOM_ADMONITIONS="" MARKDOWN_SITE_ROOT="$tmpdir" MARKDOWN_FALLBACK_FILE="" sh "$project_dir/markdown.sh" "$tmpdir/test.md")
|
||||
assert_contains 'href="https://example.com"' "$result" "markdown link href"
|
||||
assert_contains "click here" "$result" "markdown link text"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_markdown_code_block() {
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
cat > "$tmpdir/test.md" <<EOF
|
||||
\`\`\`
|
||||
code here
|
||||
\`\`\`
|
||||
EOF
|
||||
|
||||
result=$(ENABLE_HEADER_LINKS="false" CUSTOM_ADMONITIONS="" MARKDOWN_SITE_ROOT="$tmpdir" MARKDOWN_FALLBACK_FILE="" sh "$project_dir/markdown.sh" "$tmpdir/test.md")
|
||||
assert_contains "<pre>" "$result" "markdown code block pre"
|
||||
assert_contains "<code>" "$result" "markdown code block code"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_markdown_unordered_list() {
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
printf -- '- item one\n- item two\n' > "$tmpdir/test.md"
|
||||
|
||||
result=$(ENABLE_HEADER_LINKS="false" CUSTOM_ADMONITIONS="" MARKDOWN_SITE_ROOT="$tmpdir" MARKDOWN_FALLBACK_FILE="" sh "$project_dir/markdown.sh" "$tmpdir/test.md")
|
||||
assert_contains "<ul>" "$result" "markdown list ul"
|
||||
assert_contains "<li>item one</li>" "$result" "markdown list item one"
|
||||
assert_contains "<li>item two</li>" "$result" "markdown list item two"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_markdown_blockquote() {
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
printf '> This is a quote\n' > "$tmpdir/test.md"
|
||||
|
||||
result=$(ENABLE_HEADER_LINKS="false" CUSTOM_ADMONITIONS="" MARKDOWN_SITE_ROOT="$tmpdir" MARKDOWN_FALLBACK_FILE="" sh "$project_dir/markdown.sh" "$tmpdir/test.md")
|
||||
assert_contains "<blockquote>" "$result" "markdown blockquote"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_markdown_frontmatter_stripped() {
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
cat > "$tmpdir/test.md" <<EOF
|
||||
---
|
||||
title = "Test"
|
||||
---
|
||||
|
||||
# Heading
|
||||
EOF
|
||||
|
||||
result=$(ENABLE_HEADER_LINKS="false" CUSTOM_ADMONITIONS="" MARKDOWN_SITE_ROOT="$tmpdir" MARKDOWN_FALLBACK_FILE="" sh "$project_dir/markdown.sh" "$tmpdir/test.md")
|
||||
assert_contains "<h1" "$result" "markdown frontmatter heading present"
|
||||
assert_contains "Heading" "$result" "markdown frontmatter heading text"
|
||||
result_not_contains=$(echo "$result" | grep -c 'title = "Test"')
|
||||
assert_eq "0" "$result_not_contains" "markdown frontmatter not in output"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_markdown_header_links() {
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
printf '# My Heading\n' > "$tmpdir/test.md"
|
||||
|
||||
result=$(ENABLE_HEADER_LINKS="true" CUSTOM_ADMONITIONS="" MARKDOWN_SITE_ROOT="$tmpdir" MARKDOWN_FALLBACK_FILE="" sh "$project_dir/markdown.sh" "$tmpdir/test.md")
|
||||
assert_contains 'id="my-heading"' "$result" "markdown header link id"
|
||||
assert_contains 'href="#my-heading"' "$result" "markdown header link href"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_markdown_pipe_table() {
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
cat > "$tmpdir/test.md" <<EOF
|
||||
| A | B |
|
||||
|---|---|
|
||||
| 1 | 2 |
|
||||
EOF
|
||||
|
||||
result=$(ENABLE_HEADER_LINKS="false" CUSTOM_ADMONITIONS="" MARKDOWN_SITE_ROOT="$tmpdir" MARKDOWN_FALLBACK_FILE="" sh "$project_dir/markdown.sh" "$tmpdir/test.md")
|
||||
assert_contains "<table>" "$result" "markdown table"
|
||||
assert_contains "<th>A</th>" "$result" "markdown table header"
|
||||
assert_contains "<td>1</td>" "$result" "markdown table cell"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
@@ -69,3 +69,20 @@ test_trim_whitespace_tabs() {
|
||||
result=$(trim_whitespace " world ")
|
||||
assert_eq "world" "$result" "trim tabs"
|
||||
}
|
||||
|
||||
test_is_posts_directory_rel() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
|
||||
posts_dir="posts"
|
||||
|
||||
result=$(is_posts_directory_rel "posts" && echo "true" || echo "false")
|
||||
assert_eq "true" "$result" "posts dir match"
|
||||
|
||||
result=$(is_posts_directory_rel "blog" && echo "true" || echo "false")
|
||||
assert_eq "false" "$result" "posts dir no match"
|
||||
|
||||
posts_dir="./posts"
|
||||
result=$(is_posts_directory_rel "posts" && echo "true" || echo "false")
|
||||
assert_eq "true" "$result" "posts dir with dot prefix config"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user