Fixed #30393 -- Added validation of startapp's directory option.

This commit is contained in:
oliver 2019-04-25 11:28:31 +09:00 committed by Mariusz Felisiak
parent 0f22671ecb
commit fc9566d42d
2 changed files with 28 additions and 5 deletions

View File

@ -74,6 +74,8 @@ class TemplateCommand(BaseCommand):
except OSError as e: except OSError as e:
raise CommandError(e) raise CommandError(e)
else: else:
if app_or_project == 'app':
self.validate_name(os.path.basename(target), 'directory')
top_dir = os.path.abspath(path.expanduser(target)) top_dir = os.path.abspath(path.expanduser(target))
if not os.path.exists(top_dir): if not os.path.exists(top_dir):
raise CommandError("Destination directory '%s' does not " raise CommandError("Destination directory '%s' does not "
@ -205,7 +207,7 @@ class TemplateCommand(BaseCommand):
raise CommandError("couldn't handle %s template %s." % raise CommandError("couldn't handle %s template %s." %
(self.app_or_project, template)) (self.app_or_project, template))
def validate_name(self, name): def validate_name(self, name, name_or_dir='name'):
if name is None: if name is None:
raise CommandError('you must provide {an} {app} name'.format( raise CommandError('you must provide {an} {app} name'.format(
an=self.a_or_an, an=self.a_or_an,
@ -214,10 +216,11 @@ class TemplateCommand(BaseCommand):
# Check it's a valid directory name. # Check it's a valid directory name.
if not name.isidentifier(): if not name.isidentifier():
raise CommandError( raise CommandError(
"'{name}' is not a valid {app} name. Please make sure the " "'{name}' is not a valid {app} {type}. Please make sure the "
"name is a valid identifier.".format( "{type} is a valid identifier.".format(
name=name, name=name,
app=self.app_or_project, app=self.app_or_project,
type=name_or_dir,
) )
) )
# Check it cannot be imported. # Check it cannot be imported.
@ -228,11 +231,12 @@ class TemplateCommand(BaseCommand):
else: else:
raise CommandError( raise CommandError(
"'{name}' conflicts with the name of an existing Python " "'{name}' conflicts with the name of an existing Python "
"module and cannot be used as {an} {app} name. Please try " "module and cannot be used as {an} {app} {type}. Please try "
"another name.".format( "another {type}.".format(
name=name, name=name,
an=self.a_or_an, an=self.a_or_an,
app=self.app_or_project, app=self.app_or_project,
type=name_or_dir,
) )
) )

View File

@ -2132,6 +2132,25 @@ class StartApp(AdminScriptTestCase):
) )
self.assertFalse(os.path.exists(testproject_dir)) self.assertFalse(os.path.exists(testproject_dir))
def test_invalid_target_name(self):
for bad_target in ('invalid.dir_name', '7invalid_dir_name', '.invalid_dir_name'):
with self.subTest(bad_target):
_, err = self.run_django_admin(['startapp', 'app', bad_target])
self.assertOutput(
err,
"CommandError: '%s' is not a valid app directory. Please "
"make sure the directory is a valid identifier." % bad_target
)
def test_importable_target_name(self):
_, err = self.run_django_admin(['startapp', 'app', 'os'])
self.assertOutput(
err,
"CommandError: 'os' conflicts with the name of an existing Python "
"module and cannot be used as an app directory. Please try "
"another directory."
)
def test_overlaying_app(self): def test_overlaying_app(self):
self.run_django_admin(['startapp', 'app1']) self.run_django_admin(['startapp', 'app1'])
out, err = self.run_django_admin(['startapp', 'app2', 'app1']) out, err = self.run_django_admin(['startapp', 'app2', 'app1'])