diff --git a/.bazelversion b/.bazelversion deleted file mode 100644 index 024b066..0000000 --- a/.bazelversion +++ /dev/null @@ -1 +0,0 @@ -6.2.1 diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 0000000..49d9bf9 --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,92 @@ +module( + name = "pybind11_protobuf", + version = "head", +) + +bazel_dep( + name = "bazel_skylib", + version = "1.5.0", +) + +bazel_dep( + name = "abseil-cpp", + version = "20230802.0.bcr.1", + repo_name = "com_google_absl", +) + +http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "com_google_absl_py", + sha256 = "8a3d0830e4eb4f66c4fa907c06edf6ce1c719ced811a12e26d9d3162f8471758", + strip_prefix = "abseil-py-2.1.0", + urls = [ + "https://github.com/abseil/abseil-py/archive/refs/tags/v2.1.0.tar.gz", + ], +) + +bazel_dep( + name = "platforms", + version = "0.0.8" +) + +bazel_dep( + name = "pybind11_bazel", + version = "2.11.1.bzl.2", +) + +bazel_dep( + name = "protobuf", + version = "23.1", + repo_name = "com_google_protobuf" +) + +bazel_dep( + name = "grpc", + version = "1.56.3.bcr.1", + repo_name = "com_github_grpc_grpc", +) + +bazel_dep( + name = "rules_python", + version = "0.31.0", +) + +SUPPORTED_PYTHON_VERSIONS = [ + "3.12", + "3.11", + "3.10", + "3.9", + "3.8" +] + +DEFAULT_PYTHON = "3.11" + +python = use_extension("@rules_python//python/extensions:python.bzl", "python") +[ + python.toolchain( + python_version = version, + is_default = version == DEFAULT_PYTHON, + ) + for version in SUPPORTED_PYTHON_VERSIONS +] + +use_repo( + python, + python = "python_versions", +) + +#### DEV ONLY DEPENDENCIES BELOW HERE #### + +pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip", dev_dependency=True) +[ + pip.parse( + hub_name = "pypi", + python_version = version, + requirements_lock = "//pybind11_protobuf/requirements:requirements_lock_" + version.replace('.','_') + ".txt", + ) + for version in SUPPORTED_PYTHON_VERSIONS + +] + +use_repo(pip, "pypi") \ No newline at end of file diff --git a/WORKSPACE b/WORKSPACE index 810c71a..3d5d7ce 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -5,43 +5,92 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "bazel_skylib", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz", - "https://github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz" ], - sha256 = "c6966ec828da198c5d9adbaa94c05e3a1c7f21bd012a0b29ba8ddbccb2c93b0d", + sha256 = "cd55a062e763b9349921f0f5db8c3933288dc8ba4f76dd9416aac68acee3cb94", ) load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") bazel_skylib_workspace() - http_archive( name = "com_google_absl", - sha256 = "5366d7e7fa7ba0d915014d387b66d0d002c03236448e1ba9ef98122c13b35c36", # SHARED_ABSL_SHA - strip_prefix = "abseil-cpp-20230125.3", + sha256 = "59d2976af9d6ecf001a81a35749a6e551a335b949d34918cfade07737b9d93c5", # SHARED_ABSL_SHA + strip_prefix = "abseil-cpp-20230802.0", urls = [ - "https://github.com/abseil/abseil-cpp/archive/refs/tags/20230125.3.tar.gz", + "https://github.com/abseil/abseil-cpp/archive/refs/tags/20230802.0.tar.gz" ], ) http_archive( name = "com_google_absl_py", - repo_mapping = {"@six_archive": "@six"}, - sha256 = "0be59b82d65dfa1f995365dcfea2cc57989297b065fda696ef13f30fcc6c8e5b", - strip_prefix = "abseil-py-pypi-v0.15.0", + sha256 = "8a3d0830e4eb4f66c4fa907c06edf6ce1c719ced811a12e26d9d3162f8471758", + strip_prefix = "abseil-py-2.1.0", urls = [ - "https://github.com/abseil/abseil-py/archive/refs/tags/pypi-v0.15.0.tar.gz", + "https://github.com/abseil/abseil-py/archive/refs/tags/v2.1.0.tar.gz", + ], +) + +http_archive( + name = "rules_python", + sha256 = "c68bdc4fbec25de5b5493b8819cfc877c4ea299c0dcb15c244c5a00208cde311", + strip_prefix = "rules_python-0.31.0", + url = "https://github.com/bazelbuild/rules_python/releases/download/0.31.0/rules_python-0.31.0.tar.gz", +) + +load("@rules_python//python:repositories.bzl", "py_repositories", "python_register_multi_toolchains") + +py_repositories() + + +DEFAULT_PYTHON = "3.11" + +python_register_multi_toolchains( + name = "python", + default_version = DEFAULT_PYTHON, + python_versions = [ + "3.12", + "3.11", + "3.10", + "3.9", + "3.8" ], ) + +load("@python//:pip.bzl", "multi_pip_parse") + +multi_pip_parse( + name = "pypi", + default_version = DEFAULT_PYTHON, + python_interpreter_target = { + "3.12": "@python_3_12_host//:python", + "3.11": "@python_3_11_host//:python", + "3.10": "@python_3_10_host//:python", + "3.9": "@python_3_9_host//:python", + "3.8": "@python_3_8_host//:python", + }, + requirements_lock = { + "3.12": "//pybind11_protobuf/requirements:requirements_lock_3_12.txt", + "3.11": "//pybind11_protobuf/requirements:requirements_lock_3_11.txt", + "3.10": "//pybind11_protobuf/requirements:requirements_lock_3_10.txt", + "3.9": "//pybind11_protobuf/requirements:requirements_lock_3_9.txt", + "3.8": "//pybind11_protobuf/requirements:requirements_lock_3_8.txt", + }, +) + +load("@pypi//:requirements.bzl", "install_deps") + +install_deps() + ## `pybind11_bazel` (PINNED) # https://github.com/pybind/pybind11_bazel http_archive( name = "pybind11_bazel", - strip_prefix = "pybind11_bazel-23926b00e2b2eb2fc46b17e587cf0c0cfd2f2c4b", - sha256 = "f58c0d5bfd125b08075224c319a02a901c3bce11ff2cf8310c024d40f4af823e", - urls = ["https://github.com/pybind/pybind11_bazel/archive/23926b00e2b2eb2fc46b17e587cf0c0cfd2f2c4b.tar.gz"], + strip_prefix = "pybind11_bazel-2.11.1.bzl.2", + sha256 = "e2ba5f81f3bf6a3fc0417448d49389cc7950bebe48c42c33dfeb4dd59859b9a4", + urls = ["https://github.com/pybind/pybind11_bazel/releases/download/v2.11.1.bzl.2/pybind11_bazel-2.11.1.bzl.2.tar.gz"], ) ## `pybind11` (FLOATING) @@ -52,17 +101,14 @@ http_archive( urls = ["https://github.com/pybind/pybind11/archive/refs/heads/master.tar.gz"], ) -load("@pybind11_bazel//:python_configure.bzl", "python_configure") -python_configure(name = "local_config_python", python_version = "3") - # proto_library, cc_proto_library, and java_proto_library rules implicitly # depend on @com_google_protobuf for protoc and proto runtimes. # This statement defines the @com_google_protobuf repo. http_archive( name = "com_google_protobuf", - sha256 = "4e176116949be52b0408dfd24f8925d1eb674a781ae242a75296b17a1c721395", - strip_prefix = "protobuf-23.3", - urls = ["https://github.com/protocolbuffers/protobuf/archive/refs/tags/v23.3.tar.gz"], + sha256 = "d19643d265b978383352b3143f04c0641eea75a75235c111cc01a1350173180e", + strip_prefix = "protobuf-25.3", + urls = ["https://github.com/protocolbuffers/protobuf/releases/download/v25.3/protobuf-25.3.tar.gz"], ) load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps") @@ -73,15 +119,10 @@ protobuf_deps() # repositories, see b/189457935. http_archive( name = "com_github_grpc_grpc", - sha256 = "9f387689b7fdf6c003fd90ef55853107f89a2121792146770df5486f0199f400", - strip_prefix = "grpc-1.42.0", - urls = ["https://github.com/grpc/grpc/archive/v1.42.0.zip"], + sha256 = "84e31a77017911b2f1647ecadb0172671d96049ea9ad5109f02b4717c0f03702", + strip_prefix = "grpc-1.56.3", + urls = ["https://github.com/grpc/grpc/archive/refs/tags/v1.56.3.tar.gz"], ) load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps") grpc_deps() - -bind( - name = "python_headers", - actual = "@local_config_python//:python_headers", -) diff --git a/WORKSPACE.bzlmod b/WORKSPACE.bzlmod new file mode 100644 index 0000000..361ac60 --- /dev/null +++ b/WORKSPACE.bzlmod @@ -0,0 +1 @@ +# Empty file for cross-compatibility between MODULE.bazel and WORKSPACE \ No newline at end of file diff --git a/pybind11_protobuf/requirements/BUILD b/pybind11_protobuf/requirements/BUILD new file mode 100644 index 0000000..03545e1 --- /dev/null +++ b/pybind11_protobuf/requirements/BUILD @@ -0,0 +1,34 @@ +package( + default_visibility = ["//visibility:private"], +) + +load("@python//3.12:defs.bzl", compile_pip_requirements_3_12 = "compile_pip_requirements") +load("@python//3.11:defs.bzl", compile_pip_requirements_3_11 = "compile_pip_requirements") +load("@python//3.10:defs.bzl", compile_pip_requirements_3_10 = "compile_pip_requirements") +load("@python//3.9:defs.bzl", compile_pip_requirements_3_9 = "compile_pip_requirements") +load("@python//3.8:defs.bzl", compile_pip_requirements_3_8 = "compile_pip_requirements") +compile_pip_requirements_3_12( + name = "requirements_3_12", + src = "requirements.in", + requirements_txt = "requirements_lock_3_12.txt", +) +compile_pip_requirements_3_11( + name = "requirements_3_11", + src = "requirements.in", + requirements_txt = "requirements_lock_3_11.txt", +) +compile_pip_requirements_3_10( + name = "requirements_3_10", + src = "requirements.in", + requirements_txt = "requirements_lock_3_10.txt", +) +compile_pip_requirements_3_9( + name = "requirements_3_9", + src = "requirements.in", + requirements_txt = "requirements_lock_3_9.txt", +) +compile_pip_requirements_3_8( + name = "requirements_3_8", + src = "requirements.in", + requirements_txt = "requirements_lock_3_8.txt", +) diff --git a/requirements.txt b/pybind11_protobuf/requirements/requirements.in similarity index 100% rename from requirements.txt rename to pybind11_protobuf/requirements/requirements.in diff --git a/pybind11_protobuf/requirements/requirements_lock_3_10.txt b/pybind11_protobuf/requirements/requirements_lock_3_10.txt new file mode 100644 index 0000000..840bb56 --- /dev/null +++ b/pybind11_protobuf/requirements/requirements_lock_3_10.txt @@ -0,0 +1,10 @@ +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# bazel run //pybind11_protobuf/requirements:requirements_3_10.update +# +absl-py==2.1.0 \ + --hash=sha256:526a04eadab8b4ee719ce68f204172ead1027549089702d99b9059f129ff1308 \ + --hash=sha256:7820790efbb316739cde8b4e19357243fc3608a152024288513dd968d7d959ff + # via -r pybind11_protobuf/requirements/requirements.in diff --git a/pybind11_protobuf/requirements/requirements_lock_3_11.txt b/pybind11_protobuf/requirements/requirements_lock_3_11.txt new file mode 100644 index 0000000..5362764 --- /dev/null +++ b/pybind11_protobuf/requirements/requirements_lock_3_11.txt @@ -0,0 +1,10 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# bazel run //pybind11_protobuf/requirements:requirements_3_11.update +# +absl-py==2.1.0 \ + --hash=sha256:526a04eadab8b4ee719ce68f204172ead1027549089702d99b9059f129ff1308 \ + --hash=sha256:7820790efbb316739cde8b4e19357243fc3608a152024288513dd968d7d959ff + # via -r pybind11_protobuf/requirements/requirements.in diff --git a/pybind11_protobuf/requirements/requirements_lock_3_12.txt b/pybind11_protobuf/requirements/requirements_lock_3_12.txt new file mode 100644 index 0000000..91fa147 --- /dev/null +++ b/pybind11_protobuf/requirements/requirements_lock_3_12.txt @@ -0,0 +1,10 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# bazel run //pybind11_protobuf/requirements:requirements_3_12.update +# +absl-py==2.1.0 \ + --hash=sha256:526a04eadab8b4ee719ce68f204172ead1027549089702d99b9059f129ff1308 \ + --hash=sha256:7820790efbb316739cde8b4e19357243fc3608a152024288513dd968d7d959ff + # via -r pybind11_protobuf/requirements/requirements.in diff --git a/pybind11_protobuf/requirements/requirements_lock_3_8.txt b/pybind11_protobuf/requirements/requirements_lock_3_8.txt new file mode 100644 index 0000000..9e16dab --- /dev/null +++ b/pybind11_protobuf/requirements/requirements_lock_3_8.txt @@ -0,0 +1,10 @@ +# +# This file is autogenerated by pip-compile with Python 3.8 +# by the following command: +# +# bazel run //pybind11_protobuf/requirements:requirements_3_8.update +# +absl-py==2.1.0 \ + --hash=sha256:526a04eadab8b4ee719ce68f204172ead1027549089702d99b9059f129ff1308 \ + --hash=sha256:7820790efbb316739cde8b4e19357243fc3608a152024288513dd968d7d959ff + # via -r pybind11_protobuf/requirements/requirements.in diff --git a/pybind11_protobuf/requirements/requirements_lock_3_9.txt b/pybind11_protobuf/requirements/requirements_lock_3_9.txt new file mode 100644 index 0000000..14e60c3 --- /dev/null +++ b/pybind11_protobuf/requirements/requirements_lock_3_9.txt @@ -0,0 +1,10 @@ +# +# This file is autogenerated by pip-compile with Python 3.9 +# by the following command: +# +# bazel run //pybind11_protobuf/requirements:requirements_3_9.update +# +absl-py==2.1.0 \ + --hash=sha256:526a04eadab8b4ee719ce68f204172ead1027549089702d99b9059f129ff1308 \ + --hash=sha256:7820790efbb316739cde8b4e19357243fc3608a152024288513dd968d7d959ff + # via -r pybind11_protobuf/requirements/requirements.in diff --git a/pybind11_protobuf/tests/BUILD b/pybind11_protobuf/tests/BUILD index 8fb72aa..0349315 100644 --- a/pybind11_protobuf/tests/BUILD +++ b/pybind11_protobuf/tests/BUILD @@ -6,6 +6,7 @@ load("@com_github_grpc_grpc//bazel:python_rules.bzl", "py_proto_library") # Placeholder: load py_library load("@pybind11_bazel//:build_defs.bzl", "pybind_extension") # [internal] load cc_proto_library.bzl +load("@pypi//:requirements.bzl", "requirement") licenses(["notice"]) @@ -118,6 +119,7 @@ py_test( ":test_py_pb2", "@com_google_absl_py//absl/testing:absltest", "@com_google_protobuf//:protobuf_python", + requirement("absl_py"), ], ) @@ -141,9 +143,10 @@ py_test( deps = [ ":compare", ":test_py_pb2", + "@com_google_protobuf//:protobuf_python", "@com_google_absl_py//absl/testing:absltest", "@com_google_absl_py//absl/testing:parameterized", - "@com_google_protobuf//:protobuf_python", + requirement("absl_py"), ], ) @@ -221,9 +224,10 @@ py_test( deps = [ ":compare", ":test_py_pb2", + "@com_google_protobuf//:protobuf_python", "@com_google_absl_py//absl/testing:absltest", "@com_google_absl_py//absl/testing:parameterized", - "@com_google_protobuf//:protobuf_python", + requirement("absl_py"), ], ) @@ -245,9 +249,10 @@ py_test( srcs_version = "PY3", deps = [ ":test_py_pb2", + "@com_google_protobuf//:protobuf_python", "@com_google_absl_py//absl/testing:absltest", "@com_google_absl_py//absl/testing:parameterized", - "@com_google_protobuf//:protobuf_python", + requirement("absl_py"), ], ) @@ -287,6 +292,7 @@ py_test( "@com_google_absl_py//absl/testing:absltest", "@com_google_absl_py//absl/testing:parameterized", "@com_google_protobuf//:protobuf_python", + requirement("absl_py"), ], ) @@ -312,6 +318,7 @@ py_test( "@com_google_absl_py//absl/testing:absltest", "@com_google_absl_py//absl/testing:parameterized", "@com_google_protobuf//:protobuf_python", + requirement("absl_py"), ], ) @@ -329,8 +336,9 @@ py_test( srcs = ["regression_wrappers_test.py"], data = [":regression_wrappers_module.so"], deps = [ + "@com_google_protobuf//:protobuf_python", "@com_google_absl_py//absl/testing:absltest", "@com_google_absl_py//absl/testing:parameterized", - "@com_google_protobuf//:protobuf_python", + requirement("absl_py"), ], ) diff --git a/scripts/build_and_run_tests.sh b/scripts/build_and_run_tests.sh index c232092..29d5622 100755 --- a/scripts/build_and_run_tests.sh +++ b/scripts/build_and_run_tests.sh @@ -18,49 +18,6 @@ then exit 1 fi -is_in_virtual_env="false" -# if we are in a virtual_env, we will not create a new one inside. -if [[ "$VIRTUAL_ENV" != "" ]] -then - echo -e "\e[1m\e[93mVirtualenv already detected. We do not create a new one.\e[0m" - is_in_virtual_env="true" -fi - -echo -e "\e[33mRunning ${0} from $PWD\e[0m" -PYBIN=`which python3` -if [ ! -x $PYBIN ] -then - echo -e "\e[1m\e[93m$PYBIN not found! Skip build and test.\e[0m" - continue -fi - -PYVERSION=$($PYBIN -c 'import sys; print(".".join(map(str, sys.version_info[:3])))') - -VENV_DIR="./venv" - -if [[ $is_in_virtual_env == "false" ]]; then - if ! [ -d "$VENV_DIR" ]; then - echo "Installing..." - echo -e "\e[33mInstalling a virtualenv to $VENV_DIR. The setup is long the first time, please wait.\e[0m" - virtualenv -p $PYBIN $VENV_DIR - else - echo -e "\e[33mReusing virtualenv from $VENV_DIR.\e[0m" - fi - source $VENV_DIR/bin/activate -fi - -# We only exit the virtualenv if we created one. -function cleanup { - if [[ $is_in_virtual_env == "true" ]]; then - echo "Exiting virtualenv" - deactivate - fi -} -trap cleanup EXIT - -echo -e "\e[33mInstalling the requirements (use --noinstall to skip).\e[0m" -pip3 install --upgrade -r ./requirements.txt - echo "Building and testing in $PWD using 'python' (version $PYVERSION)." export PYTHON_BIN_PATH=`which python3` @@ -68,10 +25,34 @@ export PYTHON_LIB_PATH=`python3 -c "import sysconfig; print(sysconfig.get_path(' echo "Using PYTHON_BIN_PATH: $PYTHON_BIN_PATH" echo "Using PYTHON_LIB_PATH: $PYTHON_LIB_PATH" +bazel clean --expunge # Clean up dep cruft + +# Currently only a subset of tests build. The next one to fix is protobuf_test +BAZEL_CXXOPTS="-std=c++17" bazel test --test_output=errors \ + pybind11_protobuf/tests:extension_test \ + pybind11_protobuf/tests:message_test \ + pybind11_protobuf/tests:pass_by_test \ + pybind11_protobuf/tests:proto_enum_test \ + pybind11_protobuf/tests:wrapped_proto_module_test --enable_bzlmod + +BAZEL_CXXOPTS="-std=c++20" bazel test --test_output=errors \ + pybind11_protobuf/tests:extension_test \ + pybind11_protobuf/tests:message_test \ + pybind11_protobuf/tests:pass_by_test \ + pybind11_protobuf/tests:proto_enum_test \ + pybind11_protobuf/tests:wrapped_proto_module_test --enable_bzlmod + # Currently only a subset of tests build. The next one to fix is protobuf_test BAZEL_CXXOPTS="-std=c++17" bazel test --test_output=errors \ pybind11_protobuf/tests:extension_test \ pybind11_protobuf/tests:message_test \ pybind11_protobuf/tests:pass_by_test \ pybind11_protobuf/tests:proto_enum_test \ - pybind11_protobuf/tests:wrapped_proto_module_test + pybind11_protobuf/tests:wrapped_proto_module_test --noenable_bzlmod + +BAZEL_CXXOPTS="-std=c++20" bazel test --test_output=errors \ + pybind11_protobuf/tests:extension_test \ + pybind11_protobuf/tests:message_test \ + pybind11_protobuf/tests:pass_by_test \ + pybind11_protobuf/tests:proto_enum_test \ + pybind11_protobuf/tests:wrapped_proto_module_test --noenable_bzlmod diff --git a/scripts/google_run_tests.sh b/scripts/google_run_tests.sh deleted file mode 100755 index b2cc67b..0000000 --- a/scripts/google_run_tests.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/bash - -# Build using cmake and run the tests, without using google3 -# This uses copybara to copy everything and applies source-code transformations. -# -# If it fails, try deleting `~/tmp/pybind11_protobuf` before escalating. - -PIPERDIR=${PWD%%google3*} - -source gbash.sh || exit - -DEFINE_bool cp_source true 'Whether to copy the source code or not.' -DEFINE_bool build true 'If false, it will just run copybara and exit.' - -gbash::init_google "$@" - -if [ ! -f scripts/google_run_tests.sh ] -then - echo "This script must be run from the main pybind11_protobuf directory." - exit -1 -fi - -# The structure is the following: -# ~/tmp/pybind11_protobuf containing all the code. -# ~/tmp/pybind11_protobuf/venv for the Python 3 virtualenv - -TMPDIR="/tmp/pybind11_protobuf" -if [ ! -z "$HOME" ]; then - TMPDIR="$HOME/tmp/pybind11_protobuf" -fi -CODEDIR="$TMPDIR" - - -# CopyBara delete the files, but not the directories, thus we do it here (we -# clean everything except what we want to keep). -echo -e "\e[33mDeleting files $CODEDIR, except for venv/ and build/\e[0m" -# Delete all the code, except for the virtualenv directory -top_level_directories=$(find ${CODEDIR}/* -maxdepth 0 -type d | grep -v "/venv") -top_level_files=$(find ${CODEDIR}/* -maxdepth 0 -type f) -for d in $top_level_directories -do - echo "Deleting ${d}/*" - rm -rf $d -done -echo "" -for d in $top_level_files -do - echo "Deleting $d" - rm -f $d -done -mkdir -p $TMPDIR - - -set -e # Stop if any command fails - -if [[ $FLAGS_cp_source ]]; then - echo -e "\e[33mCopying source code from $PIPERDIR to $CODEDIR with copybara.\e[0m" - /google/data/ro/teams/copybara/copybara \ - $PIPERDIR/google3/pybind11_protobuf/copy.bara.sky \ - local_install $PIPERDIR --folder-dir $CODEDIR --ignore-noop -else - echo -e "\e[33mReusing source code from $CODEDIR.\e[0m" -fi - -if [[ $FLAGS_build == "false" ]]; then - echo -e "\e[33mFlag --build=false passed. Exiting now.\e[0m" - exit 1 -fi - -pushd $CODEDIR - -echo -e "\e[33mRunning $CODEDIR/scripts/build_and_run_tests.sh from $PWD\e[0m" - -echo -e "\e[32m*****************************\e[0m" -echo -e "\e[32mBuilding and testing in $PWD.\e[0m" -echo -e "\e[32m*****************************\e[0m" -echo "" - -bash "$CODEDIR/scripts/build_and_run_tests.sh" - -cd .. - -popd > /dev/null