chore: cli tools
parent
30f477550a
commit
f64b361d3b
@ -1,6 +0,0 @@
|
|||||||
@echo off
|
|
||||||
setlocal
|
|
||||||
|
|
||||||
set "SCRIPT_DIR=%~dp0"
|
|
||||||
call "%SCRIPT_DIR%scripts\iti.cmd" %*
|
|
||||||
exit /b %ERRORLEVEL%
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
|
||||||
exec sh "$SCRIPT_DIR/scripts/iti.sh" "$@"
|
|
||||||
@ -1,226 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
ROOT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
|
||||||
cd "$ROOT_DIR"
|
|
||||||
|
|
||||||
ABOUT_FILE="$ROOT_DIR/iti/__about__.py"
|
|
||||||
COPIER_FILE="$ROOT_DIR/copier.yml"
|
|
||||||
COPIER_TEMPLATE_FILE="$ROOT_DIR/copier-template/pyproject.toml.jinja"
|
|
||||||
README_FILE="$ROOT_DIR/README.md"
|
|
||||||
|
|
||||||
die() {
|
|
||||||
printf '%s\n' "$*" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
parse_version() {
|
|
||||||
raw=$1
|
|
||||||
version=${raw#v}
|
|
||||||
old_ifs=$IFS
|
|
||||||
IFS=.
|
|
||||||
set -- $version
|
|
||||||
IFS=$old_ifs
|
|
||||||
|
|
||||||
if [ "$#" -ne 3 ]; then
|
|
||||||
die "invalid version: $raw"
|
|
||||||
fi
|
|
||||||
|
|
||||||
for part in "$@"; do
|
|
||||||
case $part in
|
|
||||||
''|*[!0-9]*)
|
|
||||||
die "invalid version: $raw"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
printf '%s %s %s\n' "$1" "$2" "$3"
|
|
||||||
}
|
|
||||||
|
|
||||||
normalize_version() {
|
|
||||||
set -- $(parse_version "$1")
|
|
||||||
printf '%s.%s.%s\n' "$1" "$2" "$3"
|
|
||||||
}
|
|
||||||
|
|
||||||
bump_patch() {
|
|
||||||
set -- $(parse_version "$1")
|
|
||||||
printf '%s.%s.%s\n' "$1" "$2" "$(( $3 + 1 ))"
|
|
||||||
}
|
|
||||||
|
|
||||||
version_is_newer() {
|
|
||||||
current_version=$1
|
|
||||||
target_version=$2
|
|
||||||
|
|
||||||
current_parts=$(parse_version "$current_version")
|
|
||||||
set -- $current_parts
|
|
||||||
current_major=$1
|
|
||||||
current_minor=$2
|
|
||||||
current_patch=$3
|
|
||||||
|
|
||||||
target_parts=$(parse_version "$target_version")
|
|
||||||
set -- $target_parts
|
|
||||||
target_major=$1
|
|
||||||
target_minor=$2
|
|
||||||
target_patch=$3
|
|
||||||
|
|
||||||
if [ "$target_major" -gt "$current_major" ]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
if [ "$target_major" -lt "$current_major" ]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
if [ "$target_minor" -gt "$current_minor" ]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
if [ "$target_minor" -lt "$current_minor" ]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
[ "$target_patch" -gt "$current_patch" ]
|
|
||||||
}
|
|
||||||
|
|
||||||
read_current_version() {
|
|
||||||
current_version=$(sed -n 's/^__version__[[:space:]]*=[[:space:]]*"\([^"]*\)".*$/\1/p' "$ABOUT_FILE" | sed -n '1p')
|
|
||||||
[ -n "$current_version" ] || die "version not found in $ABOUT_FILE"
|
|
||||||
printf '%s\n' "$current_version"
|
|
||||||
}
|
|
||||||
|
|
||||||
replace_first_line_with_prefix() {
|
|
||||||
file=$1
|
|
||||||
prefix=$2
|
|
||||||
new_line=$3
|
|
||||||
tmp_file=$(mktemp)
|
|
||||||
|
|
||||||
if awk -v prefix="$prefix" -v new="$new_line" '
|
|
||||||
BEGIN { done = 0 }
|
|
||||||
index($0, prefix) == 1 && !done {
|
|
||||||
print new
|
|
||||||
done = 1
|
|
||||||
next
|
|
||||||
}
|
|
||||||
{ print }
|
|
||||||
END { if (!done) exit 1 }
|
|
||||||
' "$file" >"$tmp_file"; then
|
|
||||||
mv "$tmp_file" "$file"
|
|
||||||
else
|
|
||||||
rm -f "$tmp_file"
|
|
||||||
die "line not updated in $file"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
replace_first_line_in_section_with_prefix() {
|
|
||||||
file=$1
|
|
||||||
section_header=$2
|
|
||||||
prefix=$3
|
|
||||||
new_line=$4
|
|
||||||
tmp_file=$(mktemp)
|
|
||||||
|
|
||||||
if awk -v section="$section_header" -v prefix="$prefix" -v new="$new_line" '
|
|
||||||
BEGIN { in_section = 0; done = 0 }
|
|
||||||
$0 == section { in_section = 1; print; next }
|
|
||||||
in_section && /^[^[:space:]]/ { in_section = 0 }
|
|
||||||
in_section && !done && index($0, prefix) == 1 {
|
|
||||||
print new
|
|
||||||
done = 1
|
|
||||||
next
|
|
||||||
}
|
|
||||||
{ print }
|
|
||||||
END { if (!done) exit 1 }
|
|
||||||
' "$file" >"$tmp_file"; then
|
|
||||||
mv "$tmp_file" "$file"
|
|
||||||
else
|
|
||||||
rm -f "$tmp_file"
|
|
||||||
die "line not updated in $file"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
write_about_version() {
|
|
||||||
target_version=$1
|
|
||||||
replace_first_line_with_prefix "$ABOUT_FILE" "__version__ = " "__version__ = \"$target_version\""
|
|
||||||
}
|
|
||||||
|
|
||||||
write_copier_framework_tag() {
|
|
||||||
target_version=$1
|
|
||||||
replace_first_line_in_section_with_prefix "$COPIER_FILE" "framework_tag:" " default: v" " default: v$target_version"
|
|
||||||
}
|
|
||||||
|
|
||||||
write_copier_system_tag() {
|
|
||||||
target_version=$1
|
|
||||||
replace_first_line_in_section_with_prefix "$COPIER_FILE" "system_tag:" " default: v" " default: v$target_version"
|
|
||||||
}
|
|
||||||
|
|
||||||
write_copier_template_version() {
|
|
||||||
target_version=$1
|
|
||||||
replace_first_line_with_prefix "$COPIER_TEMPLATE_FILE" "version = " "version = \"$target_version\""
|
|
||||||
}
|
|
||||||
|
|
||||||
write_readme_dependency_tag() {
|
|
||||||
target_version=$1
|
|
||||||
replace_first_line_with_prefix "$README_FILE" ' "iti-flask @ git+https://git.noahlan.cn/iti-framework/iTi-Flask.git@v' ' "iti-flask @ git+https://git.noahlan.cn/iti-framework/iTi-Flask.git@v'"$target_version"'",'
|
|
||||||
}
|
|
||||||
|
|
||||||
write_readme_release_examples() {
|
|
||||||
target_version=$1
|
|
||||||
replace_first_line_with_prefix "$README_FILE" './iti.sh release v' "./iti.sh release v$target_version"
|
|
||||||
replace_first_line_with_prefix "$README_FILE" 'iti.cmd release v' "iti.cmd release v$target_version"
|
|
||||||
}
|
|
||||||
|
|
||||||
ensure_clean_tree() {
|
|
||||||
if [ -n "$(git status --porcelain)" ]; then
|
|
||||||
die "working tree is not clean"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
ensure_branch() {
|
|
||||||
if branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null); then
|
|
||||||
[ -n "$branch" ] || die "release requires a branch checkout"
|
|
||||||
printf '%s\n' "$branch"
|
|
||||||
else
|
|
||||||
die "release requires a branch checkout"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
ensure_tag_absent() {
|
|
||||||
tag=$1
|
|
||||||
if git rev-parse --verify --quiet "refs/tags/$tag" >/dev/null; then
|
|
||||||
die "tag already exists: $tag"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
main() {
|
|
||||||
version_arg=${1:-}
|
|
||||||
current_version=$(read_current_version)
|
|
||||||
if [ -n "$version_arg" ]; then
|
|
||||||
target_version=$(normalize_version "$version_arg")
|
|
||||||
else
|
|
||||||
target_version=$(bump_patch "$current_version")
|
|
||||||
fi
|
|
||||||
target_tag="v$target_version"
|
|
||||||
|
|
||||||
if [ "$target_version" = "$current_version" ]; then
|
|
||||||
die "version already set to $target_version"
|
|
||||||
fi
|
|
||||||
if ! version_is_newer "$current_version" "$target_version"; then
|
|
||||||
die "target version must be newer than $current_version"
|
|
||||||
fi
|
|
||||||
|
|
||||||
ensure_clean_tree
|
|
||||||
branch=$(ensure_branch)
|
|
||||||
ensure_tag_absent "$target_tag"
|
|
||||||
uv run pytest -q
|
|
||||||
|
|
||||||
write_about_version "$target_version"
|
|
||||||
write_copier_framework_tag "$target_version"
|
|
||||||
write_copier_system_tag "$target_version"
|
|
||||||
write_copier_template_version "$target_version"
|
|
||||||
write_readme_dependency_tag "$target_version"
|
|
||||||
write_readme_release_examples "$target_version"
|
|
||||||
|
|
||||||
git add iti/__about__.py copier.yml copier-template/pyproject.toml.jinja README.md
|
|
||||||
git commit -m "chore: release $target_tag"
|
|
||||||
git tag -a "$target_tag" -m "release $target_tag"
|
|
||||||
git push origin "$branch" "$target_tag"
|
|
||||||
|
|
||||||
printf 'released %s\n' "$target_tag"
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
||||||
Loading…
Reference in New Issue