mirror of
https://github.com/craigerl/aprsd.git
synced 2024-12-19 08:05:56 -05:00
Merge pull request #13 from hemna/test
Update tox environment to fix formatting python errors
This commit is contained in:
commit
40472ca7d6
22
.github/workflows/python.yml
vendored
Normal file
22
.github/workflows/python.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
name: python
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
tox:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [2.7, 3.6, 3.7, 3.8, 3.9]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install tox tox-gh-actions
|
||||
- name: Test with tox
|
||||
run: tox
|
@ -14,6 +14,4 @@
|
||||
|
||||
import pbr.version
|
||||
|
||||
|
||||
__version__ = pbr.version.VersionInfo(
|
||||
'aprsd').version_string()
|
||||
__version__ = pbr.version.VersionInfo("aprsd").version_string()
|
||||
|
@ -1,33 +1,27 @@
|
||||
import argparse
|
||||
import logging
|
||||
import socketserver
|
||||
import sys
|
||||
import time
|
||||
import socketserver
|
||||
|
||||
from logging.handlers import RotatingFileHandler
|
||||
|
||||
from aprsd import utils
|
||||
|
||||
# command line args
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--loglevel",
|
||||
default='DEBUG',
|
||||
choices=['CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG'],
|
||||
help="The log level to use for aprsd.log")
|
||||
parser.add_argument("--quiet",
|
||||
action='store_true',
|
||||
help="Don't log to stdout")
|
||||
parser.add_argument(
|
||||
"--loglevel",
|
||||
default="DEBUG",
|
||||
choices=["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"],
|
||||
help="The log level to use for aprsd.log",
|
||||
)
|
||||
parser.add_argument("--quiet", action="store_true", help="Don't log to stdout")
|
||||
|
||||
parser.add_argument("--port",
|
||||
default=9099,
|
||||
type=int,
|
||||
help="The port to listen on .")
|
||||
parser.add_argument("--ip",
|
||||
default='127.0.0.1',
|
||||
help="The IP to listen on ")
|
||||
parser.add_argument("--port", default=9099, type=int, help="The port to listen on .")
|
||||
parser.add_argument("--ip", default="127.0.0.1", help="The IP to listen on ")
|
||||
|
||||
CONFIG = None
|
||||
LOG = logging.getLogger('ARPSSERVER')
|
||||
LOG = logging.getLogger("ARPSSERVER")
|
||||
|
||||
|
||||
# Setup the logging faciility
|
||||
@ -36,22 +30,19 @@ LOG = logging.getLogger('ARPSSERVER')
|
||||
def setup_logging(args):
|
||||
global LOG
|
||||
levels = {
|
||||
'CRITICAL': logging.CRITICAL,
|
||||
'ERROR': logging.ERROR,
|
||||
'WARNING': logging.WARNING,
|
||||
'INFO': logging.INFO,
|
||||
'DEBUG': logging.DEBUG}
|
||||
"CRITICAL": logging.CRITICAL,
|
||||
"ERROR": logging.ERROR,
|
||||
"WARNING": logging.WARNING,
|
||||
"INFO": logging.INFO,
|
||||
"DEBUG": logging.DEBUG,
|
||||
}
|
||||
log_level = levels[args.loglevel]
|
||||
|
||||
LOG.setLevel(log_level)
|
||||
log_format = ("%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s]"
|
||||
" %(message)s")
|
||||
date_format = '%m/%d/%Y %I:%M:%S %p'
|
||||
log_formatter = logging.Formatter(fmt=log_format,
|
||||
datefmt=date_format)
|
||||
fh = RotatingFileHandler('aprs-server.log',
|
||||
maxBytes=(10248576 * 5),
|
||||
backupCount=4)
|
||||
log_format = "%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s]" " %(message)s"
|
||||
date_format = "%m/%d/%Y %I:%M:%S %p"
|
||||
log_formatter = logging.Formatter(fmt=log_format, datefmt=date_format)
|
||||
fh = RotatingFileHandler("aprs-server.log", maxBytes=(10248576 * 5), backupCount=4)
|
||||
fh.setFormatter(log_formatter)
|
||||
LOG.addHandler(fh)
|
||||
|
||||
@ -62,7 +53,6 @@ def setup_logging(args):
|
||||
|
||||
|
||||
class MyAPRSTCPHandler(socketserver.BaseRequestHandler):
|
||||
|
||||
def handle(self):
|
||||
# self.request is the TCP socket connected to the client
|
||||
self.data = self.request.recv(1024).strip()
|
||||
@ -81,8 +71,8 @@ def main():
|
||||
|
||||
CONFIG = utils.parse_config(args)
|
||||
|
||||
ip = CONFIG['aprs']['host']
|
||||
port = CONFIG['aprs']['port']
|
||||
ip = CONFIG["aprs"]["host"]
|
||||
port = CONFIG["aprs"]["port"]
|
||||
LOG.info("Start server listening on %s:%s" % (args.ip, args.port))
|
||||
|
||||
with socketserver.TCPServer((ip, port), MyAPRSTCPHandler) as server:
|
||||
|
@ -19,37 +19,49 @@ import time
|
||||
|
||||
|
||||
def fuzzy(hour, minute, degree=1):
|
||||
'''Implements the fuzzy clock.
|
||||
"""Implements the fuzzy clock.
|
||||
returns the the string that spells out the time - hour:minute
|
||||
Supports two degrees of fuzziness. Set with degree = 1 or degree = 2
|
||||
When degree = 1, time is in quantum of 5 minutes.
|
||||
When degree = 2, time is in quantum of 15 minutes.'''
|
||||
When degree = 2, time is in quantum of 15 minutes."""
|
||||
|
||||
if degree <= 0 or degree > 2:
|
||||
print('Please use a degree of 1 or 2. Using fuzziness degree=1')
|
||||
print("Please use a degree of 1 or 2. Using fuzziness degree=1")
|
||||
degree = 1
|
||||
|
||||
begin = 'It\'s '
|
||||
begin = "It's "
|
||||
|
||||
f0 = 'almost '
|
||||
f1 = 'exactly '
|
||||
f2 = 'around '
|
||||
f0 = "almost "
|
||||
f1 = "exactly "
|
||||
f2 = "around "
|
||||
|
||||
b0 = ' past '
|
||||
b1 = ' to '
|
||||
b0 = " past "
|
||||
b1 = " to "
|
||||
|
||||
hourList = ('One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight',
|
||||
'Nine', 'Ten', 'Eleven', 'Twelve')
|
||||
hourlist = (
|
||||
"One",
|
||||
"Two",
|
||||
"Three",
|
||||
"Four",
|
||||
"Five",
|
||||
"Six",
|
||||
"Seven",
|
||||
"Eight",
|
||||
"Nine",
|
||||
"Ten",
|
||||
"Eleven",
|
||||
"Twelve",
|
||||
)
|
||||
|
||||
s1 = s2 = s3 = s4 = ''
|
||||
s1 = s2 = s3 = s4 = ""
|
||||
base = 5
|
||||
|
||||
if degree == 1:
|
||||
base = 5
|
||||
val = ('Five', 'Ten', 'Quarter', 'Twenty', 'Twenty-Five', 'Half')
|
||||
val = ("Five", "Ten", "Quarter", "Twenty", "Twenty-Five", "Half")
|
||||
elif degree == 2:
|
||||
base = 15
|
||||
val = ('Quarter', 'Half')
|
||||
val = ("Quarter", "Half")
|
||||
|
||||
# to find whether we have to use 'almost', 'exactly' or 'around'
|
||||
dmin = minute % base
|
||||
@ -74,20 +86,20 @@ def fuzzy(hour, minute, degree=1):
|
||||
|
||||
if minute <= base / 2:
|
||||
# Case like "It's around/exactly Ten"
|
||||
s2 = s3 = ''
|
||||
s4 = hourList[hour - 12 - 1]
|
||||
s2 = s3 = ""
|
||||
s4 = hourlist[hour - 12 - 1]
|
||||
elif minute >= 60 - base / 2:
|
||||
# Case like "It's almost Ten"
|
||||
s2 = s3 = ''
|
||||
s4 = hourList[hour - 12]
|
||||
s2 = s3 = ""
|
||||
s4 = hourlist[hour - 12]
|
||||
else:
|
||||
# Other cases with all words, like "It's around Quarter past One"
|
||||
if minute > 30:
|
||||
s3 = b1 # to
|
||||
s4 = hourList[hour - 12]
|
||||
s4 = hourlist[hour - 12]
|
||||
else:
|
||||
s3 = b0 # past
|
||||
s4 = hourList[hour - 12 - 1]
|
||||
s4 = hourlist[hour - 12 - 1]
|
||||
|
||||
return begin + s1 + s2 + s3 + s4
|
||||
|
||||
@ -102,17 +114,17 @@ def main():
|
||||
try:
|
||||
deg = int(sys.argv[1])
|
||||
except Exception:
|
||||
print('Please use a degree of 1 or 2. Using fuzziness degree=1')
|
||||
print("Please use a degree of 1 or 2. Using fuzziness degree=1")
|
||||
|
||||
if len(sys.argv) >= 3:
|
||||
tm = sys.argv[2].split(':')
|
||||
tm = sys.argv[2].split(":")
|
||||
try:
|
||||
h = int(tm[0])
|
||||
m = int(tm[1])
|
||||
if h < 0 or h > 23 or m < 0 or m > 59:
|
||||
raise Exception
|
||||
except Exception:
|
||||
print('Bad time entered. Using the system time.')
|
||||
print("Bad time entered. Using the system time.")
|
||||
h = stm.tm_hour
|
||||
m = stm.tm_min
|
||||
print(fuzzy(h, m, deg))
|
||||
|
637
aprsd/main.py
637
aprsd/main.py
File diff suppressed because it is too large
Load Diff
175
aprsd/utils.py
175
aprsd/utils.py
@ -1,40 +1,44 @@
|
||||
"""Utilities and helper functions."""
|
||||
|
||||
import logging
|
||||
import errno
|
||||
import os
|
||||
import sys
|
||||
|
||||
import click
|
||||
import yaml
|
||||
|
||||
# an example of what should be in the ~/.aprsd/config.yml
|
||||
example_config = '''
|
||||
ham:
|
||||
callsign: KFART
|
||||
DEFAULT_CONFIG_DICT = {
|
||||
"ham": {"callsign": "KFART"},
|
||||
"aprs": {
|
||||
"login": "someusername",
|
||||
"password": "somepassword",
|
||||
"host": "noam.aprs2.net",
|
||||
"port": 14580,
|
||||
"logfile": "/tmp/arsd.log",
|
||||
},
|
||||
"shortcuts": {
|
||||
"aa": "5551239999@vtext.com",
|
||||
"cl": "craiglamparter@somedomain.org",
|
||||
"wb": "555309@vtext.com",
|
||||
},
|
||||
"smtp": {
|
||||
"login": "something",
|
||||
"password": "some lame password",
|
||||
"host": "imap.gmail.com",
|
||||
"port": 465,
|
||||
"use_ssl": False,
|
||||
},
|
||||
"imap": {
|
||||
"login": "imapuser",
|
||||
"password": "something here too",
|
||||
"host": "imap.gmail.com",
|
||||
"port": 993,
|
||||
"use_ssl": True,
|
||||
},
|
||||
}
|
||||
|
||||
aprs:
|
||||
login: someusername
|
||||
password: password
|
||||
host: noam.aprs2.net
|
||||
port: 14580
|
||||
logfile: /tmp/aprsd.log
|
||||
|
||||
shortcuts:
|
||||
'aa': '5551239999@vtext.com'
|
||||
'cl': 'craiglamparter@somedomain.org'
|
||||
'wb': '555309@vtext.com'
|
||||
|
||||
smtp:
|
||||
login: something
|
||||
password: some lame password
|
||||
host: imap.gmail.com
|
||||
port: 465
|
||||
|
||||
imap:
|
||||
login: imapuser
|
||||
password: something dumb
|
||||
host: imap.gmail.com
|
||||
'''
|
||||
|
||||
log = logging.getLogger('APRSD')
|
||||
DEFAULT_CONFIG_FILE = "~/.config/aprsd/aprsd.yml"
|
||||
|
||||
|
||||
def env(*vars, **kwargs):
|
||||
@ -45,20 +49,56 @@ def env(*vars, **kwargs):
|
||||
value = os.environ.get(v, None)
|
||||
if value:
|
||||
return value
|
||||
return kwargs.get('default', '')
|
||||
return kwargs.get("default", "")
|
||||
|
||||
|
||||
def get_config():
|
||||
"""This tries to read the yaml config from ~/.aprsd/config.yml."""
|
||||
config_file = os.path.expanduser("~/.aprsd/config.yml")
|
||||
if os.path.exists(config_file):
|
||||
with open(config_file, "r") as stream:
|
||||
def mkdir_p(path):
|
||||
"""Make directory and have it work in py2 and py3."""
|
||||
try:
|
||||
os.makedirs(path)
|
||||
except OSError as exc: # Python >= 2.5
|
||||
if exc.errno == errno.EEXIST and os.path.isdir(path):
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
def create_default_config():
|
||||
"""Create a default config file."""
|
||||
# make sure the directory location exists
|
||||
config_file_expanded = os.path.expanduser(DEFAULT_CONFIG_FILE)
|
||||
config_dir = os.path.dirname(config_file_expanded)
|
||||
if not os.path.exists(config_dir):
|
||||
click.echo("Config dir '{}' doesn't exist, creating.".format(config_dir))
|
||||
mkdir_p(config_dir)
|
||||
with open(config_file_expanded, "w+") as cf:
|
||||
yaml.dump(DEFAULT_CONFIG_DICT, cf)
|
||||
|
||||
|
||||
def get_config(config_file):
|
||||
"""This tries to read the yaml config from <config_file>."""
|
||||
config_file_expanded = os.path.expanduser(config_file)
|
||||
if os.path.exists(config_file_expanded):
|
||||
with open(config_file_expanded, "r") as stream:
|
||||
config = yaml.load(stream, Loader=yaml.FullLoader)
|
||||
return config
|
||||
else:
|
||||
log.critical("%s is missing, please create config file" % config_file)
|
||||
print("\nCopy to ~/.aprsd/config.yml and edit\n\nSample config:\n %s"
|
||||
% example_config)
|
||||
if config_file == DEFAULT_CONFIG_FILE:
|
||||
click.echo(
|
||||
"{} is missing, creating config file".format(config_file_expanded)
|
||||
)
|
||||
create_default_config()
|
||||
msg = (
|
||||
"Default config file created at {}. Please edit with your "
|
||||
"settings.".format(config_file)
|
||||
)
|
||||
click.echo(msg)
|
||||
else:
|
||||
# The user provided a config file path different from the
|
||||
# Default, so we won't try and create it, just bitch and bail.
|
||||
msg = "Custom config file '{}' is missing.".format(config_file)
|
||||
click.echo(msg)
|
||||
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
@ -66,42 +106,55 @@ def get_config():
|
||||
# and consume the settings.
|
||||
# If the required params don't exist,
|
||||
# it will look in the environment
|
||||
def parse_config():
|
||||
def parse_config(config_file):
|
||||
# for now we still use globals....ugh
|
||||
global CONFIG, LOG
|
||||
global CONFIG
|
||||
|
||||
def fail(msg):
|
||||
LOG.critical(msg)
|
||||
click.echo(msg)
|
||||
sys.exit(-1)
|
||||
|
||||
def check_option(config, section, name=None, default=None):
|
||||
def check_option(config, section, name=None, default=None, default_fail=None):
|
||||
if section in config:
|
||||
|
||||
if name and name not in config[section]:
|
||||
if not default:
|
||||
fail("'%s' was not in '%s' section of config file" %
|
||||
(name, section))
|
||||
fail(
|
||||
"'%s' was not in '%s' section of config file" % (name, section)
|
||||
)
|
||||
else:
|
||||
config[section][name] = default
|
||||
else:
|
||||
if (
|
||||
default_fail
|
||||
and name in config[section]
|
||||
and config[section][name] == default_fail
|
||||
):
|
||||
# We have to fail and bail if the user hasn't edited
|
||||
# this config option.
|
||||
fail("Config file needs to be edited from provided defaults.")
|
||||
else:
|
||||
fail("'%s' section wasn't in config file" % section)
|
||||
return config
|
||||
|
||||
# Now read the ~/.aprds/config.yml
|
||||
config = get_config()
|
||||
check_option(config, 'shortcuts')
|
||||
check_option(config, 'ham', 'callsign')
|
||||
check_option(config, 'aprs', 'login')
|
||||
check_option(config, 'aprs', 'password')
|
||||
check_option(config, 'aprs', 'host')
|
||||
check_option(config, 'aprs', 'port')
|
||||
config = check_option(config, 'aprs', 'logfile', './aprsd.log')
|
||||
check_option(config, 'imap', 'host')
|
||||
check_option(config, 'imap', 'login')
|
||||
check_option(config, 'imap', 'password')
|
||||
check_option(config, 'smtp', 'host')
|
||||
check_option(config, 'smtp', 'port')
|
||||
check_option(config, 'smtp', 'login')
|
||||
check_option(config, 'smtp', 'password')
|
||||
config = get_config(config_file)
|
||||
check_option(config, "shortcuts")
|
||||
# special check here to make sure user has edited the config file
|
||||
# and changed the ham callsign
|
||||
check_option(
|
||||
config, "ham", "callsign", default_fail=DEFAULT_CONFIG_DICT["ham"]["callsign"]
|
||||
)
|
||||
check_option(config, "aprs", "login")
|
||||
check_option(config, "aprs", "password")
|
||||
check_option(config, "aprs", "host")
|
||||
check_option(config, "aprs", "port")
|
||||
check_option(config, "aprs", "logfile", "./aprsd.log")
|
||||
check_option(config, "imap", "host")
|
||||
check_option(config, "imap", "login")
|
||||
check_option(config, "imap", "password")
|
||||
check_option(config, "smtp", "host")
|
||||
check_option(config, "smtp", "port")
|
||||
check_option(config, "smtp", "login")
|
||||
check_option(config, "smtp", "password")
|
||||
|
||||
return config
|
||||
LOG.info("aprsd config loaded")
|
||||
|
9
dev-requirements.in
Normal file
9
dev-requirements.in
Normal file
@ -0,0 +1,9 @@
|
||||
tox
|
||||
pytest
|
||||
pytest-cov
|
||||
mypy
|
||||
flake8
|
||||
pep8-naming
|
||||
black
|
||||
isort
|
||||
Sphinx
|
60
dev-requirements.txt
Normal file
60
dev-requirements.txt
Normal file
@ -0,0 +1,60 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile
|
||||
# To update, run:
|
||||
#
|
||||
# pip-compile dev-requirements.in
|
||||
#
|
||||
alabaster==0.7.12 # via sphinx
|
||||
appdirs==1.4.4 # via black, virtualenv
|
||||
attrs==20.3.0 # via pytest
|
||||
babel==2.9.0 # via sphinx
|
||||
black==20.8b1 # via -r dev-requirements.in
|
||||
certifi==2020.12.5 # via requests
|
||||
chardet==3.0.4 # via requests
|
||||
coverage==5.3 # via pytest-cov
|
||||
distlib==0.3.1 # via virtualenv
|
||||
docutils==0.16 # via sphinx
|
||||
filelock==3.0.12 # via tox, virtualenv
|
||||
flake8-polyfill==1.0.2 # via pep8-naming
|
||||
flake8==3.8.4 # via -r dev-requirements.in, flake8-polyfill
|
||||
idna==2.10 # via requests
|
||||
imagesize==1.2.0 # via sphinx
|
||||
iniconfig==1.1.1 # via pytest
|
||||
isort==5.6.4 # via -r dev-requirements.in
|
||||
jinja2==2.11.2 # via sphinx
|
||||
markupsafe==1.1.1 # via jinja2
|
||||
mccabe==0.6.1 # via flake8
|
||||
mypy-extensions==0.4.3 # via black, mypy
|
||||
mypy==0.790 # via -r dev-requirements.in
|
||||
packaging==20.7 # via pytest, sphinx, tox
|
||||
pathspec==0.8.1 # via black
|
||||
pep8-naming==0.11.1 # via -r dev-requirements.in
|
||||
pluggy==0.13.1 # via pytest, tox
|
||||
py==1.9.0 # via pytest, tox
|
||||
pycodestyle==2.6.0 # via flake8
|
||||
pyflakes==2.2.0 # via flake8
|
||||
pygments==2.7.3 # via sphinx
|
||||
pyparsing==2.4.7 # via packaging
|
||||
pytest-cov==2.10.1 # via -r dev-requirements.in
|
||||
pytest==6.1.2 # via -r dev-requirements.in, pytest-cov
|
||||
pytz==2020.4 # via babel
|
||||
regex==2020.11.13 # via black
|
||||
requests==2.25.0 # via sphinx
|
||||
six==1.15.0 # via tox, virtualenv
|
||||
snowballstemmer==2.0.0 # via sphinx
|
||||
sphinx==3.3.1 # via -r dev-requirements.in
|
||||
sphinxcontrib-applehelp==1.0.2 # via sphinx
|
||||
sphinxcontrib-devhelp==1.0.2 # via sphinx
|
||||
sphinxcontrib-htmlhelp==1.0.3 # via sphinx
|
||||
sphinxcontrib-jsmath==1.0.1 # via sphinx
|
||||
sphinxcontrib-qthelp==1.0.3 # via sphinx
|
||||
sphinxcontrib-serializinghtml==1.1.4 # via sphinx
|
||||
toml==0.10.2 # via black, pytest, tox
|
||||
tox==3.20.1 # via -r dev-requirements.in
|
||||
typed-ast==1.4.1 # via black, mypy
|
||||
typing-extensions==3.7.4.3 # via black, mypy
|
||||
urllib3==1.26.2 # via requests
|
||||
virtualenv==20.2.2 # via tox
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
# setuptools
|
@ -4,3 +4,4 @@ imapclient
|
||||
pbr
|
||||
pyyaml
|
||||
six
|
||||
requests
|
||||
|
4
setup.py
4
setup.py
@ -24,6 +24,4 @@ try:
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['pbr'],
|
||||
pbr=True)
|
||||
setuptools.setup(setup_requires=["pbr"], pbr=True)
|
||||
|
3
test-requirements-py2.txt
Normal file
3
test-requirements-py2.txt
Normal file
@ -0,0 +1,3 @@
|
||||
flake8
|
||||
pytest
|
||||
mock
|
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
23
tests/test_main.py
Normal file
23
tests/test_main.py
Normal file
@ -0,0 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import pytest
|
||||
|
||||
from aprsd import main
|
||||
|
||||
if sys.version_info >= (3, 2):
|
||||
from unittest import mock
|
||||
else:
|
||||
import mock
|
||||
|
||||
|
||||
class testMain(unittest.TestCase):
|
||||
@mock.patch("aprsd.main._imap_connect")
|
||||
@mock.patch("aprsd.main._smtp_connect")
|
||||
def test_validate_email(self, imap_mock, smtp_mock):
|
||||
"""Test to make sure we fail."""
|
||||
imap_mock.return_value = None
|
||||
smtp_mock.return_value = {"smaiof": "fire"}
|
||||
|
||||
main.validate_email()
|
89
tox.ini
89
tox.ini
@ -1,26 +1,51 @@
|
||||
[tox]
|
||||
minversion = 1.6
|
||||
minversion = 2.9.0
|
||||
skipdist = True
|
||||
envlist = py27,py36,py37,fast8,pep8,cover,docs
|
||||
skip_missing_interpreters = true
|
||||
envlist = py{27,36,37,38},pep8,fmt-check
|
||||
|
||||
# Activate isolated build environment. tox will use a virtual environment
|
||||
# to build a source distribution from the source tree. For build tools and
|
||||
# arguments use the pyproject.toml file as specified in PEP-517 and PEP-518.
|
||||
isolated_build = true
|
||||
|
||||
[testenv]
|
||||
setenv = VIRTUAL_ENV={envdir}
|
||||
usedevelop = True
|
||||
install_command = pip install {opts} {packages}
|
||||
|
||||
deps = -r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
-r{toxinidir}/dev-requirements.txt
|
||||
commands =
|
||||
pytest aprsd/main.py {posargs}
|
||||
# Use -bb to enable BytesWarnings as error to catch str/bytes misuse.
|
||||
# Use -Werror to treat warnings as errors.
|
||||
# {envpython} -bb -Werror -m pytest \
|
||||
# --cov="{envsitepackagesdir}/aprsd" --cov-report=html --cov-report=term {posargs}
|
||||
{envpython} -bb -Werror -m pytest {posargs}
|
||||
|
||||
[testenv:cover]
|
||||
[testenv:py27]
|
||||
setenv = VIRTUAL_ENV={envdir}
|
||||
usedevelop = True
|
||||
install_command = pip install {opts} {packages}
|
||||
deps = -r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements-py2.txt
|
||||
commands =
|
||||
pytest --cov=aprsd
|
||||
# Use -bb to enable BytesWarnings as error to catch str/bytes misuse.
|
||||
# Use -Werror to treat warnings as errors.
|
||||
# {envpython} -bb -Werror -m pytest \
|
||||
# --cov="{envsitepackagesdir}/aprsd" --cov-report=html --cov-report=term {posargs}
|
||||
{envpython} -bb -Werror -m pytest
|
||||
|
||||
[testenv:docs]
|
||||
deps = -r{toxinidir}/test-requirements.txt
|
||||
commands = sphinx-build -b html docs/source docs/html
|
||||
|
||||
[testenv:pep8-27]
|
||||
deps = -r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements-py2.txt
|
||||
commands =
|
||||
flake8 {posargs} aprsd
|
||||
|
||||
[testenv:pep8]
|
||||
commands =
|
||||
flake8 {posargs} aprsd
|
||||
@ -33,7 +58,57 @@ commands =
|
||||
{toxinidir}/tools/fast8.sh
|
||||
passenv = FAST8_NUM_COMMITS
|
||||
|
||||
[testenv:lint]
|
||||
skip_install = true
|
||||
deps =
|
||||
-r{toxinidir}/dev-requirements.txt
|
||||
commands =
|
||||
flake8 aprsd
|
||||
|
||||
[flake8]
|
||||
max-line-length = 99
|
||||
show-source = True
|
||||
ignore = E713,E501
|
||||
ignore = E713,E501,W503
|
||||
extend-ignore = E203,W503
|
||||
extend-exclude = venv
|
||||
exclude = .venv,.git,.tox,dist,doc,.ropeproject
|
||||
|
||||
# This is the configuration for the tox-gh-actions plugin for GitHub Actions
|
||||
# https://github.com/ymyzk/tox-gh-actions
|
||||
# This section is not needed if not using GitHub Actions for CI.
|
||||
[gh-actions]
|
||||
python =
|
||||
2.7: py27, pep8-27
|
||||
3.6: py36, pep8, fmt-check
|
||||
3.7: py38, pep8, fmt-check
|
||||
3.8: py38, pep8, fmt-check, type-check, docs
|
||||
3.9: py39
|
||||
|
||||
[testenv:fmt]
|
||||
# This will reformat your code to comply with pep8
|
||||
# and standard formatting
|
||||
skip_install = true
|
||||
deps =
|
||||
-r{toxinidir}/dev-requirements.txt
|
||||
commands =
|
||||
isort .
|
||||
black .
|
||||
|
||||
[testenv:fmt-check]
|
||||
# Runs a check only on code formatting.
|
||||
# you can fix imports by running isort standalone
|
||||
# you can fix code formatting by running black standalone
|
||||
skip_install = true
|
||||
deps =
|
||||
-r{toxinidir}/dev-requirements.txt
|
||||
commands =
|
||||
isort --check-only .
|
||||
black --check .
|
||||
|
||||
[testenv:type-check]
|
||||
skip_install = true
|
||||
deps =
|
||||
-r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/dev-requirements.txt
|
||||
commands =
|
||||
mypy aprsd
|
||||
|
Loading…
Reference in New Issue
Block a user