Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
FROM python:3.12-slim-trixie
FROM ubuntu:20.04

# The installer requires curl (and certificates) to download the release archive
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates git dos2unix vim
ENV DEBIAN_FRONTEND=noninteractive

# Download the latest installer
ADD https://astral.sh/uv/install.sh /uv-installer.sh
RUN apt-get update && apt-get install -y --no-install-recommends \
git curl build-essential dos2unix vim \
libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev \
wget llvm libncursesw5-dev xz-utils tk-dev libxml2-dev \
libxmlsec1-dev libffi-dev liblzma-dev ca-certificates \
&& rm -rf /var/lib/apt/lists/*

# Run the installer then remove it
RUN sh /uv-installer.sh && rm /uv-installer.sh
ENV PYENV_ROOT=/root/.pyenv
ENV PATH="$PYENV_ROOT/bin:$PYENV_ROOT/shims:/home/bugsinpy/framework/bin:$PATH"

# Ensure the installed binary is on the `PATH`
ENV PATH="/root/.local/bin/:$PATH"
ENV BUGSINPY_HOME="/home/bugsinpy/"
ENV PATH="$BUGSINPY_HOME/framework/bin:$PATH"
RUN curl -fsSL https://pyenv.run | bash && \
mkdir -p "$PYENV_ROOT/versions" "$PYENV_ROOT/cache" && \
pyenv rehash

ENV BUGSINPY_HOME=/home/bugsinpy

# Set working directory
WORKDIR /home

# Default command
CMD ["bash"]
CMD ["bash"]
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ docker build -t bugsinpy .
docker run -dt \
-v ./framework:/home/bugsinpy/framework \
-v ./projects:/home/bugsinpy/projects \
-v ./workspace:/home/workspace
-v ./workspace:/home/workspace \
-v bugsinpy-pyenv-versions:/root/.pyenv/versions \
-v bugsinpy-pyenv-cache:/root/.pyenv/cache \
--name {your_container_name} bugsinpy
docker exec -it {your_container_name} bash
```
Expand All @@ -35,6 +37,7 @@ Command | Description
info | Get the information of a specific project or a specific bug
checkout | Checkout buggy or fixed version project from dataset
compile | Compile sources from project that have been checkout
safe-compile | Compile sources using the Python version declared by the checked-out project's `bugsinpy_bug.info`
test | Run test case that relevant with bug, single-test case from input user, or all test cases from project
coverage | Run code coverage analysis from test case that relevant with bug, single-test case from input user, or all test cases
mutation | Run mutation analysis from input user or test case that relevant with bug
Expand All @@ -46,6 +49,5 @@ fuzz | Run a test input generation from specific bug
- Checkout a buggy source code version (youtube-dl, bug 2, buggy version):
- `bugsinpy-checkout -p youtube-dl -v 0 -i 2 -w /temp/projects`
- Compile sources and tests, and run tests from current directory:
- `bugsinpy-compile`
- `bugsinpy-safe-compile`
- `bugsinpy-test`

111 changes: 111 additions & 0 deletions framework/bin/bugsinpy-safe-compile
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/usr/bin/env bash

set -euo pipefail

usage="-w work_dir
The checked-out project directory to compile. Default will be the current directory.
--no-editable-install
Skip the post-compile editable install step.
--require-editable-install
Treat a failed editable install as a compile failure. By default it is best-effort.
"

print_usage() {
cat <<____HALP
Usage: ${0##*/} [ --help ] [ -w work_dir ] [ --no-editable-install ] [ --require-editable-install ]
$usage
____HALP
}

die() {
echo "bugsinpy-safe-compile: $*" >&2
exit 1
}

work_dir=""
run_editable_install="1"
require_editable_install="0"

while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
print_usage
exit 0
;;
-w)
shift
[[ $# -gt 0 ]] || die "-w requires a work directory"
work_dir="$1"
;;
--no-editable-install)
run_editable_install="0"
;;
--require-editable-install)
require_editable_install="1"
;;
*)
die "unknown argument: $1"
;;
esac
shift
done

if [[ -z "$work_dir" ]]; then
work_dir=$(pwd)
fi

cd "$work_dir" || die "cannot enter work directory: $work_dir"
work_dir=$(pwd)

[[ -e "$work_dir/bugsinpy_bug.info" ]] || die "this is not a checkout project folder: missing bugsinpy_bug.info"
[[ -e "$work_dir/bugsinpy_requirements.txt" ]] || die "this is not a checkout project folder: missing bugsinpy_requirements.txt"
[[ -e "$work_dir/bugsinpy_run_test.sh" ]] || die "this is not a checkout project folder: missing bugsinpy_run_test.sh"

PYVER=$(awk -F'"' '/^python_version=/{ print $2; exit }' "$work_dir/bugsinpy_bug.info")
[[ -n "$PYVER" ]] || die "could not read python_version from bugsinpy_bug.info"

command -v pyenv >/dev/null 2>&1 || die "pyenv is required but was not found on PATH"

echo "Using Python $PYVER for $work_dir"
pyenv install -s "$PYVER"
printf '%s\n' "$PYVER" > "$work_dir/.python-version"
export PYENV_VERSION="$PYVER"
pyenv rehash >/dev/null 2>&1 || true

actual_pyver=$(python3 -c 'import sys; print("{}.{}.{}".format(*sys.version_info[:3]))')
if [[ "$actual_pyver" != "$PYVER" ]]; then
die "python3 resolved to $actual_pyver, expected $PYVER"
fi

echo "Running bugsinpy-compile with Python $actual_pyver"
script_dir=$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
"$script_dir/bugsinpy-compile"

if [[ "$run_editable_install" == "1" ]]; then
if [[ -f "$work_dir/setup.py" || -f "$work_dir/pyproject.toml" ]]; then
echo "Running post-compile editable install"
set +e
if [[ -d "$work_dir/env/Scripts" ]]; then
# shellcheck disable=SC1091
source "$work_dir/env/Scripts/activate"
else
# shellcheck disable=SC1091
source "$work_dir/env/bin/activate"
fi
python -m pip install -e . --no-deps
editable_status=$?
deactivate >/dev/null 2>&1 || true
set -e

if [[ "$editable_status" -ne 0 ]]; then
if [[ "$require_editable_install" == "1" ]]; then
die "editable install failed"
fi
echo "Warning: editable install failed; continuing because it is best-effort by default" >&2
fi
else
echo "Skipping editable install: no setup.py or pyproject.toml found"
fi
fi

echo "Safe compile finished for $work_dir"