mirror of
https://github.com/pre-commit/pre-commit-hooks.git
synced 2026-04-08 20:44:18 +00:00
64 lines
1.8 KiB
Python
64 lines
1.8 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
import string
|
|
import urllib.parse
|
|
import urllib.request
|
|
from typing import Optional
|
|
|
|
from .compat import WINDOWS
|
|
|
|
|
|
def get_url_scheme(url: str) -> str | None:
|
|
if ':' not in url:
|
|
return None
|
|
return url.split(':', 1)[0].lower()
|
|
|
|
|
|
def path_to_url(path: str) -> str:
|
|
"""
|
|
Convert a path to a file: URL. The path will be made absolute and have
|
|
quoted path parts.
|
|
"""
|
|
path = os.path.normpath(os.path.abspath(path))
|
|
url = urllib.parse.urljoin('file:', urllib.request.pathname2url(path))
|
|
return url
|
|
|
|
|
|
def url_to_path(url: str) -> str:
|
|
"""
|
|
Convert a file: URL to a path.
|
|
"""
|
|
assert url.startswith(
|
|
'file:',
|
|
), f'You can only turn file: urls into filenames (not {url!r})'
|
|
|
|
_, netloc, path, _, _ = urllib.parse.urlsplit(url)
|
|
|
|
if not netloc or netloc == 'localhost':
|
|
# According to RFC 8089, same as empty authority.
|
|
netloc = ''
|
|
elif WINDOWS:
|
|
# If we have a UNC path, prepend UNC share notation.
|
|
netloc = '\\\\' + netloc
|
|
else:
|
|
raise ValueError(
|
|
f'non-local file URIs are not supported on this platform: {url!r}',
|
|
)
|
|
|
|
path = urllib.request.url2pathname(netloc + path)
|
|
|
|
# On Windows, urlsplit parses the path as something like "/C:/Users/foo".
|
|
# This creates issues for path-related functions like io.open(), so we try
|
|
# to detect and strip the leading slash.
|
|
if (
|
|
WINDOWS and
|
|
not netloc and # Not UNC.
|
|
len(path) >= 3 and
|
|
path[0] == '/' and # Leading slash to strip.
|
|
path[1] in string.ascii_letters and # Drive letter.
|
|
path[2:4] in (':', ':/') # Colon + end of string, or colon + absolute path.
|
|
):
|
|
path = path[1:]
|
|
|
|
return path
|