@@ -69,22 +69,22 @@ def get_package_name_from_filename(filename, normalize=True):
6969 Optionally ``normalize`` the name according to distribution name rules.
7070 Raise an ``InvalidDistributionFilename`` if the ``filename`` is invalid::
7171
72+ >>> get_package_name_from_filename("aboutcode_toolkit-5.1.0-py2.py3-none-any.whl")
73+ 'aboutcode-toolkit'
74+ >>> get_package_name_from_filename("boolean.py-3.7-py2.py3-none-any.whl")
75+ 'boolean-py'
76+ >>> get_package_name_from_filename("boolean.py-3.7.tar.gz")
77+ 'boolean-py'
7278 >>> get_package_name_from_filename("foo-1.2.3_rc1.tar.gz")
7379 'foo'
74- >>> get_package_name_from_filename("foo-bar -1.2-py27-none-any.whl")
80+ >>> get_package_name_from_filename("foo_bar -1.2-py27-none-any.whl")
7581 'foo-bar'
82+ >>> get_package_name_from_filename("foo.py-1.2-py27-none-any.whl")
83+ 'foo-py'
7684 >>> get_package_name_from_filename("Cython-0.17.2-cp26-none-linux_x86_64.whl")
7785 'cython'
7886 >>> get_package_name_from_filename("python_ldap-2.4.19-cp27-none-macosx_10_10_x86_64.whl")
7987 'python-ldap'
80- >>> get_package_name_from_filename("foo.whl")
81- Traceback (most recent call last):
82- ...
83- InvalidDistributionFilename: ...
84- >>> get_package_name_from_filename("foo.png")
85- Traceback (most recent call last):
86- ...
87- InvalidFilePackageName: ...
8888 """
8989 if not filename or not filename .endswith (dist_exts ):
9090 raise InvalidDistributionFilename (filename )
@@ -133,15 +133,30 @@ def get_package_name_from_filename(filename, normalize=True):
133133 raise InvalidDistributionFilename (filename )
134134
135135 if normalize :
136- name = name . lower (). replace ( "_" , "-" )
136+ name = normalize_name ( name )
137137 return name
138138
139139
140- def build_pypi_index ( directory , write_index = False ):
140+ def normalize_name ( name ):
141141 """
142- Using a ``directory`` directory of wheels and sdists, create the a PyPI simple
143- directory index at ``directory``/simple/ populated with the proper PyPI simple
144- index directory structure crafted using symlinks.
142+ Return a normalized package name per PEP503, and copied from
143+ https://www.python.org/dev/peps/pep-0503/#id4
144+ """
145+ return name and re .sub (r"[-_.]+" , "-" , name ).lower () or name
146+
147+
148+ def normalize_name_plain (name ):
149+ """
150+ Return a normalized package name, but do not replace dots
151+ """
152+ return name and re .sub (r"[-_]+" , "-" , name ).lower () or name
153+
154+
155+ def build_pypi_index (directory ):
156+ """
157+ Using a ``directory`` directory of wheels and sdists, create the a PyPI
158+ simple directory index at ``directory``/simple/ populated with the proper
159+ PyPI simple index directory structure crafted using symlinks.
145160
146161 WARNING: The ``directory``/simple/ directory is removed if it exists.
147162 """
@@ -154,11 +169,15 @@ def build_pypi_index(directory, write_index=False):
154169
155170 index_dir .mkdir (parents = True )
156171
157- if write_index :
158- simple_html_index = [
159- "<html><head><title>PyPI Simple Index</title>" ,
160- "<meta name='api-version' value='2' /></head><body>" ,
161- ]
172+ simple_html_index = [
173+ "<html>"
174+ "<head>"
175+ "<title>PyPI Simple Index</title>" ,
176+ '<meta charset="UTF-8">'
177+ '<meta name="api-version" value="2" />'
178+ "</head>"
179+ "<body>" ,
180+ ]
162181
163182 package_names = set ()
164183 for pkg_file in directory .iterdir ():
@@ -172,26 +191,30 @@ def build_pypi_index(directory, write_index=False):
172191 ):
173192 continue
174193
175- pkg_name = get_package_name_from_filename (pkg_filename )
176- pkg_index_dir = index_dir / pkg_name
194+ original_name = get_package_name_from_filename (pkg_filename , normalize = False )
195+ pkg_dir_name = normalize_name (original_name )
196+ pkg_link_name = normalize_name_plain (original_name )
197+
198+ pkg_index_dir = index_dir / pkg_dir_name
177199 pkg_index_dir .mkdir (parents = True , exist_ok = True )
178200 pkg_indexed_file = pkg_index_dir / pkg_filename
179201 link_target = Path ("../.." ) / pkg_filename
180202 pkg_indexed_file .symlink_to (link_target )
181203
182- if write_index and pkg_name not in package_names :
183- esc_name = escape (pkg_name )
184- simple_html_index .append (f'<a href="{ esc_name } /">{ esc_name } </a><br/>' )
185- package_names .add (pkg_name )
204+ if pkg_link_name not in package_names :
205+ esc_dir = escape (pkg_dir_name )
206+ esc_link = escape (pkg_link_name )
207+
208+ simple_html_index .append (f'<a href="{ esc_dir } /">{ esc_link } </a><br/>' )
209+ package_names .add (pkg_link_name )
186210
187- if write_index :
188- simple_html_index .append ("</body></html>" )
189- index_html = index_dir / "index.html"
190- index_html .write_text ("\n " .join (simple_html_index ))
211+ simple_html_index .append ("</body></html>" )
212+ index_html = index_dir / "index.html"
213+ index_html .write_text ("\n " .join (simple_html_index ))
191214
192215
193216if __name__ == "__main__" :
194217 import sys
195218
196219 pkg_dir = sys .argv [1 ]
197- build_pypi_index (pkg_dir , True )
220+ build_pypi_index (pkg_dir )
0 commit comments