Fixed #30393 -- Added validation of startapp's directory option.
This commit is contained in:
parent
0f22671ecb
commit
fc9566d42d
|
@ -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,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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'])
|
||||||
|
|
Loading…
Reference in New Issue