Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
zeriyoshi committed Aug 23, 2024
1 parent b161116 commit 7f9454c
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 86 deletions.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,31 @@ A sample MySQL configuration is included in `compose.yaml` (commented out).
Testing on Windows is possible through GitHub Actions.
A sample configuration for Windows CI is included in `.github/workflows/ci.yaml` (commented out).

## Code Coverage

### Checking Coverage in Development Environment

You can check the code coverage using lcov with the `pskel` command:

```bash
$ pskel coverage
~~~
Reading tracefile /workspaces/pskel/ext/lcov.info
|Lines |Functions |Branches
Filename |Rate Num|Rate Num|Rate Num
==================================================
[/workspaces/pskel/ext/]
bongo.c |75.0% 20|80.0% 5| - 0
==================================================
Total:|75.0% 20|80.0% 5| - 0
```

### Checking Coverage in GitHub Actions

You can use [octocov](https://github.com/k1LoW/octocov) to check coverage information in GitHub Actions.

When you create a Pull Request, octocov automatically comments with the coverage information.

## Frequently Asked Questions

### Q: Can I use debuggers like gdb or lldb?
Expand Down
25 changes: 25 additions & 0 deletions README_ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,31 @@ MySQL のサンプル設定が `compose.yaml` にコメントアウトされた
Windows上でのテストも、 GitHub Actions を通じて実行可能です。
`.github/workflows/ci.yaml`に Windows CI 用のサンプル設定がコメントアウトされています。

## コードカバレッジ

### 開発環境下での確認

`pskel` コマンドで lcov を利用したカバレッジの確認を行うことができます。

```bash
$ pskel coverage
~~~
Reading tracefile /workspaces/pskel/ext/lcov.info
|Lines |Functions |Branches
Filename |Rate Num|Rate Num|Rate Num
==================================================
[/workspaces/pskel/ext/]
bongo.c |75.0% 20|80.0% 5| - 0
==================================================
Total:|75.0% 20|80.0% 5| - 0
```

### GitHub Actions での確認

[octocov](https://github.com/k1LoW/octocov) を用いて GitHub Actions でカバレッジ情報を確認することができます。

Pull Request を作成すると自動的に octocov によるカバレッジがコメントされます。

## よくある質問

### Q: gdb や lldb などのデバッガは使用できますか?
Expand Down
2 changes: 1 addition & 1 deletion patches/ltmain.sh.patch
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
--- ext/build/ltmain.sh 2024-08-20 13:47:39.489351765 +0000
+++ ext/build/ltmainp.sh 2024-08-20 13:51:02.825496572 +0000
+++ ext/build/ltmain.sh 2024-08-20 13:51:02.825496572 +0000
@@ -3467,7 +3467,7 @@ EOF
tempremovelist=`$echo "$output_objdir/*"`
for p in $tempremovelist; do
Expand Down
214 changes: 129 additions & 85 deletions pskel.sh
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
#!/bin/sh -e
#!/bin/sh

set -e

get_ext_dir() {
PSKEL_EXT_DIR="/ext"

if test -d "${CODESPACE_VSCODE_FOLDER}"; then
echo "[Pskel] GitHub Codespace workspace detected, use \"${CODESPACE_VSCODE_FOLDER}/ext\"." >&2
if [ -d "${CODESPACE_VSCODE_FOLDER}" ]; then
echo "[Pskel] GitHub Codespace workspace detected, using \"${CODESPACE_VSCODE_FOLDER}/ext\"." >&2
PSKEL_EXT_DIR="${CODESPACE_VSCODE_FOLDER}/ext"
elif test -d "/workspaces/pskel/ext"; then
echo "[Pskel] Development Containers workspace detected, use \"/workspaces/pskel/ext\"." >&2
elif [ -d "/workspaces/pskel/ext" ]; then
echo "[Pskel] Development Containers workspace detected, using \"/workspaces/pskel/ext\"." >&2
PSKEL_EXT_DIR="/workspaces/pskel/ext"
else
if test -f "/ext/.gitkeep" && test $(cat "/ext/.gitkeep") = "pskel_uninitialized" && ! test "x${1}" = "x--no-init"; then
echo "[Pskel] Uninitialized project detected, initialize default skeleton." >&2
cmd_init "skeleton" >&2
fi
elif [ -f "/ext/.gitkeep" ] && [ "$(cat "/ext/.gitkeep")" = "pskel_uninitialized" ] && [ "${1}" != "--no-init" ]; then
echo "[Pskel] Uninitialized project detected, initializing default skeleton." >&2
cmd_init "skeleton" >&2
fi

echo "${PSKEL_EXT_DIR}"
Expand All @@ -24,79 +24,99 @@ cmd_usage() {
Usage: ${0} [task] ...
Available commands:
init create new extension
test test extension
build build PHP runtime
init create new extension
test test extension
build build PHP runtime
coverage generate code coverage
EOF
}

cmd_init() {
if test "${1}" = "-h" || test "${1}" = "--help" || test "${#}" -lt 1; then
cat << EOF
Usage: $0 init [extension_name] [ext_skel.php options...]
case "${1}" in
-h|--help)
cat << EOF
Usage: ${0} init [extension_name] [ext_skel.php options...]
EOF
return 0
fi
return 0
;;
"")
echo "Error: Extension name is required." >&2
return 1
;;
esac

PSKEL_EXT_DIR="$(get_ext_dir --no-init)"
/usr/local/bin/php "/usr/src/php/ext/ext_skel.php" --ext "${1}" --dir "/tmp" ${@}
/usr/local/bin/php "/usr/src/php/ext/ext_skel.php" --ext "${1}" --dir "/tmp" "${@}"
rm "${PSKEL_EXT_DIR}/.gitkeep"
rsync -av "/tmp/${1}/" "${PSKEL_EXT_DIR}/"
rm -rf "/tmp/${1}"
}

cmd_test() {
if test "${1}" = "-h" || test "${1}" = "--help"; then
cat << EOF
case "${1}" in
-h|--help)
cat << EOF
Usage: ${0} test [test_type|php_binary_name]
env:
CFLAGS, CPPFLAGS: Compile flags
TEST_PHP_ARGS: Test flags
Environment variables:
CFLAGS, CPPFLAGS: Compilation flags
TEST_PHP_ARGS: Test flags
EOF
return 0
fi

if test "x${1}" = "x"; then
CC="$(which "gcc")"; CXX="$(which "g++")"; CMD="php"
else
case "${1}" in
debug)
if ! type "debug-php" > /dev/null 2>&1; then
CC="$(which "gcc")" CXX="$(which "g++")" CFLAGS="-DZEND_TRACK_ARENA_ALLOC" CPPFLAGS="${CFLAGS}" CONFIGURE_OPTS="--enable-debug $(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';") --enable-option-checking=fatal --disable-phpdbg --disable-cgi --disable-fpm --enable-cli --without-pcre-jit --disable-opcache-jit --disable-zend-max-execution-timers" cmd_build "debug"
fi && \
CC="$(which "gcc")"; CXX="$(which "g++")"; CMD="debug-php";;
gcov)
if ! type "gcc-gcov-php" > /dev/null 2>&1; then
CC="$(which "gcc")" CXX="$(which "g++")" CFLAGS="--coverage -DZEND_TRACK_ARENA_ALLOC" CPPFLAGS="${CFLAGS}" CONFIGURE_OPTS="--enable-gcov --enable-debug $(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';") --enable-option-checking=fatal --disable-phpdbg --disable-cgi --disable-fpm --enable-cli --without-pcre-jit --disable-opcache-jit --disable-zend-max-execution-timers" cmd_build "gcc-gcov"
fi && \
CFLAGS="${CFLAGS} --coverage" CPPFLAGS="${CPPFLAGS} --coverage" CC="$(which "gcc")"; CXX="$(which "g++")"; CMD="gcc-gcov-php";;
valgrind)
if ! type "gcc-valgrind-php" > /dev/null 2>&1; then
CC="$(which "gcc")" CXX="$(which "g++")" CFLAGS="-DZEND_TRACK_ARENA_ALLOC" CPPFLAGS="${CFLAGS}" CONFIGURE_OPTS="--enable-debug $(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';") --enable-option-checking=fatal --disable-phpdbg --disable-cgi --disable-fpm --enable-cli --without-pcre-jit --disable-opcache-jit --disable-zend-max-execution-timers --with-valgrind" cmd_build "gcc-valgrind"
fi && \
TEST_PHP_ARGS="${TEST_PHP_ARGS} -m" CC="$(which "gcc")"; CXX="$(which "g++")"; CMD="gcc-valgrind-php";;
msan)
if ! type "clang-msan-php" > /dev/null 2>&1; then
CC="$(which "clang")" CXX="$(which "clang++")" CFLAGS="-DZEND_TRACK_ARENA_ALLOC" CPPFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS} -fsanitize=memory" CONFIGURE_OPTS="--enable-debug $(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';") --enable-option-checking=fatal --disable-phpdbg --disable-cgi --disable-fpm --enable-cli --without-pcre-jit --disable-opcache-jit --disable-zend-max-execution-timers --enable-memory-sanitizer" cmd_build "clang-msan"
fi && \
CFLAGS="${CFLAGS} -fsanitize=memory"; CPPFLAGS="${CPPFLAGS}"; LDFLAGS="-fsanitize=memory"; CC="$(which "clang")"; CXX="$(which "clang++")"; CMD="clang-msan-php";;
asan)
if ! type "clang-asan-php" > /dev/null 2>&1; then
CC="$(which "clang")" CXX="$(which "clang++")" CFLAGS="-DZEND_TRACK_ARENA_ALLOC" CPPFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS} -fsanitize=address" CONFIGURE_OPTS="--enable-debug $(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';") --enable-option-checking=fatal --disable-phpdbg --disable-cgi --disable-fpm --enable-cli --without-pcre-jit --disable-opcache-jit --disable-zend-max-execution-timers --enable-address-sanitizer" cmd_build "clang-asan"
fi && \
CFLAGS="${CFLAGS} -fsanitize=address"; CPPFLAGS="${CPPFLAGS}"; LDFLAGS="-fsanitize=address"; CC="$(which "clang")"; CXX="$(which "clang++")"; CMD="clang-asan-php";;
ubsan)
if ! type "clang-ubsan-php" > /dev/null 2>&1; then
CC="$(which "clang")" CXX="$(which "clang++")" CFLAGS="-DZEND_TRACK_ARENA_ALLOC" CPPFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS} -fsanitize=undefined" CONFIGURE_OPTS="--enable-debug $(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';") --enable-option-checking=fatal --disable-phpdbg --disable-cgi --disable-fpm --enable-cli --without-pcre-jit --disable-opcache-jit --disable-zend-max-execution-timers --enable-undefined-sanitizer" cmd_build "clang-ubsan"
fi && \
CFLAGS="${CFLAGS} -fsanitize=undefined"; CPPFLAGS="${CPPFLAGS}"; LDFLAGS="-fsanitize=undefined"; CC="$(which "clang")"; CXX="$(which "clang++")"; CMD="clang-ubsan-php";;
*) CMD="${1}"
esac
fi
return 0
;;
debug|gcov|valgrind)
CC="$(command -v "gcc")"
CXX="$(command -v "g++")"
case "${1}" in
debug) build_php_if_not_exists "debug";;
gcov)
CONFIGURE_OPTS="--enable-gcov"
build_php_if_not_exists "gcov"
CFLAGS="${CFLAGS} --coverage"
;;
valgrind)
CONFIGURE_OPTS="--with-valgrind"
build_php_if_not_exists "valgrind"
TEST_PHP_ARGS="${TEST_PHP_ARGS} -m"
;;
esac
CMD="$(basename "${CC}")-${1}-php"
;;
msan|asan|ubsan)
CC="$(command -v "clang")"
CXX="$(command -v "clang++")"
case "${1}" in
msan)
CONFIGURE_OPTS="--enable-memory-sanitizer"
build_php_if_not_exists "msan"
CFLAGS="${CFLAGS} -fsanitize=memory"
LDFLAGS="${LDFLAGS} -fsanitize=memory"
;;
asan)
CONFIGURE_OPTS="--enable-address-sanitizer"
build_php_if_not_exists "asan"
CFLAGS="${CFLAGS} -fsanitize=address"
LDFLAGS="${LDFLAGS} -fsanitize=address"
;;
ubsan)
CONFIGURE_OPTS="--enable-undefined-sanitizer"
build_php_if_not_exists "ubsan"
CFLAGS="${CFLAGS} -fsanitize=undefined"
LDFLAGS="${LDFLAGS} -fsanitize=undefined"
;;
esac
CMD="$(basename "${CC}")-${1}-php"
;;
"")
CMD="php"
;;
*)
CMD="${1}"
;;
esac

