arch-hs: Distribute hackage packages to archlinux

[ distribution, library, mit, program ] [ Propose Tags ]

arch-hs is a command-line program, which simplifies the process of producing and maintaining haskell packages for archlinux distribution by automating the PKGBUILD generation with the dependency resolving and template filling. Currently, arch-hs is unstable, so packagers should not trust it 100%, but always follow the Haskell package guidelines.


[Skip to Readme]

Flags

Manual Flags

NameDescriptionDefault
alpm

Whether to use libalpm

Disabled

Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

Versions [RSS] 0.0.0.0, 0.1.0.0, 0.1.1.0, 0.2.0.0, 0.3.0.0, 0.4.0.0, 0.5.0.0, 0.6.0.0, 0.6.1.0, 0.6.2.0, 0.7.0.0, 0.7.1.0, 0.8.0.0, 0.9.0.0, 0.9.1.0, 0.10.0.0, 0.10.1.0, 0.10.2.0, 0.11.0.0, 0.11.1.0
Change log CHANGELOG.md
Dependencies aeson (>=1.5.4 && <1.6), algebraic-graphs (>=0.5 && <0.6), arch-hs, base (>=4.14.0 && <4.15), bytestring (>=0.10.10 && <0.11), Cabal (>=3.2.0 && <3.3), colourista (>=0.1 && <0.2), conduit (>=1.3.2 && <1.4), conduit-extra (>=1.3.5 && <1.4), containers (>=0.6.2 && <0.7), deepseq (>=1.4.4 && <1.5), directory (>=1.3.6 && <1.4), filepath (>=1.4.2 && <1.5), hackage-db (>=2.1.0 && <2.2), megaparsec (>=8.0.0 && <8.1), microlens (>=0.4.11 && <0.5), microlens-th (>=0.4.3 && <0.5), neat-interpolation (>=0.5.1 && <0.6), optparse-applicative (>=0.16.0 && <0.17), polysemy, req (>=3.8.0 && <3.9), split (>=0.2.3 && <0.3), tar-conduit (>=0.3.2 && <0.4), template-haskell (>=2.16.0 && <2.17), text (>=1.2.3 && <1.3) [details]
License MIT
Copyright 2020 berberman
Author berberman
Maintainer berberman <1793913507@qq.com>
Category Distribution
Home page https://github.com/berberman/arch-hs
Bug tracker https://github.com/berberman/arch-hs/issues
Source repo head: git clone https://github.com/berberman/arch-hs.git
Uploaded by berberman at 2020-11-30T11:21:41Z
Distributions Arch:0.11.1.0
Executables arch-hs-submit, arch-hs-diff, arch-hs
Downloads 3553 total (63 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2020-11-30 [all 1 reports]

Readme for arch-hs-0.5.0.0

[back to package description]

arch-hs

GitHub CI Build Status Hackage MIT license

A program generating PKGBUILD for hackage packages. Special thanks to felixonmars.

Notice that arch-hs will always support only the latest GHC version.

Introduction

Given the name of a package in hackage, arch-hs can generate PKGBUILD files, not only for the package whose name is given, but also for all dependencies missing in [community]. arch-hs has a naive built-in dependency solver, which can fetch those dependencies and find out which are required to be packaged. During the dependency calculation, all version constraints will be discarded due to the arch haskell packaging strategy, thus there is no guarantee of dependencies' version consistency.

Prerequisite

arch-hs is a PKGBUILD text file generator, which is not integrated with pacman(See Alpm Support), depending on nothing than:

  • Pacman database (community.db)

  • Hackage index tarball (01-index.tar, or 00-index.tar previously) -- usually provided by cabal-install

Installation

arch-hs is portable, which means it's not restricted to Arch Linux. However, arch-hs can use libalpm to load pacman database on Arch Linux, and if you want to run them on other systems, you have to build it from source.

Install the latest release

# pacman -S arch-hs

arch-hs is available in [community], so you can install it using pacman.

Install the development version

# pacman -S arch-hs-git

The -git version is available in [archlinuxcn], following the latest git commit.

Build

$ git clone https://github.com/berberman/arch-hs

Then build it via stack or cabal.

Stack

$ stack build

Cabal (dynamic)

$ cabal configure --disable-library-vanilla --enable-shared --enable-executable-dynamic --ghc-options=-dynamic 
$ cabal build

Usage

Just run arch-hs in command line with options and a target. Here is an example: we will create the archlinux package of accelerate:

$ arch-hs -o ~/test accelerate

......

  ⓘ Recommended package order (from topological sort):
1. unique
2. tasty-kat
3. accelerate

......

  ⓘ Write file: /home/berberman/test/haskell-accelerate/PKGBUILD
  ⓘ Write file: /home/berberman/test/haskell-unique/PKGBUILD
  ⓘ Write file: /home/berberman/test/haskell-tasty-kat/PKGBUILD
  ✔ Success!

This message tells us that in order to package accelerate, we must package unique and tasty-kat first sequentially, because accelerate dependents on them to build or test, whereas they are not present in archlinux [community] repo.

$ tree ~/test
/home/berberman/Desktop/test
├── haskell-accelerate
│   └── PKGBUILD
├── haskell-tasty-kat
│   └── PKGBUILD
└── haskell-unique
    └── PKGBUILD

arch-hs will generate PKGBUILD for each package. Let's see what we have in ./haskell-accelerate/PKGBUILD:

# This file was generated by arch-hs, please check it manually.
# Maintainer: Your Name <youremail@domain.com>

_hkgname=accelerate
pkgname=haskell-accelerate
pkgver=1.3.0.0
pkgrel=1
pkgdesc="An embedded language for accelerated array processing"
url="https://github.com/AccelerateHS/accelerate/"
license=("custom:BSD3")
arch=('x86_64')
depends=('ghc-libs' 'haskell-ansi-terminal' 'haskell-base-orphans' 'haskell-cryptonite' 'haskell-half' 'haskell-hashable' 'haskell-hashtables' 'haskell-hedgehog' 'haskell-lens' 'haskell-prettyprinter' 'haskell-prettyprinter-ansi-terminal' 'haskell-primitive' 'haskell-tasty' 'haskell-terminal-size' 'haskell-unique' 'haskell-unordered-containers' 'haskell-vector')
makedepends=('ghc' 'haskell-doctest')
source=("https://hackage.haskell.org/packages/archive/$_hkgname/$pkgver/$_hkgname-$pkgver.tar.gz")
sha256sums=('4b97161f145c81f7554679802059598587e06d49b2c153e7bafc4dd6974bad92')

build() {
  cd $_hkgname-$pkgver

  runhaskell Setup configure -O --enable-shared --enable-executable-dynamic --disable-library-vanilla \
    --prefix=/usr --docdir=/usr/share/doc/$pkgname --enable-tests \
    --dynlibdir=/usr/lib --libsubdir=\$compiler/site-local/\$pkgid \
    --ghc-option=-optl-Wl\,-z\,relro\,-z\,now \
    --ghc-option='-pie'

  runhaskell Setup build
  runhaskell Setup register --gen-script
  runhaskell Setup unregister --gen-script
  sed -i -r -e "s|ghc-pkg.*update[^ ]* |&'--force' |" register.sh
  sed -i -r -e "s|ghc-pkg.*unregister[^ ]* |&'--force' |" unregister.sh
}

check() {
  cd $_hkgname-$pkgver
  runhaskell Setup test
}

package() {
  cd $_hkgname-$pkgver

  install -D -m744 register.sh "$pkgdir"/usr/share/haskell/register/$pkgname.sh
  install -D -m744 unregister.sh "$pkgdir"/usr/share/haskell/unregister/$pkgname.sh
  runhaskell Setup copy --destdir="$pkgdir"
  install -D -m644 LICENSE -t "$pkgdir"/usr/share/licenses/$pkgname/
  rm -f "$pkgdir"/usr/share/doc/$pkgname/LICENSE
}

arch-hs will collect the information from hackage db, and apply it into a fixed template after some processing steps including renaming, matching license, and filling out dependencies etc. However, packaging haven't been done so far. arch-hs may does well statically, but we should guarantee that this package can be built by ghc with the latest dependencies; hence some patchs may be required in prepare(), such as uusi.

Options

Output

$ arch-hs -o ~/test TARGET

Using -o can generate a series of PKGBUILD including TARGET with its dependencies into the output dir. If you don't pass it, only dependency calculation will occur.

Flag Assignments

$ arch-hs -f TARGET:FLAG_A:true TARGET

Using -f can pass flags, which may affect the results of resolving.

AUR Searching

$ arch-hs -a TARGET

With -a, arch-hs will regard AUR as another package provider, and it will try to search missing packages in AUR as well.

Skipping Components

$ arch-hs -s COMPONENT_A TARGET

Using -s can force skip runnable components in dependency resolving. This is useful when a package doesn't provide flag to disable its runnables, which will be built by default but are trivial in system level packaging. Notice that this only makes sense in the lifetime of arch-hs, whereas generated PKGBUILD and actual build processes will not be affected.

Extra Cabal Files

$ arch-hs -e ~/TARGET/TARGET.cabal TARGET

For Testing Purposes Only

Using -e can include extra .cabal files as supplementary. Useful when the TARGET hasn't been released to hackage.

Trace

$ arch-hs --trace TARGET

With --trace, arch-hs can print the process of dependency resolving into stdout.

$ arch-hs --trace-file foo.log TARGET

Similar to --trace, but the log will be written into a file.

Uusi

$ arch-hs -o ~/test --uusi TARGET

With --uusi, arch-hs will generate following snippet for each package:

prepare() {
  uusi $_hkgname-$pkgver/$_hkgname.cabal
}

See uusi for details.

Alpm

$ arch-hs --alpm TARGET

See Alpm Support.

Name preset

To distribute a haskell package to archlinux, the name of package should be changed according to the naming convention:

  • for haskell libraries, their names must have haskell- prefix

  • for programs, it depends on circumstances

  • names should always be in lower case

However, it's not enough to prefix the string with haskell- and transform to lower case; in some special situations, the hackage name may have haskell- prefix already, or the case is irregular, thus we have to a name preset manually. Once a package distributed to archlinux, whose name conform to above-mentioned situation, the name preset should be upgraded correspondingly.

Diff

arch-hs also provides a component called arch-hs-diff. arch-hs-diff can show the differences of package description between two versions of a package. This is useful in the subsequent maintenance of a package. Example:

$ arch-hs-diff HTTP 4000.3.14 4000.3.15
  ▶ You didn't pass -f, different flag values may make difference in dependency resolving.
  ⓘ Start running...
  ⓘ Downloading cabal file from https://hackage.haskell.org/package/HTTP-4000.3.14/revision/0.cabal...
  ⓘ Downloading cabal file from https://hackage.haskell.org/package/HTTP-4000.3.15/revision/0.cabal...
Package: HTTP
Version: 4000.3.14  ⇒  4000.3.15
Synopsis: A library for client-side HTTP
URL: https://github.com/haskell/HTTP
Depends:
    base  >=4.3.0.0 && <4.14
    time  >=1.1.2.3 && <1.10
    array  >=0.3.0.2 && <0.6
    bytestring  >=0.9.1.5 && <0.11
    mtl  >=2.0 && <2.3
    network  >=2.6 && <3.2
    network-uri  ==2.6.*
    parsec  >=2.0 && <3.2
--------------------------------------
    base  >=4.3.0.0 && <4.15
    time  >=1.1.2.3 && <1.11
    array  >=0.3.0.2 && <0.6
    bytestring  >=0.9.1.5 && <0.11
    mtl  >=2.0 && <2.3
    network  >=2.6 && <3.2
    network-uri  ==2.6.*
    parsec  >=2.0 && <3.2
MakeDepends:
    HUnit  >=1.2.0.1 && <1.7
    deepseq  >=1.3.0.0 && <1.5
    httpd-shed  >=0.4 && <0.5
    mtl  >=1.1.1.0 && <2.3
    pureMD5  >=0.2.4 && <2.2
    split  >=0.1.3 && <0.3
    test-framework  >=0.2.0 && <0.9
    test-framework-hunit  >=0.3.0 && <0.4
Flags:
  HTTP
    ⚐ mtl1:
      description:
        Use the old mtl version 1.
      default: False
      isManual: False
    ⚐ warn-as-error:
      description:
        Build with warnings-as-errors
      default: False
      isManual: True
    ⚐ conduit10:
      description:
        Use version 1.0.x or below of the conduit package (for the test suite)
      default: False
      isManual: False
    ⚐ warp-tests:
      description:
        Test against warp
      default: False
      isManual: True
    ⚐ network-uri:
      description:
        Get Network.URI from the network-uri package
      default: True
      isManual: False


  ✔ Success!

arch-hs-diff does not require hackage db, it downloads cabal files from hackage server instead.

Submit

For hackage distribution maintainers only.

Limitations

  • arch-hs will run into error, if solved targets contain cycle. Indeed, circular dependency lies ubiquitously in hackage because of tests, but basic cycles are resolved manually in [community] by maintainers. So after the provider simplification, arch-hs can eliminate these cycles. Nevertheless, if the target introduces new cycle or it dependens on a package in an unknown cycle, arch-hs will throw CyclicExist exception.

  • arch-hs is not able to handle with complicated situations: the libraries of a package partially exist in hackage, some libraries include external sources, etc.

  • arch-hs's functionality is limited to dependency processing, whereas necessary procedures like file patches, version range processes, etc. They need to be done manually, so DO NOT give too much trust in generated PKGBUILD files.

Alpm Support

alpm is Arch Linux Package Management library. When running on Arch Linux, loading community.db through this library is slightly faster than using the internal parser of arch-hs. Thus, arch-hs provides a flag alpm to enable this feature:

cabal build -f alpm

This flag is enabled by default in arch-hs Arch Linux package. Compiled with alpm, arch-hs can accept runtime flag --alpm. That said, if you want to use alpm to boost arch-hs, you need compile arch-hs with cabal flag alpm, and pass --aplm to arch-hs when running.

When alpm is enabled, arch-hs will lose the capability of specifying the path of community.db.

ToDoList

  • Standardized pretty printing.

  • AUR support.

  • Working with given .cabal files which haven't been released to hackage.

Contributing

Issues and PRs are always welcome. _(:з」∠)_