mirror of
https://github.com/enpaul/tox-poetry-installer.git
synced 2025-10-28 07:00:43 +00:00
Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 17885b50f7 | |||
|
72c719c26c
|
|||
|
5f30656683
|
|||
| b3a5e869ac | |||
| afc94a5e01 | |||
| a9d29aea9f | |||
| 45e33b7d27 | |||
| ff3e1603d2 | |||
| fb65fa812e | |||
| f08a18728e | |||
| 07027181ce | |||
| 7400d1e3cd | |||
| a7e5020d5f | |||
| 015915adf7 | |||
| a457cb99d2 | |||
| 1004a247b1 | |||
| f1f7a63774 | |||
| 087db95c43 | |||
| bb0db0fa1d | |||
| 6ac16a5c4d | |||
| 7f8d27709a | |||
| 17a2e5af64 | |||
| c05187f2e6 | |||
| 5ccc56956b | |||
| dae91a3a69 | |||
| 2f35d83363 | |||
| bba0c54b70 | |||
| 9d4e6d76fd | |||
| 68af3a1075 | |||
| 6384f289aa | |||
| 1f6550e77c | |||
| c322e68371 | |||
|
|
603cca6fd9 | ||
|
|
1478e35c0b | ||
| 3c0b76a30f | |||
| 99db4c9ec0 | |||
| 7fc322419a | |||
| 5b91918bea | |||
| 44b7238304 | |||
| f2ab91603a | |||
| 5188a30e77 | |||
| 26bbe13722 | |||
| 182fa24214 | |||
| 6b84764d5d | |||
| d5def209f2 | |||
| c4bf9bec24 | |||
| e4139d9875 | |||
| dbbbf8186f | |||
| 915233c529 |
65
.github/scripts/setup-env.sh
vendored
65
.github/scripts/setup-env.sh
vendored
@@ -7,66 +7,29 @@
|
|||||||
|
|
||||||
set -e;
|
set -e;
|
||||||
|
|
||||||
# ##### Prereqs #####
|
|
||||||
#
|
|
||||||
# Set global vars for usage in the script, create the cache directory so we can rely
|
|
||||||
# on that existing, then dump some diagnostic info for later reference.
|
|
||||||
#
|
|
||||||
CI_VENV=$HOME/ci;
|
|
||||||
CI_CACHE=$HOME/.cache;
|
CI_CACHE=$HOME/.cache;
|
||||||
CI_CACHE_GET_POETRY="$CI_CACHE/get-poetry.py";
|
POETRY_VERSION=1.1.12;
|
||||||
CI_POETRY=$HOME/.poetry/bin/poetry;
|
|
||||||
CI_VENV_PIP="$CI_VENV/bin/pip";
|
|
||||||
CI_VENV_PIP_VERSION=19.3.1;
|
|
||||||
CI_VENV_TOX="$CI_VENV/bin/tox";
|
|
||||||
|
|
||||||
mkdir --parents "$CI_CACHE";
|
mkdir --parents "$CI_CACHE";
|
||||||
|
|
||||||
command -v python;
|
command -v python;
|
||||||
python --version;
|
python --version;
|
||||||
|
|
||||||
# ##### Install Poetry #####
|
curl --location https://install.python-poetry.org \
|
||||||
#
|
--output "$CI_CACHE/install-poetry.py" \
|
||||||
# Download the poetry install script to the cache directory and then install poetry.
|
|
||||||
# After dump the poetry version for later reference.
|
|
||||||
#
|
|
||||||
curl https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py \
|
|
||||||
--output "$CI_CACHE_GET_POETRY" \
|
|
||||||
--silent \
|
--silent \
|
||||||
--show-error \
|
--show-error;
|
||||||
--location;
|
python "$CI_CACHE/install-poetry.py" \
|
||||||
python "$CI_CACHE_GET_POETRY" --yes 1>/dev/null;
|
--version "$POETRY_VERSION" \
|
||||||
|
--yes;
|
||||||
|
poetry --version --no-ansi;
|
||||||
|
poetry run pip --version;
|
||||||
|
|
||||||
python "$CI_POETRY" --version --no-ansi;
|
poetry install \
|
||||||
|
|
||||||
# ##### Setup Runtime Venv #####
|
|
||||||
#
|
|
||||||
# Create a virtual environment for poetry to use, upgrade pip in that venv to a pinned
|
|
||||||
# version, then install the current project to the venv.
|
|
||||||
#
|
|
||||||
# Note 1: Poetry, Tox, and this project plugin all use pip under the hood for package
|
|
||||||
# installation. This means that even though we are creating up to eight venvs
|
|
||||||
# during a given CI run they all share the same download cache.
|
|
||||||
# Note 2: The "VIRTUAL_ENV=$CI_VENV" prefix on the poetry commands below sets the venv
|
|
||||||
# that poetry will use for operations. There is no CLI flag for poetry that
|
|
||||||
# directs it to use a given environment, but if it finds itself in an existing
|
|
||||||
# environment it will use it and skip environment creation.
|
|
||||||
#
|
|
||||||
python -m venv "$CI_VENV";
|
|
||||||
|
|
||||||
$CI_VENV_PIP install "pip==$CI_VENV_PIP_VERSION" \
|
|
||||||
--upgrade \
|
|
||||||
--quiet;
|
|
||||||
|
|
||||||
VIRTUAL_ENV=$CI_VENV "$CI_POETRY" install \
|
|
||||||
--extras poetry \
|
--extras poetry \
|
||||||
--quiet \
|
--quiet \
|
||||||
--no-ansi \
|
--remove-untracked \
|
||||||
&>/dev/null;
|
--no-ansi;
|
||||||
|
|
||||||
# ##### Print Debug Info #####
|
poetry env info;
|
||||||
#
|
poetry run tox --version;
|
||||||
# Print the pip and tox versions (which will include registered plugins)
|
|
||||||
#
|
|
||||||
$CI_VENV_PIP --version;
|
|
||||||
echo "tox $($CI_VENV_TOX --version)";
|
|
||||||
|
|||||||
42
.github/workflows/ci.yaml
vendored
42
.github/workflows/ci.yaml
vendored
@@ -11,22 +11,24 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python:
|
python:
|
||||||
- version: 3.6
|
- version: "3.6"
|
||||||
toxenv: py36
|
toxenv: py36
|
||||||
- version: 3.7
|
- version: "3.7"
|
||||||
toxenv: py37
|
toxenv: py37
|
||||||
- version: 3.8
|
- version: "3.8"
|
||||||
toxenv: py38
|
toxenv: py38
|
||||||
- version: 3.9
|
- version: "3.9"
|
||||||
toxenv: py39
|
toxenv: py39
|
||||||
|
- version: "3.10"
|
||||||
|
toxenv: py310
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
- name: Setup:python${{ matrix.python.version }}
|
- name: Install Python ${{ matrix.python.version }}
|
||||||
uses: actions/setup-python@v1
|
uses: actions/setup-python@v1
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python.version }}
|
python-version: ${{ matrix.python.version }}
|
||||||
- name: Setup:cache
|
- name: Configure Job Cache
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
@@ -37,20 +39,22 @@ jobs:
|
|||||||
# will be invalidated, and thus all packages will be redownloaded, if the
|
# will be invalidated, and thus all packages will be redownloaded, if the
|
||||||
# lockfile is updated
|
# lockfile is updated
|
||||||
key: ${{ runner.os }}-${{ matrix.python.toxenv }}-${{ hashFiles('**/poetry.lock') }}
|
key: ${{ runner.os }}-${{ matrix.python.toxenv }}-${{ hashFiles('**/poetry.lock') }}
|
||||||
- name: Setup:env
|
- name: Configure Path
|
||||||
|
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||||
|
- name: Configure Environment
|
||||||
run: .github/scripts/setup-env.sh
|
run: .github/scripts/setup-env.sh
|
||||||
- name: Run:${{ matrix.python.toxenv }}
|
- name: Run Toxenv ${{ matrix.python.toxenv }}
|
||||||
run: $HOME/ci/bin/tox -e ${{ matrix.python.toxenv }} --parallelize-locked-install=10
|
run: poetry run tox -e ${{ matrix.python.toxenv }}
|
||||||
Check:
|
Check:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
- name: Setup:python3.8
|
- name: Install Python 3.8
|
||||||
uses: actions/setup-python@v1
|
uses: actions/setup-python@v1
|
||||||
with:
|
with:
|
||||||
python-version: 3.8
|
python-version: 3.8
|
||||||
- name: Setup:cache
|
- name: Configure Job Cache
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
@@ -60,11 +64,13 @@ jobs:
|
|||||||
# Hardcoded 'py38' slug here lets this cache piggyback on the 'py38' cache
|
# Hardcoded 'py38' slug here lets this cache piggyback on the 'py38' cache
|
||||||
# that is generated for the tests above
|
# that is generated for the tests above
|
||||||
key: ${{ runner.os }}-py38-${{ hashFiles('**/poetry.lock') }}
|
key: ${{ runner.os }}-py38-${{ hashFiles('**/poetry.lock') }}
|
||||||
- name: Setup:env
|
- name: Configure Path
|
||||||
|
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||||
|
- name: Configure Environment
|
||||||
run: .github/scripts/setup-env.sh
|
run: .github/scripts/setup-env.sh
|
||||||
- name: Run:static
|
- name: Run Static Analysis Checks
|
||||||
run: $HOME/ci/bin/tox -e static --parallelize-locked-install=10
|
run: poetry run tox -e static
|
||||||
- name: Run:static-tests
|
- name: Run Static Analysis Checks (Tests)
|
||||||
run: $HOME/ci/bin/tox -e static-tests --parallelize-locked-install=10
|
run: poetry run tox -e static-tests
|
||||||
- name: Run:security
|
- name: Run Security Checks
|
||||||
run: $HOME/ci/bin/tox -e security --parallelize-locked-install=10
|
run: poetry run tox -e security
|
||||||
|
|||||||
400
.pylintrc
400
.pylintrc
@@ -1,46 +1,5 @@
|
|||||||
[MASTER]
|
|
||||||
|
|
||||||
# A comma-separated list of package or module names from where C extensions may
|
|
||||||
# be loaded. Extensions are loading into the active Python interpreter and may
|
|
||||||
# run arbitrary code
|
|
||||||
extension-pkg-whitelist=
|
|
||||||
|
|
||||||
# Add files or directories to the blacklist. They should be base names, not
|
|
||||||
# paths.
|
|
||||||
ignore=
|
|
||||||
|
|
||||||
# Add files or directories matching the regex patterns to the blacklist. The
|
|
||||||
# regex matches against base names, not paths.
|
|
||||||
ignore-patterns=
|
|
||||||
|
|
||||||
# Python code to execute, usually for sys.path manipulation such as
|
|
||||||
# pygtk.require().
|
|
||||||
#init-hook=
|
|
||||||
|
|
||||||
# Use multiple processes to speed up Pylint.
|
|
||||||
jobs=1
|
|
||||||
|
|
||||||
# List of plugins (as comma separated values of python modules names) to load,
|
|
||||||
# usually to register additional checkers.
|
|
||||||
load-plugins=
|
|
||||||
|
|
||||||
# Pickle collected data for later comparisons.
|
|
||||||
persistent=yes
|
|
||||||
|
|
||||||
# Specify a configuration file.
|
|
||||||
#rcfile=
|
|
||||||
|
|
||||||
# Allow loading of arbitrary C extensions. Extensions are imported into the
|
|
||||||
# active Python interpreter and may run arbitrary code.
|
|
||||||
unsafe-load-any-extension=no
|
|
||||||
|
|
||||||
|
|
||||||
[MESSAGES CONTROL]
|
[MESSAGES CONTROL]
|
||||||
|
|
||||||
# Only show warnings with the listed confidence levels. Leave empty to show
|
|
||||||
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
|
|
||||||
confidence=
|
|
||||||
|
|
||||||
# Disable the message, report, category or checker with the given id(s). You
|
# Disable the message, report, category or checker with the given id(s). You
|
||||||
# can either give multiple identifiers separated by comma (,) or put this
|
# can either give multiple identifiers separated by comma (,) or put this
|
||||||
# option multiple times (only on the command line, not in the configuration
|
# option multiple times (only on the command line, not in the configuration
|
||||||
@@ -50,378 +9,47 @@ confidence=
|
|||||||
# --enable=similarities". If you want to run only the classes checker, but have
|
# --enable=similarities". If you want to run only the classes checker, but have
|
||||||
# no Warning level messages displayed, use"--disable=all --enable=classes
|
# no Warning level messages displayed, use"--disable=all --enable=classes
|
||||||
# --disable=W"
|
# --disable=W"
|
||||||
disable=logging-fstring-interpolation, logging-format-interpolation, bad-continuation, line-too-long
|
disable=logging-fstring-interpolation
|
||||||
#print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,
|
,logging-format-interpolation
|
||||||
|
,bad-continuation
|
||||||
# Enable the message, report, category or checker with the given id(s). You can
|
,line-too-long
|
||||||
# either give multiple identifier separated by comma (,) or put this option
|
,ungrouped-imports
|
||||||
# multiple time (only on the command line, not in the configuration file where
|
,typecheck
|
||||||
# it should appear only once). See also the "--disable" option for examples.
|
,wrong-import-order
|
||||||
enable=
|
,wrong-import-position
|
||||||
|
|
||||||
|
|
||||||
[REPORTS]
|
[REPORTS]
|
||||||
|
|
||||||
# Python expression which should return a note less than 10 (10 is the highest
|
|
||||||
# note). You have access to the variables errors warning, statement which
|
|
||||||
# respectively contain the number of errors / warnings messages and the total
|
|
||||||
# number of statements analyzed. This is used by the global evaluation report
|
|
||||||
# (RP0004).
|
|
||||||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
|
|
||||||
|
|
||||||
# Template used to display messages. This is a python new-style format string
|
|
||||||
# used to format the message information. See doc for all details
|
|
||||||
#msg-template=
|
|
||||||
|
|
||||||
# Set the output format. Available formats are text, parseable, colorized, json
|
# Set the output format. Available formats are text, parseable, colorized, json
|
||||||
# and msvs (visual studio).You can also give a reporter class, eg
|
# and msvs (visual studio).You can also give a reporter class, eg
|
||||||
# mypackage.mymodule.MyReporterClass.
|
# mypackage.mymodule.MyReporterClass.
|
||||||
output-format=text
|
output-format=colorized
|
||||||
|
|
||||||
# Tells whether to display a full report or only the messages
|
|
||||||
reports=no
|
|
||||||
|
|
||||||
# Activate the evaluation score.
|
|
||||||
score=yes
|
|
||||||
|
|
||||||
|
|
||||||
[REFACTORING]
|
|
||||||
|
|
||||||
# Maximum number of nested blocks for function / method body
|
|
||||||
max-nested-blocks=5
|
|
||||||
|
|
||||||
|
|
||||||
[BASIC]
|
[BASIC]
|
||||||
|
|
||||||
# Naming hint for argument names
|
|
||||||
argument-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
|
||||||
|
|
||||||
# Regular expression matching correct argument names
|
|
||||||
argument-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
|
||||||
|
|
||||||
# Naming hint for attribute names
|
|
||||||
attr-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
|
||||||
|
|
||||||
# Regular expression matching correct attribute names
|
|
||||||
attr-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
|
||||||
|
|
||||||
# Bad variable names which should always be refused, separated by a comma
|
|
||||||
bad-names=foo,bar,baz,toto,tutu,tata
|
|
||||||
|
|
||||||
# Naming hint for class attribute names
|
|
||||||
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
|
|
||||||
|
|
||||||
# Regular expression matching correct class attribute names
|
|
||||||
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
|
|
||||||
|
|
||||||
# Naming hint for class names
|
|
||||||
class-name-hint=[A-Z_][a-zA-Z0-9]+$
|
|
||||||
|
|
||||||
# Regular expression matching correct class names
|
|
||||||
class-rgx=[A-Z_][a-zA-Z0-9]+$
|
|
||||||
|
|
||||||
# Naming hint for constant names
|
|
||||||
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
|
|
||||||
|
|
||||||
# Regular expression matching correct constant names
|
|
||||||
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
|
|
||||||
|
|
||||||
# Minimum line length for functions/classes that require docstrings, shorter
|
|
||||||
# ones are exempt.
|
|
||||||
docstring-min-length=-1
|
|
||||||
|
|
||||||
# Naming hint for function names
|
|
||||||
function-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
|
||||||
|
|
||||||
# Regular expression matching correct function names
|
|
||||||
function-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
|
||||||
|
|
||||||
# Good variable names which should always be accepted, separated by a comma
|
# Good variable names which should always be accepted, separated by a comma
|
||||||
good-names=_,ip,ap
|
good-names=_,ip,T
|
||||||
|
|
||||||
# Include a hint for the correct naming format with invalid-name
|
|
||||||
include-naming-hint=no
|
|
||||||
|
|
||||||
# Naming hint for inline iteration names
|
|
||||||
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
|
|
||||||
|
|
||||||
# Regular expression matching correct inline iteration names
|
|
||||||
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
|
|
||||||
|
|
||||||
# Naming hint for method names
|
|
||||||
method-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
|
||||||
|
|
||||||
# Regular expression matching correct method names
|
|
||||||
method-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
|
||||||
|
|
||||||
# Naming hint for module names
|
|
||||||
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
|
|
||||||
|
|
||||||
# Regular expression matching correct module names
|
|
||||||
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
|
|
||||||
|
|
||||||
# Colon-delimited sets of names that determine each other's naming style when
|
|
||||||
# the name regexes allow several styles.
|
|
||||||
name-group=
|
|
||||||
|
|
||||||
# Regular expression which should only match function or class names that do
|
|
||||||
# not require a docstring.
|
|
||||||
no-docstring-rgx=^_
|
|
||||||
|
|
||||||
# List of decorators that produce properties, such as abc.abstractproperty. Add
|
|
||||||
# to this list to register other decorators that produce valid properties.
|
|
||||||
property-classes=abc.abstractproperty
|
|
||||||
|
|
||||||
# Naming hint for variable names
|
|
||||||
variable-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
|
||||||
|
|
||||||
# Regular expression matching correct variable names
|
|
||||||
variable-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
|
|
||||||
|
|
||||||
|
|
||||||
[MISCELLANEOUS]
|
[MISCELLANEOUS]
|
||||||
|
# Not FIXME or TODO
|
||||||
# List of note tags to take in consideration, separated by a comma.
|
|
||||||
#notes=FIXME,XXX,TODO
|
|
||||||
notes=XXX
|
notes=XXX
|
||||||
|
|
||||||
|
|
||||||
[LOGGING]
|
|
||||||
|
|
||||||
# Logging modules to check that the string format arguments are in logging
|
|
||||||
# function parameter format
|
|
||||||
logging-modules=logging
|
|
||||||
|
|
||||||
|
|
||||||
[SIMILARITIES]
|
[SIMILARITIES]
|
||||||
|
|
||||||
# Ignore comments when computing similarities.
|
|
||||||
ignore-comments=yes
|
|
||||||
|
|
||||||
# Ignore docstrings when computing similarities.
|
|
||||||
ignore-docstrings=yes
|
|
||||||
|
|
||||||
# Ignore imports when computing similarities.
|
# Ignore imports when computing similarities.
|
||||||
ignore-imports=yes
|
ignore-imports=yes
|
||||||
|
|
||||||
|
# Ignore function signatures when computing similarities.
|
||||||
|
ignore-signatures=yes
|
||||||
|
|
||||||
# Minimum lines number of a similarity.
|
# Minimum lines number of a similarity.
|
||||||
min-similarity-lines=10
|
min-similarity-lines=10
|
||||||
|
|
||||||
|
|
||||||
[VARIABLES]
|
|
||||||
|
|
||||||
# List of additional names supposed to be defined in builtins. Remember that
|
|
||||||
# you should avoid to define new builtins when possible.
|
|
||||||
additional-builtins=
|
|
||||||
|
|
||||||
# Tells whether unused global variables should be treated as a violation.
|
|
||||||
allow-global-unused-variables=yes
|
|
||||||
|
|
||||||
# List of strings which can identify a callback function by name. A callback
|
|
||||||
# name must start or end with one of those strings.
|
|
||||||
callbacks=cb_,_cb
|
|
||||||
|
|
||||||
# A regular expression matching the name of dummy variables (i.e. expectedly
|
|
||||||
# not used).
|
|
||||||
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
|
|
||||||
|
|
||||||
# Argument names that match this expression will be ignored. Default to name
|
|
||||||
# with leading underscore
|
|
||||||
ignored-argument-names=_.*|^ignored_|^unused_|^fxt_
|
|
||||||
|
|
||||||
# Tells whether we should check for unused import in __init__ files.
|
|
||||||
init-import=no
|
|
||||||
|
|
||||||
# List of qualified module names which can have objects that can redefine
|
|
||||||
# builtins.
|
|
||||||
redefining-builtins-modules=six.moves,future.builtins
|
|
||||||
|
|
||||||
|
|
||||||
[SPELLING]
|
|
||||||
|
|
||||||
# Spelling dictionary name. Available dictionaries: none. To make it working
|
|
||||||
# install python-enchant package.
|
|
||||||
spelling-dict=
|
|
||||||
|
|
||||||
# List of comma separated words that should not be checked.
|
|
||||||
spelling-ignore-words=
|
|
||||||
|
|
||||||
# A path to a file that contains private dictionary; one word per line.
|
|
||||||
spelling-private-dict-file=
|
|
||||||
|
|
||||||
# Tells whether to store unknown words to indicated private dictionary in
|
|
||||||
# --spelling-private-dict-file option instead of raising a message.
|
|
||||||
spelling-store-unknown-words=no
|
|
||||||
|
|
||||||
|
|
||||||
[FORMAT]
|
|
||||||
|
|
||||||
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
|
||||||
expected-line-ending-format=
|
|
||||||
|
|
||||||
# Regexp for a line that is allowed to be longer than the limit.
|
|
||||||
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
|
|
||||||
|
|
||||||
# Number of spaces of indent required inside a hanging or continued line.
|
|
||||||
indent-after-paren=4
|
|
||||||
|
|
||||||
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
|
|
||||||
# tab).
|
|
||||||
indent-string=' '
|
|
||||||
|
|
||||||
# Maximum number of characters on a single line.
|
|
||||||
max-line-length=100
|
|
||||||
|
|
||||||
# Maximum number of lines in a module
|
|
||||||
max-module-lines=1000
|
|
||||||
|
|
||||||
# List of optional constructs for which whitespace checking is disabled. `dict-
|
|
||||||
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
|
|
||||||
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
|
|
||||||
# `empty-line` allows space-only lines.
|
|
||||||
no-space-check=trailing-comma,dict-separator
|
|
||||||
|
|
||||||
# Allow the body of a class to be on the same line as the declaration if body
|
|
||||||
# contains single statement.
|
|
||||||
single-line-class-stmt=no
|
|
||||||
|
|
||||||
# Allow the body of an if to be on the same line as the test if there is no
|
|
||||||
# else.
|
|
||||||
single-line-if-stmt=no
|
|
||||||
|
|
||||||
|
|
||||||
[TYPECHECK]
|
|
||||||
|
|
||||||
# List of decorators that produce context managers, such as
|
|
||||||
# contextlib.contextmanager. Add to this list to register other decorators that
|
|
||||||
# produce valid context managers.
|
|
||||||
contextmanager-decorators=contextlib.contextmanager
|
|
||||||
|
|
||||||
# List of members which are set dynamically and missed by pylint inference
|
|
||||||
# system, and so shouldn't trigger E1101 when accessed. Python regular
|
|
||||||
# expressions are accepted.
|
|
||||||
generated-members=
|
|
||||||
|
|
||||||
# Tells whether missing members accessed in mixin class should be ignored. A
|
|
||||||
# mixin class is detected if its name ends with "mixin" (case insensitive).
|
|
||||||
ignore-mixin-members=yes
|
|
||||||
|
|
||||||
# This flag controls whether pylint should warn about no-member and similar
|
|
||||||
# checks whenever an opaque object is returned when inferring. The inference
|
|
||||||
# can return multiple potential results while evaluating a Python object, but
|
|
||||||
# some branches might not be evaluated, which results in partial inference. In
|
|
||||||
# that case, it might be useful to still emit no-member and other checks for
|
|
||||||
# the rest of the inferred objects.
|
|
||||||
ignore-on-opaque-inference=yes
|
|
||||||
|
|
||||||
# List of class names for which member attributes should not be checked (useful
|
|
||||||
# for classes with dynamically set attributes). This supports the use of
|
|
||||||
# qualified names.
|
|
||||||
ignored-classes=optparse.Values,thread._local,_thread._local
|
|
||||||
|
|
||||||
# List of module names for which member attributes should not be checked
|
|
||||||
# (useful for modules/projects where namespaces are manipulated during runtime
|
|
||||||
# and thus existing member attributes cannot be deduced by static analysis. It
|
|
||||||
# supports qualified module names, as well as Unix pattern matching.
|
|
||||||
ignored-modules=
|
|
||||||
|
|
||||||
# Show a hint with possible names when a member name was not found. The aspect
|
|
||||||
# of finding the hint is based on edit distance.
|
|
||||||
missing-member-hint=yes
|
|
||||||
|
|
||||||
# The minimum edit distance a name should have in order to be considered a
|
|
||||||
# similar match for a missing member name.
|
|
||||||
missing-member-hint-distance=1
|
|
||||||
|
|
||||||
# The total number of similar names that should be taken in consideration when
|
|
||||||
# showing a hint for a missing member.
|
|
||||||
missing-member-max-choices=1
|
|
||||||
|
|
||||||
|
|
||||||
[CLASSES]
|
|
||||||
|
|
||||||
# List of method names used to declare (i.e. assign) instance attributes.
|
|
||||||
defining-attr-methods=__init__,__new__,setUp
|
|
||||||
|
|
||||||
# List of member names, which should be excluded from the protected access
|
|
||||||
# warning.
|
|
||||||
exclude-protected=_asdict,_fields,_replace,_source,_make
|
|
||||||
|
|
||||||
# List of valid names for the first argument in a class method.
|
|
||||||
valid-classmethod-first-arg=cls
|
|
||||||
|
|
||||||
# List of valid names for the first argument in a metaclass class method.
|
|
||||||
valid-metaclass-classmethod-first-arg=mcs
|
|
||||||
|
|
||||||
|
|
||||||
[IMPORTS]
|
|
||||||
|
|
||||||
# Allow wildcard imports from modules that define __all__.
|
|
||||||
allow-wildcard-with-all=no
|
|
||||||
|
|
||||||
# Analyse import fallback blocks. This can be used to support both Python 2 and
|
|
||||||
# 3 compatible code, which means that the block might have code that exists
|
|
||||||
# only in one or another interpreter, leading to false positives when analysed.
|
|
||||||
analyse-fallback-blocks=no
|
|
||||||
|
|
||||||
# Deprecated modules which should not be used, separated by a comma
|
|
||||||
deprecated-modules=regsub,TERMIOS,Bastion,rexec
|
|
||||||
|
|
||||||
# Create a graph of external dependencies in the given file (report RP0402 must
|
|
||||||
# not be disabled)
|
|
||||||
ext-import-graph=
|
|
||||||
|
|
||||||
# Create a graph of every (i.e. internal and external) dependencies in the
|
|
||||||
# given file (report RP0402 must not be disabled)
|
|
||||||
import-graph=
|
|
||||||
|
|
||||||
# Create a graph of internal dependencies in the given file (report RP0402 must
|
|
||||||
# not be disabled)
|
|
||||||
int-import-graph=
|
|
||||||
|
|
||||||
# Force import order to recognize a module as part of the standard
|
|
||||||
# compatibility libraries.
|
|
||||||
known-standard-library=
|
|
||||||
|
|
||||||
# Force import order to recognize a module as part of a third party library.
|
|
||||||
known-third-party=enchant
|
|
||||||
|
|
||||||
|
|
||||||
[DESIGN]
|
[DESIGN]
|
||||||
|
|
||||||
# Maximum number of arguments for function / method
|
# Maximum number of arguments for function / method
|
||||||
max-args=7
|
max-args=7
|
||||||
|
|
||||||
# Maximum number of attributes for a class (see R0902).
|
|
||||||
max-attributes=7
|
|
||||||
|
|
||||||
# Maximum number of boolean expressions in a if statement
|
|
||||||
max-bool-expr=5
|
|
||||||
|
|
||||||
# Maximum number of branch for function / method body
|
|
||||||
max-branches=12
|
|
||||||
|
|
||||||
# Maximum number of locals for function / method body
|
|
||||||
max-locals=15
|
|
||||||
|
|
||||||
# Maximum number of parents for a class (see R0901).
|
|
||||||
max-parents=7
|
|
||||||
|
|
||||||
# Maximum number of public methods for a class (see R0904).
|
|
||||||
max-public-methods=20
|
|
||||||
|
|
||||||
# Maximum number of return / yield for function / method body
|
|
||||||
max-returns=6
|
|
||||||
|
|
||||||
# Maximum number of statements in function / method body
|
|
||||||
max-statements=50
|
|
||||||
|
|
||||||
# Minimum number of public methods for a class (see R0903).
|
|
||||||
min-public-methods=2
|
|
||||||
|
|
||||||
|
|
||||||
[EXCEPTIONS]
|
|
||||||
|
|
||||||
# Exceptions that will emit a warning when being caught. Defaults to
|
|
||||||
# "Exception"
|
|
||||||
overgeneral-exceptions=Exception
|
|
||||||
|
|||||||
59
CHANGELOG.md
59
CHANGELOG.md
@@ -2,6 +2,65 @@
|
|||||||
|
|
||||||
See also: [Github Release Page](https://github.com/enpaul/tox-poetry-installer/releases).
|
See also: [Github Release Page](https://github.com/enpaul/tox-poetry-installer/releases).
|
||||||
|
|
||||||
|
## Version 0.8.5
|
||||||
|
|
||||||
|
View this release on:
|
||||||
|
[Github](https://github.com/enpaul/tox-poetry-installer/releases/tag/0.8.5),
|
||||||
|
[PyPI](https://pypi.org/project/tox-poetry-installer/0.8.5/)
|
||||||
|
|
||||||
|
- Fix Poetry version specification supporting the incompatible Poetry-1.2.0 release
|
||||||
|
|
||||||
|
## Version 0.8.4
|
||||||
|
|
||||||
|
View this release on:
|
||||||
|
[Github](https://github.com/enpaul/tox-poetry-installer/releases/tag/0.8.4),
|
||||||
|
[PyPI](https://pypi.org/project/tox-poetry-installer/0.8.4/)
|
||||||
|
|
||||||
|
- Fix issue where incompatible package versions were selected for installation when multiple
|
||||||
|
package versions were in the lockfile
|
||||||
|
|
||||||
|
## Version 0.8.3
|
||||||
|
|
||||||
|
View this release on:
|
||||||
|
[Github](https://github.com/enpaul/tox-poetry-installer/releases/tag/0.8.3),
|
||||||
|
[PyPI](https://pypi.org/project/tox-poetry-installer/0.8.3/)
|
||||||
|
|
||||||
|
- Add PyPI classifier for Python 3.10 compatibility
|
||||||
|
|
||||||
|
## Version 0.8.2
|
||||||
|
|
||||||
|
View this release on:
|
||||||
|
[Github](https://github.com/enpaul/tox-poetry-installer/releases/tag/0.8.2),
|
||||||
|
[PyPI](https://pypi.org/project/tox-poetry-installer/0.8.2/)
|
||||||
|
|
||||||
|
- Improve debug-level logging for package installation, and time how long installing each
|
||||||
|
package takes. Contributed by [Rebecca
|
||||||
|
Turner](https://github.com/9999years).
|
||||||
|
- Fix crash caused by the package-under-test depending on Poetry's unsafe dependencies ([#65](https://github.com/enpaul/tox-poetry-installer/issues/65))
|
||||||
|
|
||||||
|
## Version 0.8.1
|
||||||
|
|
||||||
|
View this release on:
|
||||||
|
[Github](https://github.com/enpaul/tox-poetry-installer/releases/tag/0.8.1),
|
||||||
|
[PyPI](https://pypi.org/project/tox-poetry-installer/0.8.1/)
|
||||||
|
|
||||||
|
- Fix unintuitive behavior of the `install_project_deps` option by ensuring the specified
|
||||||
|
value always causes the implied action
|
||||||
|
|
||||||
|
## Version 0.8.0
|
||||||
|
|
||||||
|
View this release on:
|
||||||
|
[Github](https://github.com/enpaul/tox-poetry-installer/releases/tag/0.8.0),
|
||||||
|
[PyPI](https://pypi.org/project/tox-poetry-installer/0.8.0/)
|
||||||
|
|
||||||
|
- Add default installation of locked dependencies using thread workers, decreasing
|
||||||
|
environment provisioning times by ~90%
|
||||||
|
- Add runtime option `--parallel-install-threads` to support configuring the number of
|
||||||
|
worker threads for parallel dependency installation
|
||||||
|
- Add configuration option `install_project_deps` to support disabling the install of
|
||||||
|
project dependencies to an environment
|
||||||
|
- Deprecate runtime option `--parallelize-locked-install`
|
||||||
|
|
||||||
## Version 0.7.0
|
## Version 0.7.0
|
||||||
|
|
||||||
View this release on:
|
View this release on:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
## Copyright 2020 Ethan Paul
|
## Copyright 2020, 2022 Ethan Paul
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
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
|
software and associated documentation files (the "Software"), to deal in the Software
|
||||||
@@ -9,4 +9,9 @@ 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
|
The above copyright notice and this permission notice shall be included in all copies or
|
||||||
substantial portions of the Software.
|
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.**
|
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.
|
||||||
|
|||||||
41
README.md
41
README.md
@@ -80,7 +80,7 @@ adding the below to `tox.ini`, though this is also not recommended:
|
|||||||
|
|
||||||
```ini
|
```ini
|
||||||
requires =
|
requires =
|
||||||
tox-poetry-installer[poetry] == 0.7.0
|
tox-poetry-installer[poetry] == 0.8.0
|
||||||
```
|
```
|
||||||
|
|
||||||
After installing, check that Tox recognizes the plugin by running
|
After installing, check that Tox recognizes the plugin by running
|
||||||
@@ -89,7 +89,7 @@ After installing, check that Tox recognizes the plugin by running
|
|||||||
```
|
```
|
||||||
3.20.0 imported from .venv/lib64/python3.8/site-packages/tox/__init__.py
|
3.20.0 imported from .venv/lib64/python3.8/site-packages/tox/__init__.py
|
||||||
registered plugins:
|
registered plugins:
|
||||||
tox-poetry-installer-0.7.0 at .venv/lib64/python3.8/site-packages/tox_poetry_installer.py
|
tox-poetry-installer-0.8.0 at .venv/lib64/python3.8/site-packages/tox_poetry_installer/__init__.py
|
||||||
```
|
```
|
||||||
|
|
||||||
### Quick Start
|
### Quick Start
|
||||||
@@ -194,26 +194,30 @@ configuration section.
|
|||||||
> test environments (for example, `testenv:foo`). To override this, specify the setting in
|
> test environments (for example, `testenv:foo`). To override this, specify the setting in
|
||||||
> the child environment with a different value.
|
> the child environment with a different value.
|
||||||
|
|
||||||
| Option | Type | Default | Description |
|
| Option | Type | Default | Description |
|
||||||
| :-------------------- | :-----: | :-----: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| :--------------------- | :-----: | :-----: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `locked_deps` | List | `[]` | Names of packages to install to the test environment from the Poetry lockfile. Transient dependencies (packages required by these dependencies) are automatically included. |
|
| `locked_deps` | List | `[]` | Names of packages to install to the test environment from the Poetry lockfile. Transient dependencies (packages required by these dependencies) are automatically included. |
|
||||||
| `require_locked_deps` | Boolean | False | Whether the plugin should block attempts to install unlocked dependencies to the test environment. If enabled, then the [`tox_testenv_install_deps`](https://tox.readthedocs.io/en/latest/plugins.html#tox.hookspecs.tox_testenv_install_deps) plugin hook will be intercepted and an error will be raised if the test environment has the `deps` option configured. |
|
| `require_locked_deps` | Boolean | False | Whether the plugin should block attempts to install unlocked dependencies to the test environment. If enabled, then the [`tox_testenv_install_deps`](https://tox.readthedocs.io/en/latest/plugins.html#tox.hookspecs.tox_testenv_install_deps) plugin hook will be intercepted and an error will be raised if the test environment has the `deps` option configured. |
|
||||||
| `install_dev_deps` | Boolean | False | Whether all of the Poetry dev-dependencies should be installed to the test environment. |
|
| `install_dev_deps` | Boolean | False | Whether all of the Poetry dev-dependencies should be installed to the test environment. |
|
||||||
| `require_poetry` | Boolean | False | Whether Tox should be forced to fail if the plugin cannot import Poetry locally. If `False` then the plugin will be skipped for the test environment if Poetry cannot be imported. If `True` then the plugin will force the environment to error and the Tox run to fail. |
|
| `install_project_deps` | Boolean | True | Whether all of the Poetry primary dependencies for the project package should be installed to the test environment. |
|
||||||
|
| `require_poetry` | Boolean | False | Whether Tox should be forced to fail if the plugin cannot import Poetry locally. If `False` then the plugin will be skipped for the test environment if Poetry cannot be imported. If `True` then the plugin will force the environment to error and the Tox run to fail. |
|
||||||
|
|
||||||
### Runtime Options
|
### Runtime Options
|
||||||
|
|
||||||
All arguments listed below can be passed to the `tox` command to modify runtime behavior
|
All arguments listed below can be passed to the `tox` command to modify runtime behavior
|
||||||
of the plugin.
|
of the plugin.
|
||||||
|
|
||||||
| Argument | Type | Default | Description |
|
| Argument | Type | Default | Description |
|
||||||
| :----------------------------- | :-----: | :-----: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| :--------------------------- | :-----: | :-----: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `--parallelize-locked-install` | Integer | `0` | Number of worker threads to use to install dependencies in parallel. Installing in parallel with more threads can greatly speed up the install process, but can cause race conditions during install. The default, `0`, disables the parallel install so that dependencies are installed sequentially. |
|
| `--parallel-install-threads` | Integer | `10` | Number of worker threads to use to install dependencies in parallel. Installing in parallel with more threads can greatly speed up the install process, but can cause race conditions during install. Pass this option with the value `0` to entirely disable parallel installation. |
|
||||||
|
|
||||||
> **Note:** The `--require-poetry` runtime option is deprecated and will be removed in
|
> **Note:** The `--require-poetry` runtime option is deprecated and will be removed in
|
||||||
> version 1.0.0. Please set `require_poetry = true` in `tox.ini` for environments that
|
> version 1.0.0. Please set `require_poetry = true` in `tox.ini` for environments that
|
||||||
> should fail if Poetry is not available.
|
> should fail if Poetry is not available.
|
||||||
|
|
||||||
|
> **Note:** The `--parallelize-locked-install` option is deprecated and will be removed in
|
||||||
|
> version 1.0.0. Please use the `--parallel-install-threads` option.
|
||||||
|
|
||||||
### Errors
|
### Errors
|
||||||
|
|
||||||
There are several errors that the plugin can encounter for a test environment when Tox is
|
There are several errors that the plugin can encounter for a test environment when Tox is
|
||||||
@@ -226,7 +230,8 @@ error will be set to one of the "Status" values below to indicate what the error
|
|||||||
| `LockedDepVersionConflictError` | Indicates that an item in the `locked_deps` config option includes a [PEP-508 version specifier](https://www.python.org/dev/peps/pep-0508/#grammar) (ex: `pytest >=6.0, <6.1`). |
|
| `LockedDepVersionConflictError` | Indicates that an item in the `locked_deps` config option includes a [PEP-508 version specifier](https://www.python.org/dev/peps/pep-0508/#grammar) (ex: `pytest >=6.0, <6.1`). |
|
||||||
| `LockedDepNotFoundError` | Indicates that an item specified in the `locked_deps` config option does not match the name of a package in the Poetry lockfile. |
|
| `LockedDepNotFoundError` | Indicates that an item specified in the `locked_deps` config option does not match the name of a package in the Poetry lockfile. |
|
||||||
| `LockedDepsRequiredError` | Indicates that a test environment with the `require_locked_deps` config option set to `true` also specified unlocked dependencies using the [`deps`](https://tox.readthedocs.io/en/latest/config.html#conf-deps) config option. |
|
| `LockedDepsRequiredError` | Indicates that a test environment with the `require_locked_deps` config option set to `true` also specified unlocked dependencies using the [`deps`](https://tox.readthedocs.io/en/latest/config.html#conf-deps) config option. |
|
||||||
| `PoetryNotInstalledError` | Indicates that the `poetry` module could not be imported under the current runtime environment, and the `--require-poetry` flag was provided. |
|
| `PoetryNotInstalledError` | Indicates that the `poetry` module could not be imported under the current runtime environment, and `require_poetry = true` was specified. |
|
||||||
|
| `RequiresUnsafeDepError` | Indicates that the package-under-test depends on a package that Poetry has classified as unsafe and cannot be installed. |
|
||||||
|
|
||||||
> **Note:** One or more of these errors can be caused by the `pyproject.toml` being out of
|
> **Note:** One or more of these errors can be caused by the `pyproject.toml` being out of
|
||||||
> sync with the Poetry lockfile. If this is the case, than a warning will be logged when Tox
|
> sync with the Poetry lockfile. If this is the case, than a warning will be logged when Tox
|
||||||
@@ -325,9 +330,9 @@ python -c '\
|
|||||||
'
|
'
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note:** To force Tox to fail if Poetry is not installed, run the `tox` command with the
|
> **Note:** To force Tox to fail if Poetry is not installed, add the `require_poetry = true`
|
||||||
> `--require-poetry` option. See the [Runtime Options](#runtime-options) for more
|
> option to the tox `[testenv]` configuration. See the
|
||||||
> information.
|
> [Config Options](#configuration-options) for more information.
|
||||||
|
|
||||||
## Developer Documentation
|
## Developer Documentation
|
||||||
|
|
||||||
@@ -347,8 +352,8 @@ are tracked on [Github](https://github.com/enpaul/tox-poetry-installer/releases)
|
|||||||
[fork the repository](https://docs.github.com/en/enterprise/2.20/user/github/getting-started-with-github/fork-a-repo)
|
[fork the repository](https://docs.github.com/en/enterprise/2.20/user/github/getting-started-with-github/fork-a-repo)
|
||||||
and [open a pull request](https://github.com/enpaul/tox-poetry-installer/compare).
|
and [open a pull request](https://github.com/enpaul/tox-poetry-installer/compare).
|
||||||
|
|
||||||
Developing this project requires at least [Python 3.6](https://www.python.org/downloads/)
|
Developing this project requires [Python 3.7+](https://www.python.org/downloads/) and
|
||||||
and at least [Poetry 1.0](https://python-poetry.org/docs/#installation). GNU Make can
|
[Poetry 1.0](https://python-poetry.org/docs/#installation) or later. GNU Make can
|
||||||
optionally be used to quickly setup a local development environment, but this is not
|
optionally be used to quickly setup a local development environment, but this is not
|
||||||
required.
|
required.
|
||||||
|
|
||||||
@@ -421,6 +426,6 @@ Everything in Beta plus...
|
|||||||
|
|
||||||
- [ ] Fully replace dependency on `poetry` with dependency on `poetry-core` ([#2](https://github.com/enpaul/tox-poetry-installer/issues/2))
|
- [ ] Fully replace dependency on `poetry` with dependency on `poetry-core` ([#2](https://github.com/enpaul/tox-poetry-installer/issues/2))
|
||||||
- [x] Add comprehensive unit tests
|
- [x] Add comprehensive unit tests
|
||||||
- [ ] Add tests for each feature version of Tox between 3.8 and 3.20
|
- [ ] ~Add tests for each feature version of Tox between 3.8 and 3.20~
|
||||||
- [x] Add tests for Python-3.6, 3.7, 3.8, and 3.9
|
- [x] Add tests for Python-3.6, 3.7, 3.8, and 3.9
|
||||||
- [x] Add Github Actions based CI
|
- [x] Add Github Actions based CI
|
||||||
|
|||||||
1387
poetry.lock
generated
1387
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "tox-poetry-installer"
|
name = "tox-poetry-installer"
|
||||||
version = "0.7.0"
|
version = "0.8.5"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"]
|
authors = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"]
|
||||||
description = "A plugin for Tox that lets you install test environment dependencies from the Poetry lockfile"
|
description = "A plugin for Tox that lets you install test environment dependencies from the Poetry lockfile"
|
||||||
@@ -27,6 +27,7 @@ classifiers = [
|
|||||||
"Programming Language :: Python :: 3.7",
|
"Programming Language :: Python :: 3.7",
|
||||||
"Programming Language :: Python :: 3.8",
|
"Programming Language :: Python :: 3.8",
|
||||||
"Programming Language :: Python :: 3.9",
|
"Programming Language :: Python :: 3.9",
|
||||||
|
"Programming Language :: Python :: 3.10",
|
||||||
"Programming Language :: Python :: Implementation :: CPython",
|
"Programming Language :: Python :: Implementation :: CPython",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -38,27 +39,28 @@ poetry = ["poetry"]
|
|||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.6.1"
|
python = "^3.6.1"
|
||||||
poetry = {version = "^1.0.0", optional = true}
|
poetry = {version = ">=1.0.0,<1.2", optional = true}
|
||||||
poetry-core = "^1.0.0"
|
poetry-core = "^1.0.0"
|
||||||
tox = "^3.8.0"
|
tox = "^3.8.0"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
bandit = "^1.6.2"
|
bandit = "^1.6.2"
|
||||||
black = { version = "^20.8b1", allow-prereleases = true }
|
black = { version = "^21.12b0", allow-prereleases = true, python = "^3.7" }
|
||||||
blacken-docs = "^1.8.0"
|
blacken-docs = { version = "^1.8.0", python = "^3.7" }
|
||||||
ipython = { version = "^7.18.1", python = "^3.7" }
|
ipython = { version = "^7.18.1", python = "^3.7" }
|
||||||
mypy = "^0.782"
|
mdformat = "^0.6"
|
||||||
|
mdformat-gfm = "^0.2"
|
||||||
|
mypy = "^0.930"
|
||||||
pre-commit = "^2.7.1"
|
pre-commit = "^2.7.1"
|
||||||
pre-commit-hooks = "^3.3.0"
|
pre-commit-hooks = "^3.3.0"
|
||||||
pylint = "^2.4.4"
|
pylint = { version = "^2.13.0", python = "^3.7" }
|
||||||
pytest = "^6.0.2"
|
pytest = "^6.0.2"
|
||||||
pytest-cov = "^2.10.1"
|
pytest-cov = "^2.10.1"
|
||||||
reorder-python-imports = "^2.3.5"
|
reorder-python-imports = "^2.3.5"
|
||||||
safety = "^1.9.0"
|
safety = "^1.9.0"
|
||||||
toml = "^0.10.1"
|
toml = "^0.10.1"
|
||||||
tox = "^3.20.0"
|
tox = "^3.20.0"
|
||||||
mdformat = "^0.6.4"
|
types-toml = "^0.10.1"
|
||||||
mdformat-gfm = "^0.2"
|
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core>=1.0.0"]
|
requires = ["poetry-core>=1.0.0"]
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ class MockVirtualEnv:
|
|||||||
def is_valid_for_marker(*args, **kwargs):
|
def is_valid_for_marker(*args, **kwargs):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_version_info():
|
||||||
|
return (1, 2, 3)
|
||||||
|
|
||||||
|
|
||||||
class MockPipInstaller:
|
class MockPipInstaller:
|
||||||
"""Mock class for the :class:`poetry.installation.pip_installer.PipInstaller`"""
|
"""Mock class for the :class:`poetry.installation.pip_installer.PipInstaller`"""
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ from poetry.factory import Factory
|
|||||||
|
|
||||||
from .fixtures import mock_poetry_factory
|
from .fixtures import mock_poetry_factory
|
||||||
from .fixtures import mock_venv
|
from .fixtures import mock_venv
|
||||||
from tox_poetry_installer import datatypes
|
|
||||||
from tox_poetry_installer import installer
|
from tox_poetry_installer import installer
|
||||||
|
from tox_poetry_installer import utilities
|
||||||
|
|
||||||
|
|
||||||
def test_deduplication(mock_venv, mock_poetry_factory):
|
def test_deduplication(mock_venv, mock_poetry_factory):
|
||||||
"""Test that the installer does not install duplicate dependencies"""
|
"""Test that the installer does not install duplicate dependencies"""
|
||||||
poetry = Factory().create_poetry(None)
|
poetry = Factory().create_poetry(None)
|
||||||
packages: datatypes.PackageMap = {
|
packages: utilities.PackageMap = {
|
||||||
item.name: item for item in poetry.locker.locked_repository(False).packages
|
item.name: item for item in poetry.locker.locked_repository(False).packages
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ def test_deduplication(mock_venv, mock_poetry_factory):
|
|||||||
def test_parallelization(mock_venv, mock_poetry_factory):
|
def test_parallelization(mock_venv, mock_poetry_factory):
|
||||||
"""Test that behavior is consistent between parallel and non-parallel usage"""
|
"""Test that behavior is consistent between parallel and non-parallel usage"""
|
||||||
poetry = Factory().create_poetry(None)
|
poetry = Factory().create_poetry(None)
|
||||||
packages: datatypes.PackageMap = {
|
packages: utilities.PackageMap = {
|
||||||
item.name: item for item in poetry.locker.locked_repository(False).packages
|
item.name: item for item in poetry.locker.locked_repository(False).packages
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ def test_parallelization(mock_venv, mock_poetry_factory):
|
|||||||
|
|
||||||
venv_sequential = tox.venv.VirtualEnv()
|
venv_sequential = tox.venv.VirtualEnv()
|
||||||
start_sequential = time.time()
|
start_sequential = time.time()
|
||||||
installer.install(poetry, venv_sequential, to_install, None)
|
installer.install(poetry, venv_sequential, to_install, 0)
|
||||||
sequential = time.time() - start_sequential
|
sequential = time.time() - start_sequential
|
||||||
|
|
||||||
venv_parallel = tox.venv.VirtualEnv()
|
venv_parallel = tox.venv.VirtualEnv()
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ from poetry.puzzle.provider import Provider
|
|||||||
from .fixtures import mock_poetry_factory
|
from .fixtures import mock_poetry_factory
|
||||||
from .fixtures import mock_venv
|
from .fixtures import mock_venv
|
||||||
from tox_poetry_installer import constants
|
from tox_poetry_installer import constants
|
||||||
from tox_poetry_installer import datatypes
|
|
||||||
from tox_poetry_installer import exceptions
|
from tox_poetry_installer import exceptions
|
||||||
from tox_poetry_installer import utilities
|
from tox_poetry_installer import utilities
|
||||||
|
|
||||||
@@ -20,19 +19,16 @@ def test_exclude_unsafe():
|
|||||||
assert Provider.UNSAFE_PACKAGES == constants.UNSAFE_PACKAGES
|
assert Provider.UNSAFE_PACKAGES == constants.UNSAFE_PACKAGES
|
||||||
|
|
||||||
for dep in constants.UNSAFE_PACKAGES:
|
for dep in constants.UNSAFE_PACKAGES:
|
||||||
assert utilities.identify_transients(dep, dict(), None) == []
|
assert not utilities.identify_transients(dep, {}, None)
|
||||||
|
|
||||||
|
|
||||||
def test_allow_missing():
|
def test_allow_missing():
|
||||||
"""Test that the ``allow_missing`` parameter works as expected"""
|
"""Test that the ``allow_missing`` parameter works as expected"""
|
||||||
with pytest.raises(exceptions.LockedDepNotFoundError):
|
with pytest.raises(exceptions.LockedDepNotFoundError):
|
||||||
utilities.identify_transients("luke-skywalker", dict(), None)
|
utilities.identify_transients("luke-skywalker", {}, None)
|
||||||
|
|
||||||
assert (
|
assert not utilities.identify_transients(
|
||||||
utilities.identify_transients(
|
"darth-vader", {}, None, allow_missing=["darth-vader"]
|
||||||
"darth-vader", dict(), None, allow_missing=["darth-vader"]
|
|
||||||
)
|
|
||||||
== []
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -51,7 +47,7 @@ def test_exclude_pep508():
|
|||||||
"=>foo",
|
"=>foo",
|
||||||
]:
|
]:
|
||||||
with pytest.raises(exceptions.LockedDepVersionConflictError):
|
with pytest.raises(exceptions.LockedDepVersionConflictError):
|
||||||
utilities.identify_transients(version, dict(), None)
|
utilities.identify_transients(version, {}, None)
|
||||||
|
|
||||||
|
|
||||||
def test_functional(mock_poetry_factory, mock_venv):
|
def test_functional(mock_poetry_factory, mock_venv):
|
||||||
@@ -61,17 +57,15 @@ def test_functional(mock_poetry_factory, mock_venv):
|
|||||||
is always the last in the returned list.
|
is always the last in the returned list.
|
||||||
"""
|
"""
|
||||||
pypoetry = poetry.factory.Factory().create_poetry(None)
|
pypoetry = poetry.factory.Factory().create_poetry(None)
|
||||||
packages: datatypes.PackageMap = {
|
packages = utilities.build_package_map(pypoetry)
|
||||||
item.name: item for item in pypoetry.locker.locked_repository(False).packages
|
|
||||||
}
|
|
||||||
venv = poetry.utils.env.VirtualEnv() # pylint: disable=no-value-for-parameter
|
venv = poetry.utils.env.VirtualEnv() # pylint: disable=no-value-for-parameter
|
||||||
|
|
||||||
requests_requires = [
|
requests_requires = [
|
||||||
packages["certifi"],
|
packages["certifi"][0],
|
||||||
packages["chardet"],
|
packages["chardet"][0],
|
||||||
packages["idna"],
|
packages["idna"][0],
|
||||||
packages["urllib3"],
|
packages["urllib3"][0],
|
||||||
packages["requests"],
|
packages["requests"][0],
|
||||||
]
|
]
|
||||||
|
|
||||||
transients = utilities.identify_transients("requests", packages, venv)
|
transients = utilities.identify_transients("requests", packages, venv)
|
||||||
@@ -79,7 +73,7 @@ def test_functional(mock_poetry_factory, mock_venv):
|
|||||||
assert all((item in requests_requires) for item in transients)
|
assert all((item in requests_requires) for item in transients)
|
||||||
assert all((item in transients) for item in requests_requires)
|
assert all((item in transients) for item in requests_requires)
|
||||||
|
|
||||||
for package in [packages["requests"], packages["tox"], packages["flask"]]:
|
for package in [packages["requests"][0], packages["tox"][0], packages["flask"][0]]:
|
||||||
transients = utilities.identify_transients(package, packages, venv)
|
transients = utilities.identify_transients(package.name, packages, venv)
|
||||||
assert transients[-1] == package
|
assert transients[-1] == package
|
||||||
assert len(transients) == len(set(transients))
|
assert len(transients) == len(set(transients))
|
||||||
|
|||||||
46
tox.ini
46
tox.ini
@@ -1,5 +1,5 @@
|
|||||||
[tox]
|
[tox]
|
||||||
envlist = py36, py37, py38, py39, static, static-tests, security
|
envlist = py36, py37, py38, py39, py310, static, static-tests, security
|
||||||
isolated_build = true
|
isolated_build = true
|
||||||
skip_missing_interpreters = true
|
skip_missing_interpreters = true
|
||||||
|
|
||||||
@@ -14,7 +14,10 @@ locked_deps =
|
|||||||
pytest-cov
|
pytest-cov
|
||||||
toml
|
toml
|
||||||
commands =
|
commands =
|
||||||
pytest --cov {toxinidir}/tox_poetry_installer --cov-config {toxinidir}/.coveragerc --cov-report term-missing {toxinidir}/tests/
|
pytest {toxinidir}/tests/ \
|
||||||
|
--cov {toxinidir}/tox_poetry_installer \
|
||||||
|
--cov-config {toxinidir}/.coveragerc \
|
||||||
|
--cov-report term-missing
|
||||||
|
|
||||||
[testenv:static]
|
[testenv:static]
|
||||||
description = Static formatting and quality enforcement
|
description = Static formatting and quality enforcement
|
||||||
@@ -31,10 +34,15 @@ locked_deps =
|
|||||||
pre-commit
|
pre-commit
|
||||||
pre-commit-hooks
|
pre-commit-hooks
|
||||||
pylint
|
pylint
|
||||||
|
types-toml
|
||||||
commands =
|
commands =
|
||||||
pre-commit run --all-files
|
pre-commit run \
|
||||||
pylint --rcfile {toxinidir}/.pylintrc {toxinidir}/tox_poetry_installer/
|
--all-files
|
||||||
mypy --ignore-missing-imports --no-strict-optional {toxinidir}/tox_poetry_installer/
|
pylint {toxinidir}/tox_poetry_installer/ \
|
||||||
|
--rcfile {toxinidir}/.pylintrc
|
||||||
|
mypy {toxinidir}/tox_poetry_installer/ \
|
||||||
|
--ignore-missing-imports \
|
||||||
|
--no-strict-optional
|
||||||
|
|
||||||
[testenv:static-tests]
|
[testenv:static-tests]
|
||||||
description = Static formatting and quality enforcement for the tests
|
description = Static formatting and quality enforcement for the tests
|
||||||
@@ -45,21 +53,37 @@ locked_deps =
|
|||||||
pylint
|
pylint
|
||||||
pytest
|
pytest
|
||||||
mypy
|
mypy
|
||||||
|
types-toml
|
||||||
commands =
|
commands =
|
||||||
pylint --rcfile {toxinidir}/.pylintrc {toxinidir}/tests/
|
pylint {toxinidir}/tests/ \
|
||||||
mypy --ignore-missing-imports --no-strict-optional {toxinidir}/tests/
|
--rcfile {toxinidir}/.pylintrc
|
||||||
|
mypy {toxinidir}/tests/ \
|
||||||
|
--ignore-missing-imports \
|
||||||
|
--no-strict-optional
|
||||||
|
|
||||||
[testenv:security]
|
[testenv:security]
|
||||||
description = Security checks
|
description = Security checks
|
||||||
basepython = python3.8
|
basepython = python3.8
|
||||||
platform = linux
|
platform = linux
|
||||||
ignore_errors = true
|
ignore_errors = true
|
||||||
|
skip_install = true
|
||||||
locked_deps =
|
locked_deps =
|
||||||
bandit
|
bandit
|
||||||
safety
|
safety
|
||||||
poetry
|
poetry
|
||||||
commands =
|
commands =
|
||||||
bandit --recursive --quiet {toxinidir}/tox_poetry_installer/
|
bandit {toxinidir}/tox_poetry_installer/ \
|
||||||
bandit --recursive --quiet --skip B101 {toxinidir}/tests/
|
--recursive \
|
||||||
poetry export --format requirements.txt --output {envtmpdir}/requirements.txt --without-hashes --dev
|
--quiet
|
||||||
safety check --bare --file {envtmpdir}/requirements.txt
|
bandit {toxinidir}/tests/ \
|
||||||
|
--recursive \
|
||||||
|
--quiet \
|
||||||
|
--skip B101
|
||||||
|
poetry export \
|
||||||
|
--format requirements.txt \
|
||||||
|
--output {envtmpdir}/requirements.txt \
|
||||||
|
--without-hashes \
|
||||||
|
--dev
|
||||||
|
safety check \
|
||||||
|
--file {envtmpdir}/requirements.txt \
|
||||||
|
--json
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# pylint: disable=missing-docstring
|
# pylint: disable=missing-docstring
|
||||||
__title__ = "tox-poetry-installer"
|
__title__ = "tox-poetry-installer"
|
||||||
__summary__ = "A plugin for Tox that lets you install test environment dependencies from the Poetry lockfile"
|
__summary__ = "A plugin for Tox that lets you install test environment dependencies from the Poetry lockfile"
|
||||||
__version__ = "0.7.0"
|
__version__ = "0.8.5"
|
||||||
__url__ = "https://github.com/enpaul/tox-poetry-installer/"
|
__url__ = "https://github.com/enpaul/tox-poetry-installer/"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
__authors__ = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"]
|
__authors__ = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"]
|
||||||
|
|||||||
@@ -21,3 +21,6 @@ REPORTER_PREFIX: str = f"{__about__.__title__}:"
|
|||||||
|
|
||||||
# Internal list of packages that poetry has deemed unsafe and are excluded from the lockfile
|
# Internal list of packages that poetry has deemed unsafe and are excluded from the lockfile
|
||||||
UNSAFE_PACKAGES: Set[str] = {"distribute", "pip", "setuptools", "wheel"}
|
UNSAFE_PACKAGES: Set[str] = {"distribute", "pip", "setuptools", "wheel"}
|
||||||
|
|
||||||
|
# Number of threads to use for installing dependencies by default
|
||||||
|
DEFAULT_INSTALL_THREADS: int = 10
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
"""Definitions for typehints/containers used by the plugin"""
|
|
||||||
from typing import Dict
|
|
||||||
|
|
||||||
from poetry.core.packages import Package as PoetryPackage
|
|
||||||
|
|
||||||
|
|
||||||
# Map of package names to the package object
|
|
||||||
PackageMap = Dict[str, PoetryPackage]
|
|
||||||
@@ -11,6 +11,7 @@ All exceptions should inherit from the common base exception :exc:`ToxPoetryInst
|
|||||||
+-- LockedDepNotFoundError
|
+-- LockedDepNotFoundError
|
||||||
+-- ExtraNotFoundError
|
+-- ExtraNotFoundError
|
||||||
+-- LockedDepsRequiredError
|
+-- LockedDepsRequiredError
|
||||||
|
+-- RequiresUnsafeDepError
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -41,3 +42,7 @@ class ExtraNotFoundError(ToxPoetryInstallerException):
|
|||||||
|
|
||||||
class LockedDepsRequiredError(ToxPoetryInstallerException):
|
class LockedDepsRequiredError(ToxPoetryInstallerException):
|
||||||
"""Environment cannot specify unlocked dependencies when locked dependencies are required"""
|
"""Environment cannot specify unlocked dependencies when locked dependencies are required"""
|
||||||
|
|
||||||
|
|
||||||
|
class RequiresUnsafeDepError(ToxPoetryInstallerException):
|
||||||
|
"""Package under test depends on an unsafe dependency and cannot be installed"""
|
||||||
|
|||||||
@@ -12,11 +12,71 @@ from tox.config import Parser as ToxParser
|
|||||||
from tox.venv import VirtualEnv as ToxVirtualEnv
|
from tox.venv import VirtualEnv as ToxVirtualEnv
|
||||||
|
|
||||||
from tox_poetry_installer import __about__
|
from tox_poetry_installer import __about__
|
||||||
|
from tox_poetry_installer import constants
|
||||||
from tox_poetry_installer import exceptions
|
from tox_poetry_installer import exceptions
|
||||||
from tox_poetry_installer import installer
|
from tox_poetry_installer import installer
|
||||||
from tox_poetry_installer import logger
|
from tox_poetry_installer import logger
|
||||||
from tox_poetry_installer import utilities
|
from tox_poetry_installer import utilities
|
||||||
from tox_poetry_installer.datatypes import PackageMap
|
|
||||||
|
|
||||||
|
def _postprocess_install_project_deps(
|
||||||
|
testenv_config, value: Optional[str] # pylint: disable=unused-argument
|
||||||
|
) -> Optional[bool]:
|
||||||
|
"""An awful hack to patch on three-state boolean logic to a config parameter
|
||||||
|
|
||||||
|
.. warning: This logic should 100% be removed in the next feature release. It's here to work
|
||||||
|
around a bad design for now but should not persist.
|
||||||
|
|
||||||
|
The bug filed in `#61`_ is caused by a combination of poor design and attempted cleverness. The
|
||||||
|
name of the ``install_project_deps`` config option implies that it has ultimate control over
|
||||||
|
whether the project dependencies are installed to the testenv, but this is not actually correct.
|
||||||
|
What it actually allows the user to do is force the project dependencies to not be installed to
|
||||||
|
an environment that would otherwise install them. This was intended behavior, however the
|
||||||
|
intention was wrong.
|
||||||
|
|
||||||
|
.. _`#61`: https://github.com/enpaul/tox-poetry-installer/issues/61
|
||||||
|
|
||||||
|
In an effort to be clever the plugin automatically skips installing project dependencies when
|
||||||
|
the project package is not installed to the testenv (``skip_install = true``) or if packaging
|
||||||
|
as a whole is disabled (``skipsdist = true``). The intention of this behavior is to install only
|
||||||
|
the expected dependencies to a testenv and no more. However, this conflicts with the
|
||||||
|
``install_project_deps`` config option, which cannot override this behavior because it defaults
|
||||||
|
to ``True``. In effect, ``install_project_deps = true`` in fact means "automatically
|
||||||
|
determine whether to install project dependencies" and ``install_project_deps = false`` means
|
||||||
|
"never install the project dependencies". This is not ideal and unintuitive.
|
||||||
|
|
||||||
|
To avoid having to make a breaking change this workaround has been added to support three-state
|
||||||
|
logic between ``True``, ``False``, and ``None``. The ``install_project_deps`` option is now
|
||||||
|
parsed by Tox as a string with a default value of ``None``. If the value is not ``None`` then
|
||||||
|
this post processing function will try to convert it to a boolean the same way that Tox's
|
||||||
|
`SectionReader.getbool()`_ method does, raising an error to mimic the default behavior if it
|
||||||
|
can't.
|
||||||
|
|
||||||
|
.. _`SectionReader.getbool()`: https://github.com/tox-dev/tox/blob/f8459218ee5ab5753321b3eb989b7beee5b391ad/src/tox/config/__init__.py#L1724
|
||||||
|
|
||||||
|
The three states for the ``install_project_deps`` setting are:
|
||||||
|
* ``None`` - User did not configure the setting, package dependency installation is
|
||||||
|
determined automatically
|
||||||
|
* ``True`` - User configured the setting to ``True``, package dependencies will be installed
|
||||||
|
* ``False`` - User configured the setting to ``False``, package dependencies will not be
|
||||||
|
installed
|
||||||
|
|
||||||
|
This config option should be deprecated with the 1.0.0 release and instead an option like
|
||||||
|
``always_install_project_deps`` should be added which overrides the default determination and
|
||||||
|
just installs the project dependencies. The counterpart (``never_install_project_deps``)
|
||||||
|
shouldn't be needed, since I don't think there's a real use case for that.
|
||||||
|
"""
|
||||||
|
if value is None:
|
||||||
|
return value
|
||||||
|
|
||||||
|
if value.lower() == "true":
|
||||||
|
return True
|
||||||
|
if value.lower() == "false":
|
||||||
|
return False
|
||||||
|
|
||||||
|
raise tox.exception.ConfigError(
|
||||||
|
f"install_project_deps: boolean value '{value}' needs to be 'True' or 'False'"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@tox.hookimpl
|
@tox.hookimpl
|
||||||
@@ -31,7 +91,7 @@ def tox_addoption(parser: ToxParser):
|
|||||||
"--require-poetry",
|
"--require-poetry",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
dest="require_poetry",
|
dest="require_poetry",
|
||||||
help="Trigger a failure if Poetry is not available to Tox",
|
help="(deprecated) Trigger a failure if Poetry is not available to Tox",
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
@@ -39,7 +99,15 @@ def tox_addoption(parser: ToxParser):
|
|||||||
type=int,
|
type=int,
|
||||||
dest="parallelize_locked_install",
|
dest="parallelize_locked_install",
|
||||||
default=None,
|
default=None,
|
||||||
help="Number of worker threads to use for installing dependencies from the Poetry lockfile in parallel",
|
help="(deprecated) Number of worker threads to use for installing dependencies from the Poetry lockfile in parallel",
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--parallel-install-threads",
|
||||||
|
type=int,
|
||||||
|
dest="parallel_install_threads",
|
||||||
|
default=constants.DEFAULT_INSTALL_THREADS,
|
||||||
|
help="Number of locked dependencies to install simultaneously; set to 0 to disable parallel installation",
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.add_testenv_attribute(
|
parser.add_testenv_attribute(
|
||||||
@@ -49,6 +117,14 @@ def tox_addoption(parser: ToxParser):
|
|||||||
help="Automatically install all Poetry development dependencies to the environment",
|
help="Automatically install all Poetry development dependencies to the environment",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
parser.add_testenv_attribute(
|
||||||
|
name="install_project_deps",
|
||||||
|
type="string",
|
||||||
|
default=None,
|
||||||
|
help="Automatically install all Poetry primary dependencies to the environment",
|
||||||
|
postprocess=_postprocess_install_project_deps,
|
||||||
|
)
|
||||||
|
|
||||||
parser.add_testenv_attribute(
|
parser.add_testenv_attribute(
|
||||||
name="require_locked_deps",
|
name="require_locked_deps",
|
||||||
type="bool",
|
type="bool",
|
||||||
@@ -82,13 +158,6 @@ def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction) -> Optional
|
|||||||
:param action: Tox action object
|
:param action: Tox action object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if venv.envconfig.config.option.require_poetry:
|
|
||||||
logger.warning(
|
|
||||||
"DEPRECATION WARNING: The '--require-poetry' runtime option is deprecated and will be "
|
|
||||||
"removed in version 1.0.0. Please update test environments that require Poetry to "
|
|
||||||
"set the 'require_poetry = true' option in tox.ini"
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
poetry = utilities.check_preconditions(venv, action)
|
poetry = utilities.check_preconditions(venv, action)
|
||||||
except exceptions.SkipEnvironment as err:
|
except exceptions.SkipEnvironment as err:
|
||||||
@@ -116,10 +185,7 @@ def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction) -> Optional
|
|||||||
f"Unlocked dependencies '{venv.envconfig.deps}' specified for environment '{venv.name}' which requires locked dependencies"
|
f"Unlocked dependencies '{venv.envconfig.deps}' specified for environment '{venv.name}' which requires locked dependencies"
|
||||||
)
|
)
|
||||||
|
|
||||||
packages: PackageMap = {
|
packages = utilities.build_package_map(poetry)
|
||||||
package.name: package
|
|
||||||
for package in poetry.locker.locked_repository(True).packages
|
|
||||||
}
|
|
||||||
|
|
||||||
if venv.envconfig.install_dev_deps:
|
if venv.envconfig.install_dev_deps:
|
||||||
dev_deps = utilities.find_dev_deps(packages, virtualenv, poetry)
|
dev_deps = utilities.find_dev_deps(packages, virtualenv, poetry)
|
||||||
@@ -138,7 +204,15 @@ def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction) -> Optional
|
|||||||
f"Identified {len(env_deps)} environment dependencies to install to env"
|
f"Identified {len(env_deps)} environment dependencies to install to env"
|
||||||
)
|
)
|
||||||
|
|
||||||
if not venv.envconfig.skip_install and not venv.envconfig.config.skipsdist:
|
install_project_deps = (
|
||||||
|
venv.envconfig.install_project_deps
|
||||||
|
if venv.envconfig.install_project_deps is not None
|
||||||
|
else (
|
||||||
|
not venv.envconfig.skip_install and not venv.envconfig.config.skipsdist
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if install_project_deps:
|
||||||
project_deps = utilities.find_project_deps(
|
project_deps = utilities.find_project_deps(
|
||||||
packages, virtualenv, poetry, venv.envconfig.extras
|
packages, virtualenv, poetry, venv.envconfig.extras
|
||||||
)
|
)
|
||||||
@@ -147,7 +221,7 @@ def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction) -> Optional
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
project_deps = []
|
project_deps = []
|
||||||
logger.info("Env does not install project package, skipping")
|
logger.info("Env does not install project package dependencies, skipping")
|
||||||
except exceptions.ToxPoetryInstallerException as err:
|
except exceptions.ToxPoetryInstallerException as err:
|
||||||
venv.status = err.__class__.__name__
|
venv.status = err.__class__.__name__
|
||||||
logger.error(str(err))
|
logger.error(str(err))
|
||||||
@@ -158,11 +232,18 @@ def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction) -> Optional
|
|||||||
raise err
|
raise err
|
||||||
|
|
||||||
dependencies = dev_deps + env_deps + project_deps
|
dependencies = dev_deps + env_deps + project_deps
|
||||||
log_parallel = (
|
if (
|
||||||
f" (using {venv.envconfig.config.option.parallelize_locked_install} threads)"
|
venv.envconfig.config.option.parallel_install_threads
|
||||||
if venv.envconfig.config.option.parallelize_locked_install
|
!= constants.DEFAULT_INSTALL_THREADS
|
||||||
else ""
|
):
|
||||||
)
|
parallel_threads = venv.envconfig.config.option.parallel_install_threads
|
||||||
|
else:
|
||||||
|
parallel_threads = (
|
||||||
|
venv.envconfig.config.option.parallelize_locked_install
|
||||||
|
if venv.envconfig.config.option.parallelize_locked_install is not None
|
||||||
|
else constants.DEFAULT_INSTALL_THREADS
|
||||||
|
)
|
||||||
|
log_parallel = f" (using {parallel_threads} threads)" if parallel_threads else ""
|
||||||
|
|
||||||
action.setactivity(
|
action.setactivity(
|
||||||
__about__.__title__,
|
__about__.__title__,
|
||||||
@@ -172,7 +253,7 @@ def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction) -> Optional
|
|||||||
poetry,
|
poetry,
|
||||||
venv,
|
venv,
|
||||||
dependencies,
|
dependencies,
|
||||||
venv.envconfig.config.option.parallelize_locked_install,
|
parallel_threads,
|
||||||
)
|
)
|
||||||
|
|
||||||
return venv.envconfig.require_locked_deps or None
|
return venv.envconfig.require_locked_deps or None
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
import concurrent.futures
|
import concurrent.futures
|
||||||
import contextlib
|
import contextlib
|
||||||
import typing
|
import typing
|
||||||
from typing import Optional
|
from datetime import datetime
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
from typing import Set
|
from typing import Set
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ def install(
|
|||||||
poetry: "_poetry.Poetry",
|
poetry: "_poetry.Poetry",
|
||||||
venv: ToxVirtualEnv,
|
venv: ToxVirtualEnv,
|
||||||
packages: Sequence[PoetryPackage],
|
packages: Sequence[PoetryPackage],
|
||||||
parallels: Optional[int] = None,
|
parallels: int = 0,
|
||||||
):
|
):
|
||||||
"""Install a bunch of packages to a virtualenv
|
"""Install a bunch of packages to a virtualenv
|
||||||
|
|
||||||
@@ -47,6 +47,13 @@ def install(
|
|||||||
|
|
||||||
installed: Set[PoetryPackage] = set()
|
installed: Set[PoetryPackage] = set()
|
||||||
|
|
||||||
|
def logged_install(dependency: PoetryPackage) -> None:
|
||||||
|
start = datetime.now()
|
||||||
|
logger.debug(f"Installing {dependency}")
|
||||||
|
pip.install(dependency)
|
||||||
|
end = datetime.now()
|
||||||
|
logger.debug(f"Finished installing {dependency} in {end - start}")
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def _optional_parallelize():
|
def _optional_parallelize():
|
||||||
"""A bit of cheat, really
|
"""A bit of cheat, really
|
||||||
@@ -55,7 +62,7 @@ def install(
|
|||||||
enables/disables the usage of the parallel thread pooler depending on the value of
|
enables/disables the usage of the parallel thread pooler depending on the value of
|
||||||
the ``parallels`` parameter.
|
the ``parallels`` parameter.
|
||||||
"""
|
"""
|
||||||
if parallels:
|
if parallels > 0:
|
||||||
with concurrent.futures.ThreadPoolExecutor(
|
with concurrent.futures.ThreadPoolExecutor(
|
||||||
max_workers=parallels
|
max_workers=parallels
|
||||||
) as executor:
|
) as executor:
|
||||||
@@ -67,8 +74,8 @@ def install(
|
|||||||
for dependency in packages:
|
for dependency in packages:
|
||||||
if dependency not in installed:
|
if dependency not in installed:
|
||||||
installed.add(dependency)
|
installed.add(dependency)
|
||||||
logger.debug(f"Installing {dependency}")
|
logger.debug(f"Queuing {dependency}")
|
||||||
executor(pip.install, dependency)
|
executor(logged_install, dependency)
|
||||||
else:
|
else:
|
||||||
logger.debug(f"Skipping {dependency}, already installed")
|
logger.debug(f"Skipping {dependency}, already installed")
|
||||||
logger.debug("Waiting for installs to finish...")
|
logger.debug("Waiting for installs to finish...")
|
||||||
|
|||||||
@@ -2,12 +2,13 @@
|
|||||||
# Silence this one globally to support the internal function imports for the proxied poetry module.
|
# Silence this one globally to support the internal function imports for the proxied poetry module.
|
||||||
# See the docstring in 'tox_poetry_installer._poetry' for more context.
|
# See the docstring in 'tox_poetry_installer._poetry' for more context.
|
||||||
# pylint: disable=import-outside-toplevel
|
# pylint: disable=import-outside-toplevel
|
||||||
|
import collections
|
||||||
import typing
|
import typing
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Dict
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
from typing import Set
|
from typing import Set
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
from poetry.core.packages import Dependency as PoetryDependency
|
from poetry.core.packages import Dependency as PoetryDependency
|
||||||
from poetry.core.packages import Package as PoetryPackage
|
from poetry.core.packages import Package as PoetryPackage
|
||||||
@@ -17,12 +18,14 @@ from tox.venv import VirtualEnv as ToxVirtualEnv
|
|||||||
from tox_poetry_installer import constants
|
from tox_poetry_installer import constants
|
||||||
from tox_poetry_installer import exceptions
|
from tox_poetry_installer import exceptions
|
||||||
from tox_poetry_installer import logger
|
from tox_poetry_installer import logger
|
||||||
from tox_poetry_installer.datatypes import PackageMap
|
|
||||||
|
|
||||||
if typing.TYPE_CHECKING:
|
if typing.TYPE_CHECKING:
|
||||||
from tox_poetry_installer import _poetry
|
from tox_poetry_installer import _poetry
|
||||||
|
|
||||||
|
|
||||||
|
PackageMap = Dict[str, List[PoetryPackage]]
|
||||||
|
|
||||||
|
|
||||||
def check_preconditions(venv: ToxVirtualEnv, action: ToxAction) -> "_poetry.Poetry":
|
def check_preconditions(venv: ToxVirtualEnv, action: ToxAction) -> "_poetry.Poetry":
|
||||||
"""Check that the local project environment meets expectations"""
|
"""Check that the local project environment meets expectations"""
|
||||||
# Skip running the plugin for the provisioning environment. The provisioned environment,
|
# Skip running the plugin for the provisioning environment. The provisioned environment,
|
||||||
@@ -43,6 +46,19 @@ def check_preconditions(venv: ToxVirtualEnv, action: ToxAction) -> "_poetry.Poet
|
|||||||
f"Skipping isolated packaging build env '{action.name}'"
|
f"Skipping isolated packaging build env '{action.name}'"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if venv.envconfig.config.option.require_poetry:
|
||||||
|
logger.warning(
|
||||||
|
"DEPRECATION: The '--require-poetry' runtime option is deprecated and will be "
|
||||||
|
"removed in version 1.0.0. Please update test environments that require Poetry to "
|
||||||
|
"set the 'require_poetry = true' option in tox.ini"
|
||||||
|
)
|
||||||
|
|
||||||
|
if venv.envconfig.config.option.parallelize_locked_install is not None:
|
||||||
|
logger.warning(
|
||||||
|
"DEPRECATION: The '--parallelize-locked-install' option is deprecated and will "
|
||||||
|
"be removed in version 1.0.0. Please use the '--parallel-install-threads' option."
|
||||||
|
)
|
||||||
|
|
||||||
from tox_poetry_installer import _poetry
|
from tox_poetry_installer import _poetry
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -69,16 +85,29 @@ def convert_virtualenv(venv: ToxVirtualEnv) -> "_poetry.VirtualEnv":
|
|||||||
return _poetry.VirtualEnv(path=Path(venv.envconfig.envdir))
|
return _poetry.VirtualEnv(path=Path(venv.envconfig.envdir))
|
||||||
|
|
||||||
|
|
||||||
|
def build_package_map(poetry: "_poetry.Poetry") -> PackageMap:
|
||||||
|
"""Build the mapping of package names to objects
|
||||||
|
|
||||||
|
:param poetry: Populated poetry object to load locked packages from
|
||||||
|
:returns: Mapping of package names to Poetry package objects
|
||||||
|
"""
|
||||||
|
packages = collections.defaultdict(list)
|
||||||
|
for package in poetry.locker.locked_repository(True).packages:
|
||||||
|
packages[package.name].append(package)
|
||||||
|
|
||||||
|
return packages
|
||||||
|
|
||||||
|
|
||||||
def identify_transients(
|
def identify_transients(
|
||||||
dep: Union[PoetryDependency, str],
|
dep_name: str,
|
||||||
packages: PackageMap,
|
packages: PackageMap,
|
||||||
venv: "_poetry.VirtualEnv",
|
venv: "_poetry.VirtualEnv",
|
||||||
allow_missing: Sequence[str] = (),
|
allow_missing: Sequence[str] = (),
|
||||||
) -> List[PoetryPackage]:
|
) -> List[PoetryPackage]:
|
||||||
"""Using a pool of packages, identify all transient dependencies of a given package name
|
"""Using a pool of packages, identify all transient dependencies of a given package name
|
||||||
|
|
||||||
:param dep: Either the Poetry dependency or the dependency's bare package name to recursively
|
:param dep_name: Either the Poetry dependency or the dependency's bare package name to recursively
|
||||||
identify the transient dependencies of
|
identify the transient dependencies of
|
||||||
:param packages: All packages from the lockfile to use for identifying dependency relationships.
|
:param packages: All packages from the lockfile to use for identifying dependency relationships.
|
||||||
:param venv: Poetry virtual environment to use for package compatibility checks
|
:param venv: Poetry virtual environment to use for package compatibility checks
|
||||||
:param allow_missing: Sequence of package names to allow to be missing from the lockfile. Any
|
:param allow_missing: Sequence of package names to allow to be missing from the lockfile. Any
|
||||||
@@ -89,53 +118,64 @@ def identify_transients(
|
|||||||
.. note:: The package corresponding to the dependency specified by the ``dep`` parameter will
|
.. note:: The package corresponding to the dependency specified by the ``dep`` parameter will
|
||||||
be included in the returned list of packages.
|
be included in the returned list of packages.
|
||||||
"""
|
"""
|
||||||
transients: List[PoetryPackage] = []
|
|
||||||
searched: Set[str] = set()
|
searched: Set[str] = set()
|
||||||
|
|
||||||
def _deps_of_dep(transient: PoetryDependency):
|
def _transients(transient: PoetryDependency) -> List[PoetryPackage]:
|
||||||
searched.add(transient.name)
|
searched.add(transient.name)
|
||||||
|
|
||||||
if venv.is_valid_for_marker(transient.marker):
|
results: List[PoetryPackage] = []
|
||||||
for requirement in packages[transient.name].requires:
|
for option in packages[transient.name]:
|
||||||
if requirement.name not in searched:
|
if venv.is_valid_for_marker(option.to_dependency().marker):
|
||||||
_deps_of_dep(requirement)
|
for requirement in option.requires:
|
||||||
logger.debug(f"Including {transient} for installation")
|
if requirement.name not in searched:
|
||||||
transients.append(packages[transient.name])
|
results += _transients(requirement)
|
||||||
|
logger.debug(f"Including {option} for installation")
|
||||||
|
results.append(option)
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
logger.debug(f"Skipping {transient}: package requires {transient.marker}")
|
logger.debug(
|
||||||
|
f"Skipping {transient.name}: target python version is {'.'.join([str(item) for item in venv.get_version_info()])} but package requires {transient.marker}"
|
||||||
|
)
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if isinstance(dep, str):
|
for option in packages[dep_name]:
|
||||||
dep = packages[dep].to_dependency()
|
if venv.is_valid_for_marker(option.to_dependency().marker):
|
||||||
|
dep = option.to_dependency()
|
||||||
_deps_of_dep(dep)
|
break
|
||||||
except KeyError as err:
|
else:
|
||||||
dep_name = err.args[0]
|
|
||||||
|
|
||||||
if dep_name in constants.UNSAFE_PACKAGES:
|
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"Installing package '{dep_name}' using Poetry is not supported and will be skipped"
|
f"Skipping {dep_name}: no locked version found compatible with target python version {'.'.join([str(item) for item in venv.get_version_info()])}"
|
||||||
)
|
)
|
||||||
logger.debug(f"Skipping {dep_name}: designated unsafe by Poetry")
|
|
||||||
return []
|
return []
|
||||||
|
|
||||||
if dep_name in allow_missing:
|
return _transients(dep)
|
||||||
logger.debug(f"Skipping {dep_name}: package is allowed to be unlocked")
|
except KeyError as err:
|
||||||
|
missing = err.args[0]
|
||||||
|
|
||||||
|
if missing in constants.UNSAFE_PACKAGES:
|
||||||
|
logger.warning(
|
||||||
|
f"Installing package '{missing}' using Poetry is not supported and will be skipped"
|
||||||
|
)
|
||||||
|
logger.debug(f"Skipping {missing}: designated unsafe by Poetry")
|
||||||
|
return []
|
||||||
|
|
||||||
|
if missing in allow_missing:
|
||||||
|
logger.debug(f"Skipping {missing}: package is allowed to be unlocked")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
if any(
|
if any(
|
||||||
delimiter in dep_name for delimiter in constants.PEP508_VERSION_DELIMITERS
|
delimiter in missing for delimiter in constants.PEP508_VERSION_DELIMITERS
|
||||||
):
|
):
|
||||||
raise exceptions.LockedDepVersionConflictError(
|
raise exceptions.LockedDepVersionConflictError(
|
||||||
f"Locked dependency '{dep_name}' cannot include version specifier"
|
f"Locked dependency '{missing}' cannot include version specifier"
|
||||||
) from None
|
) from None
|
||||||
|
|
||||||
raise exceptions.LockedDepNotFoundError(
|
raise exceptions.LockedDepNotFoundError(
|
||||||
f"No version of locked dependency '{dep_name}' found in the project lockfile"
|
f"No version of locked dependency '{missing}' found in the project lockfile"
|
||||||
) from None
|
) from None
|
||||||
|
|
||||||
return transients
|
|
||||||
|
|
||||||
|
|
||||||
def find_project_deps(
|
def find_project_deps(
|
||||||
packages: PackageMap,
|
packages: PackageMap,
|
||||||
@@ -153,26 +193,29 @@ def find_project_deps(
|
|||||||
:param extras: Sequence of extra names to include the dependencies of
|
:param extras: Sequence of extra names to include the dependencies of
|
||||||
"""
|
"""
|
||||||
|
|
||||||
base_deps: List[PoetryPackage] = [
|
if any(dep.name in constants.UNSAFE_PACKAGES for dep in poetry.package.requires):
|
||||||
packages[item.name]
|
raise exceptions.RequiresUnsafeDepError(
|
||||||
for item in poetry.package.requires
|
f"Project package requires one or more unsafe dependencies ({', '.join(constants.UNSAFE_PACKAGES)}) which cannot be installed with Poetry"
|
||||||
if not item.is_optional()
|
)
|
||||||
|
|
||||||
|
required_dep_names = [
|
||||||
|
item.name for item in poetry.package.requires if not item.is_optional()
|
||||||
]
|
]
|
||||||
|
|
||||||
extra_deps: List[PoetryPackage] = []
|
extra_dep_names: List[str] = []
|
||||||
for extra in extras:
|
for extra in extras:
|
||||||
logger.info(f"Processing project extra '{extra}'")
|
logger.info(f"Processing project extra '{extra}'")
|
||||||
try:
|
try:
|
||||||
extra_deps += [packages[item.name] for item in poetry.package.extras[extra]]
|
extra_dep_names += [item.name for item in poetry.package.extras[extra]]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise exceptions.ExtraNotFoundError(
|
raise exceptions.ExtraNotFoundError(
|
||||||
f"Environment specifies project extra '{extra}' which was not found in the lockfile"
|
f"Environment specifies project extra '{extra}' which was not found in the lockfile"
|
||||||
) from None
|
) from None
|
||||||
|
|
||||||
dependencies: List[PoetryPackage] = []
|
dependencies: List[PoetryPackage] = []
|
||||||
for dep in base_deps + extra_deps:
|
for dep_name in required_dep_names + extra_dep_names:
|
||||||
dependencies += identify_transients(
|
dependencies += identify_transients(
|
||||||
dep.name.lower(), packages, venv, allow_missing=[poetry.package.name]
|
dep_name.lower(), packages, venv, allow_missing=[poetry.package.name]
|
||||||
)
|
)
|
||||||
|
|
||||||
return dependencies
|
return dependencies
|
||||||
@@ -194,13 +237,13 @@ def find_additional_deps(
|
|||||||
:param dep_names: Sequence of additional dependency names to recursively find the transient
|
:param dep_names: Sequence of additional dependency names to recursively find the transient
|
||||||
dependencies for
|
dependencies for
|
||||||
"""
|
"""
|
||||||
deps: List[PoetryPackage] = []
|
dependencies: List[PoetryPackage] = []
|
||||||
for dep_name in dep_names:
|
for dep_name in dep_names:
|
||||||
deps += identify_transients(
|
dependencies += identify_transients(
|
||||||
dep_name.lower(), packages, venv, allow_missing=[poetry.package.name]
|
dep_name.lower(), packages, venv, allow_missing=[poetry.package.name]
|
||||||
)
|
)
|
||||||
|
|
||||||
return deps
|
return dependencies
|
||||||
|
|
||||||
|
|
||||||
def find_dev_deps(
|
def find_dev_deps(
|
||||||
|
|||||||
Reference in New Issue
Block a user