diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b385a6..e4d6333 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,14 +21,31 @@ jobs: printf 'Apt::Install-Recommends "false";\n' | tee -a /etc/apt/apt.conf apt-get update apt-get install -y python3-gi-cairo gir1.2-pango-1.0 - apt-get install -y perl + apt-get install -y make perl + - name: set up PATH + run: | + PATH="$PATH:$HOME/.local/bin" + echo "$PATH" >> $GITHUB_PATH - name: check Python version run: | python3 --version - name: run tests run: | export LC_ALL=C.UTF-8 - prove -v + make test verbose=1 + - name: install + run: | + make install PREFIX=~/.local + - name: check whether the executable was installed correctly + run: | + cd / + command -v ubanner + - name: run post-install tests + run: | + mv ubanner ubanner.bak + export LC_ALL=C.UTF-8 + make test-installed verbose=1 + mv ubanner.bak ubanner static: runs-on: ${{matrix.os}} diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..75cc0c1 --- /dev/null +++ b/Makefile @@ -0,0 +1,42 @@ +# Copyright © 2024 Jakub Wilk +# SPDX-License-Identifier: MIT + +PYTHON = python3 + +PREFIX = /usr/local +DESTDIR = + +bindir = $(PREFIX)/bin +mandir = $(PREFIX)/share/man + +.PHONY: all +all: ; + +.PHONY: install +install: ubanner + install -d $(DESTDIR)$(bindir) + python_exe=$$($(PYTHON) -c 'import sys; print(sys.executable)') && \ + sed \ + -e "1 s@^#!.*@#!$$python_exe@" \ + -e "s#^basedir = .*#basedir = '$(basedir)/'#" \ + $(<) > $(<).tmp + install $(<).tmp $(DESTDIR)$(bindir)/$(<) + rm $(<).tmp + +.PHONY: test +test: verbose= +test: ubanner + prove $(and $(verbose),-v) + +.PHONY: test-installed +test-installed: verbose= +test-installed: $(or $(shell command -v ubanner;),$(bindir)/ubanner) + UBANNER_TEST_TARGET=ubanner prove $(and $(verbose),-v) + +.PHONY: clean +clean: + rm -f *.tmp + +.error = GNU make is required + +# vim:ts=4 sts=4 sw=4 noet diff --git a/t/common.sh b/t/common.sh index f08d816..0e76b01 100644 --- a/t/common.sh +++ b/t/common.sh @@ -8,6 +8,8 @@ set -e -u dir="${0%/*}/.." prog="${UBANNER_TEST_TARGET:-"$dir/ubanner"}" +echo "# test target = $prog" + is_unicode_locale() { local charset=$'\u2591\u2592\u2588' diff --git a/t/help.t b/t/help.t new file mode 100755 index 0000000..dd72ccc --- /dev/null +++ b/t/help.t @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +# Copyright © 2024 Jakub Wilk +# SPDX-License-Identifier: MIT + +set -e -u + +. "${0%/*}/common.sh" + +echo 1..1 +if out=$("$prog" --help) +then + sed -e 's/^/# /' <<< "$out" + case $out in + 'usage: ubanner '*) + echo ok 1;; + *) + echo not ok 1;; + esac +else + echo not ok 1 +fi + +# vim:ts=4 sts=4 sw=4 et ft=sh diff --git a/t/version.t b/t/version.t new file mode 100755 index 0000000..5908ad7 --- /dev/null +++ b/t/version.t @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +# Copyright © 2024 Jakub Wilk +# SPDX-License-Identifier: MIT + +set -e -u + +. "${0%/*}/common.sh" + +echo 1..1 +if out=$("$prog" --version) +then + sed -e 's/^/# /' <<< "$out" + case $out in + $'ubanner 0\n'*) + echo ok 1;; + *) + echo not ok 1;; + esac +else + echo not ok 1 +fi + +# vim:ts=4 sts=4 sw=4 et ft=sh diff --git a/ubanner b/ubanner index 771ebb1..9ab4dd0 100755 --- a/ubanner +++ b/ubanner @@ -22,6 +22,29 @@ from gi.repository import PangoCairo 0_0 # Python >= 3.6 is required +__version__ = '0' # not released yet + +class VersionAction(argparse.Action): + ''' + argparse --version action + ''' + + def __init__(self, option_strings, dest=argparse.SUPPRESS): + super().__init__( + option_strings=option_strings, + dest=dest, + nargs=0, + help='show version information and exit' + ) + + def __call__(self, parser, namespace, values, option_string=None): + print(f'{parser.prog} {__version__}') + print('+ Python {0}.{1}.{2}'.format(*sys.version_info)) + print('+ PyGI', gi.__version__) + print('+ Pango', Pango.version_string()) + print('+ Cairo', cairo.version) + parser.exit() + if sys.version_info < (3, 11): def kbisect(a, x, *, key): lo = 0 @@ -103,6 +126,7 @@ except UnicodeError: def main(): signal.signal(signal.SIGPIPE, signal.SIG_DFL) ap = argparse.ArgumentParser() + ap.add_argument('--version', action=VersionAction) ap.add_argument('--list-fonts', nargs=0, action=act_list_fonts, help='print list of available font faces', ) @@ -110,11 +134,11 @@ def main(): ap.add_argument('--trim', action='store_true', help='trim leading/trailing empty lines', ) - ap.add_argument('--font', help='use this font face') - ap.add_argument('--font-size', type=int, metavar='N', default=default.font_size, + ap.add_argument('-f', '--font', help='use this font face') + ap.add_argument('-s', '--font-size', type=int, metavar='N', default=default.font_size, help=f'font size in pixels (default: {default.font_size})' ) - ap.add_argument('-s', '--full-screen', dest='font_size', action='store_const', const=None) + ap.add_argument('-S', '--full-screen', dest='font_size', action='store_const', const=None) opts = ap.parse_args() if not opts.text: if sys.stdin.isatty():