Skip to content

Commit

Permalink
Merge pull request #541 from doorstop-dev/use-pytest
Browse files Browse the repository at this point in the history
Drop nose in favor of pytest
  • Loading branch information
jacebrowning committed Jan 22, 2022
2 parents ca11cdd + e66ef53 commit ff87bbc
Show file tree
Hide file tree
Showing 11 changed files with 345 additions and 326 deletions.
2 changes: 0 additions & 2 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ environment:
global:
RANDOM_SEED: 0
matrix:
- PYTHON_MAJOR: 3
PYTHON_MINOR: 6
- PYTHON_MAJOR: 3
PYTHON_MINOR: 7
- PYTHON_MAJOR: 3
Expand Down
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ dist: xenial

language: python
python:
- 3.6
- 3.7
- 3.8
- 3.9
Expand Down
2 changes: 1 addition & 1 deletion .verchew.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ version = GNU Make
[Python]

cli = python
version = 3.6 || 3.7 || 3.8 || 3.9
version = 3.7 || 3.8 || 3.9

[Poetry]

Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 3.0 (alpha)

- Dropped support for Python 3.6.

# 2.2 (2022-01-22)

- Added support for UTF-8 symbols in references. ([@stanislaw](https://github.com/doorstop-dev/doorstop/pull/485))
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* Linux: [https://www.gnu.org/software/make](https://www.gnu.org/software/make)
* Windows: [https://mingw.org/download/installer](https://mingw.org/download/installer)
* Python: `$ pyenv install`
* Poetry: [https://poetry.eustace.io/docs/#installation](https://poetry.eustace.io/docs/#installation)
* Poetry: [https://python-poetry.org/docs/#installation](https://python-poetry.org/docs/#installation)
* Graphviz:
* macOS: `$ brew install graphviz`
* Linux: [https://graphviz.org/download](https://graphviz.org/download/)
Expand Down
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,17 @@ endif

RANDOM_SEED ?= $(shell date +%s)

NOSE_OPTIONS := --with-doctest --traverse-namespace
PYTEST_OPTIONS := --doctest-modules
ifndef DISABLE_COVERAGE
NOSE_OPTIONS += --with-cov --cov=$(PACKAGE) --cov-report=html --cov-report=term-missing
PYTEST_OPTIONS += --cov=$(PACKAGE) --cov-report=html --cov-report=term-missing
endif

.PHONY: test
test: test-all ## Run unit and integration tests

.PHONY: test-unit
test-unit: install
poetry run nosetests $(PACKAGE) $(NOSE_OPTIONS)
poetry run pytest $(PACKAGE) $(PYTEST_OPTIONS)
ifndef DISABLE_COVERAGE
poetry run coveragespace update unit
endif
Expand All @@ -98,7 +98,7 @@ test-int: test-all

.PHONY: test-all
test-all: install
TEST_INTEGRATION=true poetry run nosetests $(PACKAGES) $(NOSE_OPTIONS) --show-skipped
TEST_INTEGRATION=true poetry run pytest $(PACKAGES) $(PYTEST_OPTIONS)
ifndef DISABLE_COVERAGE
poetry run coveragespace update overall
endif
Expand Down
91 changes: 66 additions & 25 deletions bin/verchew
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,22 @@ import re
import sys
from collections import OrderedDict
from subprocess import PIPE, STDOUT, Popen
from typing import Any, Dict


PY2 = sys.version_info[0] == 2

if PY2:
import ConfigParser as configparser # pylint: disable=import-error
import ConfigParser as configparser
from urllib import urlretrieve
else:
import configparser # type: ignore
import configparser
from urllib.request import urlretrieve

__version__ = '3.0'
__version__ = '3.2'

SCRIPT_URL = (
"https://raw.githubusercontent.com/jacebrowning/verchew/main/verchew/script.py"
)

CONFIG_FILENAMES = ['verchew.ini', '.verchew.ini', '.verchewrc', '.verchew']

Expand Down Expand Up @@ -75,13 +80,18 @@ optional = true
""".strip()

STYLE = {"~": "✔", "*": "⭑", "?": "⚠", "x": "✘"}
STYLE = {
"~": "✔",
"?": "▴",
"x": "✘",
"#": "䷉",
}

COLOR = {
"x": "\033[91m", # red
"~": "\033[92m", # green
"?": "\033[93m", # yellow
"*": "\033[94m", # cyan
"x": "\033[91m", # red
"#": "\033[96m", # cyan
None: "\033[0m", # reset
}

Expand All @@ -101,6 +111,10 @@ def main():
log.debug("PWD: %s", os.getenv('PWD'))
log.debug("PATH: %s", os.getenv('PATH'))

if args.vendor:
vendor_script(args.vendor)
sys.exit(0)

path = find_config(args.root, generate=args.init)
config = parse_config(path)

Expand All @@ -109,30 +123,38 @@ def main():


def parse_args():
parser = argparse.ArgumentParser()
parser = argparse.ArgumentParser(description="System dependency version checker.",)

version = "%(prog)s v" + __version__
parser.add_argument('--version', action='version', version=version)
parser.add_argument(
'-r', '--root', metavar='PATH', help="specify a custom project root directory"
'--version', action='version', version=version,
)
parser.add_argument(
'--init', action='store_true', help="generate a sample configuration file"
'-r', '--root', metavar='PATH', help="specify a custom project root directory"
)
parser.add_argument(
'--exit-code',
action='store_true',
help="return a non-zero exit code on failure",
)

group = parser.add_mutually_exclusive_group()
group.add_argument(
group_logging = parser.add_mutually_exclusive_group()
group_logging.add_argument(
'-v', '--verbose', action='count', default=0, help="enable verbose logging"
)
group.add_argument(
group_logging.add_argument(
'-q', '--quiet', action='store_true', help="suppress all output on success"
)

group_commands = parser.add_argument_group('commands')
group_commands.add_argument(
'--init', action='store_true', help="generate a sample configuration file"
)

group_commands.add_argument(
'--vendor', metavar='PATH', help="download the program for offline use"
)

args = parser.parse_args()

return args
Expand All @@ -149,6 +171,20 @@ def configure_logging(count=0):
logging.basicConfig(level=level, format="%(levelname)s: %(message)s")


def vendor_script(path):
root = os.path.abspath(os.path.join(path, os.pardir))
if not os.path.isdir(root):
log.info("Creating directory %s", root)
os.makedirs(root)

log.info("Downloading %s to %s", SCRIPT_URL, path)
urlretrieve(SCRIPT_URL, path)

log.debug("Making %s executable", path)
mode = os.stat(path).st_mode
os.chmod(path, mode | 0o111)


def find_config(root=None, filenames=None, generate=False):
root = root or os.getcwd()
filenames = filenames or CONFIG_FILENAMES
Expand Down Expand Up @@ -184,7 +220,7 @@ def generate_config(root=None, filenames=None):


def parse_config(path):
data: Dict[str, Any] = OrderedDict()
data = OrderedDict() # type: ignore

log.info("Parsing config file: %s", path)
config = configparser.ConfigParser()
Expand All @@ -200,6 +236,10 @@ def parse_config(path):
data[name]['version'] = version
data[name]['patterns'] = [v.strip() for v in version.split('||')]

data[name]['optional'] = data[name].get(
'optional', 'false'
).strip().lower() in ('true', 'yes', 'y', True)

return data


Expand All @@ -217,22 +257,23 @@ def check_dependencies(config):
break
else:
if settings.get('optional'):
show(_("?") + " EXPECTED: {0}".format(settings['version']))
show(_("?") + " EXPECTED (OPTIONAL): {0}".format(settings['version']))
success.append(_("?"))
else:
if QUIET:
print(
"Unmatched {0} version: {1}".format(
name, settings['version'] or "<anything>"
)
)
if "not found" in output:
actual = "Not found"
else:
actual = output.split('\n', maxsplit=1)[0].strip('.')
expected = settings['version'] or "<anything>"
print("{0}: {1}, EXPECTED: {2}".format(name, actual, expected))
show(
_("x")
+ " EXPECTED: {0}".format(settings['version'] or "<anything>")
)
success.append(_("x"))
if settings.get('message'):
show(_("*") + " MESSAGE: {0}".format(settings['message']))
show(_("#") + " MESSAGE: {0}".format(settings['message']))

show("Results: " + " ".join(success), head=True)

Expand All @@ -243,7 +284,7 @@ def get_version(program, argument=None):
if argument is None:
args = [program, '--version']
elif argument:
args = [program, argument]
args = [program] + argument.split()
else:
args = [program]

Expand All @@ -256,7 +297,7 @@ def get_version(program, argument=None):


def match_version(pattern, output):
if "not found" in output:
if "not found" in output.split('\n')[0]:
return False

regex = pattern.replace('.', r'\.') + r'(\b|/)'
Expand Down Expand Up @@ -309,7 +350,7 @@ def _(word, is_tty=None, supports_utf8=None, supports_ansi=None):
if is_tty is None:
is_tty = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()
if supports_utf8 is None:
supports_utf8 = sys.stdout.encoding == 'UTF-8'
supports_utf8 = str(sys.stdout.encoding).lower() == 'utf-8'
if supports_ansi is None:
supports_ansi = sys.platform != 'win32' or 'ANSICON' in os.environ

Expand Down
4 changes: 2 additions & 2 deletions docs/getting-started/installation.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<h1> Installation </h1>

Doorstop requires [Python](https://www.python.org/) v3.5+ and [Git](https://git-scm.com/) or other version control system.
Doorstop requires [Python](https://www.python.org/) and [Git](https://git-scm.com/) or another version control system.

Once Python is installed on your platform, install Doorstop using pip.

```sh
pip install doorstop
```

or add it to your [Poetry](https://poetry.eustace.io/) project:
or add it to your [Poetry](https://python-poetry.org/) project:

```sh
$ poetry add doorstop
Expand Down
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
mkdocs==1.1.2
mkdocs==1.2.3
Pygments==2.7.4

0 comments on commit ff87bbc

Please sign in to comment.