From 08224c92f4b17c0b88b9df8f94479a9a66a352c8 Mon Sep 17 00:00:00 2001 From: Nuno Maximiano Date: Fri, 18 Oct 2013 14:46:55 +0100 Subject: [PATCH 1/2] add project name validation --- scrapy/commands/startproject.py | 34 ++++++++++++++++++--------------- tests/test_commands.py | 1 + 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/scrapy/commands/startproject.py b/scrapy/commands/startproject.py index c266f75c4..a6d200607 100644 --- a/scrapy/commands/startproject.py +++ b/scrapy/commands/startproject.py @@ -43,18 +43,22 @@ class Command(ScrapyCommand): elif exists(project_name): print("Error: directory %r already exists" % project_name) sys.exit(1) - - moduletpl = join(TEMPLATES_PATH, 'module') - copytree(moduletpl, join(project_name, project_name), ignore=IGNORE) - shutil.copy(join(TEMPLATES_PATH, 'scrapy.cfg'), project_name) - for paths in TEMPLATES_TO_RENDER: - path = join(*paths) - tplfile = join(project_name, - string.Template(path).substitute(project_name=project_name)) - render_templatefile(tplfile, project_name=project_name, - ProjectName=string_camelcase(project_name)) - print("New Scrapy project %r created in:" % project_name) - print(" %s\n" % abspath(project_name)) - print("You can start your first spider with:") - print(" cd %s" % project_name) - print(" scrapy genspider example example.com") + try: + __import__(project_name, [], 0) + print('Error: Project name can\'t be %r, choose another project name' % project_name) + sys.exit(1) + except ImportError: + moduletpl = join(TEMPLATES_PATH, 'module') + copytree(moduletpl, join(project_name, project_name), ignore=IGNORE) + shutil.copy(join(TEMPLATES_PATH, 'scrapy.cfg'), project_name) + for paths in TEMPLATES_TO_RENDER: + path = join(*paths) + tplfile = join(project_name, + string.Template(path).substitute(project_name=project_name)) + render_templatefile(tplfile, project_name=project_name, + ProjectName=string_camelcase(project_name)) + print("New Scrapy project %r created in:" % project_name) + print(" %s\n" % abspath(project_name)) + print("You can start your first spider with:") + print(" cd %s" % project_name) + print(" scrapy genspider example example.com") diff --git a/tests/test_commands.py b/tests/test_commands.py index f7710f03b..eefda833e 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -64,6 +64,7 @@ class StartprojectTest(ProjectTest): self.assertEqual(1, self.call('startproject', self.project_name)) self.assertEqual(1, self.call('startproject', 'wrong---project---name')) + self.assertEqual(1, self.call('startproject', 'sys')) class CommandTest(ProjectTest): From 53e74a69ded1a187e77bb4ca199f0948b8b88d9a Mon Sep 17 00:00:00 2001 From: nramirezuy Date: Fri, 25 Jul 2014 15:02:15 -0300 Subject: [PATCH 2/2] exitcode and prints fixed, some code reworking --- scrapy/commands/startproject.py | 70 ++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/scrapy/commands/startproject.py b/scrapy/commands/startproject.py index a6d200607..5c8783ceb 100644 --- a/scrapy/commands/startproject.py +++ b/scrapy/commands/startproject.py @@ -1,8 +1,8 @@ from __future__ import print_function -import sys -import string import re import shutil +import string +from importlib import import_module from os.path import join, exists, abspath from shutil import copytree, ignore_patterns @@ -11,6 +11,7 @@ from scrapy.command import ScrapyCommand from scrapy.utils.template import render_templatefile, string_camelcase from scrapy.exceptions import UsageError + TEMPLATES_PATH = join(scrapy.__path__[0], 'templates', 'project') TEMPLATES_TO_RENDER = ( @@ -22,6 +23,7 @@ TEMPLATES_TO_RENDER = ( IGNORE = ignore_patterns('*.pyc', '.svn') + class Command(ScrapyCommand): requires_project = False @@ -32,33 +34,45 @@ class Command(ScrapyCommand): def short_desc(self): return "Create new project" + def _is_valid_name(self, project_name): + def _module_exists(module_name): + try: + import_module(module_name) + return True + except ImportError: + return False + + if not re.search(r'^[_a-zA-Z]\w*$', project_name): + print('Error: Project names must begin with a letter and contain'\ + ' only\nletters, numbers and underscores') + elif exists(project_name): + print('Error: Directory %r already exists' % project_name) + elif _module_exists(project_name): + print('Error: Module %r already exists' % project_name) + else: + return True + return False + def run(self, args, opts): if len(args) != 1: raise UsageError() project_name = args[0] - if not re.search(r'^[_a-zA-Z]\w*$', project_name): - print('Error: Project names must begin with a letter and contain only\n' \ - 'letters, numbers and underscores') - sys.exit(1) - elif exists(project_name): - print("Error: directory %r already exists" % project_name) - sys.exit(1) - try: - __import__(project_name, [], 0) - print('Error: Project name can\'t be %r, choose another project name' % project_name) - sys.exit(1) - except ImportError: - moduletpl = join(TEMPLATES_PATH, 'module') - copytree(moduletpl, join(project_name, project_name), ignore=IGNORE) - shutil.copy(join(TEMPLATES_PATH, 'scrapy.cfg'), project_name) - for paths in TEMPLATES_TO_RENDER: - path = join(*paths) - tplfile = join(project_name, - string.Template(path).substitute(project_name=project_name)) - render_templatefile(tplfile, project_name=project_name, - ProjectName=string_camelcase(project_name)) - print("New Scrapy project %r created in:" % project_name) - print(" %s\n" % abspath(project_name)) - print("You can start your first spider with:") - print(" cd %s" % project_name) - print(" scrapy genspider example example.com") + + if not self._is_valid_name(project_name): + self.exitcode = 1 + return + + moduletpl = join(TEMPLATES_PATH, 'module') + copytree(moduletpl, join(project_name, project_name), ignore=IGNORE) + shutil.copy(join(TEMPLATES_PATH, 'scrapy.cfg'), project_name) + for paths in TEMPLATES_TO_RENDER: + path = join(*paths) + tplfile = join(project_name, + string.Template(path).substitute(project_name=project_name)) + render_templatefile(tplfile, project_name=project_name, + ProjectName=string_camelcase(project_name)) + print("New Scrapy project %r created in:" % project_name) + print(" %s\n" % abspath(project_name)) + print("You can start your first spider with:") + print(" cd %s" % project_name) + print(" scrapy genspider example example.com")