Commit 0c9e8869 authored by PJ Eby's avatar PJ Eby

Add "safe_name" and "safe_version" functions to allow sanitizing of

distribution names and versions in arbitrary packages that might be built
using EasyInstall.

--HG--
branch : setuptools
extra : convert_revision : svn%3A6015fed2-1504-0410-9fe1-9d1591cc4771/sandbox/trunk/setuptools%4041040
parent 992e379c
...@@ -22,11 +22,23 @@ __all__ = [ ...@@ -22,11 +22,23 @@ __all__ = [
'InvalidOption', 'Distribution', 'Requirement', 'yield_lines', 'InvalidOption', 'Distribution', 'Requirement', 'yield_lines',
'get_importer', 'find_distributions', 'find_on_path', 'register_finder', 'get_importer', 'find_distributions', 'find_on_path', 'register_finder',
'split_sections', 'declare_namespace', 'register_namespace_handler', 'split_sections', 'declare_namespace', 'register_namespace_handler',
'safe_name', 'safe_version'
] ]
import sys, os, zipimport, time, re, imp import sys, os, zipimport, time, re, imp
from sets import ImmutableSet from sets import ImmutableSet
class ResolutionError(Exception): class ResolutionError(Exception):
"""Abstract base for dependency resolution errors""" """Abstract base for dependency resolution errors"""
...@@ -57,6 +69,17 @@ def get_provider(moduleName): ...@@ -57,6 +69,17 @@ def get_provider(moduleName):
loader = getattr(module, '__loader__', None) loader = getattr(module, '__loader__', None)
return _find_adapter(_provider_factories, loader)(module) return _find_adapter(_provider_factories, loader)(module)
def get_platform(): def get_platform():
"""Return this platform's string for platform-specific distributions """Return this platform's string for platform-specific distributions
...@@ -80,6 +103,24 @@ def compatible_platforms(provided,required): ...@@ -80,6 +103,24 @@ def compatible_platforms(provided,required):
return False return False
class IMetadataProvider: class IMetadataProvider:
def has_metadata(name): def has_metadata(name):
...@@ -424,22 +465,22 @@ def require(*requirements): ...@@ -424,22 +465,22 @@ def require(*requirements):
dist.install_on(sys.path) dist.install_on(sys.path)
def safe_name(name):
"""Convert an arbitrary string to a standard distribution name
Any runs of non-alphanumeric characters are replaced with a single '-'.
"""
return re.sub('[^A-Za-z0-9]+', '-', name)
def safe_version(version):
"""Convert an arbitrary string to a standard version string
Spaces become dots, and all other non-alphanumeric characters become
dashes, with runs of multiple dashes condensed to a single dash.
"""
version = version.replace(' ','.')
return re.sub('[^A-Za-z0-9.]+', '-', version)
......
...@@ -10,7 +10,7 @@ from distutils.dir_util import create_tree, remove_tree, ensure_relative,mkpath ...@@ -10,7 +10,7 @@ from distutils.dir_util import create_tree, remove_tree, ensure_relative,mkpath
from distutils.sysconfig import get_python_version, get_python_lib from distutils.sysconfig import get_python_version, get_python_lib
from distutils.errors import * from distutils.errors import *
from distutils import log from distutils import log
from pkg_resources import parse_requirements, get_platform from pkg_resources import parse_requirements, get_platform, safe_name, safe_version
class bdist_egg(Command): class bdist_egg(Command):
description = "create an \"egg\" distribution" description = "create an \"egg\" distribution"
...@@ -54,7 +54,7 @@ class bdist_egg(Command): ...@@ -54,7 +54,7 @@ class bdist_egg(Command):
self.tag_date = 0 self.tag_date = 0
def finalize_options (self): def finalize_options (self):
self.egg_name = self.distribution.get_name().replace(' ','-') self.egg_name = safe_name(self.distribution.get_name())
self.egg_version = self.tagged_version() self.egg_version = self.tagged_version()
try: try:
list( list(
...@@ -122,7 +122,6 @@ class bdist_egg(Command): ...@@ -122,7 +122,6 @@ class bdist_egg(Command):
self.distribution.data_files = old self.distribution.data_files = old
def run(self): def run(self):
if not self.skip_build: if not self.skip_build:
self.run_command('build') self.run_command('build')
...@@ -161,6 +160,7 @@ class bdist_egg(Command): ...@@ -161,6 +160,7 @@ class bdist_egg(Command):
self.egg_version.replace('-','_'), get_python_version()) self.egg_version.replace('-','_'), get_python_version())
if ext_outputs: if ext_outputs:
archive_basename += "-" + self.plat_name archive_basename += "-" + self.plat_name
ext_outputs = [out.replace(os.sep,'/') for out in ext_outputs]
# OS/2 objects to any ":" characters in a filename (such as when # OS/2 objects to any ":" characters in a filename (such as when
# a timestamp is used in a version) so change them to underscores. # a timestamp is used in a version) so change them to underscores.
...@@ -223,7 +223,7 @@ class bdist_egg(Command): ...@@ -223,7 +223,7 @@ class bdist_egg(Command):
import time import time
version += time.strftime("-%Y%m%d") version += time.strftime("-%Y%m%d")
return version return safe_version(version)
def get_svn_revision(self): def get_svn_revision(self):
stdin, stdout = os.popen4("svn info"); stdin.close() stdin, stdout = os.popen4("svn info"); stdin.close()
......
...@@ -319,13 +319,20 @@ class ParseTests(TestCase): ...@@ -319,13 +319,20 @@ class ParseTests(TestCase):
) )
self.assertRaises(ValueError,list,pkg_resources.split_sections("[foo")) self.assertRaises(ValueError,list,pkg_resources.split_sections("[foo"))
def testSafeName(self):
self.assertEqual(safe_name("adns-python"), "adns-python")
self.assertEqual(safe_name("WSGI Utils"), "WSGI-Utils")
self.assertEqual(safe_name("WSGI Utils"), "WSGI-Utils")
self.assertEqual(safe_name("Money$$$Maker"), "Money-Maker")
self.assertEqual(safe_name("peak.web"), "peak-web")
def testSafeVersion(self):
self.assertEqual(safe_version("1.2-1"), "1.2-1")
self.assertEqual(safe_version("1.2 alpha"), "1.2.alpha")
self.assertEqual(safe_version("2.3.4 20050521"), "2.3.4.20050521")
self.assertEqual(safe_version("Money$$$Maker"), "Money-Maker")
self.assertEqual(safe_version("peak.web"), "peak.web")
def testSimpleRequirements(self): def testSimpleRequirements(self):
self.assertEqual( self.assertEqual(
list(parse_requirements('Twis-Ted>=1.2-1')), list(parse_requirements('Twis-Ted>=1.2-1')),
...@@ -358,14 +365,7 @@ class ParseTests(TestCase): ...@@ -358,14 +365,7 @@ class ParseTests(TestCase):
c('0pre1', '0.0c1') c('0pre1', '0.0c1')
c('0.0.0preview1', '0c1') c('0.0.0preview1', '0c1')
c('0.0c1', '0rc1') c('0.0c1', '0rc1')
c('1.2a1', '1.2.a.1'); c('1.2...a', '1.2a')
def testVersionOrdering(self): def testVersionOrdering(self):
def c(s1,s2): def c(s1,s2):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment