Update to v0.6.0

- Add new `commands` setting to handle multiple commands
- Deprecate `command` and `subcommands`
- Drop support for python 2
- Handle dependancy and build with Poetry
commands
Christophe Mehay 4 years ago
parent 55907d1a8c
commit 1770ac87f6

@ -3,3 +3,5 @@
!setup.py !setup.py
!README.md !README.md
!tests !tests
!poetry.lock
!pyproject.toml

1
.gitignore vendored

@ -90,4 +90,3 @@ ENV/
# Rope project settings # Rope project settings
.ropeproject .ropeproject

@ -1,19 +1,22 @@
- repo: git://github.com/pre-commit/pre-commit-hooks repos:
sha: v0.9.2 - repo: git://github.com/pre-commit/pre-commit-hooks
hooks: rev: v2.5.0
- id: check-added-large-files hooks:
- id: check-docstring-first - id: check-added-large-files
- id: check-merge-conflict - id: check-docstring-first
- id: check-yaml - id: check-merge-conflict
- id: end-of-file-fixer - id: check-yaml
- id: flake8 - id: end-of-file-fixer
args: - id: flake8
- --exclude=__init__.py,docs/conf.py language_version: python3
- id: autopep8-wrapper - id: requirements-txt-fixer
- id: requirements-txt-fixer - id: trailing-whitespace
- id: trailing-whitespace - repo: https://github.com/pre-commit/mirrors-autopep8
- repo: git://github.com/asottile/reorder_python_imports rev: v1.5.2
sha: v0.3.5 hooks:
hooks: - id: autopep8
- id: reorder-python-imports - repo: git://github.com/asottile/reorder_python_imports
language_version: 'python2.7' rev: v2.3.0
hooks:
- id: reorder-python-imports
language_version: python3

@ -3,13 +3,20 @@ services:
- docker - docker
language: python language: python
before_install: before_install:
- pip install -r requirements-dev.txt - pip install poetry
- poetry install -v
script: script:
- make test - make test
deploy: deploy:
provider: pypi before_deploy:
user: cmehay - poetry config http-basic.pypi $PYPI_USER $PYPI_PASSWORD
password: - poetry build
secure: P3Xz/ZKIwY5AxFKqzf86gwXRCThKzsXK/D7tKXGH4yETI9JZuh4EyWHI0ozNXzNSThnwLmDhlhaTjq+hVtMEpfBF3iEXQ9svlXHDW70+PXkEp81Zkm2yNBKM0uZB1DJDMXFKbVaBIKiFXHocUmOEGwwPxmPe+6QXNFUuNNTlb/iBnpSATyhvFRdgpVT327DOsco7fzFytAdi9yA4y11fTTo/mQlTaLcWqKRrUFNeP50LLKXB7a/YSC2HNYy2op6linkrCgx+kLj2FxTuWBh5jxAk97t146h7VaoYh4FhSjZ2gssbKQkU0CUD1SjELWHKrsquHI6qJJyGiIUd4GUmoNMv4GWvja9n0KjP2Dc+M5qBkHkBBpe7DIzltil5RH91Fq3m2SLeCFmNg7nYHwh5Ng3dr5gHwo9L5EmSaixFYeax2jxaInPpUfW7pIxCiRFoIFBp63w2TGg3MGRnWOZYmozzJVRHmx9wE5zgX19Eb1Tm1MA9q8Pk5xXs0US0AGnIZ/yKBLAj4pbhN57c29zfcSbzpNM/Yq69RxYBCrmq484oKDU7DhXZXgsnErTufDYJ3/o4qNjiOmXMwxLn8zmJAhJ63JGQNNz+XHGOvwNq+OI2g6SnI3f5EU9UxiZ0n3un8M5YYiG67b6KdSu+dsYKMCV3Tiv0zjJbasVr6TzXHts= deploy:
provider: script
script: poetry publish
on: on:
tags: true tags: true
env:
global:
- secure: p5Cm+cSzWB5MsCSbl9p+NHT3OrxBGhhtXJxVoYh2twrYbVOZiUVqmd1YIzMJ/kI3Vq7hDN7AX1XKQcCX7URlf/Ms6Xb66I2jsmeX/pzMkyT+SonjeDR4AHif1Spa5uoS+kn5HKKprgfd5sAgJL7G6ML34wvNsemM4MukbucpdVPLh+kIXaN1mIhBVda3i48rHO3A08GCZbd4rSaTK/eHSXgo7kkfWSSMNeGhBW61xZeR63wo4EB5Ih84XdCObOV1QHMISnF8NuqEvfmPz6cxJuRiSMarCqxdQ3jZWSaNORhHUPyrJUDeLcU9DN24IvF5BPomTneCwgGKmwgZfVPwVXBGKKK7FaX0K5PpshA/qZpi62LRGPuScsn27NEiGIezsfqFnRRvn+3Pgs1/fhuFsFVMcWqORhprwrCr1SEM7yz5pFQTJTnCEcfUaRe29EHMVPD+dJ0FlSykxfbFhu4dcKsR6yCZXsoiepKMYPb0MLO0qyQLwjKhMhd+NLlw/Jl0dNF761MRX4QPuC4ecRBCmHwajgo+mc5VLdZp0VQwN938HWe1lughbk34lLDvRP1uHkWpvB6U2F1JYmwUYAkhgVlbjgK6rQIMpHen594XwPQcXqPlechMrA3q86A/JewwcYYmn35d5yHxRXhWLd/0CktryxysOZ9oldhgNgPkysA=
- secure: KE27UMwkm3L7uCLO3fR7JEfBULAfd2/lfwxjmGXZAD4WTASlraKByYj6hq9Pzj3E6tu1yemCWfZWr52pKLg1iFO7+fNOP52spNayjK4gYDrkp3O2bTTQeI5o6mClYGssGK1CsND+PyXcpLqfgj0QmC+y1U9zOsJhE9zB0/4a4QY9P/yNuehaKfOrCdeNpWa4cWPwHUMhwHBZxwTA5AUe8jCmv4tBkpsmTwNvu7PV0pdKo/s9uth7ggVBt6VDap7dSTwNEQiG7s85wf7l4vLIuQ0hmy5EvAyLa6/HED67b2yAN6Yv9kXCmDclSQxQmwN3jrjGEIv/kC5tJ6FqGSFtL1suRGVPSZLRMBB+vERMYHEDaUZ3G6Kayf6TGfvWE++WaqrruqyV6mQcsoTP9X/7SiOQtYso3mRtdMmx7HySc+hGPZOsDkACipwTy1lfvM6Y0rLXreidFBeK/unV2P5lGFsjP8ow04MgJ8F21BvFq+HYVcfwzRbE6VQnJWdN2lRuS3hKOHZ0Y5t4gBe8qGFhIwSsN/rIMdzeg4dzKaVKAKSK9qwOUIVC9mAl/V1ZfN7CpC8biYEY1XlhmVV+KECR9SGapb2laLftDYfz3R4833nOCGjgyFB9DxG5Rc9HfGMVqdYaDURbblSRb5vjVMWZLIvfNttrLmjLJI+j5T2dfQM=

@ -1,17 +1,22 @@
# Testing with python 3 # Testing with last python 3
FROM python:3 FROM python:3
RUN pip3 install pytest six pyyaml jinja2 colorlog watchdog pytest-mock ENV POETRY_VIRTUALENVS_CREATE=false
RUN pip install poetry
RUN adduser --uid 1009 --system testuser RUN adduser --uid 1009 --system testuser
RUN addgroup --gid 1010 testgroup RUN addgroup --gid 1010 testgroup
ENV PYTHONPATH /opt/ ENV PYTHONPATH /opt/
ADD tests/test_template.yml.tpl /tmp/test_template.yml COPY tests/test_template.yml.tpl /tmp/test_template.yml
ADD tests/test_template.yml.tpl /tmp/test_template2.yml.tpl COPY tests/test_template.yml.tpl /tmp/test_template2.yml.tpl
COPY pyproject.toml poetry.lock /opt/
RUN cd /opt && poetry install
WORKDIR /opt/tests WORKDIR /opt/tests
CMD ["py.test", "--verbose", "-rw", "."] CMD ["pytest", "--verbose", "-rw", "."]

@ -0,0 +1,24 @@
# Testing with python 3.6
FROM python:3.6
ENV POETRY_VIRTUALENVS_CREATE=false
RUN pip install poetry
RUN adduser --uid 1009 --system testuser
RUN addgroup --gid 1010 testgroup
ENV PYTHONPATH /opt/
ADD tests/test_template.yml.tpl /tmp/test_template.yml
ADD tests/test_template.yml.tpl /tmp/test_template2.yml.tpl
COPY pyproject.toml poetry.lock /opt/
RUN cd /opt && poetry install
WORKDIR /opt/tests
CMD ["pytest", "--verbose", "-rw", "."]

@ -1,8 +1,10 @@
# Testing with python 2 # Testing with python 3.7
FROM python:2 FROM python:3.7
ENV POETRY_VIRTUALENVS_CREATE=false
RUN pip install pytest six pyyaml jinja2 colorlog watchdog pytest-mock
RUN pip install poetry
RUN adduser --uid 1009 --system testuser RUN adduser --uid 1009 --system testuser
RUN addgroup --gid 1010 testgroup RUN addgroup --gid 1010 testgroup
@ -11,7 +13,11 @@ ENV PYTHONPATH /opt/
ADD tests/test_template.yml.tpl /tmp/test_template.yml ADD tests/test_template.yml.tpl /tmp/test_template.yml
ADD tests/test_template.yml.tpl /tmp/test_template2.yml.tpl ADD tests/test_template.yml.tpl /tmp/test_template2.yml.tpl
COPY pyproject.toml poetry.lock /opt/
RUN cd /opt && poetry install
WORKDIR /opt/tests WORKDIR /opt/tests
CMD ["py.test", "--verbose", "-rw", "."] CMD ["pytest", "--verbose", "-rw", "."]

@ -0,0 +1,22 @@
# Testing with python 3.8
FROM python:3.8
ENV POETRY_VIRTUALENVS_CREATE=false
RUN pip install poetry
RUN adduser --uid 1009 --system testuser
RUN addgroup --gid 1010 testgroup
ENV PYTHONPATH /opt/
COPY tests/test_template.yml.tpl /tmp/test_template.yml
COPY tests/test_template.yml.tpl /tmp/test_template2.yml.tpl
COPY pyproject.toml poetry.lock /opt/
RUN cd /opt && poetry install
WORKDIR /opt/tests
CMD ["pytest", "--verbose", "-rw", "."]

