├── .circleci ├── config.yml └── test-deploy.yml ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── BUG.md │ ├── FEATURE_REQUEST.md │ └── config.yml └── PULL_REQUEST_TEMPLATE │ └── PULL_REQUEST.md ├── .gitignore ├── .yamllint ├── LICENSE ├── README.md ├── sample_pip ├── requirements.txt ├── setup.py ├── src │ └── example.py └── tests │ ├── __init__.py │ ├── test_ex.py │ └── test_job.py ├── sample_pip_pyproject ├── pyproject.toml ├── requirements.txt ├── src │ └── example.py └── tests │ ├── __init__.py │ ├── test_ex.py │ └── test_job.py ├── sample_pipenv ├── Pipfile ├── Pipfile.lock └── tests │ ├── __init__.py │ └── test_job.py ├── sample_poetry ├── poetry.lock ├── pyproject.toml └── tests │ ├── __init__.py │ └── test_job.py ├── sample_uv ├── pyproject.toml ├── tests │ ├── __init__.py │ └── test_job.py └── uv.lock └── src ├── @orb.yml ├── commands ├── dist.yml └── install-packages.yml ├── examples ├── using-test-job.yml ├── work-with-pip.yml ├── work-with-pipenv.yml ├── work-with-poetry.yml └── work-with-uv.yml ├── executors └── default.yml ├── jobs └── test.yml └── scripts ├── alias-python.sh ├── auto-install-command.sh ├── auto-test-command.sh ├── cache-link-lockfile.sh ├── cache-restore.sh ├── cache-save.sh ├── detect-env.sh ├── ensure-test-tool.sh ├── export-detect-env.sh ├── pypa-build.sh └── pypa-wheel.sh /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | setup: true 3 | orbs: 4 | orb-tools: circleci/orb-tools@11.1 5 | shellcheck: circleci/shellcheck@3.1 6 | 7 | filters: &filters 8 | tags: 9 | only: /.*/ 10 | 11 | workflows: 12 | lint-pack: 13 | jobs: 14 | - orb-tools/lint: 15 | filters: *filters 16 | - orb-tools/pack: 17 | filters: *filters 18 | - orb-tools/review: 19 | filters: *filters 20 | - shellcheck/check: 21 | exclude: SC2148,SC2038,SC2086,SC2002,SC2016,SC1091 22 | filters: *filters 23 | - orb-tools/publish: 24 | orb-name: circleci/python 25 | vcs-type: << pipeline.project.type >> 26 | github-token: GHI_TOKEN 27 | requires: 28 | [orb-tools/lint, orb-tools/review, orb-tools/pack, shellcheck/check] 29 | # Use a context to hold your publishing token. 30 | context: orb-publisher 31 | filters: *filters 32 | # Triggers the next workflow in the Orb Development Kit. 33 | - orb-tools/continue: 34 | pipeline-number: << pipeline.number >> 35 | vcs-type: << pipeline.project.type >> 36 | requires: [orb-tools/publish] 37 | filters: *filters 38 | -------------------------------------------------------------------------------- /.circleci/test-deploy.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | orbs: 3 | python: circleci/python@dev:<> 4 | orb-tools: circleci/orb-tools@11.1 5 | filters: &filters 6 | tags: 7 | only: /.*/ 8 | parameters: 9 | cache-version: 10 | type: string 11 | default: v5 12 | 13 | executors: 14 | macos: 15 | macos: 16 | xcode: 16.1 17 | 18 | jobs: 19 | pip-install-test: 20 | parameters: 21 | executor: 22 | type: executor 23 | default: python/default 24 | executor: << parameters.executor >> 25 | steps: 26 | - checkout 27 | - python/install-packages: 28 | pkg-manager: pip 29 | cache-version: << pipeline.parameters.cache-version >> 30 | app-dir: ~/project/sample_pip 31 | - run: 32 | name: "Test" 33 | working_directory: ~/project/sample_pip 34 | command: | 35 | pytest 36 | pip-install-rel-dir: 37 | executor: python/default 38 | steps: 39 | - checkout 40 | - python/install-packages: 41 | pkg-manager: pip 42 | cache-version: << pipeline.parameters.cache-version >> 43 | app-dir: "./sample_pip" 44 | - run: 45 | name: "Test" 46 | working_directory: ~/project/sample_pip 47 | command: | 48 | pytest 49 | pip-install-test-no-packages: 50 | executor: python/default 51 | steps: 52 | - checkout 53 | - run: 54 | name: "Test" 55 | working_directory: ~/project/sample_pip 56 | command: | 57 | pytest 58 | pip-install-test-args: 59 | executor: python/default 60 | steps: 61 | - checkout 62 | - python/install-packages: 63 | pkg-manager: pip 64 | app-dir: ~/project/sample_pip 65 | cache-version: << pipeline.parameters.cache-version >> 66 | args: pytest 67 | pip-dependency-file: "" 68 | - run: 69 | name: "Test" 70 | working_directory: ~/project/sample_pip 71 | command: | 72 | pytest 73 | dist-test: 74 | executor: python/default 75 | parameters: 76 | build-tool: 77 | type: enum 78 | enum: ["wheel", "build"] 79 | default: "wheel" 80 | description: Build command to run. 81 | steps: 82 | - checkout 83 | - python/dist: 84 | build-tool: << parameters.build-tool >> 85 | app-dir: ~/project/sample_pip 86 | dist-test-build-opts: 87 | executor: python/default 88 | steps: 89 | - checkout 90 | - python/dist: 91 | build-tool: build 92 | wheel-separate: true 93 | sdist-separate: true 94 | no-isolation: true 95 | skip-dependency-check: true 96 | app-dir: ~/project/sample_pip 97 | pipenv-test: 98 | executor: python/default 99 | steps: 100 | - checkout 101 | - python/install-packages: 102 | app-dir: ~/project/sample_pipenv 103 | pkg-manager: "pipenv" 104 | cache-version: << pipeline.parameters.cache-version >> 105 | - run: 106 | working_directory: ~/project/sample_pipenv 107 | command: | 108 | cp Pipfile.lock Pipfile.lock.tmp 109 | cp Pipfile Pipfile.tmp 110 | pipenv run pytest --version 111 | name: Ensure pipenv is working and copy lock file for cache testing 112 | - run: 113 | command: pipenv install pytest==4.6.1 114 | working_directory: ~/project/sample_pipenv 115 | - run: 116 | working_directory: ~/project/sample_pipenv 117 | command: | 118 | cp Pipfile.lock.tmp Pipfile.lock 119 | cp Pipfile.tmp Pipfile 120 | name: Overwrite the lockfile with the one that should load the cache. 121 | - python/install-packages: 122 | app-dir: ~/project/sample_pipenv 123 | pkg-manager: "pipenv" 124 | pypi-cache: false 125 | venv-cache: false 126 | cache-version: << pipeline.parameters.cache-version >> 127 | - run: 128 | command: pipenv run pytest 129 | working_directory: ~/project/sample_pipenv 130 | poetry-test: 131 | executor: python/default 132 | steps: 133 | - checkout 134 | - python/install-packages: 135 | app-dir: ~/project/sample_poetry 136 | cache-version: << pipeline.parameters.cache-version >> 137 | pkg-manager: poetry 138 | args: --no-root 139 | - run: 140 | working_directory: ~/project/sample_poetry 141 | command: |- 142 | poetry run pytest 143 | uv-test: 144 | executor: python/default 145 | steps: 146 | - checkout 147 | - python/install-packages: 148 | app-dir: ~/project/sample_uv 149 | cache-version: << pipeline.parameters.cache-version >> 150 | pkg-manager: uv 151 | - run: 152 | working_directory: ~/project/sample_uv 153 | command: |- 154 | uv run pytest 155 | workflows: 156 | test-deploy: 157 | jobs: 158 | # Make sure to include "filters: *filters" in every test job you want to run as part of your deployment. 159 | - pip-install-test: 160 | name: "pip-install-macos" 161 | filters: *filters 162 | executor: macos 163 | - pip-install-test: 164 | filters: *filters 165 | - pip-install-test-args: 166 | filters: *filters 167 | - pipenv-test: 168 | filters: *filters 169 | - poetry-test: 170 | filters: *filters 171 | - uv-test: 172 | filters: *filters 173 | - dist-test: 174 | name: "dist-test-wheel" 175 | filters: *filters 176 | - dist-test: 177 | name: "dist-test-build" 178 | build-tool: "build" 179 | filters: *filters 180 | - dist-test-build-opts: 181 | name: "dist-test-build-opts" 182 | filters: *filters 183 | - pip-install-rel-dir: 184 | filters: *filters 185 | - python/test: 186 | filters: *filters 187 | name: job-test-poetry 188 | pkg-manager: poetry 189 | cache-version: poetry-<< pipeline.parameters.cache-version >> 190 | args: "--no-root | tee install_output.txt" 191 | include-branch-in-cache-key: false 192 | app-dir: ~/project/sample_poetry 193 | post-steps: 194 | - run: 195 | name: Verify cache was successful 196 | working_directory: ~/project/sample_poetry 197 | command: 'cat install_output.txt | grep "No dependencies to install or update"' 198 | - python/test: 199 | filters: *filters 200 | name: job-test-uv 201 | pkg-manager: uv 202 | cache-version: uv-<< pipeline.parameters.cache-version >> 203 | args: " -v 2> install_output.txt" 204 | include-branch-in-cache-key: false 205 | app-dir: ~/project/sample_uv 206 | post-steps: 207 | - run: 208 | name: Verify cache was successful 209 | working_directory: ~/project/sample_uv 210 | command: 'cat install_output.txt | grep "already cached: pytest"' 211 | - python/test: 212 | filters: *filters 213 | name: job-test-pipenv 214 | pkg-manager: pipenv 215 | include-branch-in-cache-key: false 216 | cache-version: pipenv-<< pipeline.parameters.cache-version >> 217 | app-dir: ~/project/sample_pipenv 218 | - python/test: 219 | filters: *filters 220 | name: job-test-pip 221 | pkg-manager: pip 222 | include-branch-in-cache-key: false 223 | cache-version: pip-<< pipeline.parameters.cache-version >> 224 | test-tool: unittest 225 | app-dir: ~/project/sample_pip 226 | args: "| tee install_output.txt" 227 | post-steps: 228 | - run: 229 | name: Verify cache was successful 230 | working_directory: ~/project/sample_pip 231 | command: 'cat install_output.txt | grep "Requirement already satisfied: pytest"' 232 | - python/test: 233 | filters: *filters 234 | name: job-auto-test-poetry 235 | cache-version: poetry-auto-<< pipeline.parameters.cache-version >> 236 | args: "--no-root | tee install_output.txt" 237 | include-branch-in-cache-key: false 238 | app-dir: ~/project/sample_poetry 239 | post-steps: 240 | - run: 241 | name: Verify cache was successful 242 | working_directory: ~/project/sample_poetry 243 | command: 'cat install_output.txt | grep "No dependencies to install or update"' 244 | - python/test: 245 | filters: *filters 246 | name: job-auto-test-uv 247 | cache-version: uv-auto-<< pipeline.parameters.cache-version >> 248 | args: "-v 2> install_output.txt" 249 | include-branch-in-cache-key: false 250 | app-dir: ~/project/sample_uv 251 | post-steps: 252 | - run: 253 | name: Verify cache was successful 254 | working_directory: ~/project/sample_uv 255 | command: 'cat install_output.txt | grep "already cached: pytest"' 256 | - python/test: 257 | filters: *filters 258 | name: job-auto-test-pipenv 259 | cache-version: pipenv-auto-<< pipeline.parameters.cache-version >> 260 | app-dir: ~/project/sample_pipenv 261 | include-branch-in-cache-key: false 262 | - python/test: 263 | filters: *filters 264 | name: job-auto-test-pip 265 | test-tool: unittest 266 | venv-cache: false 267 | include-branch-in-cache-key: false 268 | args: "| tee install_output.txt" 269 | cache-version: pip-auto-<< pipeline.parameters.cache-version >> 270 | app-dir: ~/project/sample_pip 271 | post-steps: 272 | - run: 273 | name: Verify cache was successful 274 | working_directory: ~/project/sample_pip 275 | command: 'cat install_output.txt | grep "Requirement already satisfied: pytest"' 276 | - python/test: 277 | filters: *filters 278 | name: job-test-pip-no-reqs 279 | pkg-manager: pip 280 | pip-dependency-file: "" 281 | include-branch-in-cache-key: false 282 | test-tool: unittest 283 | cache-version: pip-noreqs-<< pipeline.parameters.cache-version >> 284 | app-dir: ~/project/sample_pip 285 | - python/test: 286 | filters: *filters 287 | executor: 288 | name: python/default 289 | tag: 3.9.22 290 | name: job-test-pip-dist 291 | pkg-manager: pip-dist 292 | include-branch-in-cache-key: false 293 | cache-version: pip-dist-<< pipeline.parameters.cache-version >> 294 | app-dir: ~/project/sample_pip 295 | # pip-dependency-file: setup.py 296 | post-steps: 297 | - run: 298 | name: Attempt to set the other python version - this should fail, but if the cache is broken, this will succeed. 299 | command: | 300 | ! pyenv local 3.8.6 301 | - run: 302 | name: If another python version is loaded - its broken - this verifies that it's broken 303 | when: on_fail 304 | command: python --version 305 | - python/test: 306 | filters: *filters 307 | executor: 308 | name: python/default 309 | tag: 3.11.12 310 | name: job-test-pip-dist-pyproject 311 | pkg-manager: pip-dist 312 | include-branch-in-cache-key: false 313 | cache-version: pip-dist-pyproject-<< pipeline.parameters.cache-version >> 314 | app-dir: ~/project/sample_pip_pyproject 315 | - orb-tools/pack: 316 | filters: *filters 317 | - orb-tools/publish: 318 | orb-name: circleci/python 319 | github-token: GHI_TOKEN 320 | vcs-type: << pipeline.project.type >> 321 | pub-type: production 322 | requires: 323 | - orb-tools/pack 324 | - pip-install-test 325 | - pip-install-macos 326 | - pip-install-test-args 327 | - pipenv-test 328 | - poetry-test 329 | - uv-test 330 | - pip-install-rel-dir 331 | - job-test-poetry 332 | - job-test-uv 333 | - job-test-pipenv 334 | - job-test-pip 335 | - job-test-pip-dist 336 | - job-test-pip-dist-pyproject 337 | - job-auto-test-poetry 338 | - job-auto-test-uv 339 | - job-auto-test-pipenv 340 | - job-auto-test-pip 341 | - dist-test-wheel 342 | - dist-test-build 343 | - dist-test-build-opts 344 | context: orb-publisher 345 | filters: 346 | branches: 347 | ignore: /.*/ 348 | tags: 349 | only: /^v[0-9]+\.[0-9]+\.[0-9]+$/ -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Ping these folks when changes are made to this repository 2 | * @CircleCI-Public/orb-publishers 3 | 4 | # We can also add orb-specifc codeowners at some point if desirable 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/BUG.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F41E Bug report" 3 | about: Report any bugs encountered while using this orb. 4 | title: "" 5 | labels: bug 6 | assignees: "" 7 | --- 8 | 9 | ## Orb version: 10 | 11 | 18 | 19 | ## What happened: 20 | 21 | 25 | 26 | ## Expected behavior: 27 | 28 | 29 | 30 | ## Additional Information: 31 | 32 | 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F680 Feature Request" 3 | about: Propose changes to the orb. 4 | title: "" 5 | labels: feature_request 6 | assignees: "" 7 | --- 8 | 9 | ## Describe Request: 10 | 11 | ## Examples: 12 | 13 | ## Supporting Documentation Links: 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE/PULL_REQUEST.md: -------------------------------------------------------------------------------- 1 | **SEMVER Update Type:** 2 | 3 | - [ ] Major 4 | - [ ] Minor 5 | - [ ] Patch 6 | 7 | ## Description: 8 | 9 | 13 | 14 | ## Motivation: 15 | 16 | 19 | 20 | **Closes Issues:** 21 | 22 | - ISSUE URL 23 | 24 | ## Checklist: 25 | 26 | 31 | 32 | - [ ] All new jobs, commands, executors, parameters have descriptions. 33 | - [ ] Usage Example version numbers have been updated. 34 | - [ ] Changelog has been updated. 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | src/orb.yml 2 | orb.yml 3 | 4 | sample_pip/*/__pycache__ 5 | 6 | # dev tools 7 | .idea 8 | **/.DS_Store -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | extends: relaxed 2 | 3 | rules: 4 | line-length: 5 | max: 200 6 | allow-non-breakable-inline-mappings: true 7 | 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Circle Internet Services, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python Orb [![CircleCI Build Status](https://circleci.com/gh/CircleCI-Public/python-orb.svg?style=shield "CircleCI Build Status")](https://circleci.com/gh/CircleCI-Public/python-orb) [![CircleCI Orb Version](https://badges.circleci.com/orbs/circleci/python.svg)][reg-page] [![GitHub License](https://img.shields.io/badge/license-MIT-lightgrey.svg)](https://raw.githubusercontent.com/CircleCI-Public/python-orb/master/LICENSE) [![CircleCI Community](https://img.shields.io/badge/community-CircleCI%20Discuss-343434.svg)](https://discuss.circleci.com/c/ecosystem/orbs) 2 | 3 | A python Orb for CircleCI. 4 | This orb allows you to do common python related tasks on CircleCI such as setup a pipenv or poetry env, manage global python dependencies, cache virtualenvs or global python packages. 5 | 6 | ## Usage 7 | 8 | Example use as well as a list of available executors, commands, and jobs are available on this orb's [registry page][reg-page]. 9 | 10 | ## Resources 11 | 12 | [CircleCI Orb Registry Page][reg-page] - The official registry page of this orb for all versions, executors, commands, and jobs described. 13 | [CircleCI Orb Docs](https://circleci.com/docs/2.0/orb-intro/#section=configuration) - Docs for using and creating CircleCI Orbs. 14 | 15 | ## Contributing 16 | 17 | We welcome [issues](https://github.com/CircleCI-Public/python-orb/issues) to and [pull requests](https://github.com/CircleCI-Public/python-orb/pulls) against this repository! 18 | For further questions/comments about this or other orbs, visit the Orb Category of [CircleCI Discuss](https://discuss.circleci.com/c/orbs). 19 | 20 | ### Publishing 21 | 22 | New versions of this orb are published by pushing a [SemVer git tag](https://semver.org/) by the [Community & Partner Engineering Team](mailto:community-partner@circleci.com). 23 | 24 | [reg-page]: https://circleci.com/orbs/registry/orb/circleci/python 25 | -------------------------------------------------------------------------------- /sample_pip/requirements.txt: -------------------------------------------------------------------------------- 1 | pytest 2 | -------------------------------------------------------------------------------- /sample_pip/setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | setuptools.setup(name="tmp-example",version="0.0.1",author="null",author_email="null",url="null",description="null",install_requires=[ 3 | 'pytest', 4 | ]) 5 | -------------------------------------------------------------------------------- /sample_pip/src/example.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def add_func(x,y): 4 | z = x+y 5 | return z -------------------------------------------------------------------------------- /sample_pip/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircleCI-Public/python-orb/e94e8f6da00cd5482e943c91657a2fcc68444645/sample_pip/tests/__init__.py -------------------------------------------------------------------------------- /sample_pip/tests/test_ex.py: -------------------------------------------------------------------------------- 1 | from src import example 2 | 3 | import unittest 4 | 5 | class TestCase(unittest.TestCase): 6 | 7 | def test_add1(self): 8 | assert example.add_func(5,5) == 10 9 | 10 | def test_add2(self): 11 | assert example.add_func(5,10) == 15 12 | -------------------------------------------------------------------------------- /sample_pip/tests/test_job.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | 4 | class TestCase(unittest.TestCase): 5 | 6 | def test_true(self): 7 | assert True 8 | -------------------------------------------------------------------------------- /sample_pip_pyproject/pyproject.toml: -------------------------------------------------------------------------------- 1 | # Example toml for integration testing - this is not used by the orb in anyway 2 | [project] 3 | authors=[ 4 | {name="TEST", email="test@test.com"} 5 | ] 6 | name="test" 7 | description="none" 8 | version = "0.0.1" 9 | requires-python=">3.11" 10 | dependencies=["pytest"] 11 | 12 | [build-system] 13 | requires = ["setuptools"] 14 | build-backend = "setuptools.build_meta" 15 | -------------------------------------------------------------------------------- /sample_pip_pyproject/requirements.txt: -------------------------------------------------------------------------------- 1 | pytest 2 | -------------------------------------------------------------------------------- /sample_pip_pyproject/src/example.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def add_func(x,y): 4 | z = x+y 5 | return z -------------------------------------------------------------------------------- /sample_pip_pyproject/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircleCI-Public/python-orb/e94e8f6da00cd5482e943c91657a2fcc68444645/sample_pip_pyproject/tests/__init__.py -------------------------------------------------------------------------------- /sample_pip_pyproject/tests/test_ex.py: -------------------------------------------------------------------------------- 1 | from src import example 2 | 3 | import unittest 4 | 5 | class TestCase(unittest.TestCase): 6 | 7 | def test_add1(self): 8 | assert example.add_func(5,5) == 10 9 | 10 | def test_add2(self): 11 | assert example.add_func(5,10) == 15 12 | -------------------------------------------------------------------------------- /sample_pip_pyproject/tests/test_job.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | 4 | class TestCase(unittest.TestCase): 5 | 6 | def test_true(self): 7 | assert True 8 | -------------------------------------------------------------------------------- /sample_pipenv/Pipfile: -------------------------------------------------------------------------------- 1 | [packages] 2 | pytest = "*" 3 | -------------------------------------------------------------------------------- /sample_pipenv/Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "0ad13a979a00ae0193ffd51f9ab38447943176a07040e5c87f68e23ca942a8c0" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": {}, 8 | "sources": [ 9 | { 10 | "name": "pypi", 11 | "url": "https://pypi.org/simple", 12 | "verify_ssl": true 13 | } 14 | ] 15 | }, 16 | "default": { 17 | "exceptiongroup": { 18 | "hashes": [ 19 | "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", 20 | "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc" 21 | ], 22 | "markers": "python_version >= '3.7'", 23 | "version": "==1.2.2" 24 | }, 25 | "iniconfig": { 26 | "hashes": [ 27 | "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", 28 | "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760" 29 | ], 30 | "markers": "python_version >= '3.8'", 31 | "version": "==2.1.0" 32 | }, 33 | "packaging": { 34 | "hashes": [ 35 | "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", 36 | "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f" 37 | ], 38 | "markers": "python_version >= '3.8'", 39 | "version": "==24.2" 40 | }, 41 | "pluggy": { 42 | "hashes": [ 43 | "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", 44 | "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" 45 | ], 46 | "markers": "python_version >= '3.8'", 47 | "version": "==1.5.0" 48 | }, 49 | "pytest": { 50 | "hashes": [ 51 | "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", 52 | "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845" 53 | ], 54 | "index": "pypi", 55 | "markers": "python_version >= '3.8'", 56 | "version": "==8.3.5" 57 | }, 58 | "tomli": { 59 | "hashes": [ 60 | "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", 61 | "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", 62 | "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", 63 | "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", 64 | "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", 65 | "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", 66 | "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", 67 | "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", 68 | "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", 69 | "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", 70 | "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", 71 | "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", 72 | "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", 73 | "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", 74 | "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", 75 | "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", 76 | "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", 77 | "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", 78 | "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", 79 | "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", 80 | "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", 81 | "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", 82 | "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", 83 | "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", 84 | "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", 85 | "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", 86 | "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", 87 | "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", 88 | "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", 89 | "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", 90 | "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", 91 | "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7" 92 | ], 93 | "markers": "python_version >= '3.8'", 94 | "version": "==2.2.1" 95 | } 96 | }, 97 | "develop": {} 98 | } 99 | -------------------------------------------------------------------------------- /sample_pipenv/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircleCI-Public/python-orb/e94e8f6da00cd5482e943c91657a2fcc68444645/sample_pipenv/tests/__init__.py -------------------------------------------------------------------------------- /sample_pipenv/tests/test_job.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | 4 | class TestCase(unittest.TestCase): 5 | 6 | def test_true(self): 7 | assert True 8 | -------------------------------------------------------------------------------- /sample_poetry/poetry.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Poetry 2.1.2 and should not be changed by hand. 2 | 3 | [[package]] 4 | name = "atomicwrites" 5 | version = "1.4.1" 6 | description = "Atomic file writes." 7 | optional = false 8 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 9 | groups = ["dev"] 10 | files = [ 11 | {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, 12 | ] 13 | 14 | [[package]] 15 | name = "attrs" 16 | version = "20.3.0" 17 | description = "Classes Without Boilerplate" 18 | optional = false 19 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 20 | groups = ["dev"] 21 | markers = "python_version == \"3.4\" or python_version >= \"3.4\" and sys_platform != \"win32\"" 22 | files = [ 23 | {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, 24 | {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, 25 | ] 26 | 27 | [package.extras] 28 | dev = ["coverage[toml] (>=5.0.2)", "furo", "hypothesis", "pre-commit", "pympler", "pytest (>=4.3.0)", "six", "sphinx", "zope.interface"] 29 | docs = ["furo", "sphinx", "zope.interface"] 30 | tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] 31 | tests-no-zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] 32 | 33 | [[package]] 34 | name = "attrs" 35 | version = "21.4.0" 36 | description = "Classes Without Boilerplate" 37 | optional = false 38 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 39 | groups = ["dev"] 40 | markers = "python_version == \"2.7\"" 41 | files = [ 42 | {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, 43 | {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, 44 | ] 45 | 46 | [package.extras] 47 | dev = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "sphinx", "sphinx-notfound-page", "zope.interface"] 48 | docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] 49 | tests = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "zope.interface"] 50 | tests-no-zope = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six"] 51 | 52 | [[package]] 53 | name = "attrs" 54 | version = "22.1.0" 55 | description = "Classes Without Boilerplate" 56 | optional = false 57 | python-versions = ">=3.5" 58 | groups = ["dev"] 59 | markers = "sys_platform == \"win32\" and python_version > \"3.4\"" 60 | files = [ 61 | {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, 62 | {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, 63 | ] 64 | 65 | [package.extras] 66 | dev = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] 67 | docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] 68 | tests = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] 69 | tests-no-zope = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] 70 | 71 | [[package]] 72 | name = "backports-functools-lru-cache" 73 | version = "1.6.6" 74 | description = "Backport of functools.lru_cache" 75 | optional = false 76 | python-versions = ">=2.6" 77 | groups = ["dev"] 78 | markers = "python_version == \"2.7\"" 79 | files = [ 80 | {file = "backports.functools_lru_cache-1.6.6-py2.py3-none-any.whl", hash = "sha256:77e27d0ffbb463904bdd5ef8b44363f6cd5ef503e664b3f599a3bf5843ed37cf"}, 81 | {file = "backports.functools_lru_cache-1.6.6.tar.gz", hash = "sha256:7b70e701ba4db58c0ed8671a9d3391b0abb9bd1bc24d4e90c3480f4baafcc2dc"}, 82 | ] 83 | 84 | [package.extras] 85 | docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] 86 | testing = ["pytest (>=6)", "pytest-black (>=0.3.7) ; platform_python_implementation != \"PyPy\"", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1) ; platform_python_implementation != \"PyPy\"", "pytest-ruff"] 87 | 88 | [[package]] 89 | name = "colorama" 90 | version = "0.4.1" 91 | description = "Cross-platform colored terminal text." 92 | optional = false 93 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 94 | groups = ["dev"] 95 | markers = "sys_platform == \"win32\" and python_version == \"3.4\"" 96 | files = [ 97 | {file = "colorama-0.4.1-py2.py3-none-any.whl", hash = "sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"}, 98 | {file = "colorama-0.4.1.tar.gz", hash = "sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d"}, 99 | ] 100 | 101 | [[package]] 102 | name = "colorama" 103 | version = "0.4.5" 104 | description = "Cross-platform colored terminal text." 105 | optional = false 106 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 107 | groups = ["dev"] 108 | markers = "sys_platform == \"win32\" and python_version > \"3.4\"" 109 | files = [ 110 | {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, 111 | {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, 112 | ] 113 | 114 | [[package]] 115 | name = "colorama" 116 | version = "0.4.6" 117 | description = "Cross-platform colored terminal text." 118 | optional = false 119 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" 120 | groups = ["dev"] 121 | markers = "sys_platform == \"win32\" and python_version == \"2.7\"" 122 | files = [ 123 | {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, 124 | {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, 125 | ] 126 | 127 | [[package]] 128 | name = "configparser" 129 | version = "4.0.2" 130 | description = "Updated configparser from Python 3.7 for Python 2.6+." 131 | optional = false 132 | python-versions = ">=2.6" 133 | groups = ["dev"] 134 | markers = "python_version == \"2.7\"" 135 | files = [ 136 | {file = "configparser-4.0.2-py2.py3-none-any.whl", hash = "sha256:254c1d9c79f60c45dfde850850883d5aaa7f19a23f13561243a050d5a7c3fe4c"}, 137 | {file = "configparser-4.0.2.tar.gz", hash = "sha256:c7d282687a5308319bf3d2e7706e575c635b0a470342641c93bea0ea3b5331df"}, 138 | ] 139 | 140 | [package.extras] 141 | docs = ["jaraco.packaging (>=3.2)", "rst.linker (>=1.9)", "sphinx"] 142 | testing = ["pytest (>=3.5,!=3.7.3)", "pytest-black-multipy", "pytest-checkdocs (>=1.2)", "pytest-flake8"] 143 | 144 | [[package]] 145 | name = "contextlib2" 146 | version = "0.6.0.post1" 147 | description = "Backports and enhancements for the contextlib module" 148 | optional = false 149 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 150 | groups = ["dev"] 151 | markers = "python_version == \"2.7\"" 152 | files = [ 153 | {file = "contextlib2-0.6.0.post1-py2.py3-none-any.whl", hash = "sha256:3355078a159fbb44ee60ea80abd0d87b80b78c248643b49aa6d94673b413609b"}, 154 | {file = "contextlib2-0.6.0.post1.tar.gz", hash = "sha256:01f490098c18b19d2bd5bb5dc445b2054d2fa97f09a4280ba2c5f3c394c8162e"}, 155 | ] 156 | 157 | [[package]] 158 | name = "funcsigs" 159 | version = "1.0.2" 160 | description = "Python function signatures from PEP362 for Python 2.6, 2.7 and 3.2+" 161 | optional = false 162 | python-versions = "*" 163 | groups = ["dev"] 164 | markers = "python_version == \"2.7\"" 165 | files = [ 166 | {file = "funcsigs-1.0.2-py2.py3-none-any.whl", hash = "sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca"}, 167 | {file = "funcsigs-1.0.2.tar.gz", hash = "sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50"}, 168 | ] 169 | 170 | [[package]] 171 | name = "importlib-metadata" 172 | version = "1.1.3" 173 | description = "Read metadata from Python packages" 174 | optional = false 175 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" 176 | groups = ["dev"] 177 | markers = "python_version == \"3.4\" or python_version >= \"3.4\" and sys_platform != \"win32\" and python_version < \"3.8\"" 178 | files = [ 179 | {file = "importlib_metadata-1.1.3-py2.py3-none-any.whl", hash = "sha256:7c7f8ac40673f507f349bef2eed21a0e5f01ddf5b2a7356a6c65eb2099b53764"}, 180 | {file = "importlib_metadata-1.1.3.tar.gz", hash = "sha256:7a99fb4084ffe6dae374961ba7a6521b79c1d07c658ab3a28aa264ee1d1b14e3"}, 181 | ] 182 | 183 | [package.dependencies] 184 | pathlib2 = {version = "*", markers = "python_version == \"3.4.*\" or python_version < \"3\""} 185 | zipp = ">=0.5" 186 | 187 | [package.extras] 188 | docs = ["rst.linker", "sphinx"] 189 | testing = ["importlib-resources ; python_version < \"3.7\"", "packaging"] 190 | 191 | [[package]] 192 | name = "importlib-metadata" 193 | version = "2.1.3" 194 | description = "Read metadata from Python packages" 195 | optional = false 196 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" 197 | groups = ["dev"] 198 | markers = "sys_platform == \"win32\" and python_version > \"3.4\" and python_version < \"3.8\" or python_version == \"2.7\"" 199 | files = [ 200 | {file = "importlib_metadata-2.1.3-py2.py3-none-any.whl", hash = "sha256:52e65a0856f9ba7ea8f2c4ced253fb6c88d1a8c352cb1e916cff4eb17d5a693d"}, 201 | {file = "importlib_metadata-2.1.3.tar.gz", hash = "sha256:02a9f62b02e9b1cc43871809ef99947e8f5d94771392d666ada2cafc4cd09d4f"}, 202 | ] 203 | 204 | [package.dependencies] 205 | configparser = {version = ">=3.5", markers = "python_version < \"3\""} 206 | contextlib2 = {version = "*", markers = "python_version < \"3\""} 207 | pathlib2 = {version = "*", markers = "python_version < \"3\""} 208 | zipp = ">=0.5" 209 | 210 | [package.extras] 211 | docs = ["rst.linker", "sphinx"] 212 | testing = ["importlib-resources (>=1.3) ; python_version < \"3.9\"", "packaging", "pep517", "unittest2 ; python_version < \"3\""] 213 | 214 | [[package]] 215 | name = "iniconfig" 216 | version = "1.1.1" 217 | description = "iniconfig: brain-dead simple config-ini parsing" 218 | optional = false 219 | python-versions = "*" 220 | groups = ["dev"] 221 | markers = "sys_platform == \"win32\" and python_version > \"3.4\"" 222 | files = [ 223 | {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, 224 | {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, 225 | ] 226 | 227 | [[package]] 228 | name = "more-itertools" 229 | version = "5.0.0" 230 | description = "More routines for operating on iterables, beyond itertools" 231 | optional = false 232 | python-versions = "*" 233 | groups = ["dev"] 234 | markers = "python_version == \"2.7\"" 235 | files = [ 236 | {file = "more-itertools-5.0.0.tar.gz", hash = "sha256:38a936c0a6d98a38bcc2d03fdaaedaba9f412879461dd2ceff8d37564d6522e4"}, 237 | {file = "more_itertools-5.0.0-py2-none-any.whl", hash = "sha256:c0a5785b1109a6bd7fac76d6837fd1feca158e54e521ccd2ae8bfe393cc9d4fc"}, 238 | {file = "more_itertools-5.0.0-py3-none-any.whl", hash = "sha256:fe7a7cae1ccb57d33952113ff4fa1bc5f879963600ed74918f1236e212ee50b9"}, 239 | ] 240 | 241 | [package.dependencies] 242 | six = ">=1.0.0,<2.0.0" 243 | 244 | [[package]] 245 | name = "more-itertools" 246 | version = "7.2.0" 247 | description = "More routines for operating on iterables, beyond itertools" 248 | optional = false 249 | python-versions = ">=3.4" 250 | groups = ["dev"] 251 | markers = "python_version == \"3.4\" or python_version >= \"3.4\" and sys_platform != \"win32\"" 252 | files = [ 253 | {file = "more-itertools-7.2.0.tar.gz", hash = "sha256:409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832"}, 254 | {file = "more_itertools-7.2.0-py3-none-any.whl", hash = "sha256:92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4"}, 255 | ] 256 | 257 | [[package]] 258 | name = "packaging" 259 | version = "20.9" 260 | description = "Core utilities for Python packages" 261 | optional = false 262 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 263 | groups = ["dev"] 264 | files = [ 265 | {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"}, 266 | {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"}, 267 | ] 268 | 269 | [package.dependencies] 270 | pyparsing = ">=2.0.2" 271 | 272 | [[package]] 273 | name = "pathlib2" 274 | version = "2.3.7.post1" 275 | description = "Object-oriented filesystem paths" 276 | optional = false 277 | python-versions = "*" 278 | groups = ["dev"] 279 | markers = "python_version == \"2.7\" or python_version >= \"3.4\" and python_version < \"3.6\"" 280 | files = [ 281 | {file = "pathlib2-2.3.7.post1-py2.py3-none-any.whl", hash = "sha256:5266a0fd000452f1b3467d782f079a4343c63aaa119221fbdc4e39577489ca5b"}, 282 | {file = "pathlib2-2.3.7.post1.tar.gz", hash = "sha256:9fe0edad898b83c0c3e199c842b27ed216645d2e177757b2dd67384d4113c641"}, 283 | ] 284 | 285 | [package.dependencies] 286 | scandir = {version = "*", markers = "python_version < \"3.5\""} 287 | six = "*" 288 | typing = {version = "*", markers = "python_version < \"3.5\""} 289 | 290 | [[package]] 291 | name = "pluggy" 292 | version = "0.13.1" 293 | description = "plugin and hook calling mechanisms for python" 294 | optional = false 295 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 296 | groups = ["dev"] 297 | files = [ 298 | {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, 299 | {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, 300 | ] 301 | 302 | [package.dependencies] 303 | importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} 304 | 305 | [package.extras] 306 | dev = ["pre-commit", "tox"] 307 | 308 | [[package]] 309 | name = "py" 310 | version = "1.10.0" 311 | description = "library with cross-python path, ini-parsing, io, code, log facilities" 312 | optional = false 313 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 314 | groups = ["dev"] 315 | markers = "python_version == \"3.4\" or python_version >= \"3.4\" and sys_platform != \"win32\"" 316 | files = [ 317 | {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, 318 | {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, 319 | ] 320 | 321 | [[package]] 322 | name = "py" 323 | version = "1.11.0" 324 | description = "library with cross-python path, ini-parsing, io, code, log facilities" 325 | optional = false 326 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 327 | groups = ["dev"] 328 | markers = "sys_platform == \"win32\" and python_version > \"3.4\" or python_version == \"2.7\"" 329 | files = [ 330 | {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, 331 | {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, 332 | ] 333 | 334 | [[package]] 335 | name = "pyparsing" 336 | version = "2.4.7" 337 | description = "Python parsing module" 338 | optional = false 339 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" 340 | groups = ["dev"] 341 | files = [ 342 | {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, 343 | {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, 344 | ] 345 | 346 | [[package]] 347 | name = "pytest" 348 | version = "4.6.11" 349 | description = "pytest: simple powerful testing with Python" 350 | optional = false 351 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" 352 | groups = ["dev"] 353 | markers = "python_version == \"3.4\" or python_version >= \"3.4\" and sys_platform != \"win32\" or python_version == \"2.7\"" 354 | files = [ 355 | {file = "pytest-4.6.11-py2.py3-none-any.whl", hash = "sha256:a00a7d79cbbdfa9d21e7d0298392a8dd4123316bfac545075e6f8f24c94d8c97"}, 356 | {file = "pytest-4.6.11.tar.gz", hash = "sha256:50fa82392f2120cc3ec2ca0a75ee615be4c479e66669789771f1758332be4353"}, 357 | ] 358 | 359 | [package.dependencies] 360 | atomicwrites = ">=1.0" 361 | attrs = ">=17.4.0" 362 | colorama = [ 363 | {version = "*", markers = "sys_platform == \"win32\" and python_version != \"3.4\""}, 364 | {version = "<=0.4.1", markers = "sys_platform == \"win32\" and python_version == \"3.4\""}, 365 | ] 366 | funcsigs = {version = ">=1.0", markers = "python_version < \"3.0\""} 367 | importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} 368 | more-itertools = [ 369 | {version = ">=4.0.0,<6.0.0", markers = "python_version <= \"2.7\""}, 370 | {version = ">=4.0.0", markers = "python_version > \"2.7\""}, 371 | ] 372 | packaging = "*" 373 | pathlib2 = {version = ">=2.2.0", markers = "python_version < \"3.6\""} 374 | pluggy = ">=0.12,<1.0" 375 | py = ">=1.5.0" 376 | six = ">=1.10.0" 377 | wcwidth = "*" 378 | 379 | [package.extras] 380 | testing = ["argcomplete", "hypothesis (>=3.56)", "mock ; python_version == \"2.7\"", "nose", "requests"] 381 | 382 | [[package]] 383 | name = "pytest" 384 | version = "6.1.2" 385 | description = "pytest: simple powerful testing with Python" 386 | optional = false 387 | python-versions = ">=3.5" 388 | groups = ["dev"] 389 | markers = "sys_platform == \"win32\" and python_version > \"3.4\"" 390 | files = [ 391 | {file = "pytest-6.1.2-py3-none-any.whl", hash = "sha256:4288fed0d9153d9646bfcdf0c0428197dba1ecb27a33bb6e031d002fa88653fe"}, 392 | {file = "pytest-6.1.2.tar.gz", hash = "sha256:c0a7e94a8cdbc5422a51ccdad8e6f1024795939cc89159a0ae7f0b316ad3823e"}, 393 | ] 394 | 395 | [package.dependencies] 396 | atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} 397 | attrs = ">=17.4.0" 398 | colorama = {version = "*", markers = "sys_platform == \"win32\""} 399 | importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} 400 | iniconfig = "*" 401 | packaging = "*" 402 | pathlib2 = {version = ">=2.2.0", markers = "python_version < \"3.6\""} 403 | pluggy = ">=0.12,<1.0" 404 | py = ">=1.8.2" 405 | toml = "*" 406 | 407 | [package.extras] 408 | checkqa-mypy = ["mypy (==0.780)"] 409 | testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] 410 | 411 | [[package]] 412 | name = "scandir" 413 | version = "1.10.0" 414 | description = "scandir, a better directory iterator and faster os.walk()" 415 | optional = false 416 | python-versions = "*" 417 | groups = ["dev"] 418 | markers = "python_version == \"2.7\" or python_version == \"3.4\"" 419 | files = [ 420 | {file = "scandir-1.10.0-cp27-cp27m-win32.whl", hash = "sha256:92c85ac42f41ffdc35b6da57ed991575bdbe69db895507af88b9f499b701c188"}, 421 | {file = "scandir-1.10.0-cp27-cp27m-win_amd64.whl", hash = "sha256:cb925555f43060a1745d0a321cca94bcea927c50114b623d73179189a4e100ac"}, 422 | {file = "scandir-1.10.0-cp34-cp34m-win32.whl", hash = "sha256:2c712840c2e2ee8dfaf36034080108d30060d759c7b73a01a52251cc8989f11f"}, 423 | {file = "scandir-1.10.0-cp34-cp34m-win_amd64.whl", hash = "sha256:2586c94e907d99617887daed6c1d102b5ca28f1085f90446554abf1faf73123e"}, 424 | {file = "scandir-1.10.0-cp35-cp35m-win32.whl", hash = "sha256:2b8e3888b11abb2217a32af0766bc06b65cc4a928d8727828ee68af5a967fa6f"}, 425 | {file = "scandir-1.10.0-cp35-cp35m-win_amd64.whl", hash = "sha256:8c5922863e44ffc00c5c693190648daa6d15e7c1207ed02d6f46a8dcc2869d32"}, 426 | {file = "scandir-1.10.0-cp36-cp36m-win32.whl", hash = "sha256:2ae41f43797ca0c11591c0c35f2f5875fa99f8797cb1a1fd440497ec0ae4b022"}, 427 | {file = "scandir-1.10.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7d2d7a06a252764061a020407b997dd036f7bd6a175a5ba2b345f0a357f0b3f4"}, 428 | {file = "scandir-1.10.0-cp37-cp37m-win32.whl", hash = "sha256:67f15b6f83e6507fdc6fca22fedf6ef8b334b399ca27c6b568cbfaa82a364173"}, 429 | {file = "scandir-1.10.0-cp37-cp37m-win_amd64.whl", hash = "sha256:b24086f2375c4a094a6b51e78b4cf7ca16c721dcee2eddd7aa6494b42d6d519d"}, 430 | {file = "scandir-1.10.0.tar.gz", hash = "sha256:4d4631f6062e658e9007ab3149a9b914f3548cb38bfb021c64f39a025ce578ae"}, 431 | ] 432 | 433 | [[package]] 434 | name = "six" 435 | version = "1.17.0" 436 | description = "Python 2 and 3 compatibility utilities" 437 | optional = false 438 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" 439 | groups = ["dev"] 440 | markers = "python_version < \"3.6\" or sys_platform != \"win32\"" 441 | files = [ 442 | {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, 443 | {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, 444 | ] 445 | 446 | [[package]] 447 | name = "toml" 448 | version = "0.10.2" 449 | description = "Python Library for Tom's Obvious, Minimal Language" 450 | optional = false 451 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" 452 | groups = ["dev"] 453 | markers = "sys_platform == \"win32\" and python_version > \"3.4\"" 454 | files = [ 455 | {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, 456 | {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, 457 | ] 458 | 459 | [[package]] 460 | name = "typing" 461 | version = "3.10.0.0" 462 | description = "Type Hints for Python" 463 | optional = false 464 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <3.5" 465 | groups = ["dev"] 466 | markers = "python_version == \"2.7\" or python_version == \"3.4\"" 467 | files = [ 468 | {file = "typing-3.10.0.0-py2-none-any.whl", hash = "sha256:c7219ef20c5fbf413b4567092adfc46fa6203cb8454eda33c3fc1afe1398a308"}, 469 | {file = "typing-3.10.0.0-py3-none-any.whl", hash = "sha256:12fbdfbe7d6cca1a42e485229afcb0b0c8259258cfb919b8a5e2a5c953742f89"}, 470 | {file = "typing-3.10.0.0.tar.gz", hash = "sha256:13b4ad211f54ddbf93e5901a9967b1e07720c1d1b78d596ac6a439641aa1b130"}, 471 | ] 472 | 473 | [[package]] 474 | name = "wcwidth" 475 | version = "0.2.13" 476 | description = "Measures the displayed width of unicode strings in a terminal" 477 | optional = false 478 | python-versions = "*" 479 | groups = ["dev"] 480 | markers = "python_version == \"3.4\" or python_version >= \"3.4\" and sys_platform != \"win32\" or python_version == \"2.7\"" 481 | files = [ 482 | {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, 483 | {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, 484 | ] 485 | 486 | [package.dependencies] 487 | "backports.functools-lru-cache" = {version = ">=1.2.1", markers = "python_version < \"3.2\""} 488 | 489 | [[package]] 490 | name = "zipp" 491 | version = "1.2.0" 492 | description = "Backport of pathlib-compatible object wrapper for zip files" 493 | optional = false 494 | python-versions = ">=2.7" 495 | groups = ["dev"] 496 | markers = "python_version == \"2.7\" or python_version >= \"3.4\" and python_version < \"3.8\"" 497 | files = [ 498 | {file = "zipp-1.2.0-py2.py3-none-any.whl", hash = "sha256:e0d9e63797e483a30d27e09fffd308c59a700d365ec34e93cc100844168bf921"}, 499 | {file = "zipp-1.2.0.tar.gz", hash = "sha256:c70410551488251b0fee67b460fb9a536af8d6f9f008ad10ac51f615b6a521b1"}, 500 | ] 501 | 502 | [package.dependencies] 503 | contextlib2 = {version = "*", markers = "python_version < \"3.4\""} 504 | 505 | [package.extras] 506 | docs = ["jaraco.packaging (>=3.2)", "rst.linker (>=1.9)", "sphinx"] 507 | testing = ["func-timeout", "jaraco.itertools", "pathlib2", "unittest2"] 508 | 509 | [metadata] 510 | lock-version = "2.1" 511 | python-versions = "*" 512 | content-hash = "356b2a323aff142b0f507d6d97396caab1aa0cd93de4da006e982e9e31511066" 513 | -------------------------------------------------------------------------------- /sample_poetry/pyproject.toml: -------------------------------------------------------------------------------- 1 | # Example toml for integration testing - this is not used by the orb in anyway 2 | [tool.poetry] 3 | authors=["Test"] 4 | name="test" 5 | description="none" 6 | version = "0.0.1" 7 | 8 | [tool.poetry.dependencies] 9 | python = "*" 10 | 11 | [tool.poetry.group.dev.dependencies] 12 | pytest = "*" 13 | 14 | [build-system] 15 | requires = ["setuptools"] 16 | build-backend = "setuptools.build_meta" 17 | 18 | -------------------------------------------------------------------------------- /sample_poetry/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircleCI-Public/python-orb/e94e8f6da00cd5482e943c91657a2fcc68444645/sample_poetry/tests/__init__.py -------------------------------------------------------------------------------- /sample_poetry/tests/test_job.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | 4 | class TestCase(unittest.TestCase): 5 | 6 | def test_true(self): 7 | assert True 8 | -------------------------------------------------------------------------------- /sample_uv/pyproject.toml: -------------------------------------------------------------------------------- 1 | # Example toml for integration testing - this is not used by the orb in anyway 2 | [build-system] 3 | requires = ["setuptools"] 4 | build-backend = "setuptools.build_meta" 5 | 6 | [project] 7 | authors = [ 8 | {name="TEST", email="test@test.com"} 9 | ] 10 | name = "test" 11 | description = "none" 12 | version = "0.0.1" 13 | requires-python = ">=3.9" 14 | dependencies = [] 15 | 16 | [dependency-groups] 17 | dev = [ 18 | "pytest" 19 | ] 20 | -------------------------------------------------------------------------------- /sample_uv/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CircleCI-Public/python-orb/e94e8f6da00cd5482e943c91657a2fcc68444645/sample_uv/tests/__init__.py -------------------------------------------------------------------------------- /sample_uv/tests/test_job.py: -------------------------------------------------------------------------------- 1 | 2 | import unittest 3 | 4 | class TestCase(unittest.TestCase): 5 | 6 | def test_true(self): 7 | assert True 8 | -------------------------------------------------------------------------------- /sample_uv/uv.lock: -------------------------------------------------------------------------------- 1 | version = 1 2 | requires-python = ">=3.9" 3 | 4 | [[package]] 5 | name = "colorama" 6 | version = "0.4.6" 7 | source = { registry = "https://pypi.org/simple" } 8 | sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } 9 | wheels = [ 10 | { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, 11 | ] 12 | 13 | [[package]] 14 | name = "exceptiongroup" 15 | version = "1.2.2" 16 | source = { registry = "https://pypi.org/simple" } 17 | sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } 18 | wheels = [ 19 | { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, 20 | ] 21 | 22 | [[package]] 23 | name = "iniconfig" 24 | version = "2.0.0" 25 | source = { registry = "https://pypi.org/simple" } 26 | sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } 27 | wheels = [ 28 | { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, 29 | ] 30 | 31 | [[package]] 32 | name = "packaging" 33 | version = "24.2" 34 | source = { registry = "https://pypi.org/simple" } 35 | sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } 36 | wheels = [ 37 | { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, 38 | ] 39 | 40 | [[package]] 41 | name = "pluggy" 42 | version = "1.5.0" 43 | source = { registry = "https://pypi.org/simple" } 44 | sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } 45 | wheels = [ 46 | { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, 47 | ] 48 | 49 | [[package]] 50 | name = "pytest" 51 | version = "8.3.3" 52 | source = { registry = "https://pypi.org/simple" } 53 | dependencies = [ 54 | { name = "colorama", marker = "sys_platform == 'win32'" }, 55 | { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, 56 | { name = "iniconfig" }, 57 | { name = "packaging" }, 58 | { name = "pluggy" }, 59 | { name = "tomli", marker = "python_full_version < '3.11'" }, 60 | ] 61 | sdist = { url = "https://files.pythonhosted.org/packages/8b/6c/62bbd536103af674e227c41a8f3dcd022d591f6eed5facb5a0f31ee33bbc/pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181", size = 1442487 } 62 | wheels = [ 63 | { url = "https://files.pythonhosted.org/packages/6b/77/7440a06a8ead44c7757a64362dd22df5760f9b12dc5f11b6188cd2fc27a0/pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2", size = 342341 }, 64 | ] 65 | 66 | [[package]] 67 | name = "test" 68 | version = "0.0.1" 69 | source = { editable = "." } 70 | 71 | [package.dev-dependencies] 72 | dev = [ 73 | { name = "pytest" }, 74 | ] 75 | 76 | [package.metadata] 77 | 78 | [package.metadata.requires-dev] 79 | dev = [{ name = "pytest" }] 80 | 81 | [[package]] 82 | name = "tomli" 83 | version = "2.1.0" 84 | source = { registry = "https://pypi.org/simple" } 85 | sdist = { url = "https://files.pythonhosted.org/packages/1e/e4/1b6cbcc82d8832dd0ce34767d5c560df8a3547ad8cbc427f34601415930a/tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8", size = 16622 } 86 | wheels = [ 87 | { url = "https://files.pythonhosted.org/packages/de/f7/4da0ffe1892122c9ea096c57f64c2753ae5dd3ce85488802d11b0992cc6d/tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391", size = 13750 }, 88 | ] 89 | -------------------------------------------------------------------------------- /src/@orb.yml: -------------------------------------------------------------------------------- 1 | description: | 2 | Common CircleCI tasks for the Python programming language. 3 | Supports Linux x86_64, MacOS, and Arm64 V8. 4 | display: 5 | source_url: https://github.com/circleci-public/python-orb 6 | version: 2.1 7 | -------------------------------------------------------------------------------- /src/commands/dist.yml: -------------------------------------------------------------------------------- 1 | description: "Build a distribution package" 2 | 3 | parameters: 4 | build-tool: 5 | type: enum 6 | enum: ["wheel", "build"] 7 | default: "wheel" 8 | description: Choose the build command to run. Options include PEP427 wheel (default) and PEP517 build. 9 | app-dir: 10 | type: string 11 | default: "." 12 | description: Path to the directory containing your python project. Not needed if 'setup.py' lives in root project dir. 13 | out-dir: 14 | type: string 15 | default: "./dist" 16 | description: Path where to write the output files. 17 | sdist-separate: 18 | type: boolean 19 | default: false 20 | description: Opt out of default behavior and build sdist independently from wheel. Exclusive to build-tool option "build" only. 21 | wheel-separate: 22 | type: boolean 23 | default: false 24 | description: Build a wheel directly from the source. Default behavior builds an sdist, then builds a wheel from that sdist. Exclusive to build-tool option "build" only. 25 | no-isolation: 26 | type: boolean 27 | default: false 28 | description: Do not isolate the build in a virtual environment. Exclusive to build-tool option "build" only. 29 | skip-dependency-check: 30 | type: boolean 31 | default: false 32 | description: Do not check that build dependencies are installed. Exclusive to build-tool option "build" only. 33 | 34 | steps: 35 | - run: 36 | name: Alias Python 37 | command: <> 38 | - when: 39 | condition: 40 | equal: [<< parameters.build-tool >>, "build"] 41 | steps: 42 | - run: 43 | name: Install pypa build 44 | command: pip install build 45 | - run: 46 | working_directory: << parameters.app-dir >> 47 | name: "Build distribution package" 48 | command: << include(scripts/pypa-build.sh) >> 49 | environment: 50 | PARAM_NO_ISOLATION: << parameters.no-isolation >> 51 | PARAM_OUTDIR: << parameters.out-dir >> 52 | PARAM_SDIST: << parameters.sdist-separate >> 53 | PARAM_WHEEL: << parameters.wheel-separate >> 54 | PARAM_SKIP_DEPENDENCY_CHECK: << parameters.skip-dependency-check >> 55 | - when: 56 | condition: 57 | equal: [<< parameters.build-tool >>, "wheel"] 58 | steps: 59 | - run: 60 | name: Install wheel 61 | command: pip install wheel 62 | - run: 63 | working_directory: << parameters.app-dir >> 64 | name: "Build distribution package" 65 | command: << include(scripts/pypa-wheel.sh) >> 66 | environment: 67 | PARAM_OUTDIR: << parameters.out-dir >> 68 | -------------------------------------------------------------------------------- /src/commands/install-packages.yml: -------------------------------------------------------------------------------- 1 | description: > 2 | Setup a python environment and install the packages for your project either globally with pip or in a virtualenv with poetry or pipenv. 3 | With pip as pkg-manager, the command will assume `-r requirements.txt`. 4 | With poetry as pkg-manager, the command will assume `--no-ansi`. 5 | For pipenv, no args are provided. Expect the default caching locations for packages and virtualenvs on a debian system with pyenv. 6 | 7 | parameters: 8 | pkg-manager: 9 | type: enum 10 | enum: [auto, poetry, pipenv, pip, pip-dist, uv] 11 | default: auto 12 | description: Which package management tool to use, pipenv, pip or poetry with dependency file. Use `pip-dist` to install with project setup.py or PEP621 (pyproject.toml). 13 | path-args: 14 | type: string 15 | default: "." 16 | description: | 17 | If using `pip-dist` these are the arguments after the command `pip install -e` that is by default set to `.`. Use of this parameter allows 18 | for multiple paths to be specified. This is important when extra paths are required to install extra packages referenced via `extras_requires`. 19 | args: 20 | type: string 21 | default: "" 22 | description: | 23 | Arguments to pass to install command for pipenv and poetry. For pip, arguments are after the command, `pip install -r requirements.txt `. 24 | For poetry, args are after `--no-ansi` as output option. 25 | pip-dependency-file: 26 | type: string 27 | default: requirements.txt 28 | description: | 29 | Name of the requirements file that needs to be installed with pip. Prepended with `app-dir`. If using pipenv or poetry, this is ignored. 30 | If using `pip-dist`, use this to use the cache checksum against the `setup.py` or `pyproject.toml` if desired. 31 | If `pip-dependency-file` is set to an empty string, no dependency file is used in the `pip install` command. 32 | app-dir: 33 | type: string 34 | default: "." 35 | description: Path to the directory containing your python project. Not needed if dependency file lives in the root. 36 | no_output_timeout: 37 | type: string 38 | default: "10m" 39 | description: Elapsed time the command can run without output. Passed to install command. 40 | venv-cache: 41 | type: boolean 42 | default: true 43 | description: Use the lockfile to cache the virtualenv. Not used with pip as pkg-manager. 44 | pypi-cache: 45 | type: boolean 46 | default: true 47 | description: Keep all versions of pypi and site-package caches for faster rebuilding overall. 48 | venv-path: 49 | type: string 50 | default: "" 51 | description: Override venv path. As json array - ex '[ "path", "path2" ]' 52 | cache-version: 53 | type: string 54 | default: v1 55 | description: Change the default cache version if you need to clear the cache for any reason. 56 | include-branch-in-cache-key: 57 | type: boolean 58 | default: true 59 | description: > 60 | If true, this cache bucket will only apply to jobs within the same branch. 61 | pre-install-steps: 62 | type: steps 63 | default: [] 64 | description: > 65 | Steps needed between restoring the cache and the install step. 66 | include-python-in-cache-key: 67 | type: boolean 68 | default: true 69 | description: > 70 | If true, this cache bucket will checksum the pyenv python version with the cache-key. 71 | 72 | steps: 73 | - run: 74 | name: "Export automatic environment detection script" 75 | command: << include(scripts/export-detect-env.sh) >> 76 | - run: 77 | name: Alias Python 78 | command: <> 79 | # restore caches 80 | - when: 81 | condition: 82 | or: 83 | - << parameters.pypi-cache >> 84 | - << parameters.venv-cache >> 85 | steps: 86 | - run: 87 | name: Link lockfile 88 | environment: 89 | PARAM_PKG_MNGR: << parameters.pkg-manager >> 90 | PARAM_DEPENDENCY_FILE: << parameters.pip-dependency-file >> 91 | PARAM_PYPI_CACHE: << parameters.pypi-cache >> 92 | PARAM_VENV_CACHE: << parameters.venv-cache >> 93 | PARAM_VENV_PATH: << parameters.venv-path >> 94 | command: <> 95 | working_directory: << parameters.app-dir >> 96 | - run: 97 | name: Save python version 98 | command: python --version | cut -d ' ' -f2 > .temp-python-version && cat .temp-python-version 99 | - restore_cache: 100 | keys: 101 | - <>-cci_pycache-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<><<#parameters.include-python-in-cache-key>>{{ checksum ".temp-python-version" }}-<>{{ checksum "<>/.cci_pycache/lockfile" }} 102 | - <>-cci_pycache-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<><<#parameters.include-python-in-cache-key>>{{ checksum ".temp-python-version" }}-<> 103 | - run: 104 | name: Move restored cache 105 | working_directory: << parameters.app-dir >> 106 | environment: 107 | PARAM_PYPI_CACHE: << parameters.pypi-cache >> 108 | PARAM_VENV_CACHE: << parameters.venv-cache >> 109 | command: <> 110 | # run install steps 111 | - steps: <> 112 | - when: 113 | condition: 114 | equal: [auto, << parameters.pkg-manager >>] 115 | steps: 116 | - run: 117 | name: "Install dependencies with automatically determined project package manager" 118 | working_directory: << parameters.app-dir >> 119 | no_output_timeout: << parameters.no_output_timeout >> 120 | environment: 121 | PARAM_PKG_MNGR: << parameters.pkg-manager >> 122 | PARAM_DEPENDENCY_FILE: << parameters.pip-dependency-file >> 123 | PARAM_PATH_ARGS: << parameters.path-args >> 124 | PARAM_ADDITIONAL_ARGS: << parameters.args >> 125 | command: <> 126 | - when: 127 | condition: 128 | equal: [pipenv, << parameters.pkg-manager >>] 129 | steps: 130 | - run: 131 | name: "Install dependencies with pipenv using project Pipfile or inline packages" 132 | no_output_timeout: << parameters.no_output_timeout >> 133 | working_directory: << parameters.app-dir >> 134 | command: | 135 | pipenv install << parameters.args >> 136 | - when: 137 | condition: 138 | equal: [poetry, << parameters.pkg-manager >>] 139 | steps: 140 | - run: 141 | name: "Install dependencies with poetry using project pyproject.toml" 142 | no_output_timeout: << parameters.no_output_timeout >> 143 | working_directory: << parameters.app-dir >> 144 | command: | 145 | poetry install --no-ansi << parameters.args >> 146 | - when: 147 | condition: 148 | equal: [uv, << parameters.pkg-manager >>] 149 | steps: 150 | - run: 151 | name: "Install dependencies with uv using project pyproject.toml and uv.lock" 152 | no_output_timeout: << parameters.no_output_timeout >> 153 | working_directory: << parameters.app-dir >> 154 | command: | 155 | uv sync << parameters.args >> 156 | - when: 157 | condition: 158 | # if pip == pkgmanager and args != "" or pip-dependency-file != "" 159 | and: 160 | - equal: [pip, << parameters.pkg-manager >>] 161 | - or: 162 | # true if no arguments 163 | - <> 164 | # true if dep file 165 | - <> 166 | steps: 167 | - run: 168 | name: "Install dependencies with pip using project <>" 169 | no_output_timeout: << parameters.no_output_timeout >> 170 | working_directory: <> 171 | command: | 172 | pip install <<#parameters.pip-dependency-file>>-r <><> << parameters.args >> 173 | - when: 174 | condition: 175 | equal: [pip-dist, << parameters.pkg-manager >>] 176 | steps: 177 | - run: 178 | name: "Install dependencies with pip using project setup.py or pyproject.toml" 179 | no_output_timeout: << parameters.no_output_timeout >> 180 | working_directory: <> 181 | command: | 182 | pip install -e << parameters.path-args >> << parameters.args >> 183 | - when: 184 | condition: 185 | or: 186 | - << parameters.pypi-cache >> 187 | - << parameters.venv-cache >> 188 | steps: 189 | - run: 190 | name: Copy to cache directory 191 | working_directory: << parameters.app-dir >> 192 | environment: 193 | PARAM_PKG_MNGR: << parameters.pkg-manager >> 194 | PARAM_DEPENDENCY_FILE: << parameters.pip-dependency-file >> 195 | PARAM_VENV_CACHE: << parameters.venv-cache >> 196 | PARAM_PYPI_CACHE: << parameters.pypi-cache >> 197 | PARAM_VENV_PATH: << parameters.venv-path >> 198 | command: <> 199 | - save_cache: 200 | key: <>-cci_pycache-<<#parameters.include-branch-in-cache-key>>{{ .Branch }}-<><<#parameters.include-python-in-cache-key>>{{ checksum ".temp-python-version" }}-<>{{ checksum "<>/.cci_pycache/lockfile" }} 201 | paths: 202 | - <>/.cci_pycache 203 | -------------------------------------------------------------------------------- /src/examples/using-test-job.yml: -------------------------------------------------------------------------------- 1 | description: | 2 | An example of running a pipenv based project with pytest. And then using twine to publish to pypi. 3 | The project using these args would have pytest as a dev dependecy in its Pipfile. 4 | The CircleCI project settings would have the environment variables for twine auth. 5 | usage: 6 | version: 2.1 7 | orbs: 8 | python: circleci/python@3.0.0 9 | workflows: 10 | main: 11 | jobs: 12 | - python/test: 13 | pkg-manager: pipenv 14 | args: --dev 15 | test-tool: pytest 16 | - publish 17 | 18 | jobs: 19 | publish: 20 | executor: python/default 21 | steps: 22 | - checkout 23 | - python/dist 24 | - run: pip install twine && twine upload dist/* 25 | -------------------------------------------------------------------------------- /src/examples/work-with-pip.yml: -------------------------------------------------------------------------------- 1 | description: | 2 | An example of working with the Pip and caching requirements.txt on CircleCI to speed up builds. 3 | usage: 4 | version: 2.1 5 | orbs: 6 | python: circleci/python@3.0.0 7 | workflows: 8 | main: 9 | jobs: 10 | - build 11 | jobs: 12 | build: 13 | executor: python/default 14 | steps: 15 | - checkout 16 | # Install requirements.txt 17 | - python/install-packages: 18 | pkg-manager: pip 19 | # Install dev-requirements.txt 20 | - python/install-packages: 21 | pkg-manager: pip 22 | pip-dependency-file: dev-requirements.txt 23 | # install pytest to run tests 24 | - python/install-packages: 25 | pkg-manager: pip 26 | args: pytest 27 | # dont add pytest to the cache 28 | pypi-cache: false 29 | - run: 30 | name: "Test" 31 | command: | 32 | pytest --version 33 | -------------------------------------------------------------------------------- /src/examples/work-with-pipenv.yml: -------------------------------------------------------------------------------- 1 | description: | 2 | An example of working with the Pipenv cache on CircleCI to speed up builds. 3 | usage: 4 | version: 2.1 5 | orbs: 6 | python: circleci/python@3.0.0 7 | workflows: 8 | main: 9 | jobs: 10 | - build 11 | jobs: 12 | build: 13 | executor: python/default 14 | steps: 15 | - checkout 16 | - python/install-packages: 17 | pkg-manager: pipenv 18 | args: pytest 19 | - run: 20 | name: "Test it" 21 | command: | 22 | pipenv run pytest --version 23 | -------------------------------------------------------------------------------- /src/examples/work-with-poetry.yml: -------------------------------------------------------------------------------- 1 | description: | 2 | An example of working with the Poetry cache on CircleCI to speed up builds. 3 | usage: 4 | version: 2.1 5 | orbs: 6 | python: circleci/python@3.0.0 7 | workflows: 8 | main: 9 | jobs: 10 | - build 11 | jobs: 12 | build: 13 | executor: python/default 14 | steps: 15 | - checkout 16 | - python/install-packages: 17 | pkg-manager: poetry 18 | - run: 19 | name: "Test it" 20 | # pytest would have to be defined in pyproject.toml 21 | # inline packages are not allowed with poetry install 22 | command: | 23 | poetry run pytest --version 24 | -------------------------------------------------------------------------------- /src/examples/work-with-uv.yml: -------------------------------------------------------------------------------- 1 | description: | 2 | An example of working with the uv cache on CircleCI to speed up builds. 3 | usage: 4 | version: 2.1 5 | orbs: 6 | python: circleci/python@3.0.0 7 | workflows: 8 | main: 9 | jobs: 10 | - build 11 | jobs: 12 | build: 13 | executor: python/default 14 | steps: 15 | - checkout 16 | - python/install-packages: 17 | pkg-manager: uv 18 | - run: 19 | name: "Test it" 20 | # pytest would have to be defined in pyproject.toml 21 | # inline packages are not allowed with uv sync 22 | command: | 23 | uv run pytest --version 24 | -------------------------------------------------------------------------------- /src/executors/default.yml: -------------------------------------------------------------------------------- 1 | description: "The official CircleCI CIMG Python Docker image." 2 | parameters: 3 | tag: 4 | description: "The `cimg/python` Docker image version tag." 5 | type: string 6 | default: "3.9.22" 7 | docker: 8 | - image: cimg/python:<< parameters.tag >> 9 | -------------------------------------------------------------------------------- /src/jobs/test.yml: -------------------------------------------------------------------------------- 1 | description: | 2 | Simple drop-in job to setup a python project, run tests and store the test results if possible. 3 | If test-tool is pytest, the job assumes the project defines pytest in the dependency file. 4 | Otherwise, use the built in unittest module as the test-tool. 5 | 6 | parameters: 7 | executor: 8 | type: executor 9 | default: default 10 | description: | 11 | The name of executor to use. 12 | pkg-manager: 13 | type: enum 14 | enum: [auto, pip, pipenv, poetry, pip-dist, uv] 15 | default: "auto" 16 | description: Select the package manager to use. Default is pip 17 | pip-dependency-file: 18 | type: string 19 | default: requirements.txt 20 | description: Name of the requirements file that needs to be installed with pip. Prepended with `app-dir`. If using pipenv, poetry or uv, this is ignored. 21 | app-dir: 22 | type: string 23 | default: "~/project" 24 | description: Path to the directory containing your python project. Not needed if dependency file lives in the root. 25 | setup-file-path: 26 | type: string 27 | default: "" 28 | description: Path to the setup.py file. 29 | module-src-dir: 30 | type: string 31 | default: "src" 32 | description: Path relative to app-dir which contains module source. 33 | args: 34 | type: string 35 | default: "" 36 | description: Arguments to pass to install command for pipenv, poetry or uv. Override '-r requirements.txt' for pip. 37 | setup: 38 | type: steps 39 | description: Provide any optional steps you would like to run prior to install the python project. 40 | default: [] 41 | test-tool: 42 | type: enum 43 | enum: ["pytest", "unittest"] 44 | default: "pytest" 45 | description: The tool to run the tests with. 46 | test-tool-args: 47 | type: string 48 | default: "" 49 | description: Arguments to pass to test tool, i.e. discovery settings for unittest - 'discover -s tests_dir'. 50 | venv-cache: 51 | type: boolean 52 | default: true 53 | description: Use the lockfile to cache the virtualenv. Not used with pip as pkg-manager. 54 | pypi-cache: 55 | type: boolean 56 | default: true 57 | description: Keep all versions of pypi and site-package caches for faster rebuilding overall. 58 | cache-version: 59 | type: string 60 | default: v1 61 | description: Change the default cache version if you need to clear the cache for any reason. 62 | include-branch-in-cache-key: 63 | type: boolean 64 | default: true 65 | description: > 66 | If true, this cache bucket will only apply to jobs within the same branch. 67 | include-python-in-cache-key: 68 | type: boolean 69 | default: true 70 | description: > 71 | If true, this cache bucket will checksum the pyenv python version with the cache-key 72 | fail-if-missing-tool: 73 | type: boolean 74 | default: false 75 | description: > 76 | If true, this job will fail if the test tool was not found. If false, it will automatically install to recover. 77 | ensure-test-tool: 78 | type: boolean 79 | default: true 80 | description: > 81 | If true, a step will be ran to ensure the configured test tool is installed. 82 | pre-install-steps: 83 | type: steps 84 | default: [] 85 | description: > 86 | Steps needed between restoring the cache and the install step. 87 | 88 | executor: <> 89 | 90 | steps: 91 | - checkout 92 | - steps: << parameters.setup >> 93 | - install-packages: 94 | app-dir: <> 95 | pkg-manager: <> 96 | cache-version: <> 97 | pypi-cache: <> 98 | venv-cache: <> 99 | pre-install-steps: <> 100 | include-branch-in-cache-key: <> 101 | args: <> 102 | pip-dependency-file: <> 103 | include-python-in-cache-key: <> 104 | - when: 105 | condition: <> 106 | steps: 107 | - run: 108 | working_directory: <> 109 | name: Ensuring test tool is installed 110 | command: <> 111 | environment: 112 | PARAM_PKG_MNGR: <> 113 | PARAM_SETUP_FILE_PATH: <>> 114 | PARAM_TEST_TOOL: <> 115 | PARAM_FAIL_IF_MISSING_TOOL: <>> 116 | - when: 117 | condition: 118 | equal: [auto, << parameters.pkg-manager >>] 119 | steps: 120 | - run: 121 | name: Create test-report directory 122 | working_directory: <> 123 | command: mkdir test-report 124 | - run: 125 | name: Run tests with auto-detected packages run 126 | working_directory: <> 127 | environment: 128 | PYTHONPATH: << parameters.app-dir >>/<< parameters.module-src-dir >> 129 | PARAM_PKG_MNGR: <> 130 | PARAM_TEST_TOOL_ARGS: <> 131 | PARAM_TEST_TOOL: <> 132 | command: <> 133 | - store_test_results: 134 | path: <<#parameters.app-dir>><>/<>test-report 135 | - when: 136 | condition: 137 | and: 138 | - equal: ["unittest", << parameters.test-tool >>] 139 | - not: 140 | equal: [auto, << parameters.pkg-manager >>] 141 | steps: 142 | - when: 143 | condition: 144 | or: 145 | - equal: [poetry, << parameters.pkg-manager >>] 146 | - equal: [pipenv, << parameters.pkg-manager >>] 147 | - equal: [uv, << parameters.pkg-manager >>] 148 | steps: 149 | - run: 150 | name: Run tests with <> run 151 | command: <> run python -m unittest << parameters.test-tool-args >> 152 | - when: 153 | condition: 154 | or: 155 | - equal: [pip, << parameters.pkg-manager >>] 156 | - equal: [pip-dist, << parameters.pkg-manager >>] 157 | steps: 158 | - run: 159 | working_directory: <> 160 | name: Run tests with global python env 161 | environment: 162 | PYTHONPATH: << parameters.app-dir >>/<< parameters.module-src-dir >> 163 | command: python -m unittest << parameters.test-tool-args >> 164 | - when: 165 | condition: 166 | and: 167 | - equal: ["pytest", << parameters.test-tool >>] 168 | - not: 169 | equal: [auto, << parameters.pkg-manager >>] 170 | steps: 171 | - run: 172 | name: Create test-report directory 173 | working_directory: <> 174 | command: mkdir test-report 175 | - when: 176 | condition: 177 | or: 178 | - equal: [poetry, << parameters.pkg-manager >>] 179 | - equal: [pipenv, << parameters.pkg-manager >>] 180 | - equal: [uv, << parameters.pkg-manager >>] 181 | steps: 182 | - run: 183 | name: Run tests with <> run 184 | working_directory: <> 185 | command: <> run pytest --junit-xml=test-report/report.xml << parameters.test-tool-args >> 186 | - when: 187 | condition: 188 | or: 189 | - equal: [pip, << parameters.pkg-manager >>] 190 | - equal: [pip-dist, << parameters.pkg-manager >>] 191 | steps: 192 | - run: 193 | name: Run tests with global python env 194 | working_directory: <> 195 | environment: 196 | PYTHONPATH: << parameters.app-dir >>/<< parameters.module-src-dir >> 197 | command: pytest --junit-xml=test-report/report.xml << parameters.test-tool-args >> 198 | - store_test_results: 199 | path: <<#parameters.app-dir>><>/<>test-report 200 | -------------------------------------------------------------------------------- /src/scripts/alias-python.sh: -------------------------------------------------------------------------------- 1 | if [ ! "${BASH_ENV_PYTHON_ALIASED}" ]; then 2 | echo 'if [ ! $(command -v python) ]; then 3 | shopt -s expand_aliases 4 | alias python=python3 5 | alias pip=pip3 6 | fi 7 | 8 | BASH_ENV_PYTHON_ALIASED=true' >> "$BASH_ENV" 9 | fi -------------------------------------------------------------------------------- /src/scripts/auto-install-command.sh: -------------------------------------------------------------------------------- 1 | # shellcheck source=detect-env.sh 2 | source "$AUTO_DETECT_ENV_SCRIPT" 3 | 4 | case ${DETECT_PKG_MNGR:-${PARAM_PKG_MNGR}} in 5 | pip) 6 | PYTHON_INSTALL_ARGS="-r ${PARAM_DEPENDENCY_FILE:-requirements.txt}" 7 | eval "${PYTHON_ENV_TOOL:-pip} install ${PYTHON_INSTALL_ARGS} ${PARAM_ADDITIONAL_ARGS}" 8 | ;; 9 | pip-dist) 10 | PYTHON_INSTALL_ARGS="-e ${PARAM_PATH_ARGS}" 11 | eval "${PYTHON_ENV_TOOL:-pip} install ${PYTHON_INSTALL_ARGS} ${PARAM_ADDITIONAL_ARGS}" 12 | ;; 13 | poetry) 14 | PYTHON_INSTALL_ARGS="--no-ansi" 15 | eval "poetry install ${PYTHON_INSTALL_ARGS} ${PARAM_ADDITIONAL_ARGS}" 16 | ;; 17 | uv) 18 | PYTHON_INSTALL_ARGS="" 19 | eval "uv sync ${PYTHON_INSTALL_ARGS} ${PARAM_ADDITIONAL_ARGS}" 20 | ;; 21 | esac 22 | -------------------------------------------------------------------------------- /src/scripts/auto-test-command.sh: -------------------------------------------------------------------------------- 1 | # shellcheck source=detect-env.sh 2 | source "$AUTO_DETECT_ENV_SCRIPT" 3 | 4 | if [ "${PARAM_TEST_TOOL}" = "pytest" ]; then 5 | INSTALL_COMMAND="pytest --junit-xml=test-report/report.xml ${PARAM_TEST_TOOL_ARGS}" 6 | else 7 | INSTALL_COMMAND="python -m unittest ${PARAM_TEST_TOOL_ARGS}" 8 | fi 9 | 10 | if [ -n "${PYTHON_ENV_TOOL}" ]; then 11 | eval "${PYTHON_ENV_TOOL} run ${INSTALL_COMMAND}" 12 | else 13 | eval "${INSTALL_COMMAND}" 14 | fi -------------------------------------------------------------------------------- /src/scripts/cache-link-lockfile.sh: -------------------------------------------------------------------------------- 1 | # shellcheck source=detect-env.sh 2 | source "$AUTO_DETECT_ENV_SCRIPT" 3 | 4 | CACHE_DIR=".cci_pycache" 5 | LOCKFILE_PATH="${CACHE_DIR}/lockfile" 6 | 7 | mkdir -p "${CACHE_DIR}" 8 | 9 | if [ ! -f "${LOCKFILE_PATH}" ]; then 10 | case ${DETECT_PKG_MNGR:-${PARAM_PKG_MNGR}} in 11 | pip | pip-dist) 12 | LOCK_FILE="${PARAM_DEPENDENCY_FILE:-requirements.txt}" 13 | ;; 14 | pipenv) 15 | LOCK_FILE="Pipfile.lock" 16 | ;; 17 | poetry) 18 | LOCK_FILE="poetry.lock" 19 | ;; 20 | uv) 21 | LOCK_FILE="uv.lock" 22 | ;; 23 | esac 24 | 25 | if [ -z "${LOCK_FILE}" ]; then 26 | echo "WARNING: Could not determine lockfile path for ${DETECT_PKG_MNGR:-PARAM_PKG_MNGR}" 27 | else 28 | FULL_LOCK_FILE=$(readlink -f "${LOCK_FILE}") 29 | 30 | if [ -f "${LOCK_FILE}" ]; then 31 | echo "INFO: Copying ${FULL_LOCK_FILE} to ${LOCKFILE_PATH}" 32 | cp "${FULL_LOCK_FILE}" "${LOCKFILE_PATH}" 33 | else 34 | echo "WARNING: Could not find lockfile at ${LOCK_FILE}" 35 | fi 36 | fi 37 | fi -------------------------------------------------------------------------------- /src/scripts/cache-restore.sh: -------------------------------------------------------------------------------- 1 | recurse() { 2 | if [ ! -d "$1" ] || [ ! -e "$2" ]; then 3 | mv -u "$1" "$2" || exit 4 | return 5 | fi 6 | for entry in "$1/"* "$1/."[!.]* "$1/.."?*; do 7 | if [ -e "$entry" ]; then 8 | recurse "$entry" "$2/${entry##"$1/"}" 9 | fi 10 | done 11 | } 12 | 13 | restore_paths() { 14 | if [ -d "${1}" ] && [ -n "$(ls -A "${1}" 2>/dev/null)" ]; then 15 | for file in "${1}"/*; do 16 | decoded=$(basename "${file}" | base64 -d) 17 | parent_dir=$(dirname "${decoded}") 18 | 19 | # make sure the parent directories exist 20 | if [ ! -d "${parent_dir}" ]; then 21 | mkdir -p "${parent_dir}" 22 | fi 23 | 24 | echo "INFO: Restoring ${file} to ${decoded}" 25 | 26 | recurse "${file}" "${decoded}" 27 | done 28 | fi 29 | } 30 | 31 | CACHE_DIR=".cci_pycache" 32 | 33 | if [ "${PARAM_VENV_CACHE}" = "1" ]; then 34 | restore_paths "${CACHE_DIR}/venv" 35 | fi 36 | 37 | if [ "${PARAM_PYPI_CACHE}" = "1" ]; then 38 | restore_paths "${CACHE_DIR}/pypi" 39 | fi -------------------------------------------------------------------------------- /src/scripts/cache-save.sh: -------------------------------------------------------------------------------- 1 | # shellcheck source=detect-env.sh 2 | source "$AUTO_DETECT_ENV_SCRIPT" 3 | 4 | case ${DETECT_PKG_MNGR:-${PARAM_PKG_MNGR}} in 5 | pip | pip-dist) 6 | LOCK_FILE="${PARAM_DEPENDENCY_FILE:-requirements.txt}" 7 | CACHE_PATHS='[ "/home/circleci/.cache/pip", "/home/circleci/.pyenv/versions", "/home/circleci/.local/lib" ]' 8 | ;; 9 | pipenv) # TODO: use PIPENV_PIPFILE 10 | LOCK_FILE="Pipfile.lock" 11 | PIPENV_VENV_PATH="${WORKON_HOME:-/home/circleci/.local/share/virtualenvs}" 12 | 13 | if [ -z "${PIPENV_VENV_IN_PROJECT}" ]; then 14 | VENV_PATHS="[ \"${PIPENV_VENV_PATH}\" ]" 15 | else 16 | VENV_PATHS="[ \"${CIRCLE_WORKING_DIRECTORY}/.venvs\" ]" 17 | fi 18 | 19 | CACHE_PATHS='[ "/home/circleci/.cache/pip", "/home/circleci/.cache/pipenv" ]' 20 | ;; 21 | poetry) 22 | LOCK_FILE="poetry.lock" 23 | VENV_PATHS='[ "/home/circleci/.cache/pypoetry/virtualenvs" ]' 24 | CACHE_PATHS='[ "/home/circleci/.cache/pip" ]' 25 | ;; 26 | uv) 27 | LOCK_FILE="uv.lock" 28 | VENV_PATHS="[ \"${CIRCLE_WORKING_DIRECTORY}/.venv\" ]" 29 | CACHE_PATHS='[ "/home/circleci/.cache/uv" ]' 30 | ;; 31 | esac 32 | 33 | if [ -n "${PARAM_VENV_PATH}" ]; then 34 | VENV_PATHS="${PARAM_VENV_PATH}" 35 | fi 36 | 37 | CACHE_DIR=".cci_pycache" 38 | mkdir -p "${CACHE_DIR}" 39 | 40 | link_paths() { 41 | if [ -d "${1}" ]; then 42 | echo "INFO: Cache directory already exists. Skipping..." 43 | return 44 | fi 45 | 46 | mkdir "${1}" 47 | 48 | for encoded in $(echo "${2}" | jq -r '.[] | @base64'); do 49 | decoded=$(echo "${encoded}" | base64 -d) 50 | 51 | if [ -e "${decoded}" ]; then 52 | echo "INFO: Copying ${decoded} to ${1}/${encoded}" 53 | cp -a "${decoded}" "${1}/${encoded}" 54 | else 55 | echo "INFO: Could not find ${decoded}. Skipping..." 56 | fi 57 | done 58 | } 59 | 60 | if [ "${PARAM_VENV_CACHE}" = "1" ] && [ -n "${VENV_PATHS}" ]; then 61 | link_paths "${CACHE_DIR}/venv" "${VENV_PATHS}" 62 | fi 63 | 64 | if [ "${PARAM_PYPI_CACHE}" = "1" ]; then 65 | link_paths "${CACHE_DIR}/pypi" "${CACHE_PATHS}" 66 | fi 67 | 68 | LOCKFILE_PATH="${CACHE_DIR}/lockfile" 69 | 70 | if [ -e "${LOCKFILE_PATH}" ]; then 71 | rm -f "${LOCKFILE_PATH}" 72 | fi 73 | 74 | if [ -e "${LOCK_FILE}" ]; then 75 | FULL_LOCK_FILE=$(readlink -f "${LOCK_FILE}") 76 | 77 | echo "INFO: Copying ${FULL_LOCK_FILE} to ${LOCKFILE_PATH}" 78 | cp "${FULL_LOCK_FILE}" "${LOCKFILE_PATH}" 79 | fi -------------------------------------------------------------------------------- /src/scripts/detect-env.sh: -------------------------------------------------------------------------------- 1 | if [ "${PARAM_PKG_MNGR}" = "auto" ]; then 2 | if [ -f "requirements.txt" ]; then 3 | if [ -f "${PARAM_SETUP_FILE_PATH:-setup.py}" ]; then 4 | export DETECT_PKG_MNGR="pip-dist" 5 | else 6 | export DETECT_PKG_MNGR="pip" 7 | fi 8 | elif [ -f "Pipfile" ]; then 9 | export DETECT_PKG_MNGR="pipenv" 10 | export PYTHON_ENV_TOOL="pipenv" 11 | elif [ -f "uv.lock" ]; then 12 | export DETECT_PKG_MNGR="uv" 13 | export PYTHON_ENV_TOOL="uv" 14 | elif [ -f "pyproject.toml" ]; then 15 | export DETECT_PKG_MNGR="poetry" 16 | export PYTHON_ENV_TOOL="poetry" 17 | fi 18 | 19 | echo "INFO: Detected Package Manager ${DETECT_PKG_MNGR}" 20 | fi -------------------------------------------------------------------------------- /src/scripts/ensure-test-tool.sh: -------------------------------------------------------------------------------- 1 | # shellcheck source=detect-env.sh 2 | source "$AUTO_DETECT_ENV_SCRIPT" 3 | 4 | case ${DETECT_PKG_MNGR:-${PARAM_PKG_MNGR}} in 5 | pip) 6 | REQUIREMENTS_PATH=${PARAM_REQUIREMENTS_PATH:-requirements.txt} 7 | ;; 8 | pip-dist) 9 | REQUIREMENTS_PATH="requirements.txt" 10 | ;; 11 | pipenv) # TODO: use PIPENV_PIPFILE 12 | REQUIREMENTS_PATH="Pipfile" 13 | PYTHON_ENV_TOOL="pipenv" 14 | ;; 15 | poetry) 16 | PYTHON_INSTALL_ARGS="--no-ansi" 17 | REQUIREMENTS_PATH="pyproject.toml" 18 | PYTHON_ENV_TOOL="poetry" 19 | ;; 20 | uv) 21 | REQUIREMENTS_PATH="uv.lock" 22 | PYTHON_ENV_TOOL="uv" 23 | ;; 24 | esac 25 | 26 | if [ -f ${REQUIREMENTS_PATH} ]; then 27 | echo "INFO: Detected dependency file: $REQUIREMENTS_PATH" 28 | else 29 | echo "WARNING: No dependency file for ${DETECT_PKG_MNGR:-${PARAM_PKG_MNGR}} found. ${REQUIREMENTS_PATH} expected." 30 | fi 31 | 32 | # Automatically install test package. unittest is preinstalled and not required. 33 | if [ "${PARAM_TEST_TOOL}" != "unittest" ]; then 34 | if ! eval "${PYTHON_ENV_TOOL:+$PYTHON_ENV_TOOL run} pip --disable-pip-version-check list" | awk 'NR > 2 && NF > 0 { print $1 }' | grep -q "^${PARAM_TEST_TOOL}$"; then 35 | if [ "${PARAM_FAIL_IF_MISSING_TOOL}" = true ]; then 36 | echo "ERROR: Test package ${PARAM_TEST_TOOL} was not found" 37 | exit 1 38 | fi 39 | 40 | # If the test package is not detected, install using PYTHON_INSTALL_TOOL 41 | echo "INFO: Test package ${PARAM_TEST_TOOL} was not found. Installing..." 42 | if [ "$PYTHON_ENV_TOOL" = "uv" ]; then 43 | eval "uv add ${PYTHON_INSTALL_ARGS} ${PARAM_TEST_TOOL}" 44 | else 45 | eval "${PYTHON_ENV_TOOL:-pip} install ${PYTHON_INSTALL_ARGS} ${PARAM_TEST_TOOL}" 46 | fi 47 | else 48 | echo "INFO: Detected test package: $DETECT_TEST_TOOL" 49 | fi 50 | fi 51 | -------------------------------------------------------------------------------- /src/scripts/export-detect-env.sh: -------------------------------------------------------------------------------- 1 | # shellcheck disable=SC2016 2 | echo 'if [ "${PARAM_PKG_MNGR}" = "auto" ]; then 3 | if [ -f "requirements.txt" ]; then 4 | if [ -f "${PARAM_SETUP_FILE_PATH:-setup.py}" ]; then 5 | export DETECT_PKG_MNGR="pip-dist" 6 | else 7 | export DETECT_PKG_MNGR="pip" 8 | fi 9 | elif [ -f "Pipfile" ]; then 10 | export DETECT_PKG_MNGR="pipenv" 11 | export PYTHON_ENV_TOOL="pipenv" 12 | elif [ -f "uv.lock" ]; then 13 | export DETECT_PKG_MNGR="uv" 14 | export PYTHON_ENV_TOOL="uv" 15 | elif [ -f "pyproject.toml" ]; then 16 | export DETECT_PKG_MNGR="poetry" 17 | export PYTHON_ENV_TOOL="poetry" 18 | fi 19 | echo "INFO: Detected Package Manager ${DETECT_PKG_MNGR}" 20 | fi' > /tmp/detect-env.sh 21 | chmod +x /tmp/detect-env.sh 22 | echo 'export AUTO_DETECT_ENV_SCRIPT="/tmp/detect-env.sh"' >> "$BASH_ENV" -------------------------------------------------------------------------------- /src/scripts/pypa-build.sh: -------------------------------------------------------------------------------- 1 | main() { 2 | local -a build_args 3 | 4 | build_args=( 5 | --outdir "$PARAM_OUTDIR" 6 | ) 7 | [[ "$PARAM_SDIST" == 1 ]] && build_args+=( --sdist ) 8 | [[ "$PARAM_WHEEL" == 1 ]] && build_args+=( --wheel ) 9 | [[ "$PARAM_SKIP_DEPENDENCY_CHECK" == 1 ]] && build_args+=( --skip-dependency-check ) 10 | [[ "$PARAM_NO_ISOLATION" == 1 ]] && build_args+=( --no-isolation ) 11 | 12 | set -x 13 | python -m build "${build_args[@]}" . 14 | set +x 15 | 16 | ls -l "$PARAM_OUTDIR" 17 | } 18 | 19 | main "$@" 20 | -------------------------------------------------------------------------------- /src/scripts/pypa-wheel.sh: -------------------------------------------------------------------------------- 1 | python setup.py sdist bdist_wheel --dist-dir "$PARAM_OUTDIR" 2 | ls -l "$PARAM_OUTDIR" 3 | --------------------------------------------------------------------------------