diff --git a/Makefile b/Makefile index 219a4dcd..91bea4bb 100644 --- a/Makefile +++ b/Makefile @@ -22,10 +22,10 @@ virtualenv: virtualenv-windows: virtualenv --prompt '|> cement <| ' env-windows - env-windows\\Scripts\\pip.exe install -r requirements-dev.txt - env\\bin\\python.exe setup.py develop + env-windows\\Scripts\\pip.exe install -r requirements-dev-windows.txt + env-windows\\Scripts\\python.exe setup.py develop @echo - @echo "VirtualENV Setup Complete. Now run: .\\env\\Scripts\\activate.ps1" + @echo "VirtualENV Setup Complete. Now run: .\env-windows\Scripts\activate.ps1" @echo comply: diff --git a/README.md b/README.md index ba729b6d..f420b459 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,18 @@ $ docker-compose up -d $ docker-compose exec cement /bin/ash ``` +### VirtualENV + +An traditional VirtualENV helper is available: + +``` +$ make virtualenv + +$ source env/bin/activate + +|> cement <| $ +``` + ### Vagrant An alternative option is included to run Vagrant for development. This is partially supported, primarily for the purpose of developing/testing on Windows as well as testing specific issues on target operating systems. @@ -88,11 +100,11 @@ vagrant@linux $ cd /vagrant vagrant@linux $ bash scripts/vagrant/bootstrap.sh +vagrant@linux $ make virtualenv + vagrant@linux $ source env/bin/activate -|> cement >| $ pip install -r requirements-dev.txt - -|> cement >| $ python setup.py develop +|> cement >| $ ``` #### Windows @@ -114,13 +126,15 @@ C:\> cd C:\Vagrant C:\Vagrant> powershell.exe scripts\vagrant\bootstrap.ps1 +C:\Vagrant> make virtualenv-windows + C:\Vagrant> .\env-windows\Scripts\activate.ps1 -C:\Vagrant> pip install -r requirements-dev.txt - -C:\Vagrant> python setup.py develop +C:\Vagrant> make test-core ``` +*Note that only the core library is fully tested on Windows.* + ### Running Tests and Compliance diff --git a/cement/core/template.py b/cement/core/template.py index fd37d81f..6edcbad3 100644 --- a/cement/core/template.py +++ b/cement/core/template.py @@ -5,6 +5,7 @@ import sys import pkgutil import re import shutil +import platform from abc import abstractmethod from ..core import exc from ..core.interface import Interface @@ -232,6 +233,11 @@ class TemplateHandler(TemplateInterface, Handler): os.makedirs(sub_dir_dest) for _file in files: + # windows paths (if condition to avoid unknown breakage) + if platform.system().lower() in ['windows']: + src = src.encode('unicode-escape') # pragma: nocover + src = str(src) # pragma: nocover + new_file = re.sub(src, '', self.render(_file, data)) _file = fs.abspath(os.path.join(cur_dir, _file)) _file_dest = fs.abspath(os.path.join(cur_dir_dest, new_file)) diff --git a/requirements-dev-windows.txt b/requirements-dev-windows.txt new file mode 100644 index 00000000..db5c42db --- /dev/null +++ b/requirements-dev-windows.txt @@ -0,0 +1,29 @@ +# The following are only required for Cement development +pytest +pytest-cov +coverage +sphinx +sphinx_rtd_theme +pep8 +autopep8 +# version cap due to bug: https://gitlab.com/pycqa/flake8/issues/406 +pycodestyle<2.4 +flake8 +guzzle_sphinx_theme +sphinxcontrib-napoleon +mock +twine>=1.11.0 +setuptools>=38.6.0 +wheel>=0.31.0 + +# Required for optional extensions +pystache +pyYaml +redis +colorlog +tabulate +jinja2 +watchdog + +# unknown/broken/untested +# pylibmc diff --git a/requirements-dev.txt b/requirements-dev.txt index f15368aa..e9a8b8df 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -24,6 +24,4 @@ colorlog tabulate jinja2 watchdog - -# These are known to fail on windows (put at end so it doesn't block) pylibmc diff --git a/scripts/vagrant/bootstrap.ps1 b/scripts/vagrant/bootstrap.ps1 index de80f4c9..55d6a362 100644 --- a/scripts/vagrant/bootstrap.ps1 +++ b/scripts/vagrant/bootstrap.ps1 @@ -78,7 +78,6 @@ Function Do-Python { } C:\Python37\Scripts\pip.exe install virtualenv - C:\Python37\Scripts\virtualenv.exe env-windows } Function Do-Misc { diff --git a/scripts/vagrant/bootstrap.sh b/scripts/vagrant/bootstrap.sh index 3958a1a9..abd6bb1f 100755 --- a/scripts/vagrant/bootstrap.sh +++ b/scripts/vagrant/bootstrap.sh @@ -98,10 +98,6 @@ case "$DISTRO" in esac -### should work on all distros we are trying to support - -virtualenv --prompt="|> cement <| " --python=$(which python3) /vagrant/env - # for tests sudo systemctl restart memcached diff --git a/tests/conftest.py b/tests/conftest.py index d166a73d..aba3f11d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,18 +3,12 @@ import os import shutil import pytest from cement.utils.misc import rando as _rando -from tempfile import mkstemp, mkdtemp +from cement.utils import fs @pytest.fixture(scope="function") def tmp(request): - class Tmp(object): - cleanup = True - - def __init__(self): - self.dir = mkdtemp() - _, self.file = mkstemp(dir=self.dir) - t = Tmp() + t = fs.Tmp() yield t # cleanup diff --git a/tests/core/test_foundation.py b/tests/core/test_foundation.py index e8af6248..37439c96 100644 --- a/tests/core/test_foundation.py +++ b/tests/core/test_foundation.py @@ -5,6 +5,7 @@ import re import pytest import json import signal +import platform from unittest.mock import Mock, MagicMock from cement import App, Controller, ex @@ -101,22 +102,35 @@ def test_basic(): app.run() -def test_loaded(): - ext_list = [ - 'alarm', - 'colorlog', - 'daemon', - 'dummy', - 'jinja2', - 'json', - 'memcached', - 'mustache', - 'redis', - 'smtp', - 'tabulate', - 'watchdog', - 'yaml', - ] +def test_loaded_extensions(): + if platform.system().lower() in ['windows']: + ext_list = [ + 'colorlog', + 'dummy', + 'jinja2', + 'json', + 'mustache', + 'smtp', + 'tabulate', + 'watchdog', + 'yaml', + ] + else: + ext_list = [ + 'alarm', + 'colorlog', + 'daemon', + 'dummy', + 'jinja2', + 'json', + 'memcached', + 'mustache', + 'redis', + 'smtp', + 'tabulate', + 'watchdog', + 'yaml', + ] class MyApp(TestApp): class Meta: @@ -324,12 +338,20 @@ def test_config_files_is_none(): with ThisApp('test-app', config_files=None) as app: user_home = fs.abspath(fs.HOME_DIR) - files = [ - os.path.join('/', 'etc', app.label, '%s.conf' % app.label), - os.path.join(user_home, '.%s.conf' % app.label), - os.path.join(user_home, '.%s' % app.label, 'config', - '%s.conf' % app.label), - ] + if platform.system().lower() in ['windows']: + files = [ + os.path.join('C:\\', 'etc', app.label, '%s.conf' % app.label), + os.path.join(user_home, '.%s.conf' % app.label), + os.path.join(user_home, '.%s' % app.label, 'config', + '%s.conf' % app.label), + ] + else: + files = [ + os.path.join('/', 'etc', app.label, '%s.conf' % app.label), + os.path.join(user_home, '.%s.conf' % app.label), + os.path.join(user_home, '.%s' % app.label, 'config', + '%s.conf' % app.label), + ] for f in files: assert f in app._meta.config_files @@ -470,6 +492,9 @@ def test_reload(): def test_run_forever(): + if platform.system().lower() in ['windows']: + pytest.skip('Unable to test run_forever on Windows') + class MyController(Controller): class Meta: label = 'base'