@ -1,12 +0,0 @@
FROM python:2
ADD . /tmp/
RUN cd /tmp && \
pip install --upgrade pip && \
python setup.py install && \
rm -rf *
ONBUILD ADD entrypoint-config.yml .
ENTRYPOINT ["pyentrypoint"]

@ -1,12 +0,0 @@
FROM python:2-alpine
ADD . /tmp/
RUN cd /tmp && \
pip install --upgrade pip && \
python setup.py install && \
rm -rf *
ONBUILD ADD entrypoint-config.yml .
ENTRYPOINT ["pyentrypoint"]

@ -1,10 +1,12 @@
FROM python:3 FROM python:3
ENV POETRY_VIRTUALENVS_CREATE=false
ADD . /tmp/ ADD . /tmp/
RUN cd /tmp && \ RUN cd /tmp && \
pip install --upgrade pip && \ pip install --upgrade pip poetry && \
python setup.py install && \ poetry install --no-dev && \
rm -rf * rm -rf *
ONBUILD ADD entrypoint-config.yml . ONBUILD ADD entrypoint-config.yml .

@ -1,10 +1,12 @@
FROM python:3-alpine FROM python:3-alpine
ENV POETRY_VIRTUALENVS_CREATE=false
ADD . /tmp/ ADD . /tmp/
RUN cd /tmp && \ RUN cd /tmp && \
pip install --upgrade pip && \ pip install --upgrade pip poetry && \
python setup.py install && \ poetry install --no-dev && \
rm -rf * rm -rf *
ONBUILD ADD entrypoint-config.yml . ONBUILD ADD entrypoint-config.yml .

@ -0,0 +1,14 @@
FROM python:3.6
ENV POETRY_VIRTUALENVS_CREATE=false
ADD . /tmp/
RUN cd /tmp && \
pip install --upgrade pip poetry && \
poetry install --no-dev && \
rm -rf *
ONBUILD ADD entrypoint-config.yml .
ENTRYPOINT ["pyentrypoint"]

@ -0,0 +1,14 @@
FROM python:3.6-alpine
ENV POETRY_VIRTUALENVS_CREATE=false
ADD . /tmp/
RUN cd /tmp && \
pip install --upgrade pip poetry && \
poetry install --no-dev && \
rm -rf *
ONBUILD ADD entrypoint-config.yml .
ENTRYPOINT ["pyentrypoint"]

@ -0,0 +1,14 @@
FROM python:3.7
ENV POETRY_VIRTUALENVS_CREATE=false
ADD . /tmp/
RUN cd /tmp && \
pip install --upgrade pip poetry && \
poetry install --no-dev && \
rm -rf *
ONBUILD ADD entrypoint-config.yml .
ENTRYPOINT ["pyentrypoint"]

@ -0,0 +1,14 @@
FROM python:3.7-alpine
ENV POETRY_VIRTUALENVS_CREATE=false
ADD . /tmp/
RUN cd /tmp && \
pip install --upgrade pip poetry && \
poetry install --no-dev && \
rm -rf *
ONBUILD ADD entrypoint-config.yml .
ENTRYPOINT ["pyentrypoint"]

@ -0,0 +1,14 @@
FROM python:3.8
ENV POETRY_VIRTUALENVS_CREATE=false
ADD . /tmp/
RUN cd /tmp && \
pip install --upgrade pip poetry && \
poetry install --no-dev && \
rm -rf *
ONBUILD ADD entrypoint-config.yml .
ENTRYPOINT ["pyentrypoint"]

@ -0,0 +1,14 @@
FROM python:3.8-alpine
ENV POETRY_VIRTUALENVS_CREATE=false
ADD . /tmp/
RUN cd /tmp && \
pip install --upgrade pip poetry && \
poetry install --no-dev && \
rm -rf *
ONBUILD ADD entrypoint-config.yml .
ENTRYPOINT ["pyentrypoint"]

@ -1,2 +1 @@
include README.md include README.md

@ -6,17 +6,20 @@ build:
clean: clean:
docker-compose down --remove-orphans docker-compose down --remove-orphans
test: build test-python2 test-python3 clean test: build test-python3.6 test-python3.7 test-python3.8 clean
test-python2: test-python3.6:
@docker-compose run --rm testpython2 @docker-compose run --rm testpython3.6
test-python3.7:
@docker-compose run --rm testpython3.7
test-python3.8:
@docker-compose run --rm testpython3.8
test-python3: test-python3:
@docker-compose run --rm testpython3 @docker-compose run --rm testpython3
test_debug: build
@docker-compose up --force-recreate testpython2_debug testpython3_debug
publish: publish:
@python setup.py register && python setup.py sdist upload @python setup.py register && python setup.py sdist upload

