mirror of
https://github.com/actions/setup-python.git
synced 2025-06-24 12:41:09 +02:00
Compare commits
46 Commits
v2.3.0
...
releases/v
Author | SHA1 | Date | |
---|---|---|---|
3542bca263 | |||
48e4ac7062 | |||
98f2ad02fd | |||
5d6f0c8a87 | |||
21c0493ecf | |||
7933d5a3dd | |||
7885ec3539 | |||
9c644ca2ab | |||
3e8e90edf0 | |||
05fb98de9a | |||
6c566026c0 | |||
9516be869f | |||
7aa3e95001 | |||
6c31eb3fc7 | |||
7a37d78806 | |||
e4be7a40b0 | |||
aac0ef93ba | |||
b0c8e3dab7 | |||
0ebf7997c4 | |||
415c3568c9 | |||
42ed863652 | |||
c275cf49c7 | |||
7c950ebdca | |||
1259541ec8 | |||
95824fd246 | |||
59cb3f4919 | |||
18c67b44e4 | |||
bbebfafece | |||
6c048c7558 | |||
0ff64a7f0e | |||
792c23f43e | |||
8c1441c007 | |||
0ebf233433 | |||
665cd78205 | |||
93cb78f17b | |||
7f80679172 | |||
dc9de69ff3 | |||
ba33a692f1 | |||
156361d073 | |||
9a115684c9 | |||
3a40ba0199 | |||
fa17801fa7 | |||
6277dd1255 | |||
2b732b899c | |||
f382193329 | |||
3ef38b826b |
7
.github/workflows/check-dist.yml
vendored
7
.github/workflows/check-dist.yml
vendored
@ -23,10 +23,11 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set Node.js 12.x
|
||||
uses: actions/setup-node@v1
|
||||
- name: Set Node.js 16.x
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 12.x
|
||||
node-version: 16.x
|
||||
cache: npm
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
1
.github/workflows/codeql-analysis.yml
vendored
1
.github/workflows/codeql-analysis.yml
vendored
@ -2,6 +2,7 @@ name: "Code scanning - action"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ 'main' ]
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '25 3 * * 5'
|
||||
|
56
.github/workflows/e2e-cache.yml
vendored
56
.github/workflows/e2e-cache.yml
vendored
@ -21,9 +21,9 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
python-version: ['3.7', '3.8', '3.9', 'pypy-3.7-v7.3.5', 'pypy-3.7-v7.x']
|
||||
python-version: ['3.9', 'pypy-3.7-v7.x']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Python
|
||||
uses: ./
|
||||
with:
|
||||
@ -39,18 +39,42 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
python-version: ['3.7', '3.8', '3.9', 'pypy-3.7-v7.3.5', 'pypy-3.7-v7.x']
|
||||
python-version: ['3.9', 'pypy-3.7-v7.x']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install pipenv
|
||||
run: pipx install pipenv
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Python
|
||||
uses: ./
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'pipenv'
|
||||
- name: Install pipenv
|
||||
run: pipx install pipenv
|
||||
- name: Install dependencies
|
||||
run: pipenv install flake8
|
||||
run: |
|
||||
cd __tests__/data
|
||||
pipenv install --verbose
|
||||
|
||||
python-poetry-dependencies-caching:
|
||||
name: Test poetry (Python ${{ matrix.python-version}}, ${{ matrix.os }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
python-version: ['3.9', 'pypy-3.7-v7.x']
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install poetry
|
||||
run: pipx install poetry
|
||||
- name: Setup Python
|
||||
uses: ./
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'poetry'
|
||||
- name: Init pyproject.toml
|
||||
run: poetry init -n
|
||||
- name: Install dependencies
|
||||
run: poetry add flake8
|
||||
|
||||
python-pip-dependencies-caching-path:
|
||||
name: Test pip (Python ${{ matrix.python-version}}, ${{ matrix.os }})
|
||||
@ -59,9 +83,9 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
python-version: ['3.7', '3.8', '3.9', 'pypy-3.7-v7.3.5', 'pypy-3.7-v7.x']
|
||||
python-version: ['3.9', 'pypy-3.7-v7.x']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Python
|
||||
uses: ./
|
||||
with:
|
||||
@ -78,16 +102,18 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
python-version: ['3.7', '3.8', '3.9', 'pypy-3.7-v7.3.5', 'pypy-3.7-v7.x']
|
||||
python-version: ['3.9', 'pypy-3.7-v7.x']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install pipenv
|
||||
run: pipx install pipenv
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Python
|
||||
uses: ./
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'pipenv'
|
||||
cache-dependency-path: '**/requirements-linux.txt'
|
||||
cache-dependency-path: '**/pipenv-requirements.txt'
|
||||
- name: Install pipenv
|
||||
run: pipx install pipenv
|
||||
- name: Install dependencies
|
||||
run: pipenv install flake8
|
||||
run: |
|
||||
cd __tests__/data
|
||||
pipenv install --verbose
|
7
.github/workflows/licensed.yml
vendored
7
.github/workflows/licensed.yml
vendored
@ -14,11 +14,16 @@ jobs:
|
||||
name: Check licenses
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set Node.js 16.x
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.x
|
||||
cache: npm
|
||||
- run: npm ci
|
||||
- name: Install licensed
|
||||
run: |
|
||||
cd $RUNNER_TEMP
|
||||
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/2.12.2/licensed-2.12.2-linux-x64.tar.gz
|
||||
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/3.4.4/licensed-3.4.4-linux-x64.tar.gz
|
||||
sudo tar -xzf licensed.tar.gz
|
||||
sudo mv licensed /usr/local/bin/licensed
|
||||
- run: licensed status
|
||||
|
2
.github/workflows/test-pypy.yml
vendored
2
.github/workflows/test-pypy.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-latest]
|
||||
os: [macos-latest, windows-latest, ubuntu-latest]
|
||||
pypy:
|
||||
- 'pypy-2.7'
|
||||
- 'pypy-3.7'
|
||||
|
26
.github/workflows/test-python.yml
vendored
26
.github/workflows/test-python.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
|
||||
os: [macos-latest, windows-latest, ubuntu-20.04]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
@ -38,7 +38,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
|
||||
os: [macos-latest, windows-latest, ubuntu-20.04]
|
||||
python: [3.5.4, 3.6.7, 3.7.5, 3.8.1]
|
||||
steps:
|
||||
- name: Checkout
|
||||
@ -68,7 +68,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
|
||||
os: [macos-latest, windows-latest, ubuntu-20.04]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
@ -91,23 +91,3 @@ jobs:
|
||||
- name: Run simple code
|
||||
run: python -c 'import math; print(math.factorial(5))'
|
||||
|
||||
setup-pypy-legacy:
|
||||
name: Setup PyPy ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-10.15, windows-latest, ubuntu-18.04, ubuntu-20.04]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: setup-python pypy3
|
||||
uses: ./
|
||||
with:
|
||||
python-version: 'pypy3'
|
||||
|
||||
- name: setup-python pypy2
|
||||
uses: ./
|
||||
with:
|
||||
python-version: 'pypy2'
|
||||
|
13
.github/workflows/workflow.yml
vendored
13
.github/workflows/workflow.yml
vendored
@ -14,18 +14,19 @@ jobs:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
matrix:
|
||||
operating-system: [ubuntu-latest, windows-latest]
|
||||
operating-system: [ubuntu-20.04, windows-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set Node.js 12.x
|
||||
uses: actions/setup-node@v1
|
||||
- name: Set Node.js 16.x
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 12.x
|
||||
node-version: 16.x
|
||||
cache: npm
|
||||
|
||||
- name: npm install
|
||||
run: npm install
|
||||
- name: npm ci
|
||||
run: npm ci
|
||||
|
||||
- name: Lint
|
||||
run: npm run format-check
|
||||
|
2
.licenses/npm/@actions/cache.dep.yml
generated
2
.licenses/npm/@actions/cache.dep.yml
generated
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: "@actions/cache"
|
||||
version: 1.0.7
|
||||
version: 2.0.2
|
||||
type: npm
|
||||
summary: Actions cache lib
|
||||
homepage: https://github.com/actions/toolkit/tree/main/packages/cache
|
||||
|
2
.licenses/npm/@actions/core.dep.yml
generated
2
.licenses/npm/@actions/core.dep.yml
generated
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: "@actions/core"
|
||||
version: 1.2.6
|
||||
version: 1.10.0
|
||||
type: npm
|
||||
summary: Actions core lib
|
||||
homepage: https://github.com/actions/toolkit/tree/main/packages/core
|
||||
|
32
.licenses/npm/@actions/http-client-2.1.0.dep.yml
generated
Normal file
32
.licenses/npm/@actions/http-client-2.1.0.dep.yml
generated
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
name: "@actions/http-client"
|
||||
version: 2.1.0
|
||||
type: npm
|
||||
summary: Actions Http Client
|
||||
homepage: https://github.com/actions/toolkit/tree/main/packages/http-client
|
||||
license: mit
|
||||
licenses:
|
||||
- sources: LICENSE
|
||||
text: |
|
||||
Actions Http Client for Node.js
|
||||
|
||||
Copyright (c) GitHub, Inc.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
notices: []
|
2
.licenses/npm/@azure/core-http.dep.yml
generated
2
.licenses/npm/@azure/core-http.dep.yml
generated
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: "@azure/core-http"
|
||||
version: 2.2.1
|
||||
version: 2.2.2
|
||||
type: npm
|
||||
summary: Isomorphic client Runtime for Typescript/node.js/browser javascript client
|
||||
libraries generated using AutoRest
|
||||
|
2
.licenses/npm/@types/node.dep.yml
generated
2
.licenses/npm/@types/node.dep.yml
generated
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: "@types/node"
|
||||
version: 12.20.36
|
||||
version: 16.11.25
|
||||
type: npm
|
||||
summary: TypeScript definitions for Node.js
|
||||
homepage: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node
|
||||
|
2
.licenses/npm/node-fetch.dep.yml
generated
2
.licenses/npm/node-fetch.dep.yml
generated
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: node-fetch
|
||||
version: 2.6.5
|
||||
version: 2.6.7
|
||||
type: npm
|
||||
summary: A light-weight module that brings window.fetch to node.js
|
||||
homepage: https://github.com/bitinn/node-fetch
|
||||
|
97
README.md
97
README.md
@ -1,4 +1,4 @@
|
||||
# setup-python V2
|
||||
# setup-python V3
|
||||
|
||||
<p align="left">
|
||||
<a href="https://github.com/actions/setup-python"><img alt="GitHub Actions status" src="https://github.com/actions/setup-python/workflows/Main%20workflow/badge.svg"></a>
|
||||
@ -9,7 +9,7 @@ This action sets up a Python environment for use in actions by:
|
||||
- optionally installing and adding to PATH a version of Python that is already installed in the tools cache.
|
||||
- downloading, installing and adding to PATH an available version of Python from GitHub Releases ([actions/python-versions](https://github.com/actions/python-versions/releases)) if a specific version is not available in the tools cache.
|
||||
- failing if a specific version of Python is not preinstalled or available for download.
|
||||
- optionally caching dependencies for pip and pipenv.
|
||||
- optionally caching dependencies for pip, pipenv and poetry.
|
||||
- registering problem matchers for error output.
|
||||
|
||||
# What's new
|
||||
@ -19,7 +19,7 @@ This action sets up a Python environment for use in actions by:
|
||||
- Automatic setup and download of Python packages if using a self-hosted runner.
|
||||
- Support for pre-release versions of Python.
|
||||
- Support for installing any version of PyPy on-flight
|
||||
- Support for built-in caching of pip and pipenv dependencies
|
||||
- Support for built-in caching of pip, pipenv and poetry dependencies
|
||||
|
||||
# Usage
|
||||
|
||||
@ -28,8 +28,8 @@ See [action.yml](action.yml)
|
||||
Basic:
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: '3.x' # Version range or exact version of a Python version to use, using SemVer's version range syntax
|
||||
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
|
||||
@ -43,12 +43,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [ '2.x', '3.x', 'pypy-2.7', 'pypy-3.6', 'pypy-3.7' ]
|
||||
python-version: [ '2.x', '3.x', 'pypy-2.7', 'pypy-3.7', 'pypy-3.8' ]
|
||||
name: Python ${{ matrix.python-version }} sample
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
architecture: x64
|
||||
@ -63,20 +63,20 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
python-version: ['2.7', '3.6', '3.7', '3.8', 'pypy-2.7', 'pypy-3.6']
|
||||
python-version: ['2.7', '3.7', '3.8', '3.9', '3.10', 'pypy-2.7', 'pypy-3.8']
|
||||
exclude:
|
||||
- os: macos-latest
|
||||
python-version: '3.8'
|
||||
- os: windows-latest
|
||||
python-version: '3.6'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Display Python version
|
||||
run: python -c "import sys; print(sys.version)"
|
||||
run: python --version
|
||||
```
|
||||
|
||||
Download and set up a version of Python that does not come preinstalled on an image:
|
||||
@ -87,10 +87,10 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
# in this example, there is a newer version already installed, 3.7.7, so the older version will be downloaded
|
||||
python-version: ['3.5', '3.6', '3.7.4', '3.8']
|
||||
python-version: ['3.7.4', '3.8', '3.9', '3.10']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- run: python my_script.py
|
||||
@ -99,20 +99,20 @@ jobs:
|
||||
Download and set up an accurate pre-release version of Python:
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: '3.9.0-beta.4'
|
||||
python-version: '3.11.0-alpha.1'
|
||||
- run: python my_script.py
|
||||
```
|
||||
|
||||
Download and set up the latest available version of Python (includes both pre-release and stable versions):
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: '3.9.0-alpha - 3.9.0' # SemVer's version range syntax
|
||||
python-version: '3.11.0-alpha - 3.11.0' # SemVer's version range syntax
|
||||
- run: python my_script.py
|
||||
```
|
||||
|
||||
@ -125,12 +125,12 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version:
|
||||
- 'pypy-3.6' # the latest available version of PyPy that supports Python 3.6
|
||||
- 'pypy-3.7' # the latest available version of PyPy that supports Python 3.7
|
||||
- 'pypy-3.7-v7.3.3' # Python 3.7 and PyPy 7.3.3
|
||||
- 'pypy-3.8' # the latest available version of PyPy that supports Python 3.8
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- run: python my_script.py
|
||||
@ -146,7 +146,7 @@ Check out our detailed guide on using [Python with GitHub Actions](https://help.
|
||||
`setup-python` is able to configure Python from two sources:
|
||||
|
||||
- Preinstalled versions of Python in the tools cache on GitHub-hosted runners.
|
||||
- For detailed information regarding the available versions of Python that are installed see [Supported software](https://docs.github.com/en/actions/reference/specifications-for-github-hosted-runners#supported-software).
|
||||
- For detailed information regarding the available versions of Python that are installed, see [Supported software](https://docs.github.com/en/actions/reference/specifications-for-github-hosted-runners#supported-software).
|
||||
- For every minor version of Python, expect only the latest patch to be preinstalled.
|
||||
- If `3.8.1` is installed for example, and `3.8.2` is released, expect `3.8.1` to be removed and replaced by `3.8.2` in the tools cache.
|
||||
- If the exact patch version doesn't matter to you, specifying just the major and minor version will get you the latest preinstalled patch version. In the previous example, the version spec `3.8` will use the `3.8.2` Python version found in the cache.
|
||||
@ -159,9 +159,9 @@ Check out our detailed guide on using [Python with GitHub Actions](https://help.
|
||||
`setup-python` is able to configure PyPy from two sources:
|
||||
|
||||
- Preinstalled versions of PyPy in the tools cache on GitHub-hosted runners
|
||||
- For detailed information regarding the available versions of PyPy that are installed see [Supported software](https://docs.github.com/en/actions/reference/specifications-for-github-hosted-runners#supported-software).
|
||||
- For detailed information regarding the available versions of PyPy that are installed, see [Supported software](https://docs.github.com/en/actions/reference/specifications-for-github-hosted-runners#supported-software).
|
||||
- For the latest PyPy release, all versions of Python are cached.
|
||||
- Cache is updated with a 1-2 week delay. If you specify the PyPy version as `pypy-3.6`, the cached version will be used although a newer version is available. If you need to start using the recently released version right after release, you should specify the exact PyPy version using `pypy-3.6-v7.3.3`.
|
||||
- Cache is updated with a 1-2 week delay. If you specify the PyPy version as `pypy-3.7`, the cached version will be used although a newer version is available. If you need to start using the recently released version right after release, you should specify the exact PyPy version using `pypy-3.7-v7.3.3`.
|
||||
|
||||
- Downloadable PyPy versions from the [official PyPy site](https://downloads.python.org/pypy/).
|
||||
- All available versions that we can download are listed in [versions.json](https://downloads.python.org/pypy/versions.json) file.
|
||||
@ -198,8 +198,8 @@ The version of PyPy should be specified in the format `pypy-<python_version>[-v<
|
||||
The `<pypy_version>` parameter is optional and can be skipped. The latest version will be used in this case.
|
||||
|
||||
```
|
||||
pypy-3.6 # the latest available version of PyPy that supports Python 3.6
|
||||
pypy-3.7 # the latest available version of PyPy that supports Python 3.7
|
||||
pypy-3.8 # the latest available version of PyPy that supports Python 3.8
|
||||
pypy-2.7 # the latest available version of PyPy that supports Python 2.7
|
||||
pypy-3.7-v7.3.3 # Python 3.7 and PyPy 7.3.3
|
||||
pypy-3.7-v7.x # Python 3.7 and the latest available PyPy 7.x
|
||||
@ -209,12 +209,13 @@ pypy-3.7-nightly # Python 3.7 and nightly PyPy
|
||||
|
||||
# Caching packages dependencies
|
||||
|
||||
The action has built-in functionality for caching and restoring dependencies. It uses [actions/cache](https://github.com/actions/toolkit/tree/main/packages/cache) under the hood for caching dependencies but requires less configuration settings. Supported package managers are `pip` and `pipenv`. The `cache` input is optional, and caching is turned off by default.
|
||||
The action has built-in functionality for caching and restoring dependencies. It uses [actions/cache](https://github.com/actions/toolkit/tree/main/packages/cache) under the hood for caching dependencies but requires less configuration settings. Supported package managers are `pip`, `pipenv` and `poetry`. The `cache` input is optional, and caching is turned off by default.
|
||||
|
||||
The action defaults to searching for a dependency file (`requirements.txt` for pip or `Pipfile.lock` for pipenv) in the repository, and uses its hash as a part of the cache key. Use `cache-dependency-path` for cases where multiple dependency files are used, they are located in different subdirectories or different files for the hash want to be used.
|
||||
The action defaults to searching for a dependency file (`requirements.txt` for pip, `Pipfile.lock` for pipenv or `poetry.lock` for poetry) in the repository, and uses its hash as a part of the cache key. Use `cache-dependency-path` for cases where multiple dependency files are used, they are located in different subdirectories or different files for the hash want to be used.
|
||||
|
||||
- For pip, the action will cache global cache directory
|
||||
- For pipenv, the action will cache virtualenv directory
|
||||
- For poetry, the action will cache virtualenv directory
|
||||
|
||||
**Please Note:** Restored cache will not be used if the requirements.txt file is not updated for a long time and a newer version of the dependency is available that can lead to an increase in total build time.
|
||||
|
||||
@ -224,49 +225,60 @@ The requirements file format allows to specify dependency versions using logical
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: '3.9'
|
||||
cache: 'pip'
|
||||
- run: pip install -r requirements.txt
|
||||
- run: pip test
|
||||
```
|
||||
|
||||
**Caching pipenv dependencies:**
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install pipenv
|
||||
run: pipx install pipenv
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: '3.9'
|
||||
cache: 'pipenv'
|
||||
- run: pipenv install
|
||||
- run: pipenv test
|
||||
```
|
||||
|
||||
**Caching poetry dependencies:**
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install poetry
|
||||
run: pipx install poetry
|
||||
- uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: '3.9'
|
||||
cache: 'poetry'
|
||||
- run: poetry install
|
||||
- run: poetry run pytest
|
||||
```
|
||||
|
||||
**Using wildcard patterns to cache dependencies**
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: '3.9'
|
||||
cache: 'pip'
|
||||
cache-dependency-path: '**/requirements-dev.txt'
|
||||
- run: pip install -r subdirectory/requirements-dev.txt
|
||||
- run: pip test
|
||||
```
|
||||
|
||||
**Using a list of file paths to cache dependencies**
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install pipenv
|
||||
run: pipx install pipenv
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: '3.9'
|
||||
cache: 'pipenv'
|
||||
@ -274,7 +286,6 @@ steps:
|
||||
server/app/Pipfile.lock
|
||||
__test__/app/Pipfile.lock
|
||||
- run: pipenv install
|
||||
- run: pipenv test
|
||||
```
|
||||
|
||||
# Using `setup-python` with a self hosted runner
|
||||
@ -304,7 +315,7 @@ If you are experiencing problems while configuring Python on your self-hosted ru
|
||||
- The user starting the runner is in the owning group, and the owning group has write permission.
|
||||
- All users have write permission.
|
||||
- One quick way to grant access is to change the user and group of `/opt/hostedtoolcache` to be the same as the runners using `chown`.
|
||||
- `sudo chown runner-user:runner-group opt/hostedtoolcache/`.
|
||||
- `sudo chown runner-user:runner-group /opt/hostedtoolcache/`.
|
||||
- If your runner is configured as a service and you run into problems, make sure the user that the service is running as is correct. For more information, you can [check the status of your self-hosted runner](https://help.github.com/en/actions/hosting-your-own-runners/configuring-the-self-hosted-runner-application-as-a-service#checking-the-status-of-the-service).
|
||||
|
||||
### Mac
|
||||
|
@ -5,11 +5,21 @@ import {getCacheDistributor} from '../src/cache-distributions/cache-factory';
|
||||
|
||||
describe('restore-cache', () => {
|
||||
const pipFileLockHash =
|
||||
'67d817abcde9c72da0ed5b8f235647cb14638b9ff9d742b42e4406d2eb16fe3c';
|
||||
'd1dd6218299d8a6db5fc2001d988b34a8b31f1e9d0bb4534d377dde7c19f64b3';
|
||||
const requirementsHash =
|
||||
'd8110e0006d7fb5ee76365d565eef9d37df1d11598b912d3eb66d398d57a1121';
|
||||
const requirementsLinuxHash =
|
||||
'2d0ff7f46b0e120e3d3294db65768b474934242637b9899b873e6283dfd16d7c';
|
||||
const poetryLockHash =
|
||||
'571bf984f8d210e6a97f854e479fdd4a2b5af67b5fdac109ec337a0ea16e7836';
|
||||
const poetryConfigOutput = `
|
||||
cache-dir = "/Users/patrick/Library/Caches/pypoetry"
|
||||
experimental.new-installer = false
|
||||
installer.parallel = true
|
||||
virtualenvs.create = true
|
||||
virtualenvs.in-project = true
|
||||
virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/patrick/Library/Caches/pypoetry/virtualenvs
|
||||
`;
|
||||
|
||||
// core spy
|
||||
let infoSpy: jest.SpyInstance;
|
||||
@ -17,6 +27,7 @@ describe('restore-cache', () => {
|
||||
let debugSpy: jest.SpyInstance;
|
||||
let saveSatetSpy: jest.SpyInstance;
|
||||
let getStateSpy: jest.SpyInstance;
|
||||
let setOutputSpy: jest.SpyInstance;
|
||||
|
||||
// cache spy
|
||||
let restoreCacheSpy: jest.SpyInstance;
|
||||
@ -47,10 +58,16 @@ describe('restore-cache', () => {
|
||||
if (input.includes('pip')) {
|
||||
return {stdout: 'pip', stderr: '', exitCode: 0};
|
||||
}
|
||||
if (input.includes('poetry')) {
|
||||
return {stdout: poetryConfigOutput, stderr: '', exitCode: 0};
|
||||
}
|
||||
|
||||
return {stdout: '', stderr: 'Error occured', exitCode: 2};
|
||||
});
|
||||
|
||||
setOutputSpy = jest.spyOn(core, 'setOutput');
|
||||
setOutputSpy.mockImplementation(input => undefined);
|
||||
|
||||
restoreCacheSpy = jest.spyOn(cache, 'restoreCache');
|
||||
restoreCacheSpy.mockImplementation(
|
||||
(cachePaths: string[], primaryKey: string, restoreKey?: string) => {
|
||||
@ -82,25 +99,23 @@ describe('restore-cache', () => {
|
||||
],
|
||||
['pip', '3.8.12', '__tests__/data/requirements.txt', requirementsHash],
|
||||
['pipenv', '3.9.1', undefined, pipFileLockHash],
|
||||
['pipenv', '3.9.12', '__tests__/data/requirements.txt', requirementsHash]
|
||||
['pipenv', '3.9.12', '__tests__/data/requirements.txt', requirementsHash],
|
||||
['poetry', '3.9.1', undefined, poetryLockHash]
|
||||
])(
|
||||
'restored dependencies for %s by primaryKey',
|
||||
async (packageManager, pythonVersion, dependencyFile, fileHash) => {
|
||||
const cacheDistributor = await getCacheDistributor(
|
||||
const cacheDistributor = getCacheDistributor(
|
||||
packageManager,
|
||||
pythonVersion,
|
||||
dependencyFile
|
||||
);
|
||||
await cacheDistributor.restoreCache();
|
||||
let pythonKey = '';
|
||||
if (packageManager === 'pipenv') {
|
||||
pythonKey = `python-${pythonVersion}-`;
|
||||
}
|
||||
|
||||
expect(infoSpy).toHaveBeenCalledWith(
|
||||
`Cache restored from key: setup-python-${process.env['RUNNER_OS']}-${pythonKey}${packageManager}-${fileHash}`
|
||||
`Cache restored from key: setup-python-${process.env['RUNNER_OS']}-python-${pythonVersion}-${packageManager}-${fileHash}`
|
||||
);
|
||||
}
|
||||
},
|
||||
30000
|
||||
);
|
||||
|
||||
it.each([
|
||||
@ -115,7 +130,7 @@ describe('restore-cache', () => {
|
||||
dependencyFile,
|
||||
cacheDependencyPath
|
||||
) => {
|
||||
const cacheDistributor = await getCacheDistributor(
|
||||
const cacheDistributor = getCacheDistributor(
|
||||
packageManager,
|
||||
pythonVersion,
|
||||
dependencyFile
|
||||
@ -141,7 +156,8 @@ describe('restore-cache', () => {
|
||||
],
|
||||
['pip', '3.8.12', '__tests__/data/requirements.txt', pipFileLockHash],
|
||||
['pipenv', '3.9.1', undefined, requirementsHash],
|
||||
['pipenv', '3.9.12', '__tests__/data/requirements.txt', requirementsHash]
|
||||
['pipenv', '3.9.12', '__tests__/data/requirements.txt', requirementsHash],
|
||||
['poetry', '3.9.1', undefined, requirementsHash]
|
||||
])(
|
||||
'restored dependencies for %s by primaryKey',
|
||||
async (packageManager, pythonVersion, dependencyFile, fileHash) => {
|
||||
@ -150,17 +166,24 @@ describe('restore-cache', () => {
|
||||
return primaryKey !== fileHash && restoreKey ? pipFileLockHash : '';
|
||||
}
|
||||
);
|
||||
const cacheDistributor = await getCacheDistributor(
|
||||
const cacheDistributor = getCacheDistributor(
|
||||
packageManager,
|
||||
pythonVersion,
|
||||
dependencyFile
|
||||
);
|
||||
await cacheDistributor.restoreCache();
|
||||
let result = '';
|
||||
if (packageManager !== 'pipenv') {
|
||||
result = `Cache restored from key: ${fileHash}`;
|
||||
} else {
|
||||
result = 'pipenv cache is not found';
|
||||
|
||||
switch (packageManager) {
|
||||
case 'pip':
|
||||
result = `Cache restored from key: ${fileHash}`;
|
||||
break;
|
||||
case 'pipenv':
|
||||
result = 'pipenv cache is not found';
|
||||
break;
|
||||
case 'poetry':
|
||||
result = 'poetry cache is not found';
|
||||
break;
|
||||
}
|
||||
|
||||
expect(infoSpy).toHaveBeenCalledWith(result);
|
||||
@ -168,6 +191,38 @@ describe('restore-cache', () => {
|
||||
);
|
||||
});
|
||||
|
||||
describe('Check if handleMatchResult', () => {
|
||||
it.each([
|
||||
['pip', '3.8.12', 'requirements.txt', 'someKey', 'someKey', true],
|
||||
['pipenv', '3.9.1', 'requirements.txt', 'someKey', 'someKey', true],
|
||||
['poetry', '3.8.12', 'requirements.txt', 'someKey', 'someKey', true],
|
||||
['pip', '3.9.2', 'requirements.txt', undefined, 'someKey', false],
|
||||
['pipenv', '3.8.12', 'requirements.txt', undefined, 'someKey', false],
|
||||
['poetry', '3.9.12', 'requirements.txt', undefined, 'someKey', false]
|
||||
])(
|
||||
'sets correct outputs',
|
||||
async (
|
||||
packageManager,
|
||||
pythonVersion,
|
||||
dependencyFile,
|
||||
matchedKey,
|
||||
restoredKey,
|
||||
expectedOutputValue
|
||||
) => {
|
||||
const cacheDistributor = getCacheDistributor(
|
||||
packageManager,
|
||||
pythonVersion,
|
||||
dependencyFile
|
||||
);
|
||||
cacheDistributor.handleMatchResult(matchedKey, restoredKey);
|
||||
expect(setOutputSpy).toHaveBeenCalledWith(
|
||||
'cache-hit',
|
||||
expectedOutputValue
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
jest.clearAllMocks();
|
||||
|
@ -6,11 +6,13 @@ import {State} from '../src/cache-distributions/cache-distributor';
|
||||
|
||||
describe('run', () => {
|
||||
const pipFileLockHash =
|
||||
'67d817abcde9c72da0ed5b8f235647cb14638b9ff9d742b42e4406d2eb16fe3c';
|
||||
'd1dd6218299d8a6db5fc2001d988b34a8b31f1e9d0bb4534d377dde7c19f64b3';
|
||||
const requirementsHash =
|
||||
'd8110e0006d7fb5ee76365d565eef9d37df1d11598b912d3eb66d398d57a1121';
|
||||
const requirementsLinuxHash =
|
||||
'2d0ff7f46b0e120e3d3294db65768b474934242637b9899b873e6283dfd16d7c';
|
||||
const poetryLockHash =
|
||||
'571bf984f8d210e6a97f854e479fdd4a2b5af67b5fdac109ec337a0ea16e7836';
|
||||
|
||||
// core spy
|
||||
let infoSpy: jest.SpyInstance;
|
||||
@ -114,6 +116,22 @@ describe('run', () => {
|
||||
);
|
||||
expect(setFailedSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not save cache for pipenv', async () => {
|
||||
inputs['cache'] = 'pipenv';
|
||||
|
||||
await run();
|
||||
|
||||
expect(getInputSpy).toHaveBeenCalled();
|
||||
expect(debugSpy).toHaveBeenCalledWith(
|
||||
`paths for caching are ${__dirname}`
|
||||
);
|
||||
expect(getStateSpy).toHaveBeenCalledTimes(3);
|
||||
expect(infoSpy).toHaveBeenCalledWith(
|
||||
`Cache hit occurred on the primary key ${requirementsHash}, not saving cache.`
|
||||
);
|
||||
expect(setFailedSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('action saves the cache', () => {
|
||||
@ -168,6 +186,32 @@ describe('run', () => {
|
||||
);
|
||||
expect(setFailedSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('saves cache from poetry', async () => {
|
||||
inputs['cache'] = 'poetry';
|
||||
getStateSpy.mockImplementation((name: string) => {
|
||||
if (name === State.CACHE_MATCHED_KEY) {
|
||||
return poetryLockHash;
|
||||
} else if (name === State.CACHE_PATHS) {
|
||||
return JSON.stringify([__dirname]);
|
||||
} else {
|
||||
return requirementsHash;
|
||||
}
|
||||
});
|
||||
|
||||
await run();
|
||||
|
||||
expect(getInputSpy).toHaveBeenCalled();
|
||||
expect(getStateSpy).toHaveBeenCalledTimes(3);
|
||||
expect(infoSpy).not.toHaveBeenCalledWith(
|
||||
`Cache hit occurred on the primary key ${poetryLockHash}, not saving cache.`
|
||||
);
|
||||
expect(saveCacheSpy).toHaveBeenCalled();
|
||||
expect(infoSpy).toHaveBeenLastCalledWith(
|
||||
`Cache saved with the key: ${requirementsHash}`
|
||||
);
|
||||
expect(setFailedSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
13
__tests__/data/Pipfile
Normal file
13
__tests__/data/Pipfile
Normal file
@ -0,0 +1,13 @@
|
||||
[[source]]
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
numpy = "1.22.3"
|
||||
pandas = "1.4.2"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[requires]
|
||||
python_version = "*"
|
301
__tests__/data/Pipfile.lock
generated
301
__tests__/data/Pipfile.lock
generated
@ -1,11 +1,11 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "408f110354c997d8df1e17841d5335ae690f5b25f8c78040d62257f9535c6005"
|
||||
"sha256": "33e3640eff8b2b6c7149b85568151f39a66c544033b4b3f3f2ec9ad5ce6dfe7e"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.7"
|
||||
"python_version": "*"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
@ -16,260 +16,81 @@
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"altgraph": {
|
||||
"numpy": {
|
||||
"hashes": [
|
||||
"sha256:743628f2ac6a7c26f5d9223c91ed8ecbba535f506f4b6f558885a8a56a105857",
|
||||
"sha256:ebf2269361b47d97b3b88e696439f6e4cbc607c17c51feb1754f90fb79839158"
|
||||
],
|
||||
"version": "==0.17.2"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3",
|
||||
"sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"
|
||||
"sha256:07a8c89a04997625236c5ecb7afe35a02af3896c8aa01890a849913a2309c676",
|
||||
"sha256:08d9b008d0156c70dc392bb3ab3abb6e7a711383c3247b410b39962263576cd4",
|
||||
"sha256:201b4d0552831f7250a08d3b38de0d989d6f6e4658b709a02a73c524ccc6ffce",
|
||||
"sha256:2c10a93606e0b4b95c9b04b77dc349b398fdfbda382d2a39ba5a822f669a0123",
|
||||
"sha256:3ca688e1b9b95d80250bca34b11a05e389b1420d00e87a0d12dc45f131f704a1",
|
||||
"sha256:48a3aecd3b997bf452a2dedb11f4e79bc5bfd21a1d4cc760e703c31d57c84b3e",
|
||||
"sha256:568dfd16224abddafb1cbcce2ff14f522abe037268514dd7e42c6776a1c3f8e5",
|
||||
"sha256:5bfb1bb598e8229c2d5d48db1860bcf4311337864ea3efdbe1171fb0c5da515d",
|
||||
"sha256:639b54cdf6aa4f82fe37ebf70401bbb74b8508fddcf4797f9fe59615b8c5813a",
|
||||
"sha256:8251ed96f38b47b4295b1ae51631de7ffa8260b5b087808ef09a39a9d66c97ab",
|
||||
"sha256:92bfa69cfbdf7dfc3040978ad09a48091143cffb778ec3b03fa170c494118d75",
|
||||
"sha256:97098b95aa4e418529099c26558eeb8486e66bd1e53a6b606d684d0c3616b168",
|
||||
"sha256:a3bae1a2ed00e90b3ba5f7bd0a7c7999b55d609e0c54ceb2b076a25e345fa9f4",
|
||||
"sha256:c34ea7e9d13a70bf2ab64a2532fe149a9aced424cd05a2c4ba662fd989e3e45f",
|
||||
"sha256:dbc7601a3b7472d559dc7b933b18b4b66f9aa7452c120e87dfb33d02008c8a18",
|
||||
"sha256:e7927a589df200c5e23c57970bafbd0cd322459aa7b1ff73b7c2e84d6e3eae62",
|
||||
"sha256:f8c1f39caad2c896bc0018f699882b345b2a63708008be29b1f355ebf6f933fe",
|
||||
"sha256:f950f8845b480cffe522913d35567e29dd381b0dc7e4ce6a4a9f9156417d2430",
|
||||
"sha256:fade0d4f4d292b6f39951b6836d7a3c7ef5b2347f3c420cd9820a1d90d794802",
|
||||
"sha256:fdf3c08bce27132395d3c3ba1503cac12e17282358cb4bddc25cc46b0aca07aa"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2020.6.20"
|
||||
"version": "==1.22.3"
|
||||
},
|
||||
"chardet": {
|
||||
"pandas": {
|
||||
"hashes": [
|
||||
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
|
||||
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
|
||||
"sha256:0010771bd9223f7afe5f051eb47c4a49534345dfa144f2f5470b27189a4dd3b5",
|
||||
"sha256:061609334a8182ab500a90fe66d46f6f387de62d3a9cb9aa7e62e3146c712167",
|
||||
"sha256:09d8be7dd9e1c4c98224c4dfe8abd60d145d934e9fc1f5f411266308ae683e6a",
|
||||
"sha256:295872bf1a09758aba199992c3ecde455f01caf32266d50abc1a073e828a7b9d",
|
||||
"sha256:3228198333dd13c90b6434ddf61aa6d57deaca98cf7b654f4ad68a2db84f8cfe",
|
||||
"sha256:385c52e85aaa8ea6a4c600a9b2821181a51f8be0aee3af6f2dcb41dafc4fc1d0",
|
||||
"sha256:51649ef604a945f781105a6d2ecf88db7da0f4868ac5d45c51cb66081c4d9c73",
|
||||
"sha256:5586cc95692564b441f4747c47c8a9746792e87b40a4680a2feb7794defb1ce3",
|
||||
"sha256:5a206afa84ed20e07603f50d22b5f0db3fb556486d8c2462d8bc364831a4b417",
|
||||
"sha256:5b79af3a69e5175c6fa7b4e046b21a646c8b74e92c6581a9d825687d92071b51",
|
||||
"sha256:5c54ea4ef3823108cd4ec7fb27ccba4c3a775e0f83e39c5e17f5094cb17748bc",
|
||||
"sha256:8c5bf555b6b0075294b73965adaafb39cf71c312e38c5935c93d78f41c19828a",
|
||||
"sha256:92bc1fc585f1463ca827b45535957815b7deb218c549b7c18402c322c7549a12",
|
||||
"sha256:95c1e422ced0199cf4a34385ff124b69412c4bc912011ce895582bee620dfcaa",
|
||||
"sha256:b8134651258bce418cb79c71adeff0a44090c98d955f6953168ba16cc285d9f7",
|
||||
"sha256:be67c782c4f1b1f24c2f16a157e12c2693fd510f8df18e3287c77f33d124ed07",
|
||||
"sha256:c072c7f06b9242c855ed8021ff970c0e8f8b10b35e2640c657d2a541c5950f59",
|
||||
"sha256:d0d4f13e4be7ce89d7057a786023c461dd9370040bdb5efa0a7fe76b556867a0",
|
||||
"sha256:df82739e00bb6daf4bba4479a40f38c718b598a84654cbd8bb498fd6b0aa8c16",
|
||||
"sha256:f549097993744ff8c41b5e8f2f0d3cbfaabe89b4ae32c8c08ead6cc535b80139",
|
||||
"sha256:ff08a14ef21d94cdf18eef7c569d66f2e24e0bc89350bcd7d243dd804e3b5eb2"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.0.4"
|
||||
"version": "==1.4.2"
|
||||
},
|
||||
"docutils": {
|
||||
"python-dateutil": {
|
||||
"hashes": [
|
||||
"sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af",
|
||||
"sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"
|
||||
"sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86",
|
||||
"sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.16"
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
|
||||
"version": "==2.8.2"
|
||||
},
|
||||
"future": {
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"
|
||||
"sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7",
|
||||
"sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"
|
||||
],
|
||||
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'",
|
||||
"version": "==0.18.2"
|
||||
"version": "==2022.1"
|
||||
},
|
||||
"idna": {
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb",
|
||||
"sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"
|
||||
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
|
||||
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.9"
|
||||
},
|
||||
"itsdangerous": {
|
||||
"hashes": [
|
||||
"sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19",
|
||||
"sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"kivy": {
|
||||
"hashes": [
|
||||
"sha256:090d3ded9835a17477cd93fbdaf0a7c42ff2218981cf198ded5ad8795bc74391",
|
||||
"sha256:11e85eaf6efbfa2362a3334ffdad179a1b0ca8d255cca79eaa6a2765560d4982",
|
||||
"sha256:1a1ff32f8a95f1e175198cbab81fcd2596783b180d4eafe63e87d171aa7fdb5e",
|
||||
"sha256:1d28b198a64c30db8d94a0488e85f3037af60d514ab0d7ad5ab45add3ab77090",
|
||||
"sha256:4a5480cbf837d3780c77a4f61b32b56d22ae9f03845e7a89dd3eaef1ae5fd037",
|
||||
"sha256:4d0e596f74271e901b551f77661dde238df4765484fce9f5d1c72e8022984e84",
|
||||
"sha256:5c3d0f2749522d62e9cce09cd54b2d823bf1b6b644ff1f627be49de6f3e3cba0",
|
||||
"sha256:815a5c0b3b72fcd81ca7b2aa0744087163ed03e4cf9ab4e7c9733cea99fc1571",
|
||||
"sha256:8819a27a09871af451760cb69486ced52e830c8a0a37480f22ef5e692f12c05b",
|
||||
"sha256:a687602d90c4629dd036f577ca39acb76ba581370f9d915f3cab99be818ba8ad",
|
||||
"sha256:b7ef6aad43a86d8df3fb865db864e354f2155a748019f8517f69f65c1a29cb64",
|
||||
"sha256:b85ccf165050cbf2ee8447671eebbc222b369b40f0e0038dd9547d49a5e37373",
|
||||
"sha256:c36652caa7f6c327dee834cfc699d5962d346b7a53e54bd81abc17c314226d89",
|
||||
"sha256:ece170514db3f49844a41e4c910ad9ce9bc46da6f47a49158e11266bdcc6e479",
|
||||
"sha256:f3bea6e4a21991827885d04127fc6d09a0e974ecfa12da7bf5faae93562ea102",
|
||||
"sha256:f835462dd9aa491272552ef079b948a088598e2e95d68bb1d885d2c3f3d4e2c3"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.11.1"
|
||||
},
|
||||
"kivy-deps-angle": {
|
||||
"hashes": [
|
||||
"sha256:50605fdd4c9fdbe9f717069734a598a9aba0afe5d3f0412afbe2ecff0326e92d",
|
||||
"sha256:64ac7f33c000585dc30194e604aed925972c6b7c3848b5c3b073ae916fb0b55c",
|
||||
"sha256:99c40d53582a958748e251dfbd61aa67fb85963e27529ca08a21f2f5eeed04e1",
|
||||
"sha256:a2cea09e8a5e899629466403fbd540459f1cdef8d08c6c479b6607b95309be02",
|
||||
"sha256:b167e19b3eea55a9a8c606a607bb909ec1bedda88deee40347c780b310155a79",
|
||||
"sha256:b9d07976b0bf6bac724a42aa8ed5a8c7caa95609046db30c8f15bb731f8e4d36",
|
||||
"sha256:bb4d53f15a093214adbbe205c108ede5cc0f6af6eff104c1b8c468ddaaf6400a",
|
||||
"sha256:d0e7b7b9eb9669837a5d70808a7ea45f2b61961b56f9f69a233bad6bd36ce260"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.3.0"
|
||||
},
|
||||
"kivy-deps.glew": {
|
||||
"hashes": [
|
||||
"sha256:09f72ee5ef33ff273332e2a229dc97d650d29818a0189339421949e4e0f63d93",
|
||||
"sha256:1e28e40017af9d081fc0fc95b4fadaf31d15e9f63478dcee1c4257d67079894e",
|
||||
"sha256:45aa7f0e8d9bcf5fc1810c9c38bc20edf7dee61df81ecf62102e0f84153f924a",
|
||||
"sha256:6bb435620c3187d2c61054adb9ec277ed487256b457a0a7b1491bc0cb7247e18",
|
||||
"sha256:92e72fa2c425887987d1aa861c99537033dc20d68ae1c54864871f0401682586",
|
||||
"sha256:ab81783a82bef88a8d2bcf8a93bc21df6b8b0db6ee551eb802727d18f9074b17",
|
||||
"sha256:c843104690c0c8f3a58105c53c57f31506f6f90562c18de00bd19317cc1045a7",
|
||||
"sha256:cf351aad171796f8051af8e49ec430a9aa128d8557d8643e73f2bb1e5f9c2dab",
|
||||
"sha256:ee8ab67abb2c98d84feede657cae472e7723e529af07394244bdd33caafb1a38",
|
||||
"sha256:ef1116d99bd9cc737cb8c0e13e676955c17d6e4d6d1af5cfccef089a430071bb"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.1.12"
|
||||
},
|
||||
"kivy-deps.gstreamer": {
|
||||
"hashes": [
|
||||
"sha256:0d9598d2d31c0e780adf4b767fa3a691123621fd0ffef94b83cf82c2da84341b",
|
||||
"sha256:309eca64dee5939f16f8465e5cbb08bdde7c90ded1af6a00690c7e928326af79",
|
||||
"sha256:3d53d2c84c0a997c4cac6c239b1e0a6486e533836321003dc365ec42b97a664b",
|
||||
"sha256:4d996377111e854b3dea90846f9b2f98766a44529fd8b72125e18c552381d928",
|
||||
"sha256:4f2ddd61d185310258d338ae80a646df7822efdd7d67e57f49dc7b87555c5d7e",
|
||||
"sha256:6fa9f76afe600baa221abee31ce7dc63e653d0affe0f6c558bfc4f35af96396f",
|
||||
"sha256:739cd331b9f33a822d700273674a79a3157054e9358a01a0d553f094a5f4a8c9",
|
||||
"sha256:c29cfc63fe70a58dad889e631f1ba4711c9ea80103f2b2b8d670a97f093076c8",
|
||||
"sha256:c4709765e2b17c6c96b46a92207b0457def147544d825654077603eaf0d424de"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.1.17"
|
||||
},
|
||||
"kivy-deps.sdl2": {
|
||||
"hashes": [
|
||||
"sha256:053f26e8c05d5545bdbc7eeb8c450b8e4410ee355792e9345af536110fe247e2",
|
||||
"sha256:1b987bdd4fbbcb31baf0d7fc9584ad99912179b8968311bb7e30fbeb14e98e0d",
|
||||
"sha256:228128cdd8112dc7505ac43027a770476e9ef282e0b84ca68037133cd025960b",
|
||||
"sha256:2c2fd5a12a7a9afe3bb962b273561099a180edae91bb9c8f8386b72253fcae4a",
|
||||
"sha256:5ce23f1a3286d6288751a12b0eaefd02f947ea101bb807e9781b964e496fc3f3",
|
||||
"sha256:7928746eaed51944c10d1bb36fcefebe3d1aff1b97ba32359c2c97ba74707e1b",
|
||||
"sha256:9270fa8ed5130074b167a7a3a9c85efc3cfe3c04584ab084cb6ae9e4edfa8168",
|
||||
"sha256:92ed97d3247bc8ce98f336cbc940bb889310199326e9ccf251c49ae7e4b80de8",
|
||||
"sha256:96e1fa89fd8b5351f2d3c26bbffd50df8d554b03fba4025ecc941d773d241698",
|
||||
"sha256:c3ace0ddde0e59cdcaf260eda1daa0c05ca9bf8cd0c4ea404539de25a5dcaec7"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.1.22"
|
||||
},
|
||||
"kivy-garden": {
|
||||
"hashes": [
|
||||
"sha256:9b7d9de5efacbcd0c4b3dd873b30622a86093c9965aa47b523c7a32f3eb34610",
|
||||
"sha256:c256f42788421273a08fbb0a228f0fb0e80dd86b629fb8c0920507f645be6c72"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.1.4"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
"sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7",
|
||||
"sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==21.0"
|
||||
},
|
||||
"pdf2image": {
|
||||
"hashes": [
|
||||
"sha256:a0d9906f5507192210a8d5d7ead63145e9dec4bccc4564b1fb644e923913c31c"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.12.1"
|
||||
},
|
||||
"pefile": {
|
||||
"hashes": [
|
||||
"sha256:344a49e40a94e10849f0fe34dddc80f773a12b40675bf2f7be4b8be578bdd94a"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.0'",
|
||||
"version": "==2021.9.3"
|
||||
},
|
||||
"pillow": {
|
||||
"hashes": [
|
||||
"sha256:0295442429645fa16d05bd567ef5cff178482439c9aad0411d3f0ce9b88b3a6f",
|
||||
"sha256:06aba4169e78c439d528fdeb34762c3b61a70813527a2c57f0540541e9f433a8",
|
||||
"sha256:09d7f9e64289cb40c2c8d7ad674b2ed6105f55dc3b09aa8e4918e20a0311e7ad",
|
||||
"sha256:0a80dd307a5d8440b0a08bd7b81617e04d870e40a3e46a32d9c246e54705e86f",
|
||||
"sha256:1ca594126d3c4def54babee699c055a913efb01e106c309fa6b04405d474d5ae",
|
||||
"sha256:25930fadde8019f374400f7986e8404c8b781ce519da27792cbe46eabec00c4d",
|
||||
"sha256:431b15cffbf949e89df2f7b48528be18b78bfa5177cb3036284a5508159492b5",
|
||||
"sha256:52125833b070791fcb5710fabc640fc1df07d087fc0c0f02d3661f76c23c5b8b",
|
||||
"sha256:5e51ee2b8114def244384eda1c82b10e307ad9778dac5c83fb0943775a653cd8",
|
||||
"sha256:612cfda94e9c8346f239bf1a4b082fdd5c8143cf82d685ba2dba76e7adeeb233",
|
||||
"sha256:6d7741e65835716ceea0fd13a7d0192961212fd59e741a46bbed7a473c634ed6",
|
||||
"sha256:6edb5446f44d901e8683ffb25ebdfc26988ee813da3bf91e12252b57ac163727",
|
||||
"sha256:725aa6cfc66ce2857d585f06e9519a1cc0ef6d13f186ff3447ab6dff0a09bc7f",
|
||||
"sha256:8dad18b69f710bf3a001d2bf3afab7c432785d94fcf819c16b5207b1cfd17d38",
|
||||
"sha256:94cf49723928eb6070a892cb39d6c156f7b5a2db4e8971cb958f7b6b104fb4c4",
|
||||
"sha256:97f9e7953a77d5a70f49b9a48da7776dc51e9b738151b22dacf101641594a626",
|
||||
"sha256:9ad7f865eebde135d526bb3163d0b23ffff365cf87e767c649550964ad72785d",
|
||||
"sha256:9c87ef410a58dd54b92424ffd7e28fd2ec65d2f7fc02b76f5e9b2067e355ebf6",
|
||||
"sha256:a060cf8aa332052df2158e5a119303965be92c3da6f2d93b6878f0ebca80b2f6",
|
||||
"sha256:c79f9c5fb846285f943aafeafda3358992d64f0ef58566e23484132ecd8d7d63",
|
||||
"sha256:c92302a33138409e8f1ad16731568c55c9053eee71bb05b6b744067e1b62380f",
|
||||
"sha256:d08b23fdb388c0715990cbc06866db554e1822c4bdcf6d4166cf30ac82df8c41",
|
||||
"sha256:d350f0f2c2421e65fbc62690f26b59b0bcda1b614beb318c81e38647e0f673a1",
|
||||
"sha256:e901964262a56d9ea3c2693df68bc9860b8bdda2b04768821e4c44ae797de117",
|
||||
"sha256:ec29604081f10f16a7aea809ad42e27764188fc258b02259a03a8ff7ded3808d",
|
||||
"sha256:edf31f1150778abd4322444c393ab9c7bd2af271dd4dafb4208fb613b1f3cdc9",
|
||||
"sha256:f7e30c27477dffc3e85c2463b3e649f751789e0f6c8456099eea7ddd53be4a8a",
|
||||
"sha256:ffe538682dc19cc542ae7c3e504fdf54ca7f86fb8a135e59dd6bc8627eae6cce"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==7.2"
|
||||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
"sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44",
|
||||
"sha256:ff7a40b4860b727ab48fad6360eb351cc1b33cbf9b15a0f689ca5353e9463324"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.6.1"
|
||||
},
|
||||
"pyinstaller": {
|
||||
"hashes": [
|
||||
"sha256:3730fa80d088f8bb7084d32480eb87cbb4ddb64123363763cf8f2a1378c1c4b7"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.6"
|
||||
},
|
||||
"pyparsing": {
|
||||
"hashes": [
|
||||
"sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1",
|
||||
"sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"
|
||||
],
|
||||
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'",
|
||||
"version": "==2.4.7"
|
||||
},
|
||||
"pywin32-ctypes": {
|
||||
"hashes": [
|
||||
"sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942",
|
||||
"sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"
|
||||
],
|
||||
"version": "==0.2.0"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b",
|
||||
"sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.24.0"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527",
|
||||
"sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.25.9"
|
||||
},
|
||||
"xlrd": {
|
||||
"hashes": [
|
||||
"sha256:546eb36cee8db40c3eaa46c351e67ffee6eeb5fa2650b71bc4c758a29a1b29b2",
|
||||
"sha256:e551fb498759fa3a5384a94ccd4c3c02eb7c00ea424426e212ac0c57be9dfbde"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.2.0"
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
|
||||
"version": "==1.16.0"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
|
2
__tests__/data/pipenv-requirements.txt
Normal file
2
__tests__/data/pipenv-requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
numpy==1.22.3
|
||||
pandas==1.4.2
|
413
__tests__/data/poetry.lock
generated
Normal file
413
__tests__/data/poetry.lock
generated
Normal file
@ -0,0 +1,413 @@
|
||||
[[package]]
|
||||
name = "altgraph"
|
||||
version = "0.17.2"
|
||||
description = "Python graph (network) package"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2020.6.20"
|
||||
description = "Python package for providing Mozilla's CA Bundle."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "chardet"
|
||||
version = "3.0.4"
|
||||
description = "Universal encoding detector for Python 2 and 3"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "dis3"
|
||||
version = "0.1.3"
|
||||
description = "Python 2.7 backport of the \"dis\" module from Python 3.5+"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "docutils"
|
||||
version = "0.16"
|
||||
description = "Docutils -- Python Documentation Utilities"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[[package]]
|
||||
name = "future"
|
||||
version = "0.18.2"
|
||||
description = "Clean single-source support for Python 3 and 2"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "2.9"
|
||||
description = "Internationalized Domain Names in Applications (IDNA)"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "itsdangerous"
|
||||
version = "1.1.0"
|
||||
description = "Various helpers to pass data to untrusted environments and back."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "kivy"
|
||||
version = "1.11.1"
|
||||
description = "A software library for rapid development of hardware-accelerated multitouch applications."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
docutils = "*"
|
||||
Kivy-Garden = ">=0.1.4"
|
||||
pygments = "*"
|
||||
|
||||
[package.extras]
|
||||
tuio = ["oscpy"]
|
||||
|
||||
[[package]]
|
||||
name = "kivy-deps.angle"
|
||||
version = "0.3.0"
|
||||
description = "Repackaged binary dependency of Kivy."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "kivy-deps.glew"
|
||||
version = "0.1.12"
|
||||
description = "Repackaged binary dependency of Kivy."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "kivy-deps.gstreamer"
|
||||
version = "0.1.17"
|
||||
description = "Repackaged binary dependency of Kivy."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "kivy-deps.sdl2"
|
||||
version = "0.1.22"
|
||||
description = "Repackaged binary dependency of Kivy."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "kivy-garden"
|
||||
version = "0.1.4"
|
||||
description = "Garden tool for kivy flowers."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
requests = "*"
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "21.0"
|
||||
description = "Core utilities for Python packages"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
pyparsing = ">=2.0.2"
|
||||
|
||||
[[package]]
|
||||
name = "pdf2image"
|
||||
version = "1.12.1"
|
||||
description = "A wrapper around the pdftoppm and pdftocairo command line tools to convert PDF to a PIL Image list."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
pillow = "*"
|
||||
|
||||
[[package]]
|
||||
name = "pefile"
|
||||
version = "2021.9.3"
|
||||
description = "Python PE parsing module"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6.0"
|
||||
|
||||
[package.dependencies]
|
||||
future = "*"
|
||||
|
||||
[[package]]
|
||||
name = "pillow"
|
||||
version = "7.2.0"
|
||||
description = "Python Imaging Library (Fork)"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "pygments"
|
||||
version = "2.6.1"
|
||||
description = "Pygments is a syntax highlighting package written in Python."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "pyinstaller"
|
||||
version = "3.6"
|
||||
description = "PyInstaller bundles a Python application and all its dependencies into a single package."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[package.dependencies]
|
||||
altgraph = "*"
|
||||
dis3 = "*"
|
||||
|
||||
[[package]]
|
||||
name = "pyparsing"
|
||||
version = "2.4.7"
|
||||
description = "Python parsing module"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
|
||||
[[package]]
|
||||
name = "pywin32-ctypes"
|
||||
version = "0.2.0"
|
||||
description = ""
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.24.0"
|
||||
description = "Python HTTP for Humans."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[package.dependencies]
|
||||
certifi = ">=2017.4.17"
|
||||
chardet = ">=3.0.2,<4"
|
||||
idna = ">=2.5,<3"
|
||||
urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26"
|
||||
|
||||
[package.extras]
|
||||
security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"]
|
||||
socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "1.25.9"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
|
||||
|
||||
[package.extras]
|
||||
brotli = ["brotlipy (>=0.6.0)"]
|
||||
secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)", "ipaddress"]
|
||||
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "xlrd"
|
||||
version = "1.2.0"
|
||||
description = "Library for developers to extract data from Microsoft Excel (tm) spreadsheet files"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.8"
|
||||
content-hash = "b3d607363c6daf2b5448aa5ee676cff28606af6200d8e9b42e89937a190a3d46"
|
||||
|
||||
[metadata.files]
|
||||
altgraph = [
|
||||
{file = "altgraph-0.17.2-py2.py3-none-any.whl", hash = "sha256:743628f2ac6a7c26f5d9223c91ed8ecbba535f506f4b6f558885a8a56a105857"},
|
||||
{file = "altgraph-0.17.2.tar.gz", hash = "sha256:ebf2269361b47d97b3b88e696439f6e4cbc607c17c51feb1754f90fb79839158"},
|
||||
]
|
||||
certifi = [
|
||||
{file = "certifi-2020.6.20-py2.py3-none-any.whl", hash = "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"},
|
||||
{file = "certifi-2020.6.20.tar.gz", hash = "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3"},
|
||||
]
|
||||
chardet = [
|
||||
{file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"},
|
||||
{file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"},
|
||||
]
|
||||
dis3 = [
|
||||
{file = "dis3-0.1.3-py2-none-any.whl", hash = "sha256:61f7720dd0d8749d23fda3d7227ce74d73da11c2fade993a67ab2f9852451b14"},
|
||||
{file = "dis3-0.1.3-py3-none-any.whl", hash = "sha256:30b6412d33d738663e8ded781b138f4b01116437f0872aa56aa3adba6aeff218"},
|
||||
{file = "dis3-0.1.3.tar.gz", hash = "sha256:9259b881fc1df02ed12ac25f82d4a85b44241854330b1a651e40e0c675cb2d1e"},
|
||||
]
|
||||
docutils = [
|
||||
{file = "docutils-0.16-py2.py3-none-any.whl", hash = "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af"},
|
||||
{file = "docutils-0.16.tar.gz", hash = "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"},
|
||||
]
|
||||
future = [
|
||||
{file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"},
|
||||
]
|
||||
idna = [
|
||||
{file = "idna-2.9-py2.py3-none-any.whl", hash = "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"},
|
||||
{file = "idna-2.9.tar.gz", hash = "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb"},
|
||||
]
|
||||
itsdangerous = [
|
||||
{file = "itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"},
|
||||
{file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"},
|
||||
]
|
||||
kivy = [
|
||||
{file = "Kivy-1.11.1-cp27-cp27m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:11e85eaf6efbfa2362a3334ffdad179a1b0ca8d255cca79eaa6a2765560d4982"},
|
||||
{file = "Kivy-1.11.1-cp27-cp27m-win32.whl", hash = "sha256:5c3d0f2749522d62e9cce09cd54b2d823bf1b6b644ff1f627be49de6f3e3cba0"},
|
||||
{file = "Kivy-1.11.1-cp27-cp27m-win_amd64.whl", hash = "sha256:f835462dd9aa491272552ef079b948a088598e2e95d68bb1d885d2c3f3d4e2c3"},
|
||||
{file = "Kivy-1.11.1-cp35-cp35m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:090d3ded9835a17477cd93fbdaf0a7c42ff2218981cf198ded5ad8795bc74391"},
|
||||
{file = "Kivy-1.11.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:b85ccf165050cbf2ee8447671eebbc222b369b40f0e0038dd9547d49a5e37373"},
|
||||
{file = "Kivy-1.11.1-cp35-cp35m-win32.whl", hash = "sha256:4a5480cbf837d3780c77a4f61b32b56d22ae9f03845e7a89dd3eaef1ae5fd037"},
|
||||
{file = "Kivy-1.11.1-cp35-cp35m-win_amd64.whl", hash = "sha256:a687602d90c4629dd036f577ca39acb76ba581370f9d915f3cab99be818ba8ad"},
|
||||
{file = "Kivy-1.11.1-cp36-cp36m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:c36652caa7f6c327dee834cfc699d5962d346b7a53e54bd81abc17c314226d89"},
|
||||
{file = "Kivy-1.11.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:b7ef6aad43a86d8df3fb865db864e354f2155a748019f8517f69f65c1a29cb64"},
|
||||
{file = "Kivy-1.11.1-cp36-cp36m-win32.whl", hash = "sha256:f3bea6e4a21991827885d04127fc6d09a0e974ecfa12da7bf5faae93562ea102"},
|
||||
{file = "Kivy-1.11.1-cp36-cp36m-win_amd64.whl", hash = "sha256:ece170514db3f49844a41e4c910ad9ce9bc46da6f47a49158e11266bdcc6e479"},
|
||||
{file = "Kivy-1.11.1-cp37-cp37m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:8819a27a09871af451760cb69486ced52e830c8a0a37480f22ef5e692f12c05b"},
|
||||
{file = "Kivy-1.11.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:1a1ff32f8a95f1e175198cbab81fcd2596783b180d4eafe63e87d171aa7fdb5e"},
|
||||
{file = "Kivy-1.11.1-cp37-cp37m-win32.whl", hash = "sha256:815a5c0b3b72fcd81ca7b2aa0744087163ed03e4cf9ab4e7c9733cea99fc1571"},
|
||||
{file = "Kivy-1.11.1-cp37-cp37m-win_amd64.whl", hash = "sha256:1d28b198a64c30db8d94a0488e85f3037af60d514ab0d7ad5ab45add3ab77090"},
|
||||
{file = "Kivy-1.11.1.tar.gz", hash = "sha256:4d0e596f74271e901b551f77661dde238df4765484fce9f5d1c72e8022984e84"},
|
||||
]
|
||||
"kivy-deps.angle" = [
|
||||
{file = "kivy_deps.angle-0.3.0-cp310-cp310-win32.whl", hash = "sha256:7b56477c726e361592f794d49b2fdd96d579b7efd7225a8aadf7fd01d4e8cb80"},
|
||||
{file = "kivy_deps.angle-0.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:a4b78fd9d47c76e5ff52fcbaa040920a2f97bff038f4c534346dd833dc8f3145"},
|
||||
{file = "kivy_deps.angle-0.3.0-cp36-cp36m-win32.whl", hash = "sha256:a2cea09e8a5e899629466403fbd540459f1cdef8d08c6c479b6607b95309be02"},
|
||||
{file = "kivy_deps.angle-0.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:b167e19b3eea55a9a8c606a607bb909ec1bedda88deee40347c780b310155a79"},
|
||||
{file = "kivy_deps.angle-0.3.0-cp37-cp37m-win32.whl", hash = "sha256:d0e7b7b9eb9669837a5d70808a7ea45f2b61961b56f9f69a233bad6bd36ce260"},
|
||||
{file = "kivy_deps.angle-0.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:b9d07976b0bf6bac724a42aa8ed5a8c7caa95609046db30c8f15bb731f8e4d36"},
|
||||
{file = "kivy_deps.angle-0.3.0-cp38-cp38-win32.whl", hash = "sha256:99c40d53582a958748e251dfbd61aa67fb85963e27529ca08a21f2f5eeed04e1"},
|
||||
{file = "kivy_deps.angle-0.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:50605fdd4c9fdbe9f717069734a598a9aba0afe5d3f0412afbe2ecff0326e92d"},
|
||||
{file = "kivy_deps.angle-0.3.0-cp39-cp39-win32.whl", hash = "sha256:64ac7f33c000585dc30194e604aed925972c6b7c3848b5c3b073ae916fb0b55c"},
|
||||
{file = "kivy_deps.angle-0.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:bb4d53f15a093214adbbe205c108ede5cc0f6af6eff104c1b8c468ddaaf6400a"},
|
||||
]
|
||||
"kivy-deps.glew" = [
|
||||
{file = "kivy_deps.glew-0.1.12-cp27-cp27m-win32.whl", hash = "sha256:92e72fa2c425887987d1aa861c99537033dc20d68ae1c54864871f0401682586"},
|
||||
{file = "kivy_deps.glew-0.1.12-cp27-cp27m-win_amd64.whl", hash = "sha256:c843104690c0c8f3a58105c53c57f31506f6f90562c18de00bd19317cc1045a7"},
|
||||
{file = "kivy_deps.glew-0.1.12-cp35-cp35m-win32.whl", hash = "sha256:ee8ab67abb2c98d84feede657cae472e7723e529af07394244bdd33caafb1a38"},
|
||||
{file = "kivy_deps.glew-0.1.12-cp35-cp35m-win_amd64.whl", hash = "sha256:ab81783a82bef88a8d2bcf8a93bc21df6b8b0db6ee551eb802727d18f9074b17"},
|
||||
{file = "kivy_deps.glew-0.1.12-cp36-cp36m-win32.whl", hash = "sha256:45aa7f0e8d9bcf5fc1810c9c38bc20edf7dee61df81ecf62102e0f84153f924a"},
|
||||
{file = "kivy_deps.glew-0.1.12-cp36-cp36m-win_amd64.whl", hash = "sha256:ef1116d99bd9cc737cb8c0e13e676955c17d6e4d6d1af5cfccef089a430071bb"},
|
||||
{file = "kivy_deps.glew-0.1.12-cp37-cp37m-win32.whl", hash = "sha256:1e28e40017af9d081fc0fc95b4fadaf31d15e9f63478dcee1c4257d67079894e"},
|
||||
{file = "kivy_deps.glew-0.1.12-cp37-cp37m-win_amd64.whl", hash = "sha256:6bb435620c3187d2c61054adb9ec277ed487256b457a0a7b1491bc0cb7247e18"},
|
||||
{file = "kivy_deps.glew-0.1.12-cp38-cp38-win32.whl", hash = "sha256:09f72ee5ef33ff273332e2a229dc97d650d29818a0189339421949e4e0f63d93"},
|
||||
{file = "kivy_deps.glew-0.1.12-cp38-cp38-win_amd64.whl", hash = "sha256:cf351aad171796f8051af8e49ec430a9aa128d8557d8643e73f2bb1e5f9c2dab"},
|
||||
]
|
||||
"kivy-deps.gstreamer" = [
|
||||
{file = "kivy_deps.gstreamer-0.1.17-cp27-cp27m-win32.whl", hash = "sha256:309eca64dee5939f16f8465e5cbb08bdde7c90ded1af6a00690c7e928326af79"},
|
||||
{file = "kivy_deps.gstreamer-0.1.17-cp27-cp27m-win_amd64.whl", hash = "sha256:0d9598d2d31c0e780adf4b767fa3a691123621fd0ffef94b83cf82c2da84341b"},
|
||||
{file = "kivy_deps.gstreamer-0.1.17-cp35-cp35m-win32.whl", hash = "sha256:4f2ddd61d185310258d338ae80a646df7822efdd7d67e57f49dc7b87555c5d7e"},
|
||||
{file = "kivy_deps.gstreamer-0.1.17-cp35-cp35m-win_amd64.whl", hash = "sha256:6fa9f76afe600baa221abee31ce7dc63e653d0affe0f6c558bfc4f35af96396f"},
|
||||
{file = "kivy_deps.gstreamer-0.1.17-cp36-cp36m-win32.whl", hash = "sha256:c4709765e2b17c6c96b46a92207b0457def147544d825654077603eaf0d424de"},
|
||||
{file = "kivy_deps.gstreamer-0.1.17-cp36-cp36m-win_amd64.whl", hash = "sha256:c29cfc63fe70a58dad889e631f1ba4711c9ea80103f2b2b8d670a97f093076c8"},
|
||||
{file = "kivy_deps.gstreamer-0.1.17-cp37-cp37m-win32.whl", hash = "sha256:4d996377111e854b3dea90846f9b2f98766a44529fd8b72125e18c552381d928"},
|
||||
{file = "kivy_deps.gstreamer-0.1.17-cp37-cp37m-win_amd64.whl", hash = "sha256:739cd331b9f33a822d700273674a79a3157054e9358a01a0d553f094a5f4a8c9"},
|
||||
{file = "kivy_deps.gstreamer-0.1.17-cp38-cp38-win_amd64.whl", hash = "sha256:3d53d2c84c0a997c4cac6c239b1e0a6486e533836321003dc365ec42b97a664b"},
|
||||
]
|
||||
"kivy-deps.sdl2" = [
|
||||
{file = "kivy_deps.sdl2-0.1.22-cp27-cp27m-win32.whl", hash = "sha256:1b987bdd4fbbcb31baf0d7fc9584ad99912179b8968311bb7e30fbeb14e98e0d"},
|
||||
{file = "kivy_deps.sdl2-0.1.22-cp27-cp27m-win_amd64.whl", hash = "sha256:228128cdd8112dc7505ac43027a770476e9ef282e0b84ca68037133cd025960b"},
|
||||
{file = "kivy_deps.sdl2-0.1.22-cp35-cp35m-win32.whl", hash = "sha256:053f26e8c05d5545bdbc7eeb8c450b8e4410ee355792e9345af536110fe247e2"},
|
||||
{file = "kivy_deps.sdl2-0.1.22-cp35-cp35m-win_amd64.whl", hash = "sha256:5ce23f1a3286d6288751a12b0eaefd02f947ea101bb807e9781b964e496fc3f3"},
|
||||
{file = "kivy_deps.sdl2-0.1.22-cp36-cp36m-win32.whl", hash = "sha256:96e1fa89fd8b5351f2d3c26bbffd50df8d554b03fba4025ecc941d773d241698"},
|
||||
{file = "kivy_deps.sdl2-0.1.22-cp36-cp36m-win_amd64.whl", hash = "sha256:c3ace0ddde0e59cdcaf260eda1daa0c05ca9bf8cd0c4ea404539de25a5dcaec7"},
|
||||
{file = "kivy_deps.sdl2-0.1.22-cp37-cp37m-win32.whl", hash = "sha256:7928746eaed51944c10d1bb36fcefebe3d1aff1b97ba32359c2c97ba74707e1b"},
|
||||
{file = "kivy_deps.sdl2-0.1.22-cp37-cp37m-win_amd64.whl", hash = "sha256:2c2fd5a12a7a9afe3bb962b273561099a180edae91bb9c8f8386b72253fcae4a"},
|
||||
{file = "kivy_deps.sdl2-0.1.22-cp38-cp38-win32.whl", hash = "sha256:9270fa8ed5130074b167a7a3a9c85efc3cfe3c04584ab084cb6ae9e4edfa8168"},
|
||||
{file = "kivy_deps.sdl2-0.1.22-cp38-cp38-win_amd64.whl", hash = "sha256:92ed97d3247bc8ce98f336cbc940bb889310199326e9ccf251c49ae7e4b80de8"},
|
||||
]
|
||||
kivy-garden = [
|
||||
{file = "Kivy Garden-0.1.4.tar.gz", hash = "sha256:9b7d9de5efacbcd0c4b3dd873b30622a86093c9965aa47b523c7a32f3eb34610"},
|
||||
{file = "kivy-garden-0.1.4.tar.gz", hash = "sha256:c256f42788421273a08fbb0a228f0fb0e80dd86b629fb8c0920507f645be6c72"},
|
||||
]
|
||||
packaging = [
|
||||
{file = "packaging-21.0-py3-none-any.whl", hash = "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14"},
|
||||
{file = "packaging-21.0.tar.gz", hash = "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7"},
|
||||
]
|
||||
pdf2image = [
|
||||
{file = "pdf2image-1.12.1.tar.gz", hash = "sha256:a0d9906f5507192210a8d5d7ead63145e9dec4bccc4564b1fb644e923913c31c"},
|
||||
]
|
||||
pefile = [
|
||||
{file = "pefile-2021.9.3.tar.gz", hash = "sha256:344a49e40a94e10849f0fe34dddc80f773a12b40675bf2f7be4b8be578bdd94a"},
|
||||
]
|
||||
pillow = [
|
||||
{file = "Pillow-7.2.0-cp35-cp35m-macosx_10_10_intel.whl", hash = "sha256:1ca594126d3c4def54babee699c055a913efb01e106c309fa6b04405d474d5ae"},
|
||||
{file = "Pillow-7.2.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c92302a33138409e8f1ad16731568c55c9053eee71bb05b6b744067e1b62380f"},
|
||||
{file = "Pillow-7.2.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:8dad18b69f710bf3a001d2bf3afab7c432785d94fcf819c16b5207b1cfd17d38"},
|
||||
{file = "Pillow-7.2.0-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:431b15cffbf949e89df2f7b48528be18b78bfa5177cb3036284a5508159492b5"},
|
||||
{file = "Pillow-7.2.0-cp35-cp35m-win32.whl", hash = "sha256:09d7f9e64289cb40c2c8d7ad674b2ed6105f55dc3b09aa8e4918e20a0311e7ad"},
|
||||
{file = "Pillow-7.2.0-cp35-cp35m-win_amd64.whl", hash = "sha256:0295442429645fa16d05bd567ef5cff178482439c9aad0411d3f0ce9b88b3a6f"},
|
||||
{file = "Pillow-7.2.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:ec29604081f10f16a7aea809ad42e27764188fc258b02259a03a8ff7ded3808d"},
|
||||
{file = "Pillow-7.2.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:612cfda94e9c8346f239bf1a4b082fdd5c8143cf82d685ba2dba76e7adeeb233"},
|
||||
{file = "Pillow-7.2.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0a80dd307a5d8440b0a08bd7b81617e04d870e40a3e46a32d9c246e54705e86f"},
|
||||
{file = "Pillow-7.2.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:06aba4169e78c439d528fdeb34762c3b61a70813527a2c57f0540541e9f433a8"},
|
||||
{file = "Pillow-7.2.0-cp36-cp36m-win32.whl", hash = "sha256:f7e30c27477dffc3e85c2463b3e649f751789e0f6c8456099eea7ddd53be4a8a"},
|
||||
{file = "Pillow-7.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:ffe538682dc19cc542ae7c3e504fdf54ca7f86fb8a135e59dd6bc8627eae6cce"},
|
||||
{file = "Pillow-7.2.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:94cf49723928eb6070a892cb39d6c156f7b5a2db4e8971cb958f7b6b104fb4c4"},
|
||||
{file = "Pillow-7.2.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6edb5446f44d901e8683ffb25ebdfc26988ee813da3bf91e12252b57ac163727"},
|
||||
{file = "Pillow-7.2.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:52125833b070791fcb5710fabc640fc1df07d087fc0c0f02d3661f76c23c5b8b"},
|
||||
{file = "Pillow-7.2.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:9ad7f865eebde135d526bb3163d0b23ffff365cf87e767c649550964ad72785d"},
|
||||
{file = "Pillow-7.2.0-cp37-cp37m-win32.whl", hash = "sha256:c79f9c5fb846285f943aafeafda3358992d64f0ef58566e23484132ecd8d7d63"},
|
||||
{file = "Pillow-7.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d350f0f2c2421e65fbc62690f26b59b0bcda1b614beb318c81e38647e0f673a1"},
|
||||
{file = "Pillow-7.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:6d7741e65835716ceea0fd13a7d0192961212fd59e741a46bbed7a473c634ed6"},
|
||||
{file = "Pillow-7.2.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:edf31f1150778abd4322444c393ab9c7bd2af271dd4dafb4208fb613b1f3cdc9"},
|
||||
{file = "Pillow-7.2.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:d08b23fdb388c0715990cbc06866db554e1822c4bdcf6d4166cf30ac82df8c41"},
|
||||
{file = "Pillow-7.2.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:5e51ee2b8114def244384eda1c82b10e307ad9778dac5c83fb0943775a653cd8"},
|
||||
{file = "Pillow-7.2.0-cp38-cp38-win32.whl", hash = "sha256:725aa6cfc66ce2857d585f06e9519a1cc0ef6d13f186ff3447ab6dff0a09bc7f"},
|
||||
{file = "Pillow-7.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:a060cf8aa332052df2158e5a119303965be92c3da6f2d93b6878f0ebca80b2f6"},
|
||||
{file = "Pillow-7.2.0-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:9c87ef410a58dd54b92424ffd7e28fd2ec65d2f7fc02b76f5e9b2067e355ebf6"},
|
||||
{file = "Pillow-7.2.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:e901964262a56d9ea3c2693df68bc9860b8bdda2b04768821e4c44ae797de117"},
|
||||
{file = "Pillow-7.2.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:25930fadde8019f374400f7986e8404c8b781ce519da27792cbe46eabec00c4d"},
|
||||
{file = "Pillow-7.2.0.tar.gz", hash = "sha256:97f9e7953a77d5a70f49b9a48da7776dc51e9b738151b22dacf101641594a626"},
|
||||
]
|
||||
pygments = [
|
||||
{file = "Pygments-2.6.1-py3-none-any.whl", hash = "sha256:ff7a40b4860b727ab48fad6360eb351cc1b33cbf9b15a0f689ca5353e9463324"},
|
||||
{file = "Pygments-2.6.1.tar.gz", hash = "sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44"},
|
||||
]
|
||||
pyinstaller = [
|
||||
{file = "PyInstaller-3.6.tar.gz", hash = "sha256:3730fa80d088f8bb7084d32480eb87cbb4ddb64123363763cf8f2a1378c1c4b7"},
|
||||
]
|
||||
pyparsing = [
|
||||
{file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
|
||||
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
|
||||
]
|
||||
pywin32-ctypes = [
|
||||
{file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"},
|
||||
{file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"},
|
||||
]
|
||||
requests = [
|
||||
{file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"},
|
||||
{file = "requests-2.24.0.tar.gz", hash = "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"},
|
||||
]
|
||||
urllib3 = [
|
||||
{file = "urllib3-1.25.9-py2.py3-none-any.whl", hash = "sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115"},
|
||||
{file = "urllib3-1.25.9.tar.gz", hash = "sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527"},
|
||||
]
|
||||
xlrd = [
|
||||
{file = "xlrd-1.2.0-py2.py3-none-any.whl", hash = "sha256:e551fb498759fa3a5384a94ccd4c3c02eb7c00ea424426e212ac0c57be9dfbde"},
|
||||
{file = "xlrd-1.2.0.tar.gz", hash = "sha256:546eb36cee8db40c3eaa46c351e67ffee6eeb5fa2650b71bc4c758a29a1b29b2"},
|
||||
]
|
@ -35,7 +35,7 @@ describe('Finder tests', () => {
|
||||
await io.mkdirP(pythonDir);
|
||||
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
|
||||
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
|
||||
await finder.findPythonVersion('3.x', 'x64');
|
||||
await finder.useCpythonVersion('3.x', 'x64');
|
||||
});
|
||||
|
||||
it('Finds stable Python version if it is not installed, but exists in the manifest', async () => {
|
||||
@ -52,7 +52,7 @@ describe('Finder tests', () => {
|
||||
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
|
||||
});
|
||||
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
|
||||
await finder.findPythonVersion('1.2.3', 'x64');
|
||||
await finder.useCpythonVersion('1.2.3', 'x64');
|
||||
});
|
||||
|
||||
it('Finds pre-release Python version in the manifest', async () => {
|
||||
@ -74,25 +74,17 @@ describe('Finder tests', () => {
|
||||
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
|
||||
});
|
||||
// This will throw if it doesn't find it in the manifest (because no such version exists)
|
||||
await finder.findPythonVersion('1.2.3-beta.2', 'x64');
|
||||
await finder.useCpythonVersion('1.2.3-beta.2', 'x64');
|
||||
});
|
||||
|
||||
it('Errors if Python is not installed', async () => {
|
||||
// This will throw if it doesn't find it in the cache and in the manifest (because no such version exists)
|
||||
let thrown = false;
|
||||
try {
|
||||
await finder.findPythonVersion('3.300000', 'x64');
|
||||
await finder.useCpythonVersion('3.300000', 'x64');
|
||||
} catch {
|
||||
thrown = true;
|
||||
}
|
||||
expect(thrown).toBeTruthy();
|
||||
});
|
||||
|
||||
it('Finds PyPy if it is installed', async () => {
|
||||
const pythonDir: string = path.join(toolDir, 'PyPy', '2.0.0', 'x64');
|
||||
await io.mkdirP(pythonDir);
|
||||
fs.writeFileSync(`${pythonDir}.complete`, 'hello');
|
||||
// This will throw if it doesn't find it in the cache (because no such version exists)
|
||||
await finder.findPythonVersion('pypy2', 'x64');
|
||||
});
|
||||
});
|
||||
|
@ -1,8 +1,14 @@
|
||||
import * as cache from '@actions/cache';
|
||||
import * as core from '@actions/core';
|
||||
import {
|
||||
validateVersion,
|
||||
validatePythonVersionFormatForPyPy
|
||||
validatePythonVersionFormatForPyPy,
|
||||
isCacheFeatureAvailable
|
||||
} from '../src/utils';
|
||||
|
||||
jest.mock('@actions/cache');
|
||||
jest.mock('@actions/core');
|
||||
|
||||
describe('validatePythonVersionFormatForPyPy', () => {
|
||||
it.each([
|
||||
['3.6', true],
|
||||
@ -32,3 +38,39 @@ describe('validateVersion', () => {
|
||||
expect(validateVersion(input)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isCacheFeatureAvailable', () => {
|
||||
it('isCacheFeatureAvailable disabled on GHES', () => {
|
||||
jest.spyOn(cache, 'isFeatureAvailable').mockImplementation(() => false);
|
||||
try {
|
||||
process.env['GITHUB_SERVER_URL'] = 'http://example.com';
|
||||
isCacheFeatureAvailable();
|
||||
} catch (error) {
|
||||
expect(error).toHaveProperty(
|
||||
'message',
|
||||
'Caching is only supported on GHES version >= 3.5. If you are on a version >= 3.5, please check with your GHES admin if the Actions cache service is enabled or not.'
|
||||
);
|
||||
} finally {
|
||||
delete process.env['GITHUB_SERVER_URL'];
|
||||
}
|
||||
});
|
||||
|
||||
it('isCacheFeatureAvailable disabled on dotcom', () => {
|
||||
jest.spyOn(cache, 'isFeatureAvailable').mockImplementation(() => false);
|
||||
const infoMock = jest.spyOn(core, 'warning');
|
||||
const message =
|
||||
'The runner was not able to contact the cache service. Caching will be skipped';
|
||||
try {
|
||||
process.env['GITHUB_SERVER_URL'] = 'http://github.com';
|
||||
expect(isCacheFeatureAvailable()).toBe(false);
|
||||
expect(infoMock).toHaveBeenCalledWith(message);
|
||||
} finally {
|
||||
delete process.env['GITHUB_SERVER_URL'];
|
||||
}
|
||||
});
|
||||
|
||||
it('isCacheFeatureAvailable is enabled', () => {
|
||||
jest.spyOn(cache, 'isFeatureAvailable').mockImplementation(() => true);
|
||||
expect(isCacheFeatureAvailable()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -7,7 +7,7 @@ inputs:
|
||||
description: "Version range or exact version of a Python version to use, using SemVer's version range syntax."
|
||||
default: '3.x'
|
||||
cache:
|
||||
description: 'Used to specify a package manager for caching in the default directory. Supported values: pip, pipenv.'
|
||||
description: 'Used to specify a package manager for caching in the default directory. Supported values: pip, pipenv, poetry.'
|
||||
required: false
|
||||
architecture:
|
||||
description: 'The target architecture (x86, x64) of the Python interpreter.'
|
||||
@ -19,8 +19,10 @@ inputs:
|
||||
outputs:
|
||||
python-version:
|
||||
description: "The installed python version. Useful when given a version range as input."
|
||||
cache-hit:
|
||||
description: 'A boolean value to indicate a cache entry was found'
|
||||
runs:
|
||||
using: 'node12'
|
||||
using: 'node16'
|
||||
main: 'dist/setup/index.js'
|
||||
post: 'dist/cache-save/index.js'
|
||||
post-if: success()
|
||||
|
2466
dist/cache-save/index.js
vendored
2466
dist/cache-save/index.js
vendored
File diff suppressed because it is too large
Load Diff
6241
dist/setup/index.js
vendored
6241
dist/setup/index.js
vendored
File diff suppressed because one or more lines are too long
93
docs/adrs/0000-caching-dependencies.md
Normal file
93
docs/adrs/0000-caching-dependencies.md
Normal file
@ -0,0 +1,93 @@
|
||||
## 0. Caching dependencies
|
||||
|
||||
Date: 2021-10-01
|
||||
|
||||
Status: Accepted
|
||||
|
||||
## Context
|
||||
|
||||
`actions/setup-python` is one the most popular python's action in GitHub Actions. A lot of customers use it in conjunction with `actions/cache` to speed up dependencies installation.
|
||||
See more examples on proper usage in [actions/cache documentation](https://github.com/actions/cache/blob/main/examples.md#python---pip).
|
||||
|
||||
## Goals & Anti-Goals
|
||||
|
||||
Integration of caching functionality into `actions/setup-python` action will bring the following benefits for action users:
|
||||
- Decrease the entry threshold for using the cache for Python dependencies and simplify initial configuration
|
||||
- Simplify YAML pipelines by reducing the need for additional steps to enable caching
|
||||
- More users will use caching for Python so users will have faster builds!
|
||||
|
||||
We will add support for Pip and Pipenv dependency caching.
|
||||
|
||||
We won't pursue the goal to provide wide customization of caching in the scope of `actions/setup-python` action. The purpose of this integration is to cover ~90% of basic use-cases. If users need flexible customization, we will advise them to use `actions/cache` directly.
|
||||
|
||||
## Decision
|
||||
|
||||
- Add a `cache` input parameter to `actions/setup-python`. For now the input will accept the following values:
|
||||
- pip - enable caching for pip dependencies
|
||||
- pipenv - enable caching for pipenv dependencies
|
||||
- '' - disable caching (default value)
|
||||
- Cache feature will be disabled by default to make sure that we don't break existing customers.
|
||||
- Action will try to search dependencies files (requirements.txt for pip and Pipfile.lock for pipenv) in the repository root (or relative to the repository root, if patterns are used) and throw error if no one is found.
|
||||
- The hash of found file will be used as part of cache key (the same approach like actions/cache recommends)
|
||||
- The following cache key will be used for pip: `setup-python-${{ runner.os }}-pip-${{ hashFiles('<package-file-path>') }}`
|
||||
- The following cache key will be used for pipenv: `setup-python-${{ runner.os }}-python-${{ python-version }}-pipenv-${{ hashFiles('<package-file-path>') }}`. We add the python version to the cache key because the created virtualenv folder with the project name contains a copy of the python binary as a symlink to paths like `/opt/hostedtoolcache/Python/3.7.11`, so the cache can be fetched with a wrong python version. See details in the related [pull request](https://github.com/actions/cache/pull/607) in the actions/cache.
|
||||
- Action will save the packages global cache:
|
||||
- Pip (retrieved via pip cache dir). The command is available With pip 20.1 or later. We always update pip during installation, that is why this command should be available.
|
||||
- Pipenv (default cache paths):
|
||||
- ~/.local/share/virtualenvs (macOS)
|
||||
- ~/.virtualenvs (Windows)
|
||||
- ~/.local/share/virtualenvs (Ubuntu)
|
||||
- Add a `cache-dependency-path` input parameter to `actions/setup-python`. The new input will accept an array or regex of dependency files. The field will accept a path (relative to the repository root) to dependency files. If the provided path contains wildcards, the action will search all matching files and calculate a common hash like the `${{ hashFiles('**/requirements-dev.txt') }}` YAML construction does
|
||||
|
||||
## Example of real use-cases
|
||||
|
||||
- Pip package manager
|
||||
|
||||
```
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
cache: pip
|
||||
```
|
||||
|
||||
- Pipenv package manager
|
||||
|
||||
```
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
cache: pipenv
|
||||
```
|
||||
- With `cache-dependency-path`
|
||||
|
||||
```
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
cache: pip
|
||||
cache-dependency-path: |
|
||||
**/requirements-dev.txt
|
||||
**/requirements-test.txt
|
||||
**/requirements.txt
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
cache: pip
|
||||
cache-dependency-path: **/requirements-dev.txt
|
||||
```
|
||||
|
||||
## Release process
|
||||
|
||||
As soon as the functionality is implemented, we will release a minor update of the action. No need to bump the major version since there are no breaking changes for existing users. After that, we will update [starter-workflows](https://github.com/actions/starter-workflows/blob/main/ci/python-app.yml) and [GitHub Action documentation](https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#caching-dependencies).
|
10326
package-lock.json
generated
10326
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "setup-python",
|
||||
"version": "2.2.2",
|
||||
"version": "3.1.1",
|
||||
"private": true,
|
||||
"description": "Setup python action",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"build": "ncc build -o dist/setup src/setup-python.ts && ncc build -o dist/cache-save src/cache-save.ts",
|
||||
"format": "prettier --write \"{,!(node_modules)/**/}*.ts\"",
|
||||
"format-check": "prettier --check \"{,!(node_modules)/**/}*.ts\"",
|
||||
"release": "ncc build -o dist/setup src/setup-python.ts && ncc build -o dist/cache-save src/cache-save.ts && git add -f dist/",
|
||||
@ -23,7 +23,7 @@
|
||||
"author": "GitHub",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/cache": "^1.0.7",
|
||||
"@actions/cache": "^2.0.2",
|
||||
"@actions/core": "^1.2.3",
|
||||
"@actions/exec": "^1.1.0",
|
||||
"@actions/glob": "^0.2.0",
|
||||
@ -33,7 +33,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/node": "^12.20.36",
|
||||
"@types/node": "^16.11.25",
|
||||
"@types/semver": "^7.1.0",
|
||||
"@zeit/ncc": "^0.22.0",
|
||||
"husky": "^7.0.2",
|
||||
@ -41,7 +41,7 @@
|
||||
"jest-circus": "^27.2.5",
|
||||
"prettier": "^2.0.2",
|
||||
"ts-jest": "^27.0.5",
|
||||
"typescript": "^3.8.3"
|
||||
"typescript": "^4.2.3"
|
||||
},
|
||||
"husky": {
|
||||
"skipCI": true,
|
||||
|
@ -41,12 +41,17 @@ abstract class CacheDistributor {
|
||||
restoreKey
|
||||
);
|
||||
|
||||
this.handleMatchResult(matchedKey, primaryKey);
|
||||
}
|
||||
|
||||
public handleMatchResult(matchedKey: string | undefined, primaryKey: string) {
|
||||
if (matchedKey) {
|
||||
core.saveState(State.CACHE_MATCHED_KEY, matchedKey);
|
||||
core.info(`Cache restored from key: ${matchedKey}`);
|
||||
} else {
|
||||
core.info(`${this.packageManager} cache is not found`);
|
||||
}
|
||||
core.setOutput('cache-hit', matchedKey === primaryKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
import PipCache from './pip-cache';
|
||||
import PipenvCache from './pipenv-cache';
|
||||
import PoetryCache from './poetry-cache';
|
||||
|
||||
export enum PackageManagers {
|
||||
Pip = 'pip',
|
||||
Pipenv = 'pipenv'
|
||||
Pipenv = 'pipenv',
|
||||
Poetry = 'poetry'
|
||||
}
|
||||
|
||||
export function getCacheDistributor(
|
||||
@ -13,9 +15,11 @@ export function getCacheDistributor(
|
||||
) {
|
||||
switch (packageManager) {
|
||||
case PackageManagers.Pip:
|
||||
return new PipCache(cacheDependencyPath);
|
||||
return new PipCache(pythonVersion, cacheDependencyPath);
|
||||
case PackageManagers.Pipenv:
|
||||
return new PipenvCache(pythonVersion, cacheDependencyPath);
|
||||
case PackageManagers.Poetry:
|
||||
return new PoetryCache(pythonVersion, cacheDependencyPath);
|
||||
default:
|
||||
throw new Error(`Caching for '${packageManager}' is not supported`);
|
||||
}
|
||||
|
@ -1,21 +1,42 @@
|
||||
import * as glob from '@actions/glob';
|
||||
import * as core from '@actions/core';
|
||||
import * as exec from '@actions/exec';
|
||||
|
||||
import * as child_process from 'child_process';
|
||||
import utils from 'util';
|
||||
import * as path from 'path';
|
||||
import os from 'os';
|
||||
|
||||
import CacheDistributor from './cache-distributor';
|
||||
import {IS_WINDOWS} from '../utils';
|
||||
|
||||
class PipCache extends CacheDistributor {
|
||||
constructor(cacheDependencyPath: string = '**/requirements.txt') {
|
||||
constructor(
|
||||
private pythonVersion: string,
|
||||
cacheDependencyPath: string = '**/requirements.txt'
|
||||
) {
|
||||
super('pip', cacheDependencyPath);
|
||||
}
|
||||
|
||||
protected async getCacheGlobalDirectories() {
|
||||
const {stdout, stderr, exitCode} = await exec.getExecOutput(
|
||||
'pip cache dir'
|
||||
);
|
||||
let exitCode = 1;
|
||||
let stdout = '';
|
||||
let stderr = '';
|
||||
|
||||
// Add temporary fix for Windows
|
||||
// On windows it is necessary to execute through an exec
|
||||
// because the getExecOutput gives a non zero code or writes to stderr for pip 22.0.2,
|
||||
// or spawn must be started with the shell option enabled for getExecOutput
|
||||
// Related issue: https://github.com/actions/setup-python/issues/328
|
||||
if (IS_WINDOWS) {
|
||||
const execPromisify = utils.promisify(child_process.exec);
|
||||
({stdout: stdout, stderr: stderr} = await execPromisify('pip cache dir'));
|
||||
} else {
|
||||
({
|
||||
stdout: stdout,
|
||||
stderr: stderr,
|
||||
exitCode: exitCode
|
||||
} = await exec.getExecOutput('pip cache dir'));
|
||||
}
|
||||
|
||||
if (exitCode && stderr) {
|
||||
throw new Error(
|
||||
@ -36,8 +57,8 @@ class PipCache extends CacheDistributor {
|
||||
|
||||
protected async computeKeys() {
|
||||
const hash = await glob.hashFiles(this.cacheDependencyPath);
|
||||
const primaryKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager}-${hash}`;
|
||||
const restoreKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-${this.packageManager}`;
|
||||
const primaryKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-python-${this.pythonVersion}-${this.packageManager}-${hash}`;
|
||||
const restoreKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-python-${this.pythonVersion}-${this.packageManager}`;
|
||||
|
||||
return {
|
||||
primaryKey,
|
||||
|
76
src/cache-distributions/poetry-cache.ts
Normal file
76
src/cache-distributions/poetry-cache.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import * as glob from '@actions/glob';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import * as exec from '@actions/exec';
|
||||
|
||||
import CacheDistributor from './cache-distributor';
|
||||
|
||||
class PoetryCache extends CacheDistributor {
|
||||
constructor(
|
||||
private pythonVersion: string,
|
||||
protected patterns: string = '**/poetry.lock'
|
||||
) {
|
||||
super('poetry', patterns);
|
||||
}
|
||||
|
||||
protected async getCacheGlobalDirectories() {
|
||||
const poetryConfig = await this.getPoetryConfiguration();
|
||||
|
||||
const cacheDir = poetryConfig['cache-dir'];
|
||||
const virtualenvsPath = poetryConfig['virtualenvs.path'].replace(
|
||||
'{cache-dir}',
|
||||
cacheDir
|
||||
);
|
||||
|
||||
const paths = [virtualenvsPath];
|
||||
|
||||
if (poetryConfig['virtualenvs.in-project'] === true) {
|
||||
paths.push(path.join(process.cwd(), '.venv'));
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
protected async computeKeys() {
|
||||
const hash = await glob.hashFiles(this.patterns);
|
||||
const primaryKey = `${this.CACHE_KEY_PREFIX}-${process.env['RUNNER_OS']}-python-${this.pythonVersion}-${this.packageManager}-${hash}`;
|
||||
const restoreKey = undefined;
|
||||
return {
|
||||
primaryKey,
|
||||
restoreKey
|
||||
};
|
||||
}
|
||||
|
||||
private async getPoetryConfiguration() {
|
||||
const {stdout, stderr, exitCode} = await exec.getExecOutput('poetry', [
|
||||
'config',
|
||||
'--list'
|
||||
]);
|
||||
|
||||
if (exitCode && stderr) {
|
||||
throw new Error(
|
||||
'Could not get cache folder path for poetry package manager'
|
||||
);
|
||||
}
|
||||
|
||||
const lines = stdout.trim().split('\n');
|
||||
|
||||
const config: any = {};
|
||||
|
||||
for (let line of lines) {
|
||||
line = line.replace(/#.*$/, '');
|
||||
|
||||
const [key, value] = line.split('=').map(part => part.trim());
|
||||
|
||||
config[key] = JSON.parse(value);
|
||||
}
|
||||
|
||||
return config as {
|
||||
'cache-dir': string;
|
||||
'virtualenvs.in-project': boolean;
|
||||
'virtualenvs.path': string;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default PoetryCache;
|
@ -52,6 +52,7 @@ export async function findPyPyVersion(
|
||||
core.exportVariable('pythonLocation', pythonLocation);
|
||||
core.addPath(pythonLocation);
|
||||
core.addPath(_binDir);
|
||||
core.setOutput('python-version', 'pypy' + resolvedPyPyVersion.trim());
|
||||
|
||||
return {resolvedPyPyVersion, resolvedPythonVersion};
|
||||
}
|
||||
|
@ -30,52 +30,7 @@ function binDir(installDir: string): string {
|
||||
}
|
||||
}
|
||||
|
||||
// Note on the tool cache layout for PyPy:
|
||||
// PyPy has its own versioning scheme that doesn't follow the Python versioning scheme.
|
||||
// A particular version of PyPy may contain one or more versions of the Python interpreter.
|
||||
// For example, PyPy 7.0 contains Python 2.7, 3.5, and 3.6-alpha.
|
||||
// We only care about the Python version, so we don't use the PyPy version for the tool cache.
|
||||
function usePyPy(
|
||||
majorVersion: '2' | '3.6',
|
||||
architecture: string
|
||||
): InstalledVersion {
|
||||
const findPyPy = tc.find.bind(undefined, 'PyPy', majorVersion);
|
||||
let installDir: string | null = findPyPy(architecture);
|
||||
|
||||
if (!installDir && IS_WINDOWS) {
|
||||
// PyPy only precompiles binaries for x86, but the architecture parameter defaults to x64.
|
||||
// On our Windows virtual environments, we only install an x86 version.
|
||||
// Fall back to x86.
|
||||
installDir = findPyPy('x86');
|
||||
}
|
||||
|
||||
if (!installDir) {
|
||||
// PyPy not installed in $(Agent.ToolsDirectory)
|
||||
throw new Error(`PyPy ${majorVersion} not found`);
|
||||
}
|
||||
|
||||
// For PyPy, Windows uses 'bin', not 'Scripts'.
|
||||
const _binDir = path.join(installDir, 'bin');
|
||||
|
||||
// On Linux and macOS, the Python interpreter is in 'bin'.
|
||||
// On Windows, it is in the installation root.
|
||||
const pythonLocation = IS_WINDOWS ? installDir : _binDir;
|
||||
core.exportVariable('pythonLocation', pythonLocation);
|
||||
|
||||
core.addPath(installDir);
|
||||
core.addPath(_binDir);
|
||||
// Starting from PyPy 7.3.1, the folder that is used for pip and anything that pip installs should be "Scripts" on Windows.
|
||||
if (IS_WINDOWS) {
|
||||
core.addPath(path.join(installDir, 'Scripts'));
|
||||
}
|
||||
|
||||
const impl = 'pypy' + majorVersion.toString();
|
||||
core.setOutput('python-version', impl);
|
||||
|
||||
return {impl: impl, version: versionFromPath(installDir)};
|
||||
}
|
||||
|
||||
async function useCpythonVersion(
|
||||
export async function useCpythonVersion(
|
||||
version: string,
|
||||
architecture: string
|
||||
): Promise<InstalledVersion> {
|
||||
@ -186,18 +141,3 @@ export function pythonVersionToSemantic(versionSpec: string) {
|
||||
const prereleaseVersion = /(\d+\.\d+\.\d+)((?:a|b|rc)\d*)/g;
|
||||
return versionSpec.replace(prereleaseVersion, '$1-$2');
|
||||
}
|
||||
|
||||
export async function findPythonVersion(
|
||||
version: string,
|
||||
architecture: string
|
||||
): Promise<InstalledVersion> {
|
||||
switch (version.toUpperCase()) {
|
||||
case 'PYPY2':
|
||||
return usePyPy('2', architecture);
|
||||
case 'PYPY3':
|
||||
// keep pypy3 pointing to 3.6 for backward compatibility
|
||||
return usePyPy('3.6', architecture);
|
||||
default:
|
||||
return await useCpythonVersion(version, architecture);
|
||||
}
|
||||
}
|
||||
|
@ -4,16 +4,13 @@ import * as finderPyPy from './find-pypy';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import {getCacheDistributor} from './cache-distributions/cache-factory';
|
||||
import {isGhes} from './utils';
|
||||
import {isCacheFeatureAvailable} from './utils';
|
||||
|
||||
function isPyPyVersion(versionSpec: string) {
|
||||
return versionSpec.startsWith('pypy-');
|
||||
}
|
||||
|
||||
async function cacheDependencies(cache: string, pythonVersion: string) {
|
||||
if (isGhes()) {
|
||||
throw new Error('Caching is not supported on GHES');
|
||||
}
|
||||
const cacheDependencyPath =
|
||||
core.getInput('cache-dependency-path') || undefined;
|
||||
const cacheDistributor = getCacheDistributor(
|
||||
@ -37,13 +34,18 @@ async function run() {
|
||||
`Successfully setup PyPy ${installed.resolvedPyPyVersion} with Python (${installed.resolvedPythonVersion})`
|
||||
);
|
||||
} else {
|
||||
const installed = await finder.findPythonVersion(version, arch);
|
||||
if (version.trim().startsWith('2')) {
|
||||
core.warning(
|
||||
'The support for python 2.7 will be removed on June 19. Related issue: https://github.com/actions/setup-python/issues/672'
|
||||
);
|
||||
}
|
||||
const installed = await finder.useCpythonVersion(version, arch);
|
||||
pythonVersion = installed.version;
|
||||
core.info(`Successfully setup ${installed.impl} (${pythonVersion})`);
|
||||
}
|
||||
|
||||
const cache = core.getInput('cache');
|
||||
if (cache) {
|
||||
if (cache && isCacheFeatureAvailable()) {
|
||||
await cacheDependencies(cache, pythonVersion);
|
||||
}
|
||||
}
|
||||
|
20
src/utils.ts
20
src/utils.ts
@ -1,3 +1,5 @@
|
||||
import * as cache from '@actions/cache';
|
||||
import * as core from '@actions/core';
|
||||
import fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as semver from 'semver';
|
||||
@ -99,3 +101,21 @@ export function isGhes(): boolean {
|
||||
);
|
||||
return ghUrl.hostname.toUpperCase() !== 'GITHUB.COM';
|
||||
}
|
||||
|
||||
export function isCacheFeatureAvailable(): boolean {
|
||||
if (!cache.isFeatureAvailable()) {
|
||||
if (isGhes()) {
|
||||
throw new Error(
|
||||
'Caching is only supported on GHES version >= 3.5. If you are on a version >= 3.5, please check with your GHES admin if the Actions cache service is enabled or not.'
|
||||
);
|
||||
} else {
|
||||
core.warning(
|
||||
'The runner was not able to contact the cache service. Caching will be skipped'
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user