for BIN in "${CMD}" "${CMD}ize" "${CMD}-config"; do
if ! type "${BIN}" > /dev/null 2>&1; then
echo "Invalid argument: '${CMD}', executable file not found" >&2
if ! command -v "${BIN}" >/dev/null 2>&1; then
echo "Error: Invalid argument '${CMD}', executable file not found" >&2
exit 1
fi
done
Expand All @@ -105,31 +125,44 @@ EOF

cd "${PSKEL_EXT_DIR}"
"${CMD}ize"
if test "$("${CMD}" -r "echo PHP_VERSION_ID;")" -lt "80400"; then
if [ "$("${CMD}" -r "echo PHP_VERSION_ID;")" -lt "80400" ]; then
patch "./build/ltmain.sh" "./../patches/ltmain.sh.patch"
echo "[Pskel] ltmain.sh patched" >&2
fi
CC=${CC} CXX=${CXX} CFLAGS="${CFLAGS}" CPPFLAGS="${CPPFLAGS}" LDFLAGS="${LDFLAGS}" ./configure --with-php-config="$(which "${CMD}-config")"
CC="${CC}" CXX="${CXX}" CFLAGS="${CFLAGS}" CPPFLAGS="${CPPFLAGS}" LDFLAGS="${LDFLAGS}" ./configure --with-php-config="$(command -v "${CMD}-config")"
make clean
make -j"$(nproc)"
TEST_PHP_ARGS="${TEST_PHP_ARGS} --show-diff -q" make test
cd -
}

