...
 
Commits (9)
......@@ -23,19 +23,13 @@ jobs:
name: Bootstrap on Linux
runs-on: ubuntu-18.04
steps:
- name: Set PATH
run: |
echo "::add-path::/opt/ghc/8.6.5/bin"
- uses: actions/checkout@v2
- name: bootstrap.sh
env:
EXTRA_CONFIGURE_OPTS: ""
- name: bootstrap.py
run: |
cd cabal-install
sh ./bootstrap.sh --no-doc
python3 bootstrap/bootstrap.py -w /opt/ghc/8.6.5/bin/ghc -d bootstrap/linux-8.6.5.json
- name: Smoke test
run: |
$HOME/.cabal/bin/cabal --version
packages/tmp/bin/cabal --version
boostrap-macos:
name: Bootstrap on macOS
......@@ -49,17 +43,13 @@ jobs:
cd ghc-*
./configure --prefix=/opt/ghc/8.6.5
sudo make install
- name: Set PATH
run: |
echo "::add-path::/opt/ghc/8.6.5/bin"
echo "::add-path::$HOME/.cabal/bin"
- uses: actions/checkout@v2
- name: bootstrap.sh
env:
EXTRA_CONFIGURE_OPTS: ""
# We use linux dependencies
- name: bootstrap.py
run: |
cd cabal-install
sh ./bootstrap.sh --no-doc
python3 bootstrap/bootstrap.py -w /opt/ghc/8.6.5/bin/ghc -d bootstrap/linux-8.6.5.json
- name: Smoke test
run: |
$HOME/.cabal/bin/cabal --version
packages/tmp/bin/cabal --version
......@@ -226,3 +226,23 @@ weeder :
.PHONY : tags
tags :
hasktags -b Cabal/Distribution Cabal/Cabal-described/src Cabal/Language cabal-install/Distribution cabal-testsuite/src
hasktags -b Cabal/src Cabal/Cabal-described/src cabal-install/src cabal-testsuite/src
# boostrapping
##############################################################################
bootstrap-plans-linux: phony
@if [ $$(uname) != "Linux" ]; then echo "Not Linux"; false; fi
cabal v2-build --project=cabal.project.release --with-compiler ghc-8.6.5 --dry-run cabal-install:exe:cabal
cp dist-newstyle/cache/plan.json bootstrap/linux-8.6.5.plan.json
cabal v2-build --project=cabal.project.release --with-compiler ghc-8.8.3 --dry-run cabal-install:exe:cabal
cp dist-newstyle/cache/plan.json bootstrap/linux-8.8.3.plan.json
cabal v2-build --project=cabal.project.release --with-compiler ghc-8.10.1 --dry-run cabal-install:exe:cabal
cp dist-newstyle/cache/plan.json bootstrap/linux-8.10.1.plan.json
bootstrap-jsons-linux: phony
@if [ $$(uname) != "Linux" ]; then echo "Not Linux"; false; fi
cabal v2-build --builddir=dist-newstyle-bootstrap --project=cabal.project.bootstrap cabal-bootstrap-gen
cabal v2-run -vnormal+stderr --builddir=dist-newstyle-bootstrap --project=cabal.project.bootstrap cabal-bootstrap-gen -- bootstrap/linux-8.6.5.plan.json | python -m json.tool | tee bootstrap/linux-8.6.5.json
cabal v2-run -vnormal+stderr --builddir=dist-newstyle-bootstrap --project=cabal.project.bootstrap cabal-bootstrap-gen -- bootstrap/linux-8.8.3.plan.json | python -m json.tool | tee bootstrap/linux-8.8.3.json
cabal v2-run -vnormal+stderr --builddir=dist-newstyle-bootstrap --project=cabal.project.bootstrap cabal-bootstrap-gen -- bootstrap/linux-8.10.1.plan.json | python -m json.tool | tee bootstrap/linux-8.10.1.json
......@@ -23,19 +23,13 @@ jobs:
name: Bootstrap on Linux
runs-on: ubuntu-18.04
steps:
- name: Set PATH
run: |
echo "::add-path::/opt/ghc/8.6.5/bin"
- uses: actions/checkout@v2
- name: bootstrap.sh
env:
EXTRA_CONFIGURE_OPTS: ""
- name: bootstrap.py
run: |
cd cabal-install
sh ./bootstrap.sh --no-doc
python3 bootstrap/bootstrap.py -w /opt/ghc/8.6.5/bin/ghc -d bootstrap/linux-8.6.5.json
- name: Smoke test
run: |
$HOME/.cabal/bin/cabal --version
packages/tmp/bin/cabal --version
boostrap-macos:
name: Bootstrap on macOS
......@@ -49,17 +43,13 @@ jobs:
cd ghc-*
./configure --prefix=/opt/ghc/8.6.5
sudo make install
- name: Set PATH
run: |
echo "::add-path::/opt/ghc/8.6.5/bin"
echo "::add-path::$HOME/.cabal/bin"
- uses: actions/checkout@v2
- name: bootstrap.sh
env:
EXTRA_CONFIGURE_OPTS: ""
# We use linux dependencies
- name: bootstrap.py
run: |
cd cabal-install
sh ./bootstrap.sh --no-doc
python3 bootstrap/bootstrap.py -w /opt/ghc/8.6.5/bin/ghc -d bootstrap/linux-8.6.5.json
- name: Smoke test
run: |
$HOME/.cabal/bin/cabal --version
packages/tmp/bin/cabal --version
# Bootstrapping cabal-install
This utility is only intended for use in building cabal-install
on a new platform. If you already have a functional (if dated) cabal-install
please rather run `cabal v2-install`.
The typical usage is porting to a new linux architecture,
then the `linux-ghcvec.json` file is available in `bootstrap/` folder:
On a (linux) system you are boostrapping, run
bootstrap.py -d linux-ghcver.json -w /path/to-ghc
To generate the `platform-ghcver` files for other platforms, do:
1. On a system with functional cabal-install, install the same GHC version
as you will use to bootstrap on the host system.
2. Build a dependency description file (`platform-ghcver.json`, e.g. `linux-8.8.3.json`) by running:
```sh
cabal v2-build --with-compiler=/path/to/ghc --dry-run cabal-install:exe:cabal
cp dist-newstyle/cache/plan.json bootstrap/platform-ghcver.plan.json
cabal v2-build --builddir=dist-newstyle-bootstrap --project=cabal.project.bootstrap cabal-bootstrap-gen
cabal v2-run -vnormal+stderr --builddir=dist-newstyle-bootstrap --project=cabal.project.bootstrap cabal-bootstrap-gen -- bootstrap/platform-ghcver.plan.json | tee bootstrap/platform-ghcver.json
```
3. You may need to tweak `bootstrap/platform-ghcver.json` file manually,
for example toggle flags.
There are rules in top-level `Makefile` for generation of these files.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
bootstrap.py - bootstrapping utility for cabal-install.
See bootstrap/README.md for usage instructions.
"""
USAGE = """
This utility is only intended for use in building cabal-install
on a new platform. If you already have a functional (if dated) cabal-install
please rather run `cabal v2-install .`.
"""
from enum import Enum
import hashlib
import logging
import json
from pathlib import Path
import shutil
import subprocess
from textwrap import dedent
from typing import Set, Optional, Dict, List, Tuple, \
NewType, BinaryIO, NamedTuple, TypeVar
#logging.basicConfig(level=logging.INFO)
PACKAGES = Path('packages')
PKG_DB = PACKAGES / 'packages.conf'
PackageName = NewType('PackageName', str)
Version = NewType('Version', str)
SHA256Hash = NewType('SHA256Hash', str)
class PackageSource(Enum):
HACKAGE = 'hackage'
LOCAL = 'local'
BuiltinDep = NamedTuple('BuiltinDep', [
('package', PackageName),
('version', Version),
])
BootstrapDep = NamedTuple('BootstrapDep', [
('package', PackageName),
('version', Version),
('source', PackageSource),
# source tarball SHA256
('src_sha256', Optional[SHA256Hash]),
# `revision` is only valid when source == HACKAGE.
('revision', Optional[int]),
('cabal_sha256', Optional[SHA256Hash]),
('flags', List[str]),
])
BootstrapInfo = NamedTuple('BootstrapInfo', [
('builtin', List[BuiltinDep]),
('dependencies', List[BootstrapDep]),
])
class Compiler:
def __init__(self, ghc_path: Path):
if not ghc_path.is_file():
raise TypeError(f'GHC {ghc_path} is not a file')
self.ghc_path = ghc_path.resolve()
info = self._get_ghc_info()
self.version = info['Project version']
#self.lib_dir = Path(info['LibDir'])
#self.ghc_pkg_path = (self.lib_dir / 'bin' / 'ghc-pkg').resolve()
self.ghc_pkg_path = (self.ghc_path.parent / 'ghc-pkg').resolve()
if not self.ghc_pkg_path.is_file():
raise TypeError(f'ghc-pkg {self.ghc_pkg_path} is not a file')
self.hsc2hs_path = (self.ghc_path.parent / 'hsc2hs').resolve()
if not self.hsc2hs_path.is_file():
raise TypeError(f'hsc2hs {self.hsc2hs_path} is not a file')
def _get_ghc_info(self) -> Dict[str,str]:
from ast import literal_eval
p = subprocess_run([self.ghc_path, '--info'], stdout=subprocess.PIPE, check=True, encoding='UTF-8')
out = p.stdout.replace('\n', '').strip()
return dict(literal_eval(out))
PackageSpec = Tuple[PackageName, Version]
class BadTarball(Exception):
def __init__(self, path: Path, expected_sha256: SHA256Hash, found_sha256: SHA256Hash):
self.path = path
self.expected_sha256 = expected_sha256
self.found_sha256 = found_sha256
def __str__(self):
return '\n'.join([
f'Bad tarball hash: {str(self.path)}',
f' expected: {self.expected_sha256}',
f' found: {self.found_sha256}',
])
def package_url(package: PackageName, version: Version) -> str:
return f'https://hackage.haskell.org/package/{package}-{version}/{package}-{version}.tar.gz'
def package_cabal_url(package: PackageName, version: Version, revision: int) -> str:
return f'https://hackage.haskell.org/package/{package}-{version}/revision/{revision}.cabal'
def verify_sha256(expected_hash: SHA256Hash, f: Path):
h = hash_file(hashlib.sha256(), f.open('rb'))
if h != expected_hash:
raise BadTarball(f, expected_hash, h)
def fetch_package(package: PackageName,
version: Version,
src_sha256: SHA256Hash,
revision: Optional[int],
cabal_sha256: Optional[SHA256Hash],
) -> Path:
import urllib.request
# Download source distribution
out = PACKAGES / (f'{package}-{version}.tar.gz')
if not out.exists():
print(f'Fetching {package}-{version}...')
out.parent.mkdir(parents=True, exist_ok=True)
url = package_url(package, version)
with urllib.request.urlopen(url) as resp:
shutil.copyfileobj(resp, out.open('wb'))
# Download revised cabal file
cabal_file = PACKAGES / f'{package}.cabal'
if revision is not None and not cabal_file.exists():
assert cabal_sha256 is not None
url = package_cabal_url(package, version, revision)
with urllib.request.urlopen(url) as resp:
shutil.copyfileobj(resp, cabal_file.open('wb'))
verify_sha256(cabal_sha256, cabal_file)
verify_sha256(src_sha256, out)
return out
def read_bootstrap_info(path: Path) -> BootstrapInfo:
obj = json.load(path.open())
def bi_from_json(o: dict) -> BuiltinDep:
return BuiltinDep(**o)
def dep_from_json(o: dict) -> BootstrapDep:
o['source'] = PackageSource(o['source'])
return BootstrapDep(**o)
builtin = [bi_from_json(dep) for dep in obj['builtin'] ]
deps = [dep_from_json(dep) for dep in obj['dependencies'] ]
return BootstrapInfo(dependencies=deps, builtin=builtin)
def check_builtin(dep: BuiltinDep, ghc: Compiler) -> None:
subprocess_run([str(ghc.ghc_pkg_path), 'describe', f'{dep.package}-{dep.version}'],
check=True, stdout=subprocess.DEVNULL)
print(f'Using {dep.package}-{dep.version} from GHC...')
return
def install_dep(dep: BootstrapDep, ghc: Compiler) -> None:
if dep.source == PackageSource.HACKAGE:
assert dep.src_sha256 is not None
tarball = fetch_package(dep.package, dep.version, dep.src_sha256,
dep.revision, dep.cabal_sha256)
subprocess_run(['tar', 'zxf', tarball.resolve()],
cwd=PACKAGES, check=True)
sdist_dir = PACKAGES / f'{dep.package}-{dep.version}'
# Update cabal file with revision
if dep.revision is not None:
shutil.copyfile(PACKAGES / f'{dep.package}.cabal',
sdist_dir / f'{dep.package}.cabal')
elif dep.source == PackageSource.LOCAL:
if dep.package == 'Cabal':
sdist_dir = Path('Cabal').resolve()
elif dep.package == 'cabal-install':
sdist_dir = Path('cabal-install').resolve()
else:
raise ValueError(f'Unknown local package {dep.package}')
install_sdist(sdist_dir, ghc, dep.flags)
def install_sdist(sdist_dir: Path, ghc: Compiler, flags: List[str]):
prefix = (PACKAGES / 'tmp').resolve()
flags_option = ' '.join(flags)
configure_args = [
f'--package-db={PKG_DB.resolve()}',
f'--prefix={prefix}',
f'--with-compiler={ghc.ghc_path}',
f'--with-hc-pkg={ghc.ghc_pkg_path}',
f'--with-hsc2hs={ghc.hsc2hs_path}',
f'--flags={flags_option}'
]
def check_call(args: List[str]) -> None:
subprocess_run(args, cwd=sdist_dir, check=True)
check_call([str(ghc.ghc_path), '--make', '-package-env', '-', 'Setup'])
check_call(['./Setup', 'configure'] + configure_args)
check_call(['./Setup', 'build'])
check_call(['./Setup', 'install'])
def hash_file(h, f: BinaryIO) -> SHA256Hash:
while True:
d = f.read(1024)
if len(d) == 0:
return SHA256Hash(h.hexdigest())
h.update(d)
# Cabal plan.json representation
UnitId = NewType('UnitId', str)
PlanUnit = NewType('PlanUnit', dict)
def read_plan(project_dir: Path) -> Dict[UnitId, PlanUnit]:
path = project_dir / 'dist-newstyle' / 'cache' / 'plan.json'
plan = json.load(path.open('rb'))
return {
UnitId(c['id']): PlanUnit(c)
for c in plan['install-plan']
}
def bootstrap(info: BootstrapInfo, ghc: Compiler) -> None:
if not PKG_DB.exists():
print(f'Creating package database {PKG_DB}')
PKG_DB.parent.mkdir(parents=True, exist_ok=True)
subprocess_run([ghc.ghc_pkg_path, 'init', PKG_DB])
for dep in info.builtin:
check_builtin(dep, ghc)
for dep in info.dependencies:
install_dep(dep, ghc)
def main() -> None:
import argparse
parser = argparse.ArgumentParser(
description="bootstrapping utility for cabal-install.",
epilog = USAGE,
formatter_class = argparse.RawDescriptionHelpFormatter)
parser.add_argument('-d', '--deps', type=Path, default='bootstrap-deps.json',
help='bootstrap dependency file')
parser.add_argument('-w', '--with-compiler', type=Path,
help='path to GHC')
args = parser.parse_args()
# Find compiler
if args.with_compiler is None:
path = shutil.which('ghc')
if path is None:
raise ValueError("Couldn't find ghc in PATH")
ghc = Compiler(Path(path))
else:
ghc = Compiler(args.with_compiler)
print(f'Bootstrapping cabal-install with GHC {ghc.version} at {ghc.ghc_path}...')
print(dedent("""
DO NOT use this script if you have another recent cabal-install available.
This script is intended only for bootstrapping cabal-install on new
architectures.
"""))
info = read_bootstrap_info(args.deps)
bootstrap(info, ghc)
cabal_path = (PACKAGES / 'tmp' / 'bin' / 'cabal').resolve()
print(dedent(f'''
Bootstrapping finished!
The resulting cabal-install executable can be found at
{cabal_path}
You now should use this to build a full cabal-install distribution
using v2-build.
'''))
def subprocess_run(args, **kwargs):
"Like subprocess.run, but also print what we run"
args_str = ' '.join(map(str, args))
extras = ''
if 'cwd' in kwargs:
extras += f' cwd={kwargs["cwd"]}'
print(f'bootstrap: running{extras} {args_str}')
return subprocess.run(args, **kwargs)
if __name__ == '__main__':
main()
cabal-version: 2.2
name: cabal-bootstrap-gen
version: 0
executable cabal-bootstrap-gen
default-language: Haskell2010
hs-source-dirs: src
ghc-options: -Wall
main-is: Main.hs
build-depends:
, aeson ^>=1.5.2.0
, base ^>=4.12.0.0 || ^>=4.13.0.0 || ^>=4.14.0.0
, bytestring ^>=0.10.8.2
, Cabal ^>=3.2.0.0
, cabal-install-parsers ^>=0.3.0.1
, cabal-plan ^>=0.7.0.0
, containers ^>=0.6.0.1
, text ^>=1.2.3.0
, topograph ^>=1.0.0.1
, transformers ^>=0.5.6.2
{
"builtin": [
{
"package": "rts",
"version": "1.0"
},
{
"package": "ghc-prim",
"version": "0.6.1"
},
{
"package": "integer-gmp",
"version": "1.0.3.0"
},
{
"package": "base",
"version": "4.14.0.0"
},
{
"package": "array",
"version": "0.5.4.0"
},
{
"package": "deepseq",
"version": "1.4.4.0"
},
{
"package": "bytestring",
"version": "0.10.10.0"
},
{
"package": "containers",
"version": "0.6.2.1"
},
{
"package": "binary",
"version": "0.8.8.0"
},
{
"package": "filepath",
"version": "1.4.2.1"
},
{
"package": "time",
"version": "1.9.3"
},
{
"package": "unix",
"version": "2.7.2.2"
},
{
"package": "directory",
"version": "1.3.6.0"
},
{
"package": "transformers",
"version": "0.5.6.2"
},
{
"package": "mtl",
"version": "2.2.2"
},
{
"package": "text",
"version": "1.2.3.2"
},
{
"package": "parsec",
"version": "3.1.14.0"
},
{
"package": "pretty",
"version": "1.1.3.6"
},
{
"package": "process",
"version": "1.6.8.2"
},
{
"package": "ghc-boot-th",
"version": "8.10.1"
},
{
"package": "template-haskell",
"version": "2.16.0.0"
},
{
"package": "stm",
"version": "2.5.0.0"
}
],
"dependencies": [
{
"cabal_sha256": null,
"flags": [
"-bundled-binary-generic"
],
"package": "Cabal",
"revision": null,
"source": "local",
"src_sha256": null,
"version": "3.4.0.0"
},
{
"cabal_sha256": "b704cb6676c03e98267190df797497587576a2e96094550ea143415239bbe66e",
"flags": [],
"package": "network",
"revision": 0,
"source": "hackage",
"src_sha256": "d7ef590173fff2ab522fbc167f3fafb867e4ecfca279eb3ef0d137b51f142c9a",
"version": "3.1.1.1"
},
{
"cabal_sha256": "d2d9ff3a80d9b2d1ff317a354bc0c56cc109c69a4c2449e5fc712d3ddce83ede",
"flags": [],
"package": "network-uri",
"revision": 0,
"source": "hackage",
"src_sha256": "a01c1389f15d2cc2e847914737f706133bb11f0c5f8ee89711a36a25b7afa723",
"version": "2.6.3.0"
},
{
"cabal_sha256": "3c19975fdfd8d057eae58847bda6a79514ad882fd6f8ead72ac0247af34bdfc6",
"flags": [
"-conduit10",
"-mtl1",
"+network-uri",
"-warn-as-error",
"-warp-tests"
],
"package": "HTTP",
"revision": 1,
"source": "hackage",
"src_sha256": "a602d7f30e917164c6a634f8cb1f5df4849048858db01380a0875e16e5aa687b",
"version": "4000.3.14"
},
{
"cabal_sha256": "4c70f1407881059e93550d3742191254296b2737b793a742bd901348fb3e1fb1",
"flags": [
"-examples",
"+integer-gmp",
"+sse2",
"-sse41"
],
"package": "hashable",
"revision": 1,
"source": "hackage",
"src_sha256": "822e5413fbccca6ae884d3aba4066422c8b5d58d23d18b9ecb5c03273bb19ab4",
"version": "1.3.0.0"
},
{
"cabal_sha256": "a178c166856da7ff22fe4500337b54812e94fd2059409452187d72e057ede9cd",
"flags": [
"-bench"
],
"package": "async",
"revision": 1,
"source": "hackage",
"src_sha256": "4b4ab1ac82c45144d82c6daf6cb6ba45eab9957dad44787fa5e869e23d73bbff",
"version": "2.2.2"
},
{
"cabal_sha256": "8cbba2505d4da4f6cfc90cd36c8e8ad0c09c056538481ea00e8b10b78f70cb10",
"flags": [],
"package": "base16-bytestring",
"revision": 0,
"source": "hackage",
"src_sha256": "525689679d5cc80fa532c1d5cfeace0f62bbb54134fad514f1ba00d0e7fe69ba",
"version": "0.1.1.7"
},
{
"cabal_sha256": "190264fef9e65d9085f00ccda419137096d1dc94777c58272bc96821dc7f37c3",
"flags": [],
"package": "base64-bytestring",
"revision": 0,
"source": "hackage",
"src_sha256": "210d6c9042241ca52ee5d89cf221dbeb4d0e64b37391345369035ad2d9b4aca9",
"version": "1.1.0.0"
},
{
"cabal_sha256": "b963d6308db096362d73d9c603b331cf188aa69310195f479dfedf6045d7e602",
"flags": [
"-exe"
],
"package": "cryptohash-sha256",
"revision": 4,
"source": "hackage",
"src_sha256": "52756435dbea248e344fbcbcc5df5307f60dfacf337dfd11ae30f1c7a4da05dd",
"version": "0.11.101.0"
},
{
"cabal_sha256": "5490be9cfbea95e14a7a68b7d055ae8d295822e0b146d2ac8285b3e5a3e3282f",
"flags": [
"-example"
],
"package": "echo",
"revision": 1,
"source": "hackage",
"src_sha256": "704f07310f8272d170f8ab7fb2a2c13f15d8501ef8310801e36964c8eff485ef",
"version": "0.1.3"
},
{
"cabal_sha256": "d50c4d0801a35be7875a040470c09863342514930c82a7d25780a6c2efc4fda9",
"flags": [
"-optimised-mixer"
],
"package": "splitmix",
"revision": 0,
"source": "hackage",
"src_sha256": "1c11c87352ddbb13365380fe163f99bb8f8845ebc96ca1d572e5d3a9bf810bfa",
"version": "0.1"
},
{
"cabal_sha256": "5ca8674e95c46c7eb90f520c26aea22d403625c97697275434afba66ebd32b05",
"flags": [],
"package": "random",
"revision": 0,
"source": "hackage",
"src_sha256": "e4519cf7c058bfd5bdbe4acc782284acc9e25e74487208619ca83cbcd63fb9de",
"version": "1.2.0"
},
{
"cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee",
"flags": [],
"package": "edit-distance",
"revision": 1,
"source": "hackage",
"src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a",
"version": "0.2.2.1"
},
{
"cabal_sha256": "fb98b08de467d51f788f8bd9391f0e9ab9bd4d8dfc264296b895ffea0d822dfa",
"flags": [
"+no-donna",
"+test-doctests",
"+test-hlint",
"+test-properties"
],
"package": "ed25519",
"revision": 3,
"source": "hackage",
"src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d",
"version": "0.0.5.0"
},
{
"cabal_sha256": "c9d3fa30fb6ab2ba16e037586ca79be6e57ec5f00381b6ee5f293400dbdf5515",
"flags": [
"+ofd-locking"
],
"package": "lukko",
"revision": 0,
"source": "hackage",
"src_sha256": "8a79d113dc0ccef16c24d83379cc457485943027e777529c46362fecc06607d2",
"version": "0.1.1.2"
},
{
"cabal_sha256": "7a715414c4d494c9048cfb6d7634e07e7732ca154cb8938dc85f6ea192192e8c",
"flags": [
"-old-bytestring",
"-old-time"
],
"package": "tar",
"revision": 2,
"source": "hackage",
"src_sha256": "b384449f62b2b0aa3e6d2cb1004b8060b01f21ec93e7b63e7af6d8fad8a9f1de",
"version": "0.5.1.1"
},
{
"cabal_sha256": "d34ddf5fece4d1e9d471b5298f36335bb3cfe12cb5a1b8525c42f0b665382f45",
"flags": [
"-non-blocking-ffi",
"-pkg-config"
],
"package": "zlib",
"revision": 1,
"source": "hackage",
"src_sha256": "f0f810ff173560b60392db448455c0513b3239f48e43cb494b3733aa559621d0",
"version": "0.6.2.1"
},
{
"cabal_sha256": "692c385c085baa2813046ae58e31df21c250346b81c882431b5ffef76451a18a",
"flags": [
"+base48",
"+lukko",
"-mtl21",
"-old-directory",
"+use-network-uri"
],
"package": "hackage-security",
"revision": 2,
"source": "hackage",
"src_sha256": "9162b473af5a21c1ff32a50b972b9acf51f4c901604a22cf08a2dccac2f82f17",
"version": "0.6.0.1"
},
{
"cabal_sha256": "44aa95ca762294ffbb28cf0af9c567d93b5d2c56e4f38ce5385a257d899f968e",
"flags": [],
"package": "regex-base",
"revision": 1,
"source": "hackage",
"src_sha256": "c41f82f5fc1157c961a4cbdc0cd5561e5aa44f339ce6e706d978d97e0ca6b914",
"version": "0.94.0.0"
},
{
"cabal_sha256": "690d1366e9ea6df71ded3daf49ca3d53c63eda3f95937962299b2391824dc3b3",
"flags": [
"-_regex-posix-clib"
],
"package": "regex-posix",
"revision": 1,
"source": "hackage",
"src_sha256": "251300f1a6bb2e91abb8bf513a21981f8fab79c98a65acea2bb6d6a524414521",
"version": "0.96.0.0"
},
{
"cabal_sha256": "0a9a6dd29706258ae60a5c22aecc140a40743b8f08fc324fd9984e7dfbf3a80d",
"flags": [],
"package": "resolv",
"revision": 0,
"source": "hackage",
"src_sha256": "81a2bafad484db123cf8d17a02d98bb388a127fd0f822fa022589468a0e64671",
"version": "0.1.2.0"
},
{
"cabal_sha256": null,
"flags": [
"-debug-conflict-sets",
"-debug-expensive-assertions",
"-debug-tracetree",
"+lukko",
"+native-dns"
],
"package": "cabal-install",
"revision": null,
"source": "local",
"src_sha256": null,
"version": "3.4.0.0"
}
]
}
This diff is collapsed.
{
"builtin": [
{
"package": "rts",
"version": "1.0"
},
{
"package": "ghc-prim",
"version": "0.5.3"
},
{
"package": "integer-gmp",
"version": "1.0.2.0"
},
{
"package": "base",
"version": "4.12.0.0"
},
{
"package": "array",
"version": "0.5.3.0"
},
{
"package": "deepseq",
"version": "1.4.4.0"
},
{
"package": "bytestring",
"version": "0.10.8.2"
},
{
"package": "containers",
"version": "0.6.0.1"
},
{
"package": "binary",
"version": "0.8.6.0"
},
{
"package": "filepath",
"version": "1.4.2.1"
},
{
"package": "time",
"version": "1.8.0.2"
},
{
"package": "unix",
"version": "2.7.2.2"
},
{
"package": "directory",
"version": "1.3.3.0"
},
{
"package": "transformers",
"version": "0.5.6.2"
},
{
"package": "mtl",
"version": "2.2.2"
},
{
"package": "text",
"version": "1.2.3.1"
},
{
"package": "parsec",
"version": "3.1.13.0"
},
{
"package": "pretty",
"version": "1.1.3.6"
},
{
"package": "process",
"version": "1.6.5.0"
},
{
"package": "ghc-boot-th",
"version": "8.6.5"
},
{
"package": "template-haskell",
"version": "2.14.0.0"
},
{
"package": "stm",
"version": "2.5.0.0"
}
],
"dependencies": [
{
"cabal_sha256": null,
"flags": [
"-bundled-binary-generic"
],
"package": "Cabal",
"revision": null,
"source": "local",
"src_sha256": null,
"version": "3.4.0.0"
},
{
"cabal_sha256": "b704cb6676c03e98267190df797497587576a2e96094550ea143415239bbe66e",
"flags": [],
"package": "network",
"revision": 0,
"source": "hackage",
"src_sha256": "d7ef590173fff2ab522fbc167f3fafb867e4ecfca279eb3ef0d137b51f142c9a",
"version": "3.1.1.1"
},
{
"cabal_sha256": "d2d9ff3a80d9b2d1ff317a354bc0c56cc109c69a4c2449e5fc712d3ddce83ede",
"flags": [],
"package": "network-uri",
"revision": 0,
"source": "hackage",
"src_sha256": "a01c1389f15d2cc2e847914737f706133bb11f0c5f8ee89711a36a25b7afa723",
"version": "2.6.3.0"
},
{
"cabal_sha256": "3c19975fdfd8d057eae58847bda6a79514ad882fd6f8ead72ac0247af34bdfc6",
"flags": [
"-conduit10",
"-mtl1",
"+network-uri",
"-warn-as-error",
"-warp-tests"
],
"package": "HTTP",
"revision": 1,
"source": "hackage",
"src_sha256": "a602d7f30e917164c6a634f8cb1f5df4849048858db01380a0875e16e5aa687b",
"version": "4000.3.14"
},
{
"cabal_sha256": "4c70f1407881059e93550d3742191254296b2737b793a742bd901348fb3e1fb1",
"flags": [
"-examples",
"+integer-gmp",
"+sse2",
"-sse41"
],
"package": "hashable",
"revision": 1,
"source": "hackage",
"src_sha256": "822e5413fbccca6ae884d3aba4066422c8b5d58d23d18b9ecb5c03273bb19ab4",
"version": "1.3.0.0"
},
{
"cabal_sha256": "a178c166856da7ff22fe4500337b54812e94fd2059409452187d72e057ede9cd",
"flags": [
"-bench"
],
"package": "async",
"revision": 1,
"source": "hackage",
"src_sha256": "4b4ab1ac82c45144d82c6daf6cb6ba45eab9957dad44787fa5e869e23d73bbff",
"version": "2.2.2"
},
{
"cabal_sha256": "8cbba2505d4da4f6cfc90cd36c8e8ad0c09c056538481ea00e8b10b78f70cb10",
"flags": [],
"package": "base16-bytestring",
"revision": 0,
"source": "hackage",
"src_sha256": "525689679d5cc80fa532c1d5cfeace0f62bbb54134fad514f1ba00d0e7fe69ba",
"version": "0.1.1.7"
},
{
"cabal_sha256": "190264fef9e65d9085f00ccda419137096d1dc94777c58272bc96821dc7f37c3",
"flags": [],
"package": "base64-bytestring",
"revision": 0,
"source": "hackage",
"src_sha256": "210d6c9042241ca52ee5d89cf221dbeb4d0e64b37391345369035ad2d9b4aca9",
"version": "1.1.0.0"
},
{
"cabal_sha256": "b963d6308db096362d73d9c603b331cf188aa69310195f479dfedf6045d7e602",
"flags": [
"-exe"
],
"package": "cryptohash-sha256",
"revision": 4,
"source": "hackage",
"src_sha256": "52756435dbea248e344fbcbcc5df5307f60dfacf337dfd11ae30f1c7a4da05dd",
"version": "0.11.101.0"
},
{
"cabal_sha256": "5490be9cfbea95e14a7a68b7d055ae8d295822e0b146d2ac8285b3e5a3e3282f",
"flags": [
"-example"
],
"package": "echo",
"revision": 1,
"source": "hackage",
"src_sha256": "704f07310f8272d170f8ab7fb2a2c13f15d8501ef8310801e36964c8eff485ef",
"version": "0.1.3"
},
{
"cabal_sha256": "d50c4d0801a35be7875a040470c09863342514930c82a7d25780a6c2efc4fda9",
"flags": [
"-optimised-mixer"
],
"package": "splitmix",
"revision": 0,
"source": "hackage",
"src_sha256": "1c11c87352ddbb13365380fe163f99bb8f8845ebc96ca1d572e5d3a9bf810bfa",
"version": "0.1"
},
{
"cabal_sha256": "5ca8674e95c46c7eb90f520c26aea22d403625c97697275434afba66ebd32b05",
"flags": [],
"package": "random",
"revision": 0,
"source": "hackage",
"src_sha256": "e4519cf7c058bfd5bdbe4acc782284acc9e25e74487208619ca83cbcd63fb9de",
"version": "1.2.0"
},
{
"cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee",
"flags": [],
"package": "edit-distance",
"revision": 1,
"source": "hackage",
"src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a",
"version": "0.2.2.1"
},
{
"cabal_sha256": "fb98b08de467d51f788f8bd9391f0e9ab9bd4d8dfc264296b895ffea0d822dfa",
"flags": [
"+no-donna",
"+test-doctests",
"+test-hlint",
"+test-properties"
],
"package": "ed25519",
"revision": 3,
"source": "hackage",
"src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d",
"version": "0.0.5.0"
},
{
"cabal_sha256": "c9d3fa30fb6ab2ba16e037586ca79be6e57ec5f00381b6ee5f293400dbdf5515",
"flags": [
"+ofd-locking"
],
"package": "lukko",
"revision": 0,
"source": "hackage",
"src_sha256": "8a79d113dc0ccef16c24d83379cc457485943027e777529c46362fecc06607d2",
"version": "0.1.1.2"
},
{
"cabal_sha256": "7a715414c4d494c9048cfb6d7634e07e7732ca154cb8938dc85f6ea192192e8c",
"flags": [
"-old-bytestring",
"-old-time"
],
"package": "tar",
"revision": 2,
"source": "hackage",
"src_sha256": "b384449f62b2b0aa3e6d2cb1004b8060b01f21ec93e7b63e7af6d8fad8a9f1de",
"version": "0.5.1.1"
},
{
"cabal_sha256": "d34ddf5fece4d1e9d471b5298f36335bb3cfe12cb5a1b8525c42f0b665382f45",
"flags": [
"-non-blocking-ffi",
"-pkg-config"
],
"package": "zlib",
"revision": 1,
"source": "hackage",
"src_sha256": "f0f810ff173560b60392db448455c0513b3239f48e43cb494b3733aa559621d0",
"version": "0.6.2.1"
},
{
"cabal_sha256": "692c385c085baa2813046ae58e31df21c250346b81c882431b5ffef76451a18a",
"flags": [
"+base48",
"+lukko",
"-mtl21",
"-old-directory",
"+use-network-uri"
],
"package": "hackage-security",
"revision": 2,
"source": "hackage",
"src_sha256": "9162b473af5a21c1ff32a50b972b9acf51f4c901604a22cf08a2dccac2f82f17",
"version": "0.6.0.1"
},
{
"cabal_sha256": "44aa95ca762294ffbb28cf0af9c567d93b5d2c56e4f38ce5385a257d899f968e",
"flags": [],
"package": "regex-base",
"revision": 1,
"source": "hackage",
"src_sha256": "c41f82f5fc1157c961a4cbdc0cd5561e5aa44f339ce6e706d978d97e0ca6b914",
"version": "0.94.0.0"
},
{
"cabal_sha256": "690d1366e9ea6df71ded3daf49ca3d53c63eda3f95937962299b2391824dc3b3",
"flags": [
"-_regex-posix-clib"
],
"package": "regex-posix",
"revision": 1,
"source": "hackage",
"src_sha256": "251300f1a6bb2e91abb8bf513a21981f8fab79c98a65acea2bb6d6a524414521",
"version": "0.96.0.0"
},
{
"cabal_sha256": "0a9a6dd29706258ae60a5c22aecc140a40743b8f08fc324fd9984e7dfbf3a80d",
"flags": [],
"package": "resolv",
"revision": 0,
"source": "hackage",
"src_sha256": "81a2bafad484db123cf8d17a02d98bb388a127fd0f822fa022589468a0e64671",
"version": "0.1.2.0"
},
{
"cabal_sha256": null,
"flags": [
"-debug-conflict-sets",
"-debug-expensive-assertions",
"-debug-tracetree",
"+lukko",
"+native-dns"
],
"package": "cabal-install",
"revision": null,
"source": "local",
"src_sha256": null,
"version": "3.4.0.0"
}
]
}
This diff is collapsed.
{
"builtin": [
{
"package": "rts",
"version": "1.0"
},
{
"package": "ghc-prim",
"version": "0.5.3"
},
{
"package": "integer-gmp",
"version": "1.0.2.0"
},
{
"package": "base",
"version": "4.13.0.0"
},
{
"package": "array",
"version": "0.5.4.0"
},
{
"package": "deepseq",
"version": "1.4.4.0"
},
{
"package": "bytestring",
"version": "0.10.10.0"
},
{
"package": "containers",
"version": "0.6.2.1"
},
{
"package": "binary",
"version": "0.8.7.0"
},
{
"package": "filepath",
"version": "1.4.2.1"
},
{
"package": "time",
"version": "1.9.3"
},
{
"package": "unix",
"version": "2.7.2.2"
},
{
"package": "directory",
"version": "1.3.6.0"
},
{
"package": "transformers",
"version": "0.5.6.2"
},
{
"package": "mtl",
"version": "2.2.2"
},
{
"package": "ghc-boot-th",
"version": "8.8.3"
},
{
"package": "pretty",
"version": "1.1.3.6"
},
{
"package": "template-haskell",
"version": "2.15.0.0"
},
{
"package": "text",
"version": "1.2.4.0"
},
{
"package": "parsec",
"version": "3.1.14.0"
},
{
"package": "process",
"version": "1.6.8.0"
},
{
"package": "stm",
"version": "2.5.0.0"
}
],
"dependencies": [
{
"cabal_sha256": null,
"flags": [
"-bundled-binary-generic"
],
"package": "Cabal",
"revision": null,
"source": "local",
"src_sha256": null,
"version": "3.4.0.0"
},
{
"cabal_sha256": "b704cb6676c03e98267190df797497587576a2e96094550ea143415239bbe66e",
"flags": [],
"package": "network",
"revision": 0,
"source": "hackage",
"src_sha256": "d7ef590173fff2ab522fbc167f3fafb867e4ecfca279eb3ef0d137b51f142c9a",
"version": "3.1.1.1"
},
{
"cabal_sha256": "d2d9ff3a80d9b2d1ff317a354bc0c56cc109c69a4c2449e5fc712d3ddce83ede",
"flags": [],
"package": "network-uri",
"revision": 0,
"source": "hackage",
"src_sha256": "a01c1389f15d2cc2e847914737f706133bb11f0c5f8ee89711a36a25b7afa723",
"version": "2.6.3.0"
},
{
"cabal_sha256": "3c19975fdfd8d057eae58847bda6a79514ad882fd6f8ead72ac0247af34bdfc6",
"flags": [
"-conduit10",
"-mtl1",
"+network-uri",
"-warn-as-error",
"-warp-tests"
],
"package": "HTTP",
"revision": 1,
"source": "hackage",
"src_sha256": "a602d7f30e917164c6a634f8cb1f5df4849048858db01380a0875e16e5aa687b",
"version": "4000.3.14"
},
{
"cabal_sha256": "4c70f1407881059e93550d3742191254296b2737b793a742bd901348fb3e1fb1",
"flags": [
"-examples",
"+integer-gmp",
"+sse2",
"-sse41"
],
"package": "hashable",
"revision": 1,
"source": "hackage",
"src_sha256": "822e5413fbccca6ae884d3aba4066422c8b5d58d23d18b9ecb5c03273bb19ab4",
"version": "1.3.0.0"
},
{
"cabal_sha256": "a178c166856da7ff22fe4500337b54812e94fd2059409452187d72e057ede9cd",
"flags": [
"-bench"
],
"package": "async",
"revision": 1,
"source": "hackage",
"src_sha256": "4b4ab1ac82c45144d82c6daf6cb6ba45eab9957dad44787fa5e869e23d73bbff",
"version": "2.2.2"
},
{
"cabal_sha256": "8cbba2505d4da4f6cfc90cd36c8e8ad0c09c056538481ea00e8b10b78f70cb10",
"flags": [],
"package": "base16-bytestring",
"revision": 0,
"source": "hackage",
"src_sha256": "525689679d5cc80fa532c1d5cfeace0f62bbb54134fad514f1ba00d0e7fe69ba",
"version": "0.1.1.7"
},
{
"cabal_sha256": "190264fef9e65d9085f00ccda419137096d1dc94777c58272bc96821dc7f37c3",
"flags": [],
"package": "base64-bytestring",
"revision": 0,
"source": "hackage",
"src_sha256": "210d6c9042241ca52ee5d89cf221dbeb4d0e64b37391345369035ad2d9b4aca9",
"version": "1.1.0.0"
},
{
"cabal_sha256": "b963d6308db096362d73d9c603b331cf188aa69310195f479dfedf6045d7e602",
"flags": [
"-exe"
],
"package": "cryptohash-sha256",
"revision": 4,
"source": "hackage",
"src_sha256": "52756435dbea248e344fbcbcc5df5307f60dfacf337dfd11ae30f1c7a4da05dd",
"version": "0.11.101.0"
},
{
"cabal_sha256": "5490be9cfbea95e14a7a68b7d055ae8d295822e0b146d2ac8285b3e5a3e3282f",
"flags": [
"-example"
],
"package": "echo",
"revision": 1,
"source": "hackage",
"src_sha256": "704f07310f8272d170f8ab7fb2a2c13f15d8501ef8310801e36964c8eff485ef",
"version": "0.1.3"
},
{
"cabal_sha256": "d50c4d0801a35be7875a040470c09863342514930c82a7d25780a6c2efc4fda9",
"flags": [
"-optimised-mixer"
],
"package": "splitmix",
"revision": 0,
"source": "hackage",
"src_sha256": "1c11c87352ddbb13365380fe163f99bb8f8845ebc96ca1d572e5d3a9bf810bfa",
"version": "0.1"
},
{
"cabal_sha256": "5ca8674e95c46c7eb90f520c26aea22d403625c97697275434afba66ebd32b05",
"flags": [],
"package": "random",
"revision": 0,
"source": "hackage",
"src_sha256": "e4519cf7c058bfd5bdbe4acc782284acc9e25e74487208619ca83cbcd63fb9de",
"version": "1.2.0"
},
{
"cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee",
"flags": [],
"package": "edit-distance",
"revision": 1,
"source": "hackage",
"src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a",
"version": "0.2.2.1"
},
{
"cabal_sha256": "fb98b08de467d51f788f8bd9391f0e9ab9bd4d8dfc264296b895ffea0d822dfa",
"flags": [
"+no-donna",
"+test-doctests",
"+test-hlint",
"+test-properties"
],
"package": "ed25519",
"revision": 3,
"source": "hackage",
"src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d",
"version": "0.0.5.0"
},
{
"cabal_sha256": "c9d3fa30fb6ab2ba16e037586ca79be6e57ec5f00381b6ee5f293400dbdf5515",
"flags": [
"+ofd-locking"
],
"package": "lukko",
"revision": 0,
"source": "hackage",
"src_sha256": "8a79d113dc0ccef16c24d83379cc457485943027e777529c46362fecc06607d2",
"version": "0.1.1.2"
},
{
"cabal_sha256": "7a715414c4d494c9048cfb6d7634e07e7732ca154cb8938dc85f6ea192192e8c",
"flags": [
"-old-bytestring",
"-old-time"
],
"package": "tar",
"revision": 2,
"source": "hackage",
"src_sha256": "b384449f62b2b0aa3e6d2cb1004b8060b01f21ec93e7b63e7af6d8fad8a9f1de",
"version": "0.5.1.1"
},
{
"cabal_sha256": "d34ddf5fece4d1e9d471b5298f36335bb3cfe12cb5a1b8525c42f0b665382f45",
"flags": [
"-non-blocking-ffi",
"-pkg-config"
],
"package": "zlib",
"revision": 1,
"source": "hackage",
"src_sha256": "f0f810ff173560b60392db448455c0513b3239f48e43cb494b3733aa559621d0",
"version": "0.6.2.1"
},
{
"cabal_sha256": "692c385c085baa2813046ae58e31df21c250346b81c882431b5ffef76451a18a",
"flags": [
"+base48",
"+lukko",
"-mtl21",
"-old-directory",
"+use-network-uri"
],
"package": "hackage-security",
"revision": 2,
"source": "hackage",
"src_sha256": "9162b473af5a21c1ff32a50b972b9acf51f4c901604a22cf08a2dccac2f82f17",
"version": "0.6.0.1"
},
{
"cabal_sha256": "44aa95ca762294ffbb28cf0af9c567d93b5d2c56e4f38ce5385a257d899f968e",
"flags": [],
"package": "regex-base",
"revision": 1,
"source": "hackage",
"src_sha256": "c41f82f5fc1157c961a4cbdc0cd5561e5aa44f339ce6e706d978d97e0ca6b914",
"version": "0.94.0.0"
},
{
"cabal_sha256": "690d1366e9ea6df71ded3daf49ca3d53c63eda3f95937962299b2391824dc3b3",
"flags": [
"-_regex-posix-clib"
],
"package": "regex-posix",
"revision": 1,
"source": "hackage",
"src_sha256": "251300f1a6bb2e91abb8bf513a21981f8fab79c98a65acea2bb6d6a524414521",
"version": "0.96.0.0"
},
{
"cabal_sha256": "0a9a6dd29706258ae60a5c22aecc140a40743b8f08fc324fd9984e7dfbf3a80d",
"flags": [],
"package": "resolv",
"revision": 0,
"source": "hackage",
"src_sha256": "81a2bafad484db123cf8d17a02d98bb388a127fd0f822fa022589468a0e64671",
"version": "0.1.2.0"
},
{
"cabal_sha256": null,
"flags": [
"-debug-conflict-sets",
"-debug-expensive-assertions",
"-debug-tracetree",
"+lukko",
"+native-dns"
],
"package": "cabal-install",
"revision": null,
"source": "local",
"src_sha256": null,
"version": "3.4.0.0"
}
]
}
This diff is collapsed.
module Main (main) where
import Control.Monad (when)
import Data.Either (partitionEithers)
import Data.Foldable (for_, traverse_)
import Data.Maybe (listToMaybe)
import Data.String (fromString)
import Data.Traversable (for)
import System.Environment (getArgs)
import System.Exit (exitFailure)
import System.IO (hPutStrLn, stderr)
import qualified Data.Text as T
import qualified Cabal.Index as I
import qualified Cabal.Plan as P
import qualified Data.Aeson as A
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import qualified Distribution.Types.PackageName as C
import qualified Distribution.Types.Version as C
import qualified Topograph as TG
-------------------------------------------------------------------------------
-- Main
-------------------------------------------------------------------------------
main :: IO ()
main = do
args <- getArgs
case args of
[fp] -> main1 fp
_ -> die "Usage: cabal-bootstrap-gen plan.json"
main1 :: FilePath -> IO ()
main1 planPath = do
meta <- I.cachedHackageMetadata
plan <- P.decodePlanJson planPath
main2 meta plan