jw-pkg/scripts/python-tools.sh

180 lines
3.4 KiB
Shell
Raw Normal View History

#!/bin/bash
log()
{
echo "$myname: $*" >&2
}
fatal()
{
echo "$myname: Fatal: $*" >&2
exit 1
}
usage()
{
cat <<-EOT
usage $myname [-e sed-extract-command] [-m module] file.py ...
EOT
[ "$1" ] && exit $1
}
module_path()
{
if [ "$module" = "." ]; then
echo .$1
elif [ "$module" ]; then
echo $module.$1
else
echo $1
fi
}
cmd_create_conftest_py()
{
cat <<-'EOT'
from __future__ import annotations
import os
import shutil
import sys
from typing import TYPE_CHECKING
from _pytest.terminal import TerminalReporter
from _pytest.timing import Instant
if TYPE_CHECKING:
from _pytest.config import Config
from _pytest.main import Session
def pytest_configure(config: Config) -> None:
"""Print a banner centered in the terminal when the session starts."""
def patched(self: TerminalReporter, session: Session) -> None:
width = shutil.get_terminal_size().columns
d = os.path.basename(os.getcwd())
text = f"Running pytest for {d}"
# Center text within terminal width, matching pytest footer style
padding = width - len(text) - 2
if padding > 0:
left = padding // 2
right = padding - left
banner = "=" * left + f" {text} " + "=" * right
else:
banner = text
print(banner, file = sys.stderr)
self._session = session
self._session_start = Instant()
TerminalReporter.pytest_sessionstart = patched # type: ignore[method-assign]
EOT
}
cmd_create_init()
{
__add_seen() {
local type="$1"
[[ -n "${seen[$type]+x}" ]] && fatal "Duplicate symbol: $type"
seen["$type"]=1
}
local import_submodules=0
local files="$*"
local del="-------------------------- generated by $myname"
echo "# >> $del >>"
echo "# ruff: noqa: E501"
echo "from pkgutil import extend_path"
echo ""
echo "__path__ = extend_path(__path__, __name__)"
echo
local -A seen=()
local f dst_type
if [ "$sed_extract_cmd" ]; then
for f in $files; do
test -d $f && continue
local base=${f##*/}
base=${base%.py}
local src_type types=$(sed "$sed_extract_cmd" $f)
for src_type in $types; do
if [ -z "$sed_symbol_filter_cmd" ]; then
dst_type="$src_type"
else
dst_type=$(echo $base $src_type | sed "$sed_symbol_filter_cmd")
fi
echo "from `module_path $base` import $src_type as $dst_type"
__add_seen $dst_type
done
done
fi
local submodule
for submodule in $submodules; do
echo "from . import $submodule as $submodule"
__add_seen $submodule
done
if [ "$import_submodules" = 1 ]; then
for f in $files; do
[ -f $f/__init__.py ] || continue
echo "import `module_path $f` as $f"
__add_seen $f
done
fi
if [ ${#seen[@]} -eq 0 ]; then
echo "__all__ = []"
else
echo
echo "__all__ = ["
for dst_type in "${!seen[@]}"; do
echo " \"$dst_type\","
done
echo "]"
fi
echo "# << $del <<"
}
# --------------------- here we go
myname=`basename $0`
submodules=""
eval set -- `getopt -l 'symbol-filter:,extract-filter:,module:,submodules:' -o 'he:m:' "$@"`
while [ "$1" != -- ]; do
case $1 in
-e|--extract-filter)
sed_extract_cmd="$2"
shift
;;
--symbol-filter)
sed_symbol_filter_cmd="$2"
shift
;;
-m|--module)
module=$2
shift
;;
-m|--submodules)
submodules="$submodules $2"
shift
;;
-h|--help)
usage 0
;;
*)
echo "Unknown argument $1"
usage 1
;;
esac
shift
done
shift
cmd=cmd_${1//-/_}
shift
eval $cmd $*