From 787ebb838510d2915283c78758a36f7dab636384 Mon Sep 17 00:00:00 2001 From: Cody Hiar Date: Mon, 8 Nov 2021 10:44:42 -0700 Subject: Initial commit --- .gitignore | 6 + README.md | 21 +++ myapp/BUILD | 12 ++ myapp/myapp.py | 8 ++ myapp/requirements.txt | 1 + mylib/BUILD | 1 + mylib/__init__.py | 3 + mylib/main.py | 0 pants | 372 +++++++++++++++++++++++++++++++++++++++++++++++++ pants.toml | 9 ++ 10 files changed, 433 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 myapp/BUILD create mode 100644 myapp/myapp.py create mode 100644 myapp/requirements.txt create mode 100644 mylib/BUILD create mode 100644 mylib/__init__.py create mode 100644 mylib/main.py create mode 100755 pants create mode 100644 pants.toml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d2553fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# Pants workspace files +/.pants.d/ +/dist/ +/.pids +/.pants.workdir.file_lock* + diff --git a/README.md b/README.md new file mode 100644 index 0000000..340104c --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# Sample Pants Project + +This is just an example of how to use Pants to manage a monorepo. To run from +scratch you will need to activate a python interpreter `3.6.15` and the +following command. + +``` +./pants run myapp:pex +``` + +or to build a pex + +``` +./pants package myapp:pex +./dist/myapp/pex.pex +``` + +Things Tested: + - How to include a requirements + - How to pin a interpreter version (myapp) + - How to include an additional local dependancy (mylib) diff --git a/myapp/BUILD b/myapp/BUILD new file mode 100644 index 0000000..4061830 --- /dev/null +++ b/myapp/BUILD @@ -0,0 +1,12 @@ +python_library() + +# You don't need to pass in 'requirements_relpath' if the file +# is called 'requirements.txt' but I added this just for explicitness +python_requirements(requirements_relpath="requirements.txt") + +pex_binary( + name="pex", + dependencies=["mylib"], + entry_point="myapp.py", + interpreter_constraints=["CPython==3.6.15"], +) diff --git a/myapp/myapp.py b/myapp/myapp.py new file mode 100644 index 0000000..7f5c16b --- /dev/null +++ b/myapp/myapp.py @@ -0,0 +1,8 @@ +import requests + +import mylib + + +print(requests.get("https://www.google.com")) +print(requests.__version__) +mylib.hello_world() diff --git a/myapp/requirements.txt b/myapp/requirements.txt new file mode 100644 index 0000000..7d34355 --- /dev/null +++ b/myapp/requirements.txt @@ -0,0 +1 @@ +requests==2.25.0 diff --git a/mylib/BUILD b/mylib/BUILD new file mode 100644 index 0000000..d80ecb5 --- /dev/null +++ b/mylib/BUILD @@ -0,0 +1 @@ +python_library() diff --git a/mylib/__init__.py b/mylib/__init__.py new file mode 100644 index 0000000..3f1e31f --- /dev/null +++ b/mylib/__init__.py @@ -0,0 +1,3 @@ +"""My super library.""" +def hello_world(): + print("Hello World!") diff --git a/mylib/main.py b/mylib/main.py new file mode 100644 index 0000000..e69de29 diff --git a/pants b/pants new file mode 100755 index 0000000..f5b2b80 --- /dev/null +++ b/pants @@ -0,0 +1,372 @@ +#!/usr/bin/env bash +# Copyright 2020 Pants project contributors (see CONTRIBUTORS.md). +# Licensed under the Apache License, Version 2.0 (see LICENSE). + +# =============================== NOTE =============================== +# This ./pants bootstrap script comes from the pantsbuild/setup +# project. It is intended to be checked into your code repository so +# that other developers have the same setup. +# +# Learn more here: https://www.pantsbuild.org/docs/installation +# ==================================================================== + +set -eou pipefail + +# NOTE: To use an unreleased version of Pants from the pantsbuild/pants main branch, +# locate the main branch SHA, set PANTS_SHA= in the environment, and run this script as usual. +# +# E.g., PANTS_SHA=725fdaf504237190f6787dda3d72c39010a4c574 ./pants --version + +PYTHON_BIN_NAME="${PYTHON:-unspecified}" + +# Set this to specify a non-standard location for this script to read the Pants version from. +# NB: This will *not* cause Pants itself to use this location as a config file. +# You can use PANTS_CONFIG_FILES or --pants-config-files to do so. +PANTS_TOML=${PANTS_TOML:-pants.toml} + +PANTS_BIN_NAME="${PANTS_BIN_NAME:-$0}" + +PANTS_SETUP_CACHE="${PANTS_SETUP_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/pants/setup}" +# If given a relative path, we fix it to be absolute. +if [[ "$PANTS_SETUP_CACHE" != /* ]]; then + PANTS_SETUP_CACHE="${PWD}/${PANTS_SETUP_CACHE}" +fi + +PANTS_BOOTSTRAP="${PANTS_SETUP_CACHE}/bootstrap-$(uname -s)-$(uname -m)" + +_PEX_VERSION=2.1.42 +_PEX_URL="https://github.com/pantsbuild/pex/releases/download/v${_PEX_VERSION}/pex" +_PEX_EXPECTED_SHA256="69d6b1b1009b00dd14a3a9f19b72cff818a713ca44b3186c9b12074b2a31e51f" + +VIRTUALENV_VERSION=20.4.7 +VIRTUALENV_REQUIREMENTS=$( +cat << EOF +virtualenv==${VIRTUALENV_VERSION} --hash sha256:2b0126166ea7c9c3661f5b8e06773d28f83322de7a3ff7d06f0aed18c9de6a76 +filelock==3.0.12 --hash sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836 +six==1.16.0 --hash sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 +distlib==0.3.2 --hash sha256:23e223426b28491b1ced97dc3bbe183027419dfc7982b4fa2f05d5f3ff10711c +appdirs==1.4.4 --hash sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128 +importlib-resources==5.1.4; python_version < "3.7" --hash sha256:e962bff7440364183203d179d7ae9ad90cb1f2b74dcb84300e88ecc42dca3351 +importlib-metadata==4.5.0; python_version < "3.8" --hash sha256:833b26fb89d5de469b24a390e9df088d4e52e4ba33b01dc5e0e4f41b81a16c00 +zipp==3.4.1; python_version < "3.10" --hash sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098 +typing-extensions==3.10.0.0; python_version < "3.8" --hash sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84 +EOF +) + +COLOR_RED="\x1b[31m" +COLOR_GREEN="\x1b[32m" +COLOR_YELLOW="\x1b[33m" +COLOR_RESET="\x1b[0m" + +function log() { + echo -e "$@" 1>&2 +} + +function die() { + (($# > 0)) && log "${COLOR_RED}$*${COLOR_RESET}" + exit 1 +} + +function green() { + (($# > 0)) && log "${COLOR_GREEN}$*${COLOR_RESET}" +} + +function warn() { + (($# > 0)) && log "${COLOR_YELLOW}$*${COLOR_RESET}" +} + +function tempdir { + mkdir -p "$1" + mktemp -d "$1"/pants.XXXXXX +} + +function get_exe_path_or_die { + local exe="$1" + if ! command -v "${exe}"; then + die "Could not find ${exe}. Please ensure ${exe} is on your PATH." + fi +} + +function get_pants_config_value { + local config_key="$1" + local optional_space="[[:space:]]*" + local prefix="^${config_key}${optional_space}=${optional_space}" + local raw_value + raw_value="$(sed -ne "/${prefix}/ s#${prefix}##p" "${PANTS_TOML}")" + echo "${raw_value}" | tr -d \"\' && return 0 + return 0 +} + +function get_python_major_minor_version { + local python_exe="$1" + "$python_exe" <&1 > /dev/null)" == "pyenv: python${version}"* ]]; then + continue + fi + if [[ -n "$(check_python_exe_compatible_version "${interpreter_path}")" ]]; then + echo "${interpreter_path}" && return 0 + fi + done +} + +function determine_python_exe { + local pants_version="$1" + set_supported_python_versions "${pants_version}" + local requirement_str="For \`pants_version = \"${pants_version}\"\`, Pants requires Python ${supported_message} to run." + + local python_exe + if [[ "${PYTHON_BIN_NAME}" != 'unspecified' ]]; then + python_exe="$(get_exe_path_or_die "${PYTHON_BIN_NAME}")" || exit 1 + if [[ -z "$(check_python_exe_compatible_version "${python_exe}")" ]]; then + die "Invalid Python interpreter version for ${python_exe}. ${requirement_str}" + fi + else + python_exe="$(determine_default_python_exe)" + if [[ -z "${python_exe}" ]]; then + die "No valid Python interpreter found. ${requirement_str} Please check that a valid interpreter is installed and on your \$PATH." + fi + fi + echo "${python_exe}" +} + +function compute_sha256 { + local python="$1" + local path="$2" + + "$python" <&2 || exit 1 + fi + echo "${bootstrapped}" +} + +function scrub_PEX_env_vars { + # Ensure the virtualenv PEX runs as shrink-wrapped. + # See: https://github.com/pantsbuild/setup/issues/105 + if [[ -n "${!PEX_@}" ]]; then + warn "Scrubbing ${!PEX_@}" + unset "${!PEX_@}" + fi +} + +function bootstrap_virtualenv { + local python="$1" + local bootstrapped="${PANTS_BOOTSTRAP}/virtualenv-${VIRTUALENV_VERSION}/virtualenv.pex" + if [[ ! -f "${bootstrapped}" ]]; then + ( + green "Creating the virtualenv PEX." + pex_path="$(bootstrap_pex "${python}")" || exit 1 + mkdir -p "${PANTS_BOOTSTRAP}" + local staging_dir + staging_dir=$(tempdir "${PANTS_BOOTSTRAP}") + cd "${staging_dir}" + echo "${VIRTUALENV_REQUIREMENTS}" > requirements.txt + ( + scrub_PEX_env_vars + "${python}" "${pex_path}" -r requirements.txt -c virtualenv -o virtualenv.pex + ) + mkdir -p "$(dirname "${bootstrapped}")" + mv -f "${staging_dir}/virtualenv.pex" "${bootstrapped}" + rm -rf "${staging_dir}" + ) 1>&2 || exit 1 + fi + echo "${bootstrapped}" +} + +function find_links_url { + local pants_version="$1" + local pants_sha="$2" + echo -n "https://binaries.pantsbuild.org/wheels/pantsbuild.pants/${pants_sha}/${pants_version/+/%2B}/index.html" +} + +function get_version_for_sha { + local sha="$1" + + # Retrieve the Pants version associated with this commit. + local pants_version + pants_version="$(curl --fail -sL "https://raw.githubusercontent.com/pantsbuild/pants/${sha}/src/python/pants/VERSION")" + + # Construct the version as the release version from src/python/pants/VERSION, plus the string `+gitXXXXXXXX`, + # where the XXXXXXXX is the first 8 characters of the SHA. + echo "${pants_version}+git${sha:0:8}" +} + +function bootstrap_pants { + local pants_version="$1" + local python="$2" + local pants_sha="${3:-}" + + local pants_requirement="pantsbuild.pants==${pants_version}" + local maybe_find_links + if [[ -z "${pants_sha}" ]]; then + maybe_find_links="" + else + maybe_find_links="--find-links=$(find_links_url "${pants_version}" "${pants_sha}")" + fi + local python_major_minor_version + python_major_minor_version="$(get_python_major_minor_version "${python}")" + local target_folder_name="${pants_version}_py${python_major_minor_version}" + local bootstrapped="${PANTS_BOOTSTRAP}/${target_folder_name}" + + if [[ ! -d "${bootstrapped}" ]]; then + ( + green "Bootstrapping Pants using ${python}" + local staging_dir + staging_dir=$(tempdir "${PANTS_BOOTSTRAP}") + local virtualenv_path + virtualenv_path="$(bootstrap_virtualenv "${python}")" || exit 1 + green "Installing ${pants_requirement} into a virtual environment at ${bootstrapped}" + ( + scrub_PEX_env_vars + # shellcheck disable=SC2086 + "${python}" "${virtualenv_path}" --no-download "${staging_dir}/install" && \ + "${staging_dir}/install/bin/pip" install -U pip && \ + "${staging_dir}/install/bin/pip" install ${maybe_find_links} --progress-bar off "${pants_requirement}" + ) && \ + ln -s "${staging_dir}/install" "${staging_dir}/${target_folder_name}" && \ + mv "${staging_dir}/${target_folder_name}" "${bootstrapped}" && \ + green "New virtual environment successfully created at ${bootstrapped}." + ) 1>&2 || exit 1 + fi + echo "${bootstrapped}" +} + +# Ensure we operate from the context of the ./pants buildroot. +cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" +pants_version="$(determine_pants_version)" +python="$(determine_python_exe "${pants_version}")" +pants_dir="$(bootstrap_pants "${pants_version}" "${python}" "${PANTS_SHA:-}")" || exit 1 + +pants_python="${pants_dir}/bin/python" +pants_binary="${pants_dir}/bin/pants" +pants_extra_args="" +if [[ -n "${PANTS_SHA:-}" ]]; then + pants_extra_args="${pants_extra_args} --python-repos-repos=$(find_links_url "$pants_version" "$PANTS_SHA")" +fi + +# shellcheck disable=SC2086 +exec "${pants_python}" "${pants_binary}" ${pants_extra_args} \ + --pants-bin-name="${PANTS_BIN_NAME}" --pants-version=${pants_version} "$@" diff --git a/pants.toml b/pants.toml new file mode 100644 index 0000000..ca4fd82 --- /dev/null +++ b/pants.toml @@ -0,0 +1,9 @@ +[GLOBAL] +pants_version = "2.7.1" +backend_packages = ["pants.backend.python"] + +[anonymous-telemetry] +enabled = false + +[source] +marker_filenames = [".SOURCE_ROOT"] -- cgit v1.2.3