Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make nixpkgs GHC 9.6.x work #1921

Merged
merged 10 commits into from
Dec 11, 2023
Prev Previous commit
Next Next commit
Handle ${pkgroot} results in relative paths outside of repository
  • Loading branch information
avdv committed Dec 4, 2023
commit 6fcc564d30f14d54388cc895f2e977aec2724533
36 changes: 27 additions & 9 deletions haskell/private/pkgdb_to_bzl.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,27 @@
package_conf_dir = os.path.join(topdir, 'package.conf.d')
else:
sys.exit("could not find package.conf.d directory at {}".format(topdir))
repo_root = os.getcwd()
else:
sys.exit("Usage: pkgdb_to_bzl.py <REPO_NAME> <TOPDIR>")

def resolve(path, pkgroot):
"""Resolve references to ${pkgroot} with the given value"""
if path.find("${pkgroot}") != -1:
return path.strip("\"").replace("${pkgroot}", pkgroot)
else:
return path

def path_to_label(path, pkgroot):
"""Substitute one pkgroot for another relative one to obtain a label."""
if path.find("${pkgroot}") != -1:
return os.path.normpath(path.strip("\"").replace("${pkgroot}", topdir)).replace('\\', '/')
# determine if the given path is inside the repository root
# if it is not, return None to signal it needs to be symlinked into the
# repository
real_path = os.path.realpath(resolve(path, pkgroot))
relative_path = os.path.relpath(real_path, start=repo_root)

return None if relative_path.startswith('..') else relative_path.replace('\\', '/')

topdir_relative_path = path.replace(pkgroot, "$topdir")
if topdir_relative_path.find("$topdir") != -1:
Expand Down Expand Up @@ -114,31 +128,35 @@ def hs_library_pattern(name, mode = "static", profiling = False):
haddock_html = None

if pkg.haddock_html:
haddock_html = path_to_label(pkg.haddock_html, pkgroot)
# We check if the file exists because cabal will unconditionally
# generate the database entry even if no haddock was generated.
if not haddock_html and os.path.exists(pkg.haddock_html):
haddock_html = os.path.join("haddock", "html", pkg.name)
output.append("#SYMLINK: {} {}".format(pkg.haddock_html, haddock_html))
resolved_haddock_html = resolve(pkg.haddock_html, pkgroot)

if os.path.exists(resolved_haddock_html):
haddock_html = path_to_label(pkg.haddock_html, pkgroot)
if not haddock_html:
haddock_html = os.path.join("haddock", "html", pkg.name)
output.append("#SYMLINK: {} {}".format(resolved_haddock_html.replace('\\', '/'), haddock_html))

# If there is many interfaces, we give them a number
interface_id = 0
haddock_interfaces = []
for interface_path in pkg.haddock_interfaces:
interface = path_to_label(interface_path, pkgroot)
resolved_path = resolve(interface_path, pkgroot).replace('\\', '/')

# We check if the file exists because cabal will unconditionally
# generate the database entry even if no haddock was generated.
if not os.path.exists(interface or interface_path):
continue
if not os.path.exists(resolved_path): continue

interface = path_to_label(interface_path, pkgroot)

if not interface:
interface = os.path.join(
"haddock",
"interfaces",
pkg.name + "_" + str(interface_id) + ".haddock",
)
output.append("#SYMLINK: {} {}".format(interface_path, interface))
output.append("#SYMLINK: {} {}".format(resolved_path, interface))
interface_id += 1
haddock_interfaces.append(interface)

Expand Down