diff --git a/kaylee/loader.py b/kaylee/loader.py index ea948db..1292f4a 100644 --- a/kaylee/loader.py +++ b/kaylee/loader.py @@ -151,7 +151,7 @@ def applications(self): def _update_classes(self, module): """Updates the _classes field by the classes found in the module.""" - classes_from_module = self.get_classes_from_module(module) + classes_from_module = get_classes_from_module(module) for base_class in self._loadable_base_classes: # update _classes[base_class] with # { class_name : class } pairs, where `class` is a subclass of @@ -192,10 +192,10 @@ def _load_controller(self, conf): **conf['controller'].get('config', {})) return cobj - @staticmethod - def get_classes_from_module(module): - return [attr for attr in module.__dict__.values() - if inspect.isclass(attr)] + +def get_classes_from_module(module): + return [attr for attr in module.__dict__.values() + if inspect.isclass(attr)] def find_packages(path): for sub_dir in os.listdir(path): diff --git a/kaylee/manager/commands/build.py b/kaylee/manager/commands/build.py index ae2b9be..0ccf37a 100644 --- a/kaylee/manager/commands/build.py +++ b/kaylee/manager/commands/build.py @@ -1,11 +1,13 @@ from __future__ import print_function import os +import sys import imp +import importlib import subprocess import shutil import kaylee from kaylee.manager import LocalCommand -from kaylee.loader import find_packages +from kaylee.loader import find_packages, get_classes_from_module from kaylee.util import ensure_dir @@ -86,20 +88,13 @@ def build_projects(settings, opts): data_handler, ] - # os.walk for files with by-extension sorting - def _fwalk(path): - sort_key = lambda fname: fname.rsplit()[-1] - #pylint: disable-msg=W0612 - #W0612: Unused variable 'dirs' - for root, dirs, files in os.walk(path): - for fname in sorted(files, key=sort_key): - yield os.path.join(root, fname) + # Make sure that the command is able to import the projects' + # Python packages. + sys.path.insert(0, settings.PROJECTS_DIR) for pkg_dir in find_packages(settings.PROJECTS_DIR): - client_dir = os.path.join(pkg_dir, 'client') - if not os.path.isdir(client_dir): - break - + if not is_kaylee_project_directory(pkg_dir): + continue print('* Building {}...'.format(pkg_dir)) dest_dir = os.path.join(opts.build_dir, pkg_dir) opts.dest_dir = dest_dir @@ -108,11 +103,27 @@ def _fwalk(path): shutil.rmtree(dest_dir) # build project client by applying appropriate # file handlers - for fpath in _fwalk(client_dir): + client_dir = os.path.join(pkg_dir, 'client') + for fname in os.listdir(client_dir): + fpath = os.path.join(client_dir, fname) + if not os.path.isfile(fpath): + continue for handler in filetype_handlers: if handler(fpath, opts) == True: break +def is_kaylee_project_directory(path): + # check if 'client' directory exists + client_dir = os.path.join(path, 'client') + if not os.path.isdir(client_dir): + return False + # check for kaylee.Project subclass + package_name = path.rsplit('/')[-1] + pymod = importlib.import_module(package_name) + for cls in get_classes_from_module(pymod): + if issubclass(cls, kaylee.project.Project): + return True + return False def coffee_handler(fpath, opts): if not fpath.endswith('.coffee'): diff --git a/kaylee/manager/commands/start_env.py b/kaylee/manager/commands/start_env.py index 17644db..3a0c844 100644 --- a/kaylee/manager/commands/start_env.py +++ b/kaylee/manager/commands/start_env.py @@ -1,6 +1,5 @@ import os import stat -import shutil from jinja2 import Template from kaylee.manager import AdminCommand from kaylee.util import random_string @@ -19,7 +18,6 @@ def execute(opts): start_env(opts) - def start_env(opts): ENV_TEMPLATE_DIR = 'templates/env_template' ENV_TEMPLATE_PATH = os.path.join(os.path.dirname(__file__), @@ -30,14 +28,17 @@ def start_env(opts): ('settings.py', 'settings.py'), ] - dest_path = os.path.join(os.getcwd(), opts.name) + if opts.name == '.': + dest_path = os.getcwd() + else: + dest_path = os.path.join(os.getcwd(), opts.name) + os.mkdir(dest_path) render_args = { 'SECRET_KEY' : random_string(32), 'PROJECTS_DIR' : dest_path, } - shutil.copytree(ENV_TEMPLATE_PATH, dest_path) for fname, out_fname in TEMPLATE_FILES: template_path = os.path.join(ENV_TEMPLATE_PATH, fname) with open(template_path) as f: @@ -52,5 +53,6 @@ def start_env(opts): st = os.stat(klmanage_path) os.chmod(klmanage_path, st.st_mode | stat.S_IEXEC) - print('Kaylee environment "{}" has been successfully created.' - .format(opts.name)) + _dirname = 'current directory' if opts.name == '.' else opts.name + print('Kaylee environment has been successfully created in {}' + .format(_dirname)) diff --git a/kaylee/testsuite/commands_manager_tests.py b/kaylee/testsuite/commands_manager_tests.py index 0a09de8..972cb2a 100644 --- a/kaylee/testsuite/commands_manager_tests.py +++ b/kaylee/testsuite/commands_manager_tests.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- import os +import sys import stat import tempfile import shutil @@ -72,7 +73,6 @@ def test_start_env(self): 'klenv/klmanage.py', 'klenv/settings.py', ] - for fpath in files_to_validate: full_path = _pjoin(tmpdir, fpath) self.assertGreater(os.path.getsize(full_path), 0) @@ -85,6 +85,18 @@ def test_start_env(self): self.assertEqual(settings.PROJECTS_DIR, _pjoin(tmpdir, 'klenv')) + # test 'startenv .' case + tmpdir = tmp_chdir() + with nostdout(): + manager.parse(['startenv', '.']) + files_to_validate = [ + 'klmanage.py', + 'settings.py', + ] + for fpath in files_to_validate: + full_path = _pjoin(tmpdir, fpath) + self.assertGreater(os.path.getsize(full_path), 0) + def test_start_project(self): manager = LocalCommandsManager() @@ -135,14 +147,23 @@ def test_build(self): env_path = _start_env() os.chdir(env_path) - # copy a ready test 'pi calc' project to the environment - shutil.copytree(_pjoin(RES_DIR, 'pi_calc'), - _pjoin(env_path, 'pi_calc')) + # copy a test 'pi calc' project to the environment + res_path = _pjoin(RES_DIR, 'pi_calc') + dest_path = _pjoin(env_path, 'pi_calc') + shutil.copytree(res_path, dest_path) + + # test plain is_kaylee_project_directory() + sys.path.insert(0, env_path) + from kaylee.manager.commands.build import is_kaylee_project_directory + self.assertTrue(is_kaylee_project_directory(res_path)) + self.assertFalse(is_kaylee_project_directory('/etc')) + del sys.path[0] with nostdout(): lmanager.parse(['build']) build_path = os.path.join(env_path, '_build') + self.assertTrue(os.path.exists(build_path), build_path) project_files_to_validate = [ 'js/pi_calc.js', 'css/pi_calc.css', @@ -154,7 +175,7 @@ def test_build(self): ] for fname in project_files_to_validate: fpath = os.path.join(build_path, 'pi_calc', fname) - self.assertTrue(os.path.exists(fpath)) + self.assertTrue(os.path.exists(fpath), fpath) kaylee_files_to_validate = [ 'js/kaylee.js', @@ -167,7 +188,6 @@ def test_build(self): fpath = os.path.join(build_path, 'kaylee', fname) self.assertTrue(os.path.exists(fpath)) - def test_run(self): env_path = _start_env() os.chdir(env_path) diff --git a/kaylee/util.py b/kaylee/util.py index c2dfd66..73193d8 100644 --- a/kaylee/util.py +++ b/kaylee/util.py @@ -182,9 +182,7 @@ def write(self, _): sys.stdout = Devnull() if stderr: sys.stderr = Devnull() - yield - sys.stdout = savestdout sys.stderr = savestderr