@ -11,6 +11,13 @@ This tool avoids writing shell scripts to:
[![Documentation Status](https://readthedocs.org/projects/pyentrypoint/badge/?version=latest)](http://pyentrypoint.readthedocs.io/en/latest/?badge=latest) [![Build Status](https://travis-ci.org/cmehay/pyentrypoint.svg?branch=master)](https://travis-ci.org/cmehay/pyentrypoint) [![Documentation Status](https://readthedocs.org/projects/pyentrypoint/badge/?version=latest)](http://pyentrypoint.readthedocs.io/en/latest/?badge=latest) [![Build Status](https://travis-ci.org/cmehay/pyentrypoint.svg?branch=master)](https://travis-ci.org/cmehay/pyentrypoint)
## Changelog
* V0.6.0 (2020-05-10)
* Drop python 2 support
* Deprecation of `command` and `subcommands` settings for `commands` (see bellow)
## Usages ## Usages
### Install in container ### Install in container
@ -56,10 +63,17 @@ FROM goldy/pyentrypoint:python3
Available with many flavours: Available with many flavours:
- `goldy/pyentrypoint:python2`
- `goldy/pyentrypoint:python3` - `goldy/pyentrypoint:python3`
- `goldy/pyentrypoint:python2-alpine` - `goldy/pyentrypoint:python3.6`
- `goldy/pyentrypoint:python3.7`
- `goldy/pyentrypoint:python3.8`
- `goldy/pyentrypoint:python3-alpine` - `goldy/pyentrypoint:python3-alpine`
- `goldy/pyentrypoint:python3.6-alpine`
- `goldy/pyentrypoint:python3.7-alpine`
- `goldy/pyentrypoint:python3.8-alpine`
### Working examples ### Working examples
- [Tor hidden service](https://github.com/cmehay/docker-tor-hidden-service) - [Tor hidden service](https://github.com/cmehay/docker-tor-hidden-service)
@ -71,12 +85,26 @@ This is an example of `entrypoint-config.yml` file.
```yaml ```yaml
# Entrypoint configuration example # Entrypoint configuration example
# This entry list commands handled by entrypoint.
# If you run the container with a command not in this list,
# pyentrypoint will run the command directly without any action
# If this option and `command` are not set, all commands will be handled.
# Support wildcard
commands:
- git
- sl*
# DEPRECATED: This option is remplaced by `commands`
# This entry should reflect CMD in Dockerfile # This entry should reflect CMD in Dockerfile
# If `commands` is present, this option will be ignored.
# DEPRECATED: This option is remplaced by `commands`
command: git command: git
# DEPRECATED: This option will be dropped
# This is a list with some subcommands to handle # This is a list with some subcommands to handle
# when CMD is not `git` here. # when CMD is not `git` here.
# By default, all args started with hyphen are handled. # By default, all args started with hyphen are handled.
# DEPRECATED: This option will be dropped
subcommands: subcommands:
- "-*" - "-*"
- clone - clone
@ -91,7 +119,7 @@ subcommands:
user: 1000 user: 1000
group: 1000 group: 1000
# These files should exist (ADD or COPY) # These files should exist (ADD, COPY or mounted)
# and should be jinja templated. # and should be jinja templated.
# Note: if config files end with ".tpl", the extension will be removed. # Note: if config files end with ".tpl", the extension will be removed.
config_files: config_files:

@ -13,9 +13,9 @@ testpython3:
file: common.yml file: common.yml
service: environ service: environ
testpython2: testpython3.6:
build: . build: .
dockerfile: Dockerfile-test.py2 dockerfile: Dockerfile-test.py3.6
volumes: volumes:
- ./pyentrypoint:/opt/pyentrypoint:ro - ./pyentrypoint:/opt/pyentrypoint:ro
- ./tests:/opt/tests - ./tests:/opt/tests
@ -28,9 +28,9 @@ testpython2:
file: common.yml file: common.yml
service: environ service: environ
testpython3_debug: testpython3.7:
build: . build: .
dockerfile: Dockerfile-test.py3 dockerfile: Dockerfile-test.py3.7
volumes: volumes:
- ./pyentrypoint:/opt/pyentrypoint:ro - ./pyentrypoint:/opt/pyentrypoint:ro
- ./tests:/opt/tests - ./tests:/opt/tests
@ -39,14 +39,13 @@ testpython3_debug:
- test2 - test2
- test3 - test3
- test4 - test4
command: ["py.test", "--verbose", "-s", "-rw", "."]
extends: extends:
file: common.yml file: common.yml
service: environ service: environ
testpython2_debug: testpython3.8:
build: . build: .
dockerfile: Dockerfile-test.py2 dockerfile: Dockerfile-test.py3.8
volumes: volumes:
- ./pyentrypoint:/opt/pyentrypoint:ro - ./pyentrypoint:/opt/pyentrypoint:ro
- ./tests:/opt/tests - ./tests:/opt/tests
@ -55,7 +54,6 @@ testpython2_debug:
- test2 - test2
- test3 - test3
- test4 - test4
command: ["py.test", "--verbose", "-s", "-rw", "."]
extends: extends:
file: common.yml file: common.yml
service: environ service: environ

@ -15,9 +15,10 @@
import os import os
import sys import sys
from setup import __version__
sys.path.insert(0, os.path.abspath('..')) sys.path.insert(0, os.path.abspath('..'))
from setup import __version__
# If extensions (or modules to document with autodoc) are in another directory, # If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the # add these directories to sys.path here. If the directory is relative to the

@ -7,12 +7,26 @@ This is an example of ``entrypoint-config.yml`` file.
# Entrypoint configuration example # Entrypoint configuration example
# This entry list commands handled by entrypoint.
# If you run the container with a command not in this list,
# pyentrypoint will run the command directly without any action
# If this option and `command` are not set, all commands will be handled.
# Support wildcard
commands:
- git
- sl*
# DEPRECATED: This option is remplaced by `commands`
# This entry should reflect CMD in Dockerfile # This entry should reflect CMD in Dockerfile
# If `commands` is present, this option will be ignored.
# DEPRECATED: This option is remplaced by `commands`
command: git command: git
# DEPRECATED: This option will be dropped
# This is a list with some subcommands to handle # This is a list with some subcommands to handle
# when CMD is not `git` here. # when CMD is not `git` here.
# By default, all args started with hyphen are handled. # By default, all args started with hyphen are handled.
# DEPRECATED: This option will be dropped
subcommands: subcommands:
- "-*" - "-*"
- clone - clone

@ -1,16 +1,31 @@
# Entrypoint configuration example # Entrypoint configuration example
# This entry list commands handled by entrypoint.
# If you run the container with a command not in this list,
# pyentrypoint will run the command directly without any action
# If this option is not set, all commands will be handled.
# Support wildcard
commands:
- git
- l*
# DEPRECATED: This option is remplaced by `commands`
# This entry should reflect CMD in Dockerfile # This entry should reflect CMD in Dockerfile
command: git # If `commands` is present, this option will be ignored.
# DEPRECATED: This option is remplaced by `commands`
# command: git
# DEPRECATED: This option will be dropped
# This is a list with some subcommands to handle # This is a list with some subcommands to handle
# when CMD is not `git` here. # when CMD is not `git` here.
# By default, all args started with hyphen are handled. # By default, all args started with hyphen are handled.
subcommands: # DEPRECATED: This option will be dropped
- "-*" # subcommands:
- clone # - "-*"
- init # - clone
- ls-files # - init
# - ls-files
# etc... # etc...
# User and group to run the cmd. # User and group to run the cmd.
@ -33,9 +48,11 @@ secret_env:
- SSHKEY - SSHKEY
- '*' # Support globbing, all environment will be wiped - '*' # Support globbing, all environment will be wiped
# DEPRECATED: Links are deprecated in `docker`
# Links are handled here # Links are handled here
# Port, name, protocol or env variable can be used to identify the links # Port, name, protocol or env variable can be used to identify the links
# Raise an error if the link could not be identified # Raise an error if the link could not be identified
# DEPRECATED: Links are deprecated in `docker`
links: links:
'ssh': 'ssh':
port: 22 port: 22

992
poetry.lock generated

@ -0,0 +1,992 @@
[[package]]
category = "dev"
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
name = "appdirs"
optional = false
python-versions = "*"
version = "1.4.3"
[[package]]
category = "dev"
description = "Atomic file writes."
marker = "sys_platform == \"win32\""
name = "atomicwrites"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "1.4.0"
[[package]]
category = "dev"
description = "Classes Without Boilerplate"
name = "attrs"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "19.3.0"
[package.extras]
azure-pipelines = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "pytest-azurepipelines"]
dev = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "pre-commit"]
docs = ["sphinx", "zope.interface"]
tests = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"]
[[package]]
category = "dev"
description = "Modern password hashing for your software and your servers"
name = "bcrypt"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "3.1.7"
[package.dependencies]
cffi = ">=1.1"
six = ">=1.4.1"
[package.extras]
tests = ["pytest (>=3.2.1,<3.3.0 || >3.3.0)"]
[[package]]
category = "dev"
description = "A decorator for caching properties in classes."
name = "cached-property"
optional = false
python-versions = "*"
version = "1.5.1"
[[package]]
category = "dev"
description = "Python package for providing Mozilla's CA Bundle."
name = "certifi"
optional = false
python-versions = "*"
version = "2020.4.5.1"
[[package]]
category = "dev"
description = "Foreign Function Interface for Python calling C code."
name = "cffi"
optional = false
python-versions = "*"
version = "1.14.0"
[package.dependencies]
pycparser = "*"
[[package]]
category = "dev"
description = "Validate configuration and produce human readable error messages."
name = "cfgv"
optional = false
python-versions = ">=3.6.1"
version = "3.1.0"
[[package]]
category = "dev"
description = "Universal encoding detector for Python 2 and 3"
name = "chardet"
optional = false
python-versions = "*"
version = "3.0.4"
[[package]]
category = "main"
description = "Cross-platform colored terminal text."
marker = "sys_platform == \"win32\""
name = "colorama"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
version = "0.4.3"
[[package]]
category = "main"
description = "Log formatting with colors!"
name = "colorlog"
optional = false
python-versions = "*"
version = "4.1.0"
[package.dependencies]
colorama = "*"
[[package]]
category = "dev"
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
name = "cryptography"
optional = false
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*"
version = "2.9.2"
[package.dependencies]
cffi = ">=1.8,<1.11.3 || >1.11.3"
six = ">=1.4.1"
[package.extras]
docs = ["sphinx (>=1.6.5,<1.8.0 || >1.8.0)", "sphinx-rtd-theme"]
docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"]
idna = ["idna (>=2.1)"]
pep8test = ["flake8", "flake8-import-order", "pep8-naming"]
test = ["pytest (>=3.6.0,<3.9.0 || >3.9.0,<3.9.1 || >3.9.1,<3.9.2 || >3.9.2)", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,<3.79.2 || >3.79.2)"]
[[package]]
category = "dev"
description = "Distribution utilities"
name = "distlib"
optional = false
python-versions = "*"
version = "0.3.0"
[[package]]
category = "dev"
description = "A Python library for the Docker Engine API."
name = "docker"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
version = "4.2.0"
[package.dependencies]
requests = ">=2.14.2,<2.18.0 || >2.18.0"
six = ">=1.4.0"
websocket-client = ">=0.32.0"
[package.dependencies.paramiko]
optional = true
version = ">=2.4.2"
[package.dependencies.pypiwin32]
python = ">=3.6"
version = "223"
[package.extras]
ssh = ["paramiko (>=2.4.2)"]
tls = ["pyOpenSSL (>=17.5.0)", "cryptography (>=1.3.4)", "idna (>=2.0.0)"]
[[package]]
category = "dev"
description = "Multi-container orchestration for Docker"
name = "docker-compose"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "1.25.5"
[package.dependencies]
PyYAML = ">=3.10,<6"
cached-property = ">=1.2.0,<2"
colorama = ">=0.4,<1"
dockerpty = ">=0.4.1,<1"
docopt = ">=0.6.1,<1"
jsonschema = ">=2.5.1,<4"
requests = ">=2.20.0,<3"
six = ">=1.3.0,<2"
texttable = ">=0.9.0,<2"
websocket-client = ">=0.32.0,<1"
[package.dependencies.docker]
extras = ["ssh"]
version = ">=3.7.0,<5"
[package.extras]
socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2)"]
[[package]]
category = "dev"
description = "Python library to use the pseudo-tty of a docker container"
name = "dockerpty"
optional = false
python-versions = "*"
version = "0.4.1"
[package.dependencies]
six = ">=1.3.0"
[[package]]
category = "dev"
description = "Pythonic argument parser, that will make you smile"
name = "docopt"
optional = false
python-versions = "*"
version = "0.6.2"
[[package]]
category = "dev"
description = "A platform independent file lock."
name = "filelock"
optional = false
python-versions = "*"
version = "3.0.12"
[[package]]
category = "dev"
description = "File identification library for Python"
name = "identify"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
version = "1.4.15"
[package.extras]
license = ["editdistance"]
[[package]]
category = "dev"
description = "Internationalized Domain Names in Applications (IDNA)"
name = "idna"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "2.9"
[[package]]
category = "dev"
description = "Read metadata from Python packages"
marker = "python_version < \"3.8\""
name = "importlib-metadata"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
version = "1.6.0"
[package.dependencies]
zipp = ">=0.5"
[package.extras]
docs = ["sphinx", "rst.linker"]
testing = ["packaging", "importlib-resources"]
[[package]]
category = "dev"
description = "Read resources from Python packages"
marker = "python_version < \"3.7\""
name = "importlib-resources"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
version = "1.5.0"
[package.dependencies]
[package.dependencies.importlib-metadata]
python = "<3.8"
version = "*"
[package.dependencies.zipp]
python = "<3.8"
version = ">=0.4"
[package.extras]
docs = ["sphinx", "rst.linker", "jaraco.packaging"]
[[package]]
category = "main"
description = "A very fast and expressive template engine."
name = "jinja2"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
version = "2.11.2"
[package.dependencies]
MarkupSafe = ">=0.23"
[package.extras]
i18n = ["Babel (>=0.8)"]
[[package]]
category = "dev"
description = "An implementation of JSON Schema validation for Python"
name = "jsonschema"
optional = false
python-versions = "*"
version = "3.2.0"
[package.dependencies]
attrs = ">=17.4.0"
pyrsistent = ">=0.14.0"
setuptools = "*"
six = ">=1.11.0"
[package.dependencies.importlib-metadata]
python = "<3.8"
version = "*"
[package.extras]
format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"]
format_nongpl = ["idna", "jsonpointer (>1.13)", "webcolors", "rfc3986-validator (>0.1.0)", "rfc3339-validator"]
[[package]]
category = "main"
description = "Safely add untrusted strings to HTML/XML markup."
name = "markupsafe"
optional = false
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
version = "1.1.1"
[[package]]
category = "dev"
description = "More routines for operating on iterables, beyond itertools"
name = "more-itertools"
optional = false
python-versions = ">=3.5"
version = "8.2.0"
[[package]]
category = "dev"
description = "Node.js virtual environment builder"
name = "nodeenv"
optional = false
python-versions = "*"
version = "1.3.5"
[[package]]
category = "dev"
description = "Core utilities for Python packages"
name = "packaging"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "20.3"
[package.dependencies]
pyparsing = ">=2.0.2"
six = "*"
[[package]]
category = "dev"
description = "SSH2 protocol library"
name = "paramiko"
optional = false
python-versions = "*"
version = "2.7.1"
[package.dependencies]
bcrypt = ">=3.1.3"
cryptography = ">=2.5"
pynacl = ">=1.0.1"
[package.extras]
all = ["pyasn1 (>=0.1.7)", "pynacl (>=1.0.1)", "bcrypt (>=3.1.3)", "invoke (>=1.3)", "gssapi (>=1.4.1)", "pywin32 (>=2.1.8)"]
ed25519 = ["pynacl (>=1.0.1)", "bcrypt (>=3.1.3)"]
gssapi = ["pyasn1 (>=0.1.7)", "gssapi (>=1.4.1)", "pywin32 (>=2.1.8)"]
invoke = ["invoke (>=1.3)"]
[[package]]
category = "main"
description = "File system general utilities"
name = "pathtools"
optional = false
python-versions = "*"
version = "0.1.2"
[[package]]
category = "dev"
description = "plugin and hook calling mechanisms for python"
name = "pluggy"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "0.13.1"
[package.dependencies]
[package.dependencies.importlib-metadata]
python = "<3.8"
version = ">=0.12"
[package.extras]
dev = ["pre-commit", "tox"]
[[package]]
category = "dev"
description = "A framework for managing and maintaining multi-language pre-commit hooks."
name = "pre-commit"
optional = false
python-versions = ">=3.6.1"
version = "2.3.0"
[package.dependencies]
cfgv = ">=2.0.0"
identify = ">=1.0.0"
nodeenv = ">=0.11.1"
pyyaml = ">=5.1"
toml = "*"
virtualenv = ">=15.2"
[package.dependencies.importlib-metadata]
python = "<3.8"
version = "*"
[package.dependencies.importlib-resources]
python = "<3.7"
version = "*"
[[package]]
category = "dev"
description = "library with cross-python path, ini-parsing, io, code, log facilities"
name = "py"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "1.8.1"
[[package]]
category = "dev"
description = "C parser in Python"
name = "pycparser"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "2.20"
[[package]]
category = "dev"
description = "Python binding to the Networking and Cryptography (NaCl) library"
name = "pynacl"
optional = false
python-versions = "*"
version = "1.3.0"
[package.dependencies]
cffi = ">=1.4.1"
six = "*"
[package.extras]
docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"]
tests = ["pytest (>=3.2.1,<3.3.0 || >3.3.0)", "hypothesis (>=3.27.0)"]
[[package]]
category = "dev"
description = "Python parsing module"
name = "pyparsing"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
version = "2.4.7"
[[package]]
category = "dev"
description = ""
marker = "sys_platform == \"win32\" and python_version >= \"3.6\""
name = "pypiwin32"
optional = false
python-versions = "*"
version = "223"
[package.dependencies]
pywin32 = ">=223"
[[package]]
category = "dev"
description = "Persistent/Functional/Immutable data structures"
name = "pyrsistent"
optional = false
python-versions = "*"
version = "0.16.0"
[package.dependencies]
six = "*"
[[package]]
category = "dev"
description = "pytest: simple powerful testing with Python"
name = "pytest"
optional = false
python-versions = ">=3.5"
version = "5.4.2"
[package.dependencies]
atomicwrites = ">=1.0"
attrs = ">=17.4.0"
colorama = "*"
more-itertools = ">=4.0.0"
packaging = "*"
pluggy = ">=0.12,<1.0"
py = ">=1.5.0"
wcwidth = "*"
[package.dependencies.importlib-metadata]
python = "<3.8"
version = ">=0.12"
[package.extras]
checkqa-mypy = ["mypy (v0.761)"]
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
[[package]]
category = "dev"
description = "Thin-wrapper around the mock package for easier use with pytest"
name = "pytest-mock"
optional = false
python-versions = ">=3.5"
version = "3.1.0"
[package.dependencies]
pytest = ">=2.7"
[package.extras]
dev = ["pre-commit", "tox", "pytest-asyncio"]
[[package]]
category = "dev"
description = "Python for Window Extensions"
marker = "sys_platform == \"win32\" and python_version >= \"3.6\""
name = "pywin32"
optional = false
python-versions = "*"
version = "227"
[[package]]
category = "main"
description = "YAML parser and emitter for Python"
name = "pyyaml"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
version = "5.3.1"
[[package]]
category = "dev"
description = "Python HTTP for Humans."
name = "requests"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
version = "2.23.0"
[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 || >1.5.7)", "win-inet-pton"]
[[package]]
category = "main"
description = "Python 2 and 3 compatibility utilities"
name = "six"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
version = "1.14.0"
[[package]]
category = "dev"
description = "module for creating simple ASCII tables"
name = "texttable"
optional = false
python-versions = "*"
version = "1.6.2"
[[package]]
category = "dev"
description = "Python Library for Tom's Obvious, Minimal Language"
name = "toml"
optional = false
python-versions = "*"
version = "0.10.0"
[[package]]
category = "dev"
description = "HTTP library with thread-safe connection pooling, file post, and more."
name = "urllib3"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
version = "1.25.9"
[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 || >1.5.7,<2.0)"]
[[package]]
category = "dev"
description = "Virtual Python Environment builder"
name = "virtualenv"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
version = "20.0.20"
[package.dependencies]
appdirs = ">=1.4.3,<2"
distlib = ">=0.3.0,<1"
filelock = ">=3.0.0,<4"
six = ">=1.9.0,<2"
[package.dependencies.importlib-metadata]
python = "<3.8"
version = ">=0.12,<2"
[package.dependencies.importlib-resources]
python = "<3.7"
version = ">=1.0,<2"
[package.extras]
docs = ["sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)", "proselint (>=0.10.2)"]
testing = ["pytest (>=4)", "coverage (>=5)", "coverage-enable-subprocess (>=1)", "pytest-xdist (>=1.31.0)", "pytest-mock (>=2)", "pytest-env (>=0.6.2)", "pytest-randomly (>=1)", "pytest-timeout", "packaging (>=20.0)", "xonsh (>=0.9.16)"]
[[package]]
category = "main"
description = "Filesystem events monitoring"
name = "watchdog"
optional = false
python-versions = "*"
version = "0.10.2"
[package.dependencies]
pathtools = ">=0.1.1"
[package.extras]
watchmedo = ["PyYAML (>=3.10)", "argh (>=0.24.1)"]
[[package]]
category = "dev"
description = "Measures number of Terminal column cells of wide-character codes"
name = "wcwidth"
optional = false
python-versions = "*"
version = "0.1.9"
[[package]]
category = "dev"
description = "WebSocket client for Python. hybi13 is supported."
name = "websocket-client"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "0.57.0"
[package.dependencies]
six = "*"
[[package]]
category = "dev"
description = "Backport of pathlib-compatible object wrapper for zip files"
marker = "python_version < \"3.8\""
name = "zipp"
optional = false
python-versions = ">=3.6"
version = "3.1.0"
[package.extras]
docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
testing = ["jaraco.itertools", "func-timeout"]
[metadata]
content-hash = "d5b4ce6c6aa76b713725b2fb9726798fffff606425e3434a1511ab75afe6dd56"
python-versions = "^3.6.1"
[metadata.files]
appdirs = [
{file = "appdirs-1.4.3-py2.py3-none-any.whl", hash = "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"},
{file = "appdirs-1.4.3.tar.gz", hash = "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92"},
]
atomicwrites = [
{file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
{file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
]
attrs = [
{file = "attrs-19.3.0-py2.py3-none-any.whl", hash = "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c"},
{file = "attrs-19.3.0.tar.gz", hash = "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"},
]
bcrypt = [
{file = "bcrypt-3.1.7-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:d7bdc26475679dd073ba0ed2766445bb5b20ca4793ca0db32b399dccc6bc84b7"},
{file = "bcrypt-3.1.7-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:69361315039878c0680be456640f8705d76cb4a3a3fe1e057e0f261b74be4b31"},
{file = "bcrypt-3.1.7-cp27-cp27m-win32.whl", hash = "sha256:5432dd7b34107ae8ed6c10a71b4397f1c853bd39a4d6ffa7e35f40584cffd161"},
{file = "bcrypt-3.1.7-cp27-cp27m-win_amd64.whl", hash = "sha256:9fe92406c857409b70a38729dbdf6578caf9228de0aef5bc44f859ffe971a39e"},
{file = "bcrypt-3.1.7-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:763669a367869786bb4c8fcf731f4175775a5b43f070f50f46f0b59da45375d0"},
{file = "bcrypt-3.1.7-cp34-abi3-macosx_10_6_intel.whl", hash = "sha256:a190f2a5dbbdbff4b74e3103cef44344bc30e61255beb27310e2aec407766052"},
{file = "bcrypt-3.1.7-cp34-abi3-manylinux1_x86_64.whl", hash = "sha256:c9457fa5c121e94a58d6505cadca8bed1c64444b83b3204928a866ca2e599105"},
{file = "bcrypt-3.1.7-cp34-cp34m-win32.whl", hash = "sha256:8b10acde4e1919d6015e1df86d4c217d3b5b01bb7744c36113ea43d529e1c3de"},
{file = "bcrypt-3.1.7-cp34-cp34m-win_amd64.whl", hash = "sha256:cb93f6b2ab0f6853550b74e051d297c27a638719753eb9ff66d1e4072be67133"},
{file = "bcrypt-3.1.7-cp35-cp35m-win32.whl", hash = "sha256:6fe49a60b25b584e2f4ef175b29d3a83ba63b3a4df1b4c0605b826668d1b6be5"},
{file = "bcrypt-3.1.7-cp35-cp35m-win_amd64.whl", hash = "sha256:a595c12c618119255c90deb4b046e1ca3bcfad64667c43d1166f2b04bc72db09"},
{file = "bcrypt-3.1.7-cp36-cp36m-win32.whl", hash = "sha256:74a015102e877d0ccd02cdeaa18b32aa7273746914a6c5d0456dd442cb65b99c"},
{file = "bcrypt-3.1.7-cp36-cp36m-win_amd64.whl", hash = "sha256:0258f143f3de96b7c14f762c770f5fc56ccd72f8a1857a451c1cd9a655d9ac89"},
{file = "bcrypt-3.1.7-cp37-cp37m-win32.whl", hash = "sha256:19a4b72a6ae5bb467fea018b825f0a7d917789bcfe893e53f15c92805d187294"},
{file = "bcrypt-3.1.7-cp37-cp37m-win_amd64.whl", hash = "sha256:ff032765bb8716d9387fd5376d987a937254b0619eff0972779515b5c98820bc"},
{file = "bcrypt-3.1.7-cp38-cp38-win32.whl", hash = "sha256:ce4e4f0deb51d38b1611a27f330426154f2980e66582dc5f438aad38b5f24fc1"},
{file = "bcrypt-3.1.7-cp38-cp38-win_amd64.whl", hash = "sha256:6305557019906466fc42dbc53b46da004e72fd7a551c044a827e572c82191752"},
{file = "bcrypt-3.1.7.tar.gz", hash = "sha256:0b0069c752ec14172c5f78208f1863d7ad6755a6fae6fe76ec2c80d13be41e42"},
]
cached-property = [
{file = "cached-property-1.5.1.tar.gz", hash = "sha256:9217a59f14a5682da7c4b8829deadbfc194ac22e9908ccf7c8820234e80a1504"},
{file = "cached_property-1.5.1-py2.py3-none-any.whl", hash = "sha256:3a026f1a54135677e7da5ce819b0c690f156f37976f3e30c5430740725203d7f"},
]
certifi = [
{file = "certifi-2020.4.5.1-py2.py3-none-any.whl", hash = "sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304"},
{file = "certifi-2020.4.5.1.tar.gz", hash = "sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519"},
]
cffi = [
{file = "cffi-1.14.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1cae98a7054b5c9391eb3249b86e0e99ab1e02bb0cc0575da191aedadbdf4384"},
{file = "cffi-1.14.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:cf16e3cf6c0a5fdd9bc10c21687e19d29ad1fe863372b5543deaec1039581a30"},
{file = "cffi-1.14.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:f2b0fa0c01d8a0c7483afd9f31d7ecf2d71760ca24499c8697aeb5ca37dc090c"},
{file = "cffi-1.14.0-cp27-cp27m-win32.whl", hash = "sha256:99f748a7e71ff382613b4e1acc0ac83bf7ad167fb3802e35e90d9763daba4d78"},
{file = "cffi-1.14.0-cp27-cp27m-win_amd64.whl", hash = "sha256:c420917b188a5582a56d8b93bdd8e0f6eca08c84ff623a4c16e809152cd35793"},
{file = "cffi-1.14.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:399aed636c7d3749bbed55bc907c3288cb43c65c4389964ad5ff849b6370603e"},
{file = "cffi-1.14.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:cab50b8c2250b46fe738c77dbd25ce017d5e6fb35d3407606e7a4180656a5a6a"},
{file = "cffi-1.14.0-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:001bf3242a1bb04d985d63e138230802c6c8d4db3668fb545fb5005ddf5bb5ff"},
{file = "cffi-1.14.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:e56c744aa6ff427a607763346e4170629caf7e48ead6921745986db3692f987f"},
{file = "cffi-1.14.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b8c78301cefcf5fd914aad35d3c04c2b21ce8629b5e4f4e45ae6812e461910fa"},
{file = "cffi-1.14.0-cp35-cp35m-win32.whl", hash = "sha256:8c0ffc886aea5df6a1762d0019e9cb05f825d0eec1f520c51be9d198701daee5"},
{file = "cffi-1.14.0-cp35-cp35m-win_amd64.whl", hash = "sha256:8a6c688fefb4e1cd56feb6c511984a6c4f7ec7d2a1ff31a10254f3c817054ae4"},
{file = "cffi-1.14.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:95cd16d3dee553f882540c1ffe331d085c9e629499ceadfbda4d4fde635f4b7d"},
{file = "cffi-1.14.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:66e41db66b47d0d8672d8ed2708ba91b2f2524ece3dee48b5dfb36be8c2f21dc"},
{file = "cffi-1.14.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:028a579fc9aed3af38f4892bdcc7390508adabc30c6af4a6e4f611b0c680e6ac"},
{file = "cffi-1.14.0-cp36-cp36m-win32.whl", hash = "sha256:cef128cb4d5e0b3493f058f10ce32365972c554572ff821e175dbc6f8ff6924f"},
{file = "cffi-1.14.0-cp36-cp36m-win_amd64.whl", hash = "sha256:337d448e5a725bba2d8293c48d9353fc68d0e9e4088d62a9571def317797522b"},
{file = "cffi-1.14.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e577934fc5f8779c554639376beeaa5657d54349096ef24abe8c74c5d9c117c3"},
{file = "cffi-1.14.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:62ae9af2d069ea2698bf536dcfe1e4eed9090211dbaafeeedf5cb6c41b352f66"},
{file = "cffi-1.14.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:14491a910663bf9f13ddf2bc8f60562d6bc5315c1f09c704937ef17293fb85b0"},
{file = "cffi-1.14.0-cp37-cp37m-win32.whl", hash = "sha256:c43866529f2f06fe0edc6246eb4faa34f03fe88b64a0a9a942561c8e22f4b71f"},
{file = "cffi-1.14.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2089ed025da3919d2e75a4d963d008330c96751127dd6f73c8dc0c65041b4c26"},
{file = "cffi-1.14.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3b911c2dbd4f423b4c4fcca138cadde747abdb20d196c4a48708b8a2d32b16dd"},
{file = "cffi-1.14.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:7e63cbcf2429a8dbfe48dcc2322d5f2220b77b2e17b7ba023d6166d84655da55"},
{file = "cffi-1.14.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:3d311bcc4a41408cf5854f06ef2c5cab88f9fded37a3b95936c9879c1640d4c2"},
{file = "cffi-1.14.0-cp38-cp38-win32.whl", hash = "sha256:675686925a9fb403edba0114db74e741d8181683dcf216be697d208857e04ca8"},
{file = "cffi-1.14.0-cp38-cp38-win_amd64.whl", hash = "sha256:00789914be39dffba161cfc5be31b55775de5ba2235fe49aa28c148236c4e06b"},
{file = "cffi-1.14.0.tar.gz", hash = "sha256:2d384f4a127a15ba701207f7639d94106693b6cd64173d6c8988e2c25f3ac2b6"},
]
cfgv = [
{file = "cfgv-3.1.0-py2.py3-none-any.whl", hash = "sha256:1ccf53320421aeeb915275a196e23b3b8ae87dea8ac6698b1638001d4a486d53"},
{file = "cfgv-3.1.0.tar.gz", hash = "sha256:c8e8f552ffcc6194f4e18dd4f68d9aef0c0d58ae7e7be8c82bee3c5e9edfa513"},
]
chardet = [
{file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"},
{file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"},
]
colorama = [
{file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"},
{file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"},
]
colorlog = [
{file = "colorlog-4.1.0-py2.py3-none-any.whl", hash = "sha256:732c191ebbe9a353ec160d043d02c64ddef9028de8caae4cfa8bd49b6afed53e"},
{file = "colorlog-4.1.0.tar.gz", hash = "sha256:30aaef5ab2a1873dec5da38fd6ba568fa761c9fa10b40241027fa3edea47f3d2"},
]
cryptography = [
{file = "cryptography-2.9.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:daf54a4b07d67ad437ff239c8a4080cfd1cc7213df57d33c97de7b4738048d5e"},
{file = "cryptography-2.9.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:3b3eba865ea2754738616f87292b7f29448aec342a7c720956f8083d252bf28b"},
{file = "cryptography-2.9.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:c447cf087cf2dbddc1add6987bbe2f767ed5317adb2d08af940db517dd704365"},
{file = "cryptography-2.9.2-cp27-cp27m-win32.whl", hash = "sha256:f118a95c7480f5be0df8afeb9a11bd199aa20afab7a96bcf20409b411a3a85f0"},
{file = "cryptography-2.9.2-cp27-cp27m-win_amd64.whl", hash = "sha256:c4fd17d92e9d55b84707f4fd09992081ba872d1a0c610c109c18e062e06a2e55"},
{file = "cryptography-2.9.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d0d5aeaedd29be304848f1c5059074a740fa9f6f26b84c5b63e8b29e73dfc270"},
{file = "cryptography-2.9.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:1e4014639d3d73fbc5ceff206049c5a9a849cefd106a49fa7aaaa25cc0ce35cf"},
{file = "cryptography-2.9.2-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:96c080ae7118c10fcbe6229ab43eb8b090fccd31a09ef55f83f690d1ef619a1d"},
{file = "cryptography-2.9.2-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:e993468c859d084d5579e2ebee101de8f5a27ce8e2159959b6673b418fd8c785"},
{file = "cryptography-2.9.2-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:88c881dd5a147e08d1bdcf2315c04972381d026cdb803325c03fe2b4a8ed858b"},
{file = "cryptography-2.9.2-cp35-cp35m-win32.whl", hash = "sha256:651448cd2e3a6bc2bb76c3663785133c40d5e1a8c1a9c5429e4354201c6024ae"},
{file = "cryptography-2.9.2-cp35-cp35m-win_amd64.whl", hash = "sha256:726086c17f94747cedbee6efa77e99ae170caebeb1116353c6cf0ab67ea6829b"},
{file = "cryptography-2.9.2-cp36-cp36m-win32.whl", hash = "sha256:091d31c42f444c6f519485ed528d8b451d1a0c7bf30e8ca583a0cac44b8a0df6"},
{file = "cryptography-2.9.2-cp36-cp36m-win_amd64.whl", hash = "sha256:bb1f0281887d89617b4c68e8db9a2c42b9efebf2702a3c5bf70599421a8623e3"},
{file = "cryptography-2.9.2-cp37-cp37m-win32.whl", hash = "sha256:18452582a3c85b96014b45686af264563e3e5d99d226589f057ace56196ec78b"},
{file = "cryptography-2.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:22e91636a51170df0ae4dcbd250d318fd28c9f491c4e50b625a49964b24fe46e"},
{file = "cryptography-2.9.2-cp38-cp38-win32.whl", hash = "sha256:844a76bc04472e5135b909da6aed84360f522ff5dfa47f93e3dd2a0b84a89fa0"},
{file = "cryptography-2.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:1dfa985f62b137909496e7fc182dac687206d8d089dd03eaeb28ae16eec8e7d5"},
{file = "cryptography-2.9.2.tar.gz", hash = "sha256:a0c30272fb4ddda5f5ffc1089d7405b7a71b0b0f51993cb4e5dbb4590b2fc229"},
]
distlib = [
{file = "distlib-0.3.0.zip", hash = "sha256:2e166e231a26b36d6dfe35a48c4464346620f8645ed0ace01ee31822b288de21"},
]
docker = [
{file = "docker-4.2.0-py2.py3-none-any.whl", hash = "sha256:1c2ddb7a047b2599d1faec00889561316c674f7099427b9c51e8cb804114b553"},
{file = "docker-4.2.0.tar.gz", hash = "sha256:ddae66620ab5f4bce769f64bcd7934f880c8abe6aa50986298db56735d0f722e"},
]
docker-compose = [
{file = "docker-compose-1.25.5.tar.gz", hash = "sha256:7a2eb6d8173fdf408e505e6f7d497ac0b777388719542be9e49a0efd477a50c6"},
{file = "docker_compose-1.25.5-py2.py3-none-any.whl", hash = "sha256:9d33520ae976f524968a64226516ec631dce09fba0974ce5366ad403e203eb5d"},
]
dockerpty = [
{file = "dockerpty-0.4.1.tar.gz", hash = "sha256:69a9d69d573a0daa31bcd1c0774eeed5c15c295fe719c61aca550ed1393156ce"},
]
docopt = [
{file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"},
]
filelock = [
{file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"},
{file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"},
]
identify = [
{file = "identify-1.4.15-py2.py3-none-any.whl", hash = "sha256:88ed90632023e52a6495749c6732e61e08ec9f4f04e95484a5c37b9caf40283c"},
{file = "identify-1.4.15.tar.gz", hash = "sha256:23c18d97bb50e05be1a54917ee45cc61d57cb96aedc06aabb2b02331edf0dbf0"},
]
idna = [
{file = "idna-2.9-py2.py3-none-any.whl", hash = "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"},
{file = "idna-2.9.tar.gz", hash = "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb"},
]
importlib-metadata = [
{file = "importlib_metadata-1.6.0-py2.py3-none-any.whl", hash = "sha256:2a688cbaa90e0cc587f1df48bdc97a6eadccdcd9c35fb3f976a09e3b5016d90f"},
{file = "importlib_metadata-1.6.0.tar.gz", hash = "sha256:34513a8a0c4962bc66d35b359558fd8a5e10cd472d37aec5f66858addef32c1e"},
]
importlib-resources = [
{file = "importlib_resources-1.5.0-py2.py3-none-any.whl", hash = "sha256:85dc0b9b325ff78c8bef2e4ff42616094e16b98ebd5e3b50fe7e2f0bbcdcde49"},
{file = "importlib_resources-1.5.0.tar.gz", hash = "sha256:6f87df66833e1942667108628ec48900e02a4ab4ad850e25fbf07cb17cf734ca"},
]
jinja2 = [
{file = "Jinja2-2.11.2-py2.py3-none-any.whl", hash = "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035"},
{file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"},
]
jsonschema = [
{file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"},
{file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"},
]
markupsafe = [
{file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"},
{file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"},
{file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"},
{file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"},
{file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"},
{file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"},
{file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"},
{file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"},
{file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"},
{file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"},
{file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"},
{file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"},
{file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"},
{file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"},
{file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"},
{file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"},
{file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"},
{file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"},
{file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"},
{file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"},
{file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"},
{file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"},
{file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"},
{file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"},
]
more-itertools = [
{file = "more-itertools-8.2.0.tar.gz", hash = "sha256:b1ddb932186d8a6ac451e1d95844b382f55e12686d51ca0c68b6f61f2ab7a507"},
{file = "more_itertools-8.2.0-py3-none-any.whl", hash = "sha256:5dd8bcf33e5f9513ffa06d5ad33d78f31e1931ac9a18f33d37e77a180d393a7c"},
]
nodeenv = [
{file = "nodeenv-1.3.5-py2.py3-none-any.whl", hash = "sha256:5b2438f2e42af54ca968dd1b374d14a1194848955187b0e5e4be1f73813a5212"},
]
packaging = [
{file = "packaging-20.3-py2.py3-none-any.whl", hash = "sha256:82f77b9bee21c1bafbf35a84905d604d5d1223801d639cf3ed140bd651c08752"},
{file = "packaging-20.3.tar.gz", hash = "sha256:3c292b474fda1671ec57d46d739d072bfd495a4f51ad01a055121d81e952b7a3"},
]
paramiko = [
{file = "paramiko-2.7.1-py2.py3-none-any.whl", hash = "sha256:9c980875fa4d2cb751604664e9a2d0f69096643f5be4db1b99599fe114a97b2f"},
{file = "paramiko-2.7.1.tar.gz", hash = "sha256:920492895db8013f6cc0179293147f830b8c7b21fdfc839b6bad760c27459d9f"},
]
pathtools = [
{file = "pathtools-0.1.2.tar.gz", hash = "sha256:7c35c5421a39bb82e58018febd90e3b6e5db34c5443aaaf742b3f33d4655f1c0"},
]
pluggy = [
{file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
{file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
]
pre-commit = [
{file = "pre_commit-2.3.0-py2.py3-none-any.whl", hash = "sha256:979b53dab1af35063a483bfe13b0fcbbf1a2cf8c46b60e0a9a8d08e8269647a1"},
{file = "pre_commit-2.3.0.tar.gz", hash = "sha256:f3e85e68c6d1cbe7828d3471896f1b192cfcf1c4d83bf26e26beeb5941855257"},
]
py = [
{file = "py-1.8.1-py2.py3-none-any.whl", hash = "sha256:c20fdd83a5dbc0af9efd622bee9a5564e278f6380fffcacc43ba6f43db2813b0"},
{file = "py-1.8.1.tar.gz", hash = "sha256:5e27081401262157467ad6e7f851b7aa402c5852dbcb3dae06768434de5752aa"},
]
pycparser = [
{file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"},
{file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"},
]
pynacl = [
{file = "PyNaCl-1.3.0-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:2424c8b9f41aa65bbdbd7a64e73a7450ebb4aa9ddedc6a081e7afcc4c97f7621"},
{file = "PyNaCl-1.3.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:30f36a9c70450c7878053fa1344aca0145fd47d845270b43a7ee9192a051bf39"},
{file = "PyNaCl-1.3.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:05c26f93964373fc0abe332676cb6735f0ecad27711035b9472751faa8521255"},
{file = "PyNaCl-1.3.0-cp27-cp27m-win32.whl", hash = "sha256:a14e499c0f5955dcc3991f785f3f8e2130ed504fa3a7f44009ff458ad6bdd17f"},
{file = "PyNaCl-1.3.0-cp27-cp27m-win_amd64.whl", hash = "sha256:f67814c38162f4deb31f68d590771a29d5ae3b1bd64b75cf232308e5c74777e0"},
{file = "PyNaCl-1.3.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:e2da3c13307eac601f3de04887624939aca8ee3c9488a0bb0eca4fb9401fc6b1"},
{file = "PyNaCl-1.3.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:0d0a8171a68edf51add1e73d2159c4bc19fc0718e79dec51166e940856c2f28e"},
{file = "PyNaCl-1.3.0-cp34-abi3-macosx_10_6_intel.whl", hash = "sha256:4943decfc5b905748f0756fdd99d4f9498d7064815c4cf3643820c9028b711d1"},
{file = "PyNaCl-1.3.0-cp34-abi3-manylinux1_i686.whl", hash = "sha256:5bd61e9b44c543016ce1f6aef48606280e45f892a928ca7068fba30021e9b786"},
{file = "PyNaCl-1.3.0-cp34-abi3-manylinux1_x86_64.whl", hash = "sha256:aabb0c5232910a20eec8563503c153a8e78bbf5459490c49ab31f6adf3f3a415"},
{file = "PyNaCl-1.3.0-cp34-cp34m-win32.whl", hash = "sha256:7d3ce02c0784b7cbcc771a2da6ea51f87e8716004512493a2b69016326301c3b"},
{file = "PyNaCl-1.3.0-cp34-cp34m-win_amd64.whl", hash = "sha256:1c780712b206317a746ace34c209b8c29dbfd841dfbc02aa27f2084dd3db77ae"},
{file = "PyNaCl-1.3.0-cp35-cp35m-win32.whl", hash = "sha256:37aa336a317209f1bb099ad177fef0da45be36a2aa664507c5d72015f956c310"},
{file = "PyNaCl-1.3.0-cp35-cp35m-win_amd64.whl", hash = "sha256:57ef38a65056e7800859e5ba9e6091053cd06e1038983016effaffe0efcd594a"},
{file = "PyNaCl-1.3.0-cp36-cp36m-win32.whl", hash = "sha256:a39f54ccbcd2757d1d63b0ec00a00980c0b382c62865b61a505163943624ab20"},
{file = "PyNaCl-1.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6482d3017a0c0327a49dddc8bd1074cc730d45db2ccb09c3bac1f8f32d1eb61b"},
{file = "PyNaCl-1.3.0-cp37-cp37m-win32.whl", hash = "sha256:2d23c04e8d709444220557ae48ed01f3f1086439f12dbf11976e849a4926db56"},
{file = "PyNaCl-1.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:bd4ecb473a96ad0f90c20acba4f0bf0df91a4e03a1f4dd6a4bdc9ca75aa3a715"},
{file = "PyNaCl-1.3.0-cp38-cp38-win32.whl", hash = "sha256:53126cd91356342dcae7e209f840212a58dcf1177ad52c1d938d428eebc9fee5"},
{file = "PyNaCl-1.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:bf459128feb543cfca16a95f8da31e2e65e4c5257d2f3dfa8c0c1031139c9c92"},
{file = "PyNaCl-1.3.0.tar.gz", hash = "sha256:0c6100edd16fefd1557da078c7a31e7b7d7a52ce39fdca2bec29d4f7b6e7600c"},
]
pyparsing = [
{file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
]
pypiwin32 = [
{file = "pypiwin32-223-py3-none-any.whl", hash = "sha256:67adf399debc1d5d14dffc1ab5acacb800da569754fafdc576b2a039485aa775"},
{file = "pypiwin32-223.tar.gz", hash = "sha256:71be40c1fbd28594214ecaecb58e7aa8b708eabfa0125c8a109ebd51edbd776a"},
]
pyrsistent = [
{file = "pyrsistent-0.16.0.tar.gz", hash = "sha256:28669905fe725965daa16184933676547c5bb40a5153055a8dee2a4bd7933ad3"},
]
pytest = [
{file = "pytest-5.4.2-py3-none-any.whl", hash = "sha256:95c710d0a72d91c13fae35dce195633c929c3792f54125919847fdcdf7caa0d3"},
{file = "pytest-5.4.2.tar.gz", hash = "sha256:eb2b5e935f6a019317e455b6da83dd8650ac9ffd2ee73a7b657a30873d67a698"},
]
pytest-mock = [
{file = "pytest-mock-3.1.0.tar.gz", hash = "sha256:ce610831cedeff5331f4e2fc453a5dd65384303f680ab34bee2c6533855b431c"},
{file = "pytest_mock-3.1.0-py2.py3-none-any.whl", hash = "sha256:997729451dfc36b851a9accf675488c7020beccda15e11c75632ee3d1b1ccd71"},
]
pywin32 = [
{file = "pywin32-227-cp27-cp27m-win32.whl", hash = "sha256:371fcc39416d736401f0274dd64c2302728c9e034808e37381b5e1b22be4a6b0"},
{file = "pywin32-227-cp27-cp27m-win_amd64.whl", hash = "sha256:4cdad3e84191194ea6d0dd1b1b9bdda574ff563177d2adf2b4efec2a244fa116"},
{file = "pywin32-227-cp35-cp35m-win32.whl", hash = "sha256:f4c5be1a293bae0076d93c88f37ee8da68136744588bc5e2be2f299a34ceb7aa"},
{file = "pywin32-227-cp35-cp35m-win_amd64.whl", hash = "sha256:a929a4af626e530383a579431b70e512e736e9588106715215bf685a3ea508d4"},
{file = "pywin32-227-cp36-cp36m-win32.whl", hash = "sha256:300a2db938e98c3e7e2093e4491439e62287d0d493fe07cce110db070b54c0be"},
{file = "pywin32-227-cp36-cp36m-win_amd64.whl", hash = "sha256:9b31e009564fb95db160f154e2aa195ed66bcc4c058ed72850d047141b36f3a2"},
{file = "pywin32-227-cp37-cp37m-win32.whl", hash = "sha256:47a3c7551376a865dd8d095a98deba954a98f326c6fe3c72d8726ca6e6b15507"},
{file = "pywin32-227-cp37-cp37m-win_amd64.whl", hash = "sha256:31f88a89139cb2adc40f8f0e65ee56a8c585f629974f9e07622ba80199057511"},
{file = "pywin32-227-cp38-cp38-win32.whl", hash = "sha256:7f18199fbf29ca99dff10e1f09451582ae9e372a892ff03a28528a24d55875bc"},
{file = "pywin32-227-cp38-cp38-win_amd64.whl", hash = "sha256:7c1ae32c489dc012930787f06244426f8356e129184a02c25aef163917ce158e"},
{file = "pywin32-227-cp39-cp39-win32.whl", hash = "sha256:c054c52ba46e7eb6b7d7dfae4dbd987a1bb48ee86debe3f245a2884ece46e295"},
{file = "pywin32-227-cp39-cp39-win_amd64.whl", hash = "sha256:f27cec5e7f588c3d1051651830ecc00294f90728d19c3bf6916e6dba93ea357c"},
]
pyyaml = [
{file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"},
{file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"},
{file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"},
{file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"},
{file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"},
{file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"},
{file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"},
{file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"},
{file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"},
{file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"},
{file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"},
]
requests = [
{file = "requests-2.23.0-py2.py3-none-any.whl", hash = "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee"},
{file = "requests-2.23.0.tar.gz", hash = "sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6"},
]
six = [
{file = "six-1.14.0-py2.py3-none-any.whl", hash = "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"},
{file = "six-1.14.0.tar.gz", hash = "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a"},
]
texttable = [
{file = "texttable-1.6.2-py2.py3-none-any.whl", hash = "sha256:7dc282a5b22564fe0fdc1c771382d5dd9a54742047c61558e071c8cd595add86"},
{file = "texttable-1.6.2.tar.gz", hash = "sha256:eff3703781fbc7750125f50e10f001195174f13825a92a45e9403037d539b4f4"},
]
toml = [
{file = "toml-0.10.0-py2.7.egg", hash = "sha256:f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"},
{file = "toml-0.10.0-py2.py3-none-any.whl", hash = "sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"},
{file = "toml-0.10.0.tar.gz", hash = "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c"},
]
urllib3 = [
{file = "urllib3-1.25.9-py2.py3-none-any.whl", hash = "sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115"},
{file = "urllib3-1.25.9.tar.gz", hash = "sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527"},
]
virtualenv = [
{file = "virtualenv-20.0.20-py2.py3-none-any.whl", hash = "sha256:b4c14d4d73a0c23db267095383c4276ef60e161f94fde0427f2f21a0132dde74"},
{file = "virtualenv-20.0.20.tar.gz", hash = "sha256:fd0e54dec8ac96c1c7c87daba85f0a59a7c37fe38748e154306ca21c73244637"},
]
watchdog = [
{file = "watchdog-0.10.2.tar.gz", hash = "sha256:c560efb643faed5ef28784b2245cf8874f939569717a4a12826a173ac644456b"},
]
wcwidth = [
{file = "wcwidth-0.1.9-py2.py3-none-any.whl", hash = "sha256:cafe2186b3c009a04067022ce1dcd79cb38d8d65ee4f4791b8888d6599d1bbe1"},
{file = "wcwidth-0.1.9.tar.gz", hash = "sha256:ee73862862a156bf77ff92b09034fc4825dd3af9cf81bc5b360668d425f3c5f1"},
]
websocket-client = [
{file = "websocket_client-0.57.0-py2.py3-none-any.whl", hash = "sha256:0fc45c961324d79c781bab301359d5a1b00b13ad1b10415a4780229ef71a5549"},
{file = "websocket_client-0.57.0.tar.gz", hash = "sha256:d735b91d6d1692a6a181f2a8c9e0238e5f6373356f561bb9dc4c7af36f452010"},
]
zipp = [
{file = "zipp-3.1.0-py3-none-any.whl", hash = "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b"},
{file = "zipp-3.1.0.tar.gz", hash = "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96"},
]

@ -1,6 +1,3 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from .constants import * from .constants import *
from .docker_links import DockerLinks from .docker_links import DockerLinks
from .entrypoint import Entrypoint from .entrypoint import Entrypoint

@ -1,6 +1,3 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from sys import argv from sys import argv
from .entrypoint import main as m from .entrypoint import main as m

@ -1,7 +1,4 @@
"Command object" "Command object"
from __future__ import absolute_import
from __future__ import unicode_literals
import os import os
from fnmatch import fnmatch from fnmatch import fnmatch
@ -71,6 +68,10 @@ class Command(object):
@property @property
def is_handled(self): def is_handled(self):
if self.config.commands and self.args:
return [
p for p in self.config.commands if fnmatch(self.args[0], p)
]
subcom = self.config.subcommands subcom = self.config.subcommands
if not self.args or self.args[0] == self.command or \ if not self.args or self.args[0] == self.command or \
[p for p in subcom if fnmatch(self.args[0], p)]: [p for p in subcom if fnmatch(self.args[0], p)]:
@ -102,7 +103,7 @@ class Command(object):
self._exec() self._exec()
if self.config.remove_dockerenv: if self.config.remove_dockerenv:
self._rm_dockerenv() self._rm_dockerenv()
if os.getuid() is 0: if os.getuid() == 0:
os.setgid(self.config.group) os.setgid(self.config.group)
os.setuid(self.config.user) os.setuid(self.config.user)
self.log.debug('Set uid {uid} and gid {gid}'.format( self.log.debug('Set uid {uid} and gid {gid}'.format(

@ -1,10 +1,9 @@
""" """
Configuration object Configuration object
""" """
from __future__ import absolute_import
from __future__ import unicode_literals
import os import os
from distutils.util import strtobool
from fnmatch import fnmatch
from grp import getgrnam from grp import getgrnam
from io import open from io import open
from pwd import getpwnam from pwd import getpwnam
@ -22,6 +21,10 @@ from .reloader import Reloader
__all__ = ['Config'] __all__ = ['Config']
def envtobool(key, default):
return bool(strtobool(os.environ.get(key, str(default))))
class ConfigMeta(object): class ConfigMeta(object):
def _return_item_lst(self, item): def _return_item_lst(self, item):
@ -127,7 +130,13 @@ class Config(ConfigMeta):
@property @property
def has_config(self): def has_config(self):
"Has config file provided." "Has config file provided."
return len(self._config) is not 0 return len(self._config) != 0
@property
def commands(self):
"Handled commands"
rtn = self._return_item_lst('commands')
return rtn
@property @property
def command(self): def command(self):
@ -135,8 +144,16 @@ class Config(ConfigMeta):
if self._command: if self._command:
return self._command return self._command
cmd = self._args[0] if self._args else '' cmd = self._args[0] if self._args else ''
if 'commands' in self._config:
commands = self._return_item_lst('commands')
if [p for p in commands if fnmatch(self._args[0], p)]:
self._command = Command(cmd, self, self._args)
return self._command
for key in ['command', 'cmd']: for key in ['command', 'cmd']:
if key in self._config: if key in self._config:
self.log.warning(
'"command" is deprecated, use "commands" instead',
)
cmd = self._config[key] cmd = self._config[key]
self._command = Command(cmd, self, self._args) self._command = Command(cmd, self, self._args)
return self._command return self._command
@ -145,9 +162,18 @@ class Config(ConfigMeta):
def subcommands(self): def subcommands(self):
"""Subcommands to handle as arguments.""" """Subcommands to handle as arguments."""
rtn = self._return_item_lst('subcommands') rtn = self._return_item_lst('subcommands')
if not rtn: if rtn:
self.log.warning(
'"subcommands" is deprecated, '
'subcommands will not be handled anymore.',
)
if self.commands:
self.log.warning(
'"subcommands" is ignored as long "commands" in present',
)
return rtn
else:
return ['-*'] return ['-*']
return rtn
@property @property
def user(self): def user(self):
@ -214,7 +240,7 @@ class Config(ConfigMeta):
if self._reload: if self._reload:
return self._reload return self._reload
if (not self._config.get('reload') or if (not self._config.get('reload') or
'ENTRYPOINT_DISABLE_RELOAD' in os.environ): envtobool('ENTRYPOINT_DISABLE_RELOAD', False)):
return None return None
self._reload = self.get_reloader() self._reload = self.get_reloader()
return self._reload return self._reload
@ -236,7 +262,7 @@ class Config(ConfigMeta):
@property @property
def debug(self): def debug(self):
"""Enable debug logs.""" """Enable debug logs."""
if 'ENTRYPOINT_DEBUG' in os.environ: if envtobool('ENTRYPOINT_DEBUG', False):
return True return True
if 'debug' in self._config: if 'debug' in self._config:
return bool(self._config['debug']) return bool(self._config['debug'])
@ -247,23 +273,23 @@ class Config(ConfigMeta):
"""Disable logging""" """Disable logging"""
if self.debug: if self.debug:
return False return False
if 'ENTRYPOINT_QUIET' in os.environ: if envtobool('ENTRYPOINT_QUIET', False):
return True return True
return bool(self._config.get('quiet', False)) return bool(self._config.get('quiet', False))
@property @property
def is_disabled(self): def is_disabled(self):
"""Return if service is disabled using environment""" """Return if service is disabled using environment"""
return 'ENTRYPOINT_DISABLE_SERVICE' in os.environ return envtobool('ENTRYPOINT_DISABLE_SERVICE', False)
@property @property
def should_config(self): def should_config(self):
"""Check environment to tell if config should apply anyway""" """Check environment to tell if config should apply anyway"""
return 'ENTRYPOINT_FORCE' in os.environ return envtobool('ENTRYPOINT_FORCE', False)
@property @property
def raw_output(self): def raw_output(self):
"""Check if command output should be displayed using logging or not""" """Check if command output should be displayed using logging or not"""
if 'ENTRYPOINT_RAW' in os.environ: if envtobool('ENTRYPOINT_RAW', False):
return True return True
return bool(self._config.get('raw_output', False)) return bool(self._config.get('raw_output', False))

@ -1,3 +1,3 @@
from __future__ import unicode_literals
ENTRYPOINT_FILE = 'entrypoint-config.yml' ENTRYPOINT_FILE = 'entrypoint-config.yml'

@ -1,8 +1,6 @@
""" """
Container object handle a single container link Container object handle a single container link
""" """
from __future__ import absolute_import
from __future__ import unicode_literals
class Container(object): class Container(object):

@ -3,9 +3,6 @@
DockerLinks a kiss class which help to get links info in a docker DockerLinks a kiss class which help to get links info in a docker
container. container.
""" """
from __future__ import absolute_import
from __future__ import unicode_literals
import json import json
import os import os
import re import re
@ -118,7 +115,7 @@ class DockerLinks(object):
def _find_ports(link_name): def _find_ports(link_name):
rtn = {} rtn = {}
p = re.compile('^{link}_PORT_(\d*)_(UDP|TCP)$'.format(link=link_name)) p = re.compile('^{link}_PORT_([0-9]+)_(UDP|TCP)$'.format(link=link_name))
for key in os.environ: for key in os.environ:
m = p.match(key) m = p.match(key)
if m: if m:

@ -2,10 +2,6 @@
""" """
Smart docker-entrypoint Smart docker-entrypoint
""" """
from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals
import json import json
import os import os
from sys import argv from sys import argv

@ -1,9 +1,6 @@
""" """
Link handle a single link to another container, determined by his port Link handle a single link to another container, determined by his port
""" """
from __future__ import absolute_import
from __future__ import unicode_literals
import fnmatch import fnmatch
from six import viewitems from six import viewitems
@ -57,7 +54,7 @@ class Links(object):
'required': True} 'required': True}
def __init__(self, config={}, links=None): def __init__(self, config={}, links=None):
if not links or len(links.links()) is 0: if not links or len(links.links()) == 0:
pass pass
self._links = [] self._links = []
@ -82,7 +79,7 @@ class Links(object):
links = [link for link in links links = [link for link in links
if getattr(link, "_filter_{}".format(key))(val)] if getattr(link, "_filter_{}".format(key))(val)]
if options['required'] and len(links) is 0: if options['required'] and len(links) == 0:
raise Exception("No links was found for {name}".format(name=name)) raise Exception("No links was found for {name}".format(name=name))
if options['single'] and len(links) > 1: if options['single'] and len(links) > 1:
raise Exception("Only one link should be provided for {name}" raise Exception("Only one link should be provided for {name}"

@ -1,9 +1,6 @@
""" """
Get log object Get log object
""" """
from __future__ import absolute_import
from __future__ import unicode_literals
import logging import logging
from colorlog import ColoredFormatter from colorlog import ColoredFormatter

@ -1,9 +1,6 @@
""" """
Send signal to pid 1 to reload service Send signal to pid 1 to reload service
""" """
from __future__ import absolute_import
from __future__ import unicode_literals
import glob import glob
import os import os
import signal import signal
@ -38,7 +35,7 @@ class Reload(FileSystemEventHandler):
else: else:
self.log.debug( self.log.debug(
'Reloader triggered but file {file} is not watched'.format( 'Reloader triggered but file {file} is not watched'.format(
file=file file=event.src_path
) )
) )
@ -57,7 +54,7 @@ class Reloader(object):
sig_attr = getattr(signal, sig) sig_attr = getattr(signal, sig)
try: try:
assert int(sig_attr) assert int(sig_attr)
except: except BaseException:
raise Exception('Wrong signal provided for reload') raise Exception('Wrong signal provided for reload')
self.observer = Observer() self.observer = Observer()
rel = Reload(sig=sig_attr, reloader=self) rel = Reload(sig=sig_attr, reloader=self)

@ -1,8 +1,4 @@
"Run commands" "Run commands"
from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals
from multiprocessing import Process from multiprocessing import Process
from subprocess import PIPE from subprocess import PIPE
from subprocess import Popen from subprocess import Popen
@ -27,9 +23,9 @@ class Runner(object):
def dispout(output, cb): def dispout(output, cb):
enc = stdout.encoding or 'UTF-8' enc = stdout.encoding or 'UTF-8'
output = output.decode(enc).split('\n') output = output.decode(enc).split('\n')
l = len(output) lenght = len(output)
for c, line in enumerate(output): for c, line in enumerate(output):
if c + 1 == l and not len(line): if c + 1 == lenght and not len(line):
# Do not display last empty line # Do not display last empty line
break break
cb(line) cb(line)

@ -0,0 +1,32 @@
[tool]
[tool.poetry]
name = "pyentrypoint"
version = "0.6.0"
description = "pyentrypoint manages entrypoints in Docker containers."
license = "WTFPL"
classifiers = ["Programming Language :: Python", "Development Status :: 1 - Planning", "License :: OSI Approved :: BSD License", "Natural Language :: English", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.6", "Topic :: System :: Installation/Setup"]
homepage = "http://github.com/cmehay/pyentrypoint"
authors = ["Christophe Mehay <cmehay@nospam.student.42.fr>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.6.1"
colorlog = "^4.1"
jinja2 = "^2.11"
pyyaml = "^5.3"
six = "^1.14"
watchdog = "^0.10"
[tool.poetry.dev-dependencies]
docker-compose = "^1.25.5"
pytest = "^5.4.2"
pytest-mock = "^3.1.0"
pre-commit = "^2.3.0"
[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
[tool.poetry.scripts]
pyentrypoint = "pyentrypoint.__main__:main"

@ -1 +0,0 @@
docker-compose==1.7.0

@ -1,59 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from setuptools import find_packages
from setuptools import setup
# Thanks Sam and Max
__version__ = '0.5.2'
if __name__ == '__main__':
setup(
name='pyentrypoint',
version=__version__,
packages=find_packages(),
author="Christophe Mehay",
author_email="cmehay@nospam.student.42.fr",
description="pyentrypoint manages entrypoints in Docker containers.",
long_description=open('README.md').read(),
install_requires=['Jinja2>=2.8',
'PyYAML>=3.11',
'colorlog>=2.6.1',
'six>=1.10.0',
'watchdog>=0.8.3'],
include_package_data=True,
url='http://github.com/cmehay/pyentrypoint',
classifiers=[
"Programming Language :: Python",
"Development Status :: 1 - Planning",
"License :: OSI Approved :: BSD License",
"Natural Language :: English",
"Operating System :: POSIX :: Linux",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3.5",
"Topic :: System :: Installation/Setup",
],
entry_points={
'console_scripts': [
'pyentrypoint = pyentrypoint.__main__:main',
],
},
license="WTFPL",
)

@ -0,0 +1,4 @@
commands:
- sleep
- cat
- ba*

@ -1,7 +1,4 @@
# Tests using pytest # Tests using pytest
from __future__ import absolute_import
from __future__ import unicode_literals
import os import os
from multiprocessing import Process from multiprocessing import Process

@ -1,15 +1,12 @@
# Tests using pytest # Tests using pytest
from __future__ import absolute_import
from __future__ import unicode_literals
import fnmatch import fnmatch
import os import os
from multiprocessing import Process from multiprocessing import Process
import pytest import pytest
from commons import clean_env from commons import clean_env
from yaml import FullLoader
from yaml import load from yaml import load
from yaml import Loader
from pyentrypoint import DockerLinks from pyentrypoint import DockerLinks
from pyentrypoint import Entrypoint from pyentrypoint import Entrypoint
@ -119,7 +116,7 @@ def test_templates():
for _, config_file in conf.get_templates(): for _, config_file in conf.get_templates():
with open(config_file, mode='r') as r: with open(config_file, mode='r') as r:
test = load(stream=r, Loader=Loader) test = load(stream=r, Loader=FullLoader)
assert len(set(test['All links'])) == 4 assert len(set(test['All links'])) == 4
assert len(set(test['All links 1'])) == 2 assert len(set(test['All links 1'])) == 2
@ -311,3 +308,17 @@ def test_disabled_service():
entry.exit_if_disabled() entry.exit_if_disabled()
del os.environ['ENTRYPOINT_DISABLE_SERVICE'] del os.environ['ENTRYPOINT_DISABLE_SERVICE']
def test_commands_handling():
cat = Entrypoint(conf='configs/commands.yml', args=['cat', 'hello'])
sleep = Entrypoint(conf='configs/commands.yml', args=['sleep', '1'])
bash = Entrypoint(conf='configs/commands.yml', args=['bash'])
zsh = Entrypoint(conf='configs/commands.yml', args=['zsh', '-c', 'exit'])
empty = Entrypoint(conf='configs/empty.yml', args=['zsh', '-c', 'exit'])
assert cat.is_handled
assert sleep.is_handled
assert bash.is_handled
assert not zsh.is_handled
assert empty.is_handled

@ -1,6 +1,4 @@
"Tests for reloader" "Tests for reloader"
from __future__ import absolute_import
from __future__ import unicode_literals
try: try:

@ -1,7 +1,4 @@
"Tests for runner" "Tests for runner"
from __future__ import absolute_import
from __future__ import unicode_literals
import os import os
from multiprocessing import Process from multiprocessing import Process

Loading…
Cancel
Save