build_php_if_not_exists() {
if ! command -v "$(basename "${CC}")-${1}-php" >/dev/null 2>&1; then
CC="${CC}" \
CXX="${CXX}" \
CFLAGS="-DZEND_TRACK_ARENA_ALLOC" \
CPPFLAGS="${CFLAGS}" \
LDFLAGS="${LDFLAGS}" \
CONFIGURE_OPTS="${CONFIGURE_OPTS} --enable-debug $(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';") --enable-option-checking=fatal --disable-phpdbg --disable-cgi --disable-fpm --enable-cli --without-pcre-jit --disable-opcache-jit --disable-zend-max-execution-timers" \
cmd_build "$(basename "${CC}")-${1}"
fi
}

cmd_build() {
if test "${1}" = "-h" || test "${1}" = "--help"; then
cat << EOF
case "${1}" in
-h|--help)
cat << EOF
Usage: ${0} build [php_binary_prefix]
env:
CFLAGS, CPPFLAGS: Compile flags
CONFIGURE_OPTS: ./configure options
Environment variables:
CFLAGS, CPPFLAGS: Compilation flags
CONFIGURE_OPTS: ./configure options
EOF
return 0
fi

if ! test "x${1}" = "x"; then
CONFIGURE_OPTS="--program-prefix="${1}-" --includedir="/usr/local/include/${1}-php" ${CONFIGURE_OPTS}"
fi
return 0
;;
?*)
CONFIGURE_OPTS="--program-prefix=${1}- --includedir=/usr/local/include/${1}-php ${CONFIGURE_OPTS}"
;;
esac

