├── .github └── workflows │ └── pants.yaml ├── .gitignore ├── BUILD ├── LICENSE ├── README.md ├── get-pants.sh ├── pants.toml ├── pyproject.toml └── src ├── docker ├── caching │ ├── BUILD │ └── Dockerfile ├── dynamic_tags │ └── BUILD ├── hello_world │ ├── BUILD │ ├── Dockerfile.codegen │ ├── Dockerfile.python │ └── Dockerfile.shell └── multiplatform │ ├── BUILD │ ├── Dockerfile.base │ └── Dockerfile.final ├── python └── hello_world │ ├── BUILD │ ├── main.py │ └── main_test.py └── shell └── hello_world ├── BUILD └── main.sh /.github/workflows/pants.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Pants project contributors. 2 | # Licensed under the Apache License, Version 2.0 (see LICENSE). 3 | 4 | # See https://www.pantsbuild.org/stable/docs/using-pants/using-pants-in-ci for tips on how to set up your CI with Pants. 5 | 6 | name: Pants 7 | 8 | on: [push, pull_request] 9 | 10 | jobs: 11 | org-check: 12 | name: Check GitHub Organization 13 | if: ${{ github.repository_owner == 'pantsbuild' }} 14 | runs-on: ubuntu-24.04 15 | steps: 16 | - name: Noop 17 | run: "true" 18 | 19 | build: 20 | name: Perform CI Checks 21 | needs: org-check 22 | runs-on: ubuntu-24.04 23 | strategy: 24 | matrix: 25 | python-version: [3.8] 26 | steps: 27 | - uses: actions/checkout@v4 28 | 29 | - uses: actions/setup-python@v5 30 | with: 31 | python-version: ${{ matrix.python-version }} 32 | 33 | - uses: crazy-max/ghaction-setup-docker@v3 34 | with: 35 | daemon-config: | 36 | { 37 | "features": { 38 | "containerd-snapshotter": true 39 | } 40 | } 41 | 42 | - uses: docker/setup-buildx-action@v3 43 | with: 44 | install: true 45 | driver: docker 46 | 47 | # Required for multi-platform builds 48 | - name: Setup QEMU 49 | uses: docker/setup-qemu-action@v3 50 | with: 51 | platforms: linux/amd64,linux/arm64 52 | 53 | - name: Set up environment variables for Pants (Docker) to use GHA Cache 54 | uses: actions/github-script@v7 55 | with: 56 | script: | 57 | core.exportVariable("ACTIONS_CACHE_URL", process.env.ACTIONS_CACHE_URL || ""); 58 | core.exportVariable("ACTIONS_RUNTIME_TOKEN", process.env.ACTIONS_RUNTIME_TOKEN || ""); 59 | 60 | - uses: pantsbuild/actions/init-pants@v9 61 | # This action bootstraps pants and manages 2-3 GHA caches. 62 | # See: github.com/pantsbuild/actions/tree/main/init-pants/ 63 | with: 64 | # v0 makes it easy to bust the cache if needed 65 | # just increase the integer to start with a fresh cache 66 | gha-cache-key: v0 67 | # This repo has no 3rd-party requirements and no lockfiles, so we don't invalidate 68 | # the named caches on anything extra. See other example repos for better examples of 69 | # how to set up this cache. 70 | named-caches-hash: "" 71 | # If you're not using a fine-grained remote caching service (see https://www.pantsbuild.org/docs/remote-caching), 72 | # then you may also want to preserve the local Pants cache (lmdb_store). However this must invalidate for 73 | # changes to any file that can affect the build, so may not be practical in larger repos. 74 | # A remote cache service integrates with Pants's fine-grained invalidation and avoids these problems. 75 | cache-lmdb-store: "true" # defaults to 'false' 76 | # Note that named_caches and lmdb_store falls back to partial restore keys which 77 | # may give a useful partial result that will save time over completely clean state, 78 | # but will cause the cache entry to grow without bound over time. 79 | # See https://www.pantsbuild.org/stable/docs/using-pants/using-pants-in-ci for tips on how to periodically clean it up. 80 | # Alternatively you change gha-cache-key to ignore old caches. 81 | 82 | - name: Bootstrap Pants 83 | run: pants --version 84 | 85 | - name: Check Pants config files 86 | run: pants tailor --check update-build-files --check '::' 87 | 88 | - name: Lint, compile, and test 89 | run: pants lint check test '::' 90 | 91 | - name: Package / Run 92 | env: 93 | DYNAMIC_TAG: workflow 94 | run: | 95 | pants --docker-build-verbose package :: 96 | 97 | - name: Upload Pants log 98 | uses: actions/upload-artifact@v4 99 | with: 100 | name: pants-log 101 | path: .pants.d/pants.log 102 | if: always() # We want the log even on failures. 103 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Pants workspace files 2 | /.pants.d/ 3 | /dist/ 4 | /.pids 5 | /.pants.workdir.file_lock* 6 | 7 | *~ 8 | *.pyc 9 | __pycache__/ 10 | -------------------------------------------------------------------------------- /BUILD: -------------------------------------------------------------------------------- 1 | shell_sources(name="get-pants") 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # example-docker 2 | 3 | An example repository to demonstrate Pantsbuild's experimental Docker support. 4 | 5 | See [pantsbuild.org](https://www.pantsbuild.org/docs) for much more detailed documentation. 6 | 7 | This is only one possible way of laying out your project with Pantsbuild. See 8 | [pantsbuild.org/docs/source-roots#examples](https://www.pantsbuild.org/docs/source-roots#examples) 9 | for some other example layouts. 10 | 11 | Note: Pantsbuild and Pants will be used interchangebly, they refer to the same thing, the Pants 12 | Build System. 13 | 14 | 15 | # Running Pantsbuild 16 | 17 | You run Pants goals using the `pants` launcher binary, which will bootstrap the 18 | version of Pants configured for this repo if necessary. 19 | 20 | See [here](https://www.pantsbuild.org/docs/installation) for how to install the `pants` binary. 21 | 22 | Use `pants --version` to see the version of Pants configured for the repo (which you can also find 23 | in `pants.toml`). 24 | 25 | 26 | # Goals 27 | 28 | Pants commands are called _goals_. You can get a list of goals with 29 | 30 | ``` 31 | pants help goals 32 | ``` 33 | 34 | Most goals take arguments to run on. To run on a single directory, use the directory name with `:` 35 | at the end. To recursively run on a directory and all its subdirectories, add `::` to the end. 36 | 37 | For example: 38 | 39 | ``` 40 | pants lint src/python/hello_world: src/docker:: 41 | ``` 42 | 43 | You can run on all changed files: 44 | 45 | ``` 46 | pants --changed-since=HEAD lint 47 | ``` 48 | 49 | You can run on all changed files, and any of their "dependees": 50 | 51 | ``` 52 | pants --changed-since=HEAD --changed-dependees=transitive test 53 | ``` 54 | 55 | 56 | # Example Goals 57 | 58 | Try these out in this repo! 59 | 60 | 61 | ## Run a Docker image 62 | 63 | ``` 64 | pants run src/docker/hello_world:python 65 | pants run src/docker/hello_world:shell 66 | ``` 67 | 68 | 69 | ## List targets 70 | 71 | ``` 72 | pants list :: # All targets. 73 | pants list 'src/**/*.py' # Just targets containing Python code. 74 | ``` 75 | 76 | 77 | ## Run linters, formatters and fixers 78 | 79 | ``` 80 | pants fix lint :: # First format and fix, then lint all sources. 81 | ``` 82 | 83 | 84 | ## Count lines of code 85 | 86 | ``` 87 | pants count-loc '**/*' 88 | ``` 89 | 90 | 91 | ## Dynamic image tag 92 | 93 | The documentation for [dynamic image 94 | tagging](https://www.pantsbuild.org/docs/tagging-docker-images#using-env-vars-to-include-dynamic-data-in-tags) 95 | has an example implementation here showcasing how it works. 96 | 97 | ``` 98 | DYNAMIC_TAG=$(date +%Y.%m.%d) pants package src/docker/dynamic_tags 99 | 100 | 10:47:43.89 [INFO] Completed: Building docker image dynamic_tags:1.0-2022.03.15 101 | 10:47:43.89 [INFO] Built docker image: dynamic_tags:1.0-2022.03.15 102 | Docker image ID: sha256:8f6922aec0de7c147862672fa2cef4bd72f51e02b5a06089b0383355410b79f2 103 | 104 | DYNAMIC_TAG=$(date +%Y.%m.%d) pants run src/docker/dynamic_tags 105 | 10:47:43.89 [INFO] Completed: Building docker image dynamic_tags:1.0-2022.03.15 106 | ____ 107 | | demo | 108 | ==== 109 | \ 110 | \ 111 | ^__^ 112 | (oo)\_______ 113 | (__)\ )\/\ 114 | ||----w | 115 | || || 116 | ``` 117 | -------------------------------------------------------------------------------- /get-pants.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2023 Pants project contributors (see CONTRIBUTORS.md). 3 | # Licensed under the Apache License, Version 2.0 (see LICENSE). 4 | 5 | set -euo pipefail 6 | 7 | COLOR_RED="\x1b[31m" 8 | COLOR_GREEN="\x1b[32m" 9 | COLOR_YELLOW="\x1b[33m" 10 | COLOR_RESET="\x1b[0m" 11 | 12 | function log() { 13 | echo -e "$@" 1>&2 14 | } 15 | 16 | function die() { 17 | (($# > 0)) && log "${COLOR_RED}$*${COLOR_RESET}" 18 | exit 1 19 | } 20 | 21 | function green() { 22 | (($# > 0)) && log "${COLOR_GREEN}$*${COLOR_RESET}" 23 | } 24 | 25 | function warn() { 26 | (($# > 0)) && log "${COLOR_YELLOW}$*${COLOR_RESET}" 27 | } 28 | 29 | function check_cmd() { 30 | local cmd="$1" 31 | command -v "$cmd" >/dev/null || die "This script requires the ${cmd} binary to be on the PATH." 32 | } 33 | 34 | help_url="https://www.pantsbuild.org/docs/getting-help" 35 | 36 | _GC=() 37 | 38 | function gc() { 39 | if (($# > 0)); then 40 | check_cmd rm 41 | _GC+=("$@") 42 | else 43 | rm -rf "${_GC[@]}" 44 | fi 45 | } 46 | 47 | trap gc EXIT 48 | 49 | check_cmd uname 50 | 51 | function calculate_os() { 52 | local os 53 | 54 | os="$(uname -s)" 55 | if [[ "${os}" =~ [Ll]inux ]]; then 56 | echo linux 57 | elif [[ "${os}" =~ [Dd]arwin ]]; then 58 | echo macos 59 | elif [[ "${os}" =~ [Ww]in|[Mm][Ii][Nn][Gg] ]]; then 60 | # Powershell reports something like: Windows_NT 61 | # Git bash reports something like: MINGW64_NT-10.0-22621 62 | echo windows 63 | else 64 | die "Pants is not supported on this operating system (${os}). Please reach out to us at ${help_url} for help." 65 | fi 66 | } 67 | 68 | OS="$(calculate_os)" 69 | 70 | check_cmd basename 71 | if [[ "${OS}" == "windows" ]]; then 72 | check_cmd pwsh 73 | else 74 | check_cmd curl 75 | fi 76 | 77 | function fetch() { 78 | local url="$1" 79 | local dest_dir="$2" 80 | 81 | local dest 82 | dest="${dest_dir}/$(basename "${url}")" 83 | 84 | if [[ "${OS}" == "windows" ]]; then 85 | pwsh -c "Invoke-WebRequest -OutFile $dest -Uri $url" 86 | else 87 | curl --proto '=https' --tlsv1.2 -sSfL -o "${dest}" "${url}" 88 | fi 89 | } 90 | 91 | if [[ "${OS}" == "macos" ]]; then 92 | check_cmd shasum 93 | else 94 | check_cmd sha256sum 95 | fi 96 | 97 | function sha256() { 98 | if [[ "${OS}" == "macos" ]]; then 99 | shasum --algorithm 256 "$@" 100 | else 101 | sha256sum "$@" 102 | fi 103 | } 104 | 105 | check_cmd mktemp 106 | 107 | function install_from_url() { 108 | local url="$1" 109 | local dest="$2" 110 | 111 | local workdir 112 | workdir="$(mktemp -d)" 113 | gc "${workdir}" 114 | 115 | fetch "${url}.sha256" "${workdir}" 116 | fetch "${url}" "${workdir}" 117 | ( 118 | cd "${workdir}" 119 | sha256 -c --status ./*.sha256 || 120 | die "Download from ${url} did not match the fingerprint at ${url}.sha256" 121 | ) 122 | rm "${workdir}/"*.sha256 123 | if [[ "${OS}" == "macos" ]]; then 124 | mkdir -p "$(dirname "${dest}")" 125 | install -m 755 "${workdir}/"* "${dest}" 126 | else 127 | install -D -m 755 "${workdir}/"* "${dest}" 128 | fi 129 | } 130 | 131 | function calculate_arch() { 132 | local arch 133 | 134 | arch="$(uname -m)" 135 | if [[ "${arch}" =~ x86[_-]64 ]]; then 136 | echo x86_64 137 | elif [[ "${arch}" =~ arm64|aarch64 ]]; then 138 | echo aarch64 139 | else 140 | die "Pants is not supported for this chip architecture (${arch}). Please reach out to us at ${help_url} for help." 141 | fi 142 | } 143 | 144 | check_cmd cat 145 | 146 | function usage() { 147 | cat < 0)); do 183 | case "$1" in 184 | --help | -h) 185 | usage 186 | exit 0 187 | ;; 188 | --bin-dir | -d) 189 | bin_dir="$2" 190 | shift 191 | ;; 192 | --base-name | -b) 193 | base_name="$2" 194 | shift 195 | ;; 196 | --version | -V) 197 | version="download/v$2" 198 | shift 199 | ;; 200 | *) 201 | usage 202 | die "Unexpected argument $1\n" 203 | ;; 204 | esac 205 | shift 206 | done 207 | 208 | ARCH="$(calculate_arch)" 209 | URL="https://github.com/pantsbuild/scie-pants/releases/${version}/scie-pants-${OS}-${ARCH}" 210 | dest="${bin_dir}/${base_name}" 211 | 212 | log "Downloading and installing the pants launcher ..." 213 | install_from_url "${URL}" "${dest}" 214 | green "Installed the pants launcher from ${URL} to ${dest}" 215 | if ! command -v "${base_name}" >/dev/null; then 216 | warn "${dest} is not on the PATH." 217 | log "You'll either need to invoke ${dest} explicitly or else add ${bin_dir} to your shell's PATH." 218 | fi 219 | 220 | green "\nRunning \`pants\` in a Pants-enabled repo will use the version of Pants configured for that repo." 221 | green "In a repo not yet Pants-enabled, it will prompt you to set up Pants for that repo." 222 | -------------------------------------------------------------------------------- /pants.toml: -------------------------------------------------------------------------------- 1 | [GLOBAL] 2 | pants_version = "2.25.1" 3 | 4 | backend_packages = [ 5 | "pants.backend.docker", 6 | "pants.backend.docker.lint.hadolint", 7 | "pants.backend.python.lint.autoflake", 8 | "pants.backend.python", 9 | "pants.backend.python.lint.black", 10 | "pants.backend.python.lint.docformatter", 11 | "pants.backend.python.lint.flake8", 12 | "pants.backend.python.lint.isort", 13 | "pants.backend.python.typecheck.mypy", 14 | "pants.backend.shell", 15 | "pants.backend.shell.lint.shellcheck", 16 | "pants.backend.shell.lint.shfmt", 17 | ] 18 | 19 | [anonymous-telemetry] 20 | enabled = true 21 | repo_id = "B573B56B-6289-40C5-ADB7-4C5FA659EAD1" 22 | 23 | 24 | [python] 25 | # We use a narrow interpreter constraint to ensure that Python PEX'es will be executable by our 26 | # selected Docker base image, `python:3.8`. 27 | interpreter_constraints = ["==3.8.*"] 28 | 29 | [python-infer] 30 | use_rust_parser = true 31 | 32 | [docker] 33 | env_vars = [ 34 | "ACTIONS_CACHE_URL", 35 | "ACTIONS_RUNTIME_TOKEN", 36 | "DYNAMIC_TAG", 37 | ] 38 | use_buildx=true 39 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.isort] 2 | profile = "black" 3 | line_length = 100 4 | 5 | [tool.black] 6 | line-length = 100 7 | 8 | [tool.mypy] 9 | namespace_packages = true 10 | explicit_package_bases = true 11 | mypy_path = "src/python" 12 | -------------------------------------------------------------------------------- /src/docker/caching/BUILD: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Pants project contributors. 2 | # Licensed under the Apache License, Version 2.0 (see LICENSE). 3 | 4 | docker_image( 5 | name="with-gha-cache-backend", 6 | cache_to={"type": "gha", "mode": "max"}, 7 | cache_from={"type": "gha"}, 8 | ) 9 | -------------------------------------------------------------------------------- /src/docker/caching/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300 2 | 3 | RUN echo "hello" > msg.txt && \ 4 | sleep 60 5 | -------------------------------------------------------------------------------- /src/docker/dynamic_tags/BUILD: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Pants project contributors. 2 | # Licensed under the Apache License, Version 2.0 (see LICENSE). 3 | 4 | # Example how to provide dynamic data to the built image tag. Demo for documentation at 5 | # https://www.pantsbuild.org/docs/tagging-docker-images#using-env-vars-to-include-dynamic-data-in-tags 6 | 7 | docker_image( 8 | # Build args may also be provided globally for all `docker_image` targets under 9 | # `[docker].build_args` in pants.toml. 10 | extra_build_args=["DYNAMIC_TAG"], 11 | image_tags=["1.0-{build_args.DYNAMIC_TAG}"], 12 | instructions=[ 13 | # In case the value is only optionally provided from the environment, a default value may be 14 | # provided in the Dockerfile instruction, while still being overridable from the environment. 15 | # 16 | # "ARG DYNAMIC_TAG=default", 17 | "FROM python:3.8", 18 | "RUN pip install --no-cache-dir cowsay==4.0", 19 | 'CMD ["cowsay", "demo"]', 20 | ], 21 | ) 22 | -------------------------------------------------------------------------------- /src/docker/hello_world/BUILD: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Pants project contributors. 2 | # Licensed under the Apache License, Version 2.0 (see LICENSE). 3 | 4 | docker_image( 5 | name="python", 6 | source="Dockerfile.python", 7 | ) 8 | 9 | docker_image( 10 | name="shell", 11 | source="Dockerfile.shell", 12 | # This dependency is not yet inferred from the Dockerfile. 13 | dependencies=["src/shell/hello_world"], 14 | ) 15 | 16 | docker_image( 17 | name="codegen", 18 | source="Dockerfile.codegen", 19 | dependencies=[":hello_msg"], 20 | context_root="./", 21 | ) 22 | 23 | shell_command( 24 | name="hello_msg", 25 | execution_dependencies=["src/shell/hello_world"], 26 | output_files=["msg.txt"], 27 | command="../../shell/hello_world/main.sh > msg.txt", 28 | tools=["echo", "sh"], 29 | ) 30 | -------------------------------------------------------------------------------- /src/docker/hello_world/Dockerfile.codegen: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Pants project contributors. 2 | # Licensed under the Apache License, Version 2.0 (see LICENSE). 3 | 4 | FROM alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300 5 | CMD ["cat", "msg.txt"] 6 | COPY msg.txt / 7 | -------------------------------------------------------------------------------- /src/docker/hello_world/Dockerfile.python: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Pants project contributors. 2 | # Licensed under the Apache License, Version 2.0 (see LICENSE). 3 | 4 | FROM python:3.8 5 | ENTRYPOINT ["/bin/main.pex"] 6 | COPY src.python.hello_world/main.pex /bin 7 | -------------------------------------------------------------------------------- /src/docker/hello_world/Dockerfile.shell: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Pants project contributors. 2 | # Licensed under the Apache License, Version 2.0 (see LICENSE). 3 | 4 | FROM alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300 5 | ENTRYPOINT ["/bin/main.sh"] 6 | COPY src/shell/hello_world/main.sh /bin/ 7 | -------------------------------------------------------------------------------- /src/docker/multiplatform/BUILD: -------------------------------------------------------------------------------- 1 | # Note that multistage buildx builds requires using the containerd image store, due to 2 | # limitations with the docker-container driver (https://github.com/moby/buildkit/issues/2343) 3 | 4 | docker_image( 5 | name="multiplatform-base", 6 | source="Dockerfile.base", 7 | skip_push=True, 8 | build_platform=["linux/amd64", "linux/arm64"], 9 | ) 10 | 11 | docker_image( 12 | name="multiplatform-final", 13 | source="Dockerfile.final", 14 | build_platform=["linux/amd64", "linux/arm64"], 15 | ) 16 | -------------------------------------------------------------------------------- /src/docker/multiplatform/Dockerfile.base: -------------------------------------------------------------------------------- 1 | FROM python:3.8 2 | 3 | RUN echo "base image" >> base.txt 4 | -------------------------------------------------------------------------------- /src/docker/multiplatform/Dockerfile.final: -------------------------------------------------------------------------------- 1 | ARG PARENT=:multiplatform-base 2 | # hadolint ignore=DL3006 3 | FROM ${PARENT} 4 | 5 | RUN cat base.txt && \ 6 | echo "final image" >> final.txt 7 | -------------------------------------------------------------------------------- /src/python/hello_world/BUILD: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Pants project contributors. 2 | # Licensed under the Apache License, Version 2.0 (see LICENSE). 3 | 4 | python_sources() 5 | 6 | pex_binary( 7 | name="main", 8 | entry_point="main.py", 9 | ) 10 | 11 | python_tests( 12 | name="tests", 13 | ) 14 | -------------------------------------------------------------------------------- /src/python/hello_world/main.py: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Pants project contributors. 2 | # Licensed under the Apache License, Version 2.0 (see LICENSE). 3 | 4 | 5 | def main() -> None: 6 | print("Hello World!") 7 | 8 | 9 | if __name__ == "__main__": 10 | main() 11 | -------------------------------------------------------------------------------- /src/python/hello_world/main_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Pants project contributors. 2 | # Licensed under the Apache License, Version 2.0 (see LICENSE). 3 | 4 | from hello_world.main import main 5 | 6 | 7 | def test_main(capsys) -> None: 8 | main() 9 | assert capsys.readouterr().out == "Hello World!\n" 10 | -------------------------------------------------------------------------------- /src/shell/hello_world/BUILD: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Pants project contributors. 2 | # Licensed under the Apache License, Version 2.0 (see LICENSE). 3 | 4 | shell_sources() 5 | -------------------------------------------------------------------------------- /src/shell/hello_world/main.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # Copyright 2022 Pants project contributors. 3 | # Licensed under the Apache License, Version 2.0 (see LICENSE). 4 | 5 | echo "Hello World!" 6 | --------------------------------------------------------------------------------