diff --git a/django/core/management/templates.py b/django/core/management/templates.py index 633eed781d..0b63631638 100644 --- a/django/core/management/templates.py +++ b/django/core/management/templates.py @@ -4,6 +4,7 @@ import os import posixpath import shutil import stat +import sys import tempfile from importlib.util import find_spec from urllib.request import build_opener @@ -230,6 +231,17 @@ class TemplateCommand(BaseCommand): shutil.rmtree(path_to_remove) run_formatters([top_dir], **formatter_paths) + self.handle_target(name, target) + + def handle_target(self, name, target=None): + if target is None: + target = os.getcwd() + else: + target = os.path.abspath(target) + + # call needed to avoid windows encoding errors + sys.stdout.reconfigure(encoding="utf-8") + self.stdout.write(f"Success! Created {name} at {target}.") def handle_template(self, template, subdir): """ diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py index 688aaa0a2f..1a326faeae 100644 --- a/tests/admin_scripts/tests.py +++ b/tests/admin_scripts/tests.py @@ -754,6 +754,7 @@ class DjangoAdminSettingsDirectory(AdminScriptTestCase): args = ["startapp", "こんにちは"] app_path = os.path.join(self.test_dir, "こんにちは") out, err = self.run_django_admin(args, "test_project.settings") + self.assertOutput(out, f"Success! Created こんにちは at {self.test_dir}") self.assertNoOutput(err) self.assertTrue(os.path.exists(app_path)) with open(os.path.join(app_path, "apps.py"), encoding="utf8") as f: @@ -2405,6 +2406,21 @@ class StartProject(LiveServerTestCase, AdminScriptTestCase): self.assertOutput(err, "usage:") self.assertOutput(err, "You must provide a project name.") + def test_output(self): + dirs = { + "testproject": self.test_dir, + "testproject1": os.path.join(self.test_dir, "otherdirectory"), + } + for name_project, dir in dirs.items(): + with self.subTest(name_project=name_project, dir=dir): + args = ["startproject", name_project] + if not os.path.exists(dir): + os.mkdir(dir) + args.append(dir) + out, err = self.run_django_admin(args) + self.assertOutput(out, f"Success! Created {name_project} at {dir}") + self.assertNoOutput(err) + def test_simple_project(self): "Make sure the startproject management command creates a project" args = ["startproject", "testproject"] @@ -2879,6 +2895,22 @@ class StartApp(AdminScriptTestCase): ) self.assertFalse(os.path.exists(testproject_dir)) + def test_output(self): + dirs = { + "foo": self.test_dir, + # Use a subdirectory so it is outside the PYTHONPATH. + "bar": os.path.join(self.test_dir, "apps/otherdir"), + } + for name_app, dir in dirs.items(): + with self.subTest(name_app=name_app, dir=dir): + args = ["startapp", name_app] + if not os.path.exists(dir): + os.makedirs(dir) + args.append(dir) + out, err = self.run_django_admin(args) + self.assertOutput(out, f"Success! Created {name_app} at {dir}") + self.assertNoOutput(err) + def test_importable_name(self): """ startapp validates that app name doesn't clash with existing Python