cd "/usr/src/php"
./buildconf --force
Expand All @@ -142,11 +175,22 @@ EOF
}

cmd_coverage() {
case "${1}" in
-h|--help)
cat << EOF
Usage: ${0} coverage
Environment variables:
LCOV_OPTS: lcov capture options
EOF
return 0
;;
esac

cmd_test "gcov"

PSKEL_EXT_DIR="$(get_ext_dir)"

lcov --capture --directory "${PSKEL_EXT_DIR}" ${LCOV_OPTIONS} --exclude "/usr/local/include/*" --output-file "${PSKEL_EXT_DIR}/lcov.info"
lcov --capture --directory "${PSKEL_EXT_DIR}" ${LCOV_OPTS} --exclude "/usr/local/include/*" --output-file "${PSKEL_EXT_DIR}/lcov.info"
lcov --list "${PSKEL_EXT_DIR}/lcov.info"
}

Expand All @@ -156,11 +200,11 @@ if [ $# -eq 0 ]; then
fi

case "${1}" in
help) shift && cmd_usage;;
init) shift && cmd_init "${@}";;
test) shift && cmd_test "${@}";;
build) shift && cmd_build "${@}";;
coverage) shift && cmd_coverage "${@}";;
help) shift; cmd_usage;;
init) shift; cmd_init "${@}";;
test) shift; cmd_test "${@}";;
build) shift; cmd_build "${@}";;
coverage) shift; cmd_coverage "${@}";;
*)
echo "${0} error: invalid command: '${1}'" >&2
cmd_usage
Expand Down

0 comments on commit 7f9454c

Please sign in to comment.