diff --git a/django/core/management/templates.py b/django/core/management/templates.py index cf6801d18bc..307841522ec 100644 --- a/django/core/management/templates.py +++ b/django/core/management/templates.py @@ -160,7 +160,7 @@ class TemplateCommand(BaseCommand): if self.verbosity >= 2: self.stdout.write("Cleaning up temporary files.\n") for path_to_remove in self.paths_to_remove: - if os.path.isfile(path_to_remove): + if path.isfile(path_to_remove): os.remove(path_to_remove) else: shutil.rmtree(path_to_remove, @@ -178,14 +178,15 @@ class TemplateCommand(BaseCommand): if template.startswith('file://'): template = template[7:] expanded_template = path.expanduser(template) - if os.path.isdir(expanded_template): + expanded_template = path.normpath(expanded_template) + if path.isdir(expanded_template): return expanded_template if self.is_url(template): # downloads the file and returns the path absolute_path = self.download(template) else: absolute_path = path.abspath(expanded_template) - if os.path.exists(absolute_path): + if path.exists(absolute_path): return self.extract(absolute_path) raise CommandError("couldn't handle %s template %s." % @@ -203,13 +204,13 @@ class TemplateCommand(BaseCommand): if self.verbosity >= 2: self.stdout.write("Downloading %s\n" % url) try: - path, info = urllib.urlretrieve(url, - os.path.join(tempdir, filename)) + the_path, info = urllib.urlretrieve(url, + path.join(tempdir, filename)) except IOError, e: raise CommandError("couldn't download URL %s to %s: %s" % (url, filename, e)) - used_name = path.split('/')[-1] + used_name = the_path.split('/')[-1] # Trying to get better name from response headers content_disposition = info.get('content-disposition') @@ -230,18 +231,18 @@ class TemplateCommand(BaseCommand): # Move the temporary file to a filename that has better # chances of being recognnized by the archive utils if used_name != guessed_filename: - guessed_path = os.path.join(tempdir, guessed_filename) - shutil.move(path, guessed_path) + guessed_path = path.join(tempdir, guessed_filename) + shutil.move(the_path, guessed_path) return guessed_path # Giving up - return path + return the_path - def splitext(self, path): + def splitext(self, the_path): """ Like os.path.splitext, but takes off .tar, too """ - base, ext = posixpath.splitext(path) + base, ext = posixpath.splitext(the_path) if base.lower().endswith('.tar'): ext = base[-4:] + ext base = base[:-4] diff --git a/tests/regressiontests/admin_scripts/tests.py b/tests/regressiontests/admin_scripts/tests.py index 062e1a2c757..d33cfee83b8 100644 --- a/tests/regressiontests/admin_scripts/tests.py +++ b/tests/regressiontests/admin_scripts/tests.py @@ -1414,6 +1414,18 @@ class StartProject(LiveServerTestCase, AdminScriptTestCase): self.assertTrue(os.path.isdir(testproject_dir)) self.assertTrue(os.path.exists(os.path.join(testproject_dir, 'additional_dir'))) + def test_template_dir_with_trailing_slash(self): + "Ticket 17475: Template dir passed has a trailing path separator" + template_path = os.path.join(test_dir, 'admin_scripts', 'custom_templates', 'project_template' + os.sep) + args = ['startproject', '--template', template_path, 'customtestproject'] + testproject_dir = os.path.join(test_dir, 'customtestproject') + + out, err = self.run_django_admin(args) + self.addCleanup(shutil.rmtree, testproject_dir) + self.assertNoOutput(err) + self.assertTrue(os.path.isdir(testproject_dir)) + self.assertTrue(os.path.exists(os.path.join(testproject_dir, 'additional_dir'))) + def test_custom_project_template_from_tarball_by_path(self): "Make sure the startproject management command is able to use a different project template from a tarball" template_path = os.path.join(test_dir, 'admin_scripts', 'custom_templates', 'project_template.tgz') diff --git a/tests/urls.py b/tests/urls.py index 4cd603e29f9..4f37ab5f52b 100644 --- a/tests/urls.py +++ b/tests/urls.py @@ -27,7 +27,7 @@ urlpatterns = patterns('', # admin custom URL tests (r'^custom_urls/', include('regressiontests.admin_custom_urls.urls')), - # admin custom URL tests + # admin scripts tests (r'^admin_scripts/', include('regressiontests.admin_scripts.urls')), )