diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
-## 0.6
+## 0.8 - 2019-11-26
 
+- Split parsing utilities into [cabal-install-parsers package](https://hackage.haskell.org/package/cabal-install-parsers)
+- `--hlint-download-binary` to download HLint instead of building it ourselves [#323](https://github.com/haskell-ci/haskell-ci/pull/323)
+- Fix `haddock` path in OSX builds [#318](https://github.com/haskell-ci/haskell-ci/pull/318)
+- Don't `brew upgrade` on OSX, which greatly speedups builds [#320](https://github.com/haskell-ci/haskell-ci/pull/320)
+- Use Travis built-in config validation [#338](https://github.com/haskell-CI/haskell-ci/pull/338)
+- Use `sourceline: ...` explicit entry for hvr-ppa unconditionally [#338](https://github.com/haskell-CI/haskell-ci/pull/338)
+
+## 0.6 - 2019-10-21
+
 - ghc-options limiting heap size
 - GHCJS tests can be run in simple cases
 - Work around cabal#6214 (haddock failing with `build-type: Custom` packages)
@@ -9,7 +18,7 @@
 - Record `haskell-ci` version in REGENDATA;
   warn if older executable is used to `regenerate`
 
-## 0.4
+## 0.4 - 2019-08-28
 
 * Make default `--output` to be `.travis.yml`; use `--stdout` to output to standard output.
 * Add GHC-8.8 support
@@ -17,11 +26,11 @@
 * Experimental support for GHCJS jobs
 * A lot of new configuration options
 
-## 0.2.1
+## 0.2.1 - 2019-03-06
 
 * `local-ghc-options` are always applied (independent of `copy-fields` value)
 * Add GHC-8.6.4 to known compilers
 
-## 0.2
+## 0.2 - 2019-03-03
 
 * Large configuration rework
diff --git a/fixtures/cabal.haskell-ci b/fixtures/cabal.haskell-ci
deleted file mode 100644
--- a/fixtures/cabal.haskell-ci
+++ /dev/null
@@ -1,137 +0,0 @@
--- Most settings can be given as command line arguments
--- Config file is convenient if you maintain large amount of packages
-
--- Supported: xenial and bionic;
--- though bionic doesn't seem to be officially supported by Travis
-distribution: xenial
-
-jobs: 2:2
-
--- Add GHC head job
-ghc-head: True
-
--- travis Caching
--- cache: True
-
--- remove cabal noise from test output
--- cabal-noise: False
-
--- Build tests. In addition to True and False you may specify
--- a version range, e.g. >= 8.0 to build tests only in some jobs.
-tests: True
-
--- Run tests. Note that only built tests are run. Accepts booleans or version range.
-run-tests: True
-
--- Build benchmarks. There are no way to run benchmarks. Accepts booleans or version range.
-benchmarks: True
-
--- Build haddocks. Accepts booleans or version range.
-haddock: True
-
--- Run cabal check
--- cabal-check: True
-
--- Install dependencies in a separate step
--- If your project has inplace packages, you want to disable this.
--- install-dependencies-step: True
-
--- --no-tests --no-benchmarks build is useful to verify that package
--- builds when less constrained
--- no-tests-no-bench: True
-
--- By default `installed` constraints are used for packages
--- in global db. We can modify which constraints are used.
-installed: +all -Cabal
-
--- Options for local packages
-local-ghc-options: -Werror
-
--- Build only these branches
-branches: master
-
--- Enable IRC notifications to the given channel
--- name: fancy-name
--- irc-channels: irc.freenode.org#my-channel
-
--- Sections to fold in the build output
-folds: constraint-sets
-
--- Run HLint (needs GHC-8.2.2 job)
-hlint: True
-hlint-yaml: .hlint.yaml
--- hlint-version: ==2.0.*
-
--- Run doctest (on GHC-8.0+ which support .ghc.environment)
-doctest: True
-doctest-options: --fast
--- doctest-version: ==0.13.*
-
--- macOS job
-osx: 8.4.4 8.6.5
-
--- Define per-job environment variables
--- env: 8.4.4:FOO=bar,
---      8.6.4:FOO=baz
-
--- Constraint sets
--- Package will be build with different constraints.
--- This is useful to check compatibility with older versions of dependencies.
-
-constraint-set deepseq-1.4
-  ghc: (>= 7.8 && <7.10) || == 8.2.2
-  constraints: deepseq ==1.4.*
-  constraints: binary installed
-
-  -- Constraint sets accept booleans for few steps, as the main script
-  -- Defaults are False.
-  -- These fields don't accept version ranges: you should rather create
-  -- another constraint set.
-
-  -- tests: False
-  -- run-tests: False
-  -- benchmarks: False
-  haddock: True
-
--- Copy over additional properties specified in a cabal.project file.
--- Possible values are:
---   none: Do not copy any properties from the cabal.project file.
---   some: Copy a subset of the properties from the cabal.project file. (Default)
---         The fields and sections that are copied over are:
---
---         * constraints
---         * allow-newer
---         * reorder-goals
---         * max-backjumps
---         * optimization
---         * source-repository-package
---   all: Copy every property from the cabal.project file.
-copy-fields: some
-
--- Configure haskell-ci's behavior when presented multiple packages (e.g., a
--- cabal.project file that specifies multiple .cabal files), each of which
--- having its own range of GHC versions in its tested-with stanza.
--- Possible values are:
---   uniform: Every package must have the same range of versions in its
---            tested-with stanza. (Default)
---   any:     Take the union of all packages' version ranges. This implies
---            that different packages' version ranges can be disjoint.
-jobs-selection: uniform
-
--- Controls whether the haskell-ci version should be inserted into the
--- generated Travis YAML file. (Default: True)
---
--- We set this option to False here only to prevent version number churn in
--- the commit history, as version numbers for haskell-ci HEAD change extremely
--- frequently.
-insert-version: False
-
--- Controls whether the output of `cabal` invocations should be highlighted
--- using special colors in the Travis output.
-color: True
-
--- Include these fields "as is" in generated cabal.project
-raw-project
-  keep-going: False
-  package bytestring
-    tests: False
diff --git a/fixtures/cabal.project.copy-fields.all.travis.yml b/fixtures/cabal.project.copy-fields.all.travis.yml
--- a/fixtures/cabal.project.copy-fields.all.travis.yml
+++ b/fixtures/cabal.project.copy-fields.all.travis.yml
@@ -4,7 +4,9 @@
 #
 # For more information, see https://github.com/haskell-CI/haskell-ci
 #
+version: ~> 1.0
 language: c
+os: linux
 dist: xenial
 git:
   # whether to recursively clone submodules
@@ -13,6 +15,7 @@
   directories:
     - $HOME/.cabal/packages
     - $HOME/.cabal/store
+    - $HOME/.hlint
 before_cache:
   - rm -fv $CABALHOME/packages/hackage.haskell.org/build-reports.log
   # remove files that are regenerated by 'cabal update'
@@ -22,50 +25,71 @@
   - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar
   - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar.idx
   - rm -rfv $CABALHOME/packages/head.hackage
-matrix:
+jobs:
   include:
     - compiler: ghc-8.8.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.8.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.8.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.5
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.5","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.5","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.4","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.4","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.4","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.4","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.2.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.2.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.2.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.2.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.2.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.2.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.0.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.0.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.0.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.0.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.0.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.0.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.10.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.10.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.10.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.4","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.4","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.1","cabal-install-3.0"]}}
+      os: linux
 before_install:
   - HC=$(echo "/opt/$CC/bin/ghc" | sed 's/-/\//')
   - WITHCOMPILER="-w $HC"
diff --git a/fixtures/cabal.project.copy-fields.none.travis.yml b/fixtures/cabal.project.copy-fields.none.travis.yml
--- a/fixtures/cabal.project.copy-fields.none.travis.yml
+++ b/fixtures/cabal.project.copy-fields.none.travis.yml
@@ -4,7 +4,9 @@
 #
 # For more information, see https://github.com/haskell-CI/haskell-ci
 #
+version: ~> 1.0
 language: c
+os: linux
 dist: xenial
 git:
   # whether to recursively clone submodules
@@ -13,6 +15,7 @@
   directories:
     - $HOME/.cabal/packages
     - $HOME/.cabal/store
+    - $HOME/.hlint
 before_cache:
   - rm -fv $CABALHOME/packages/hackage.haskell.org/build-reports.log
   # remove files that are regenerated by 'cabal update'
@@ -22,50 +25,71 @@
   - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar
   - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar.idx
   - rm -rfv $CABALHOME/packages/head.hackage
-matrix:
+jobs:
   include:
     - compiler: ghc-8.8.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.8.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.8.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.5
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.5","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.5","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.4","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.4","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.4","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.4","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.2.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.2.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.2.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.2.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.2.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.2.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.0.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.0.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.0.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.0.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.0.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.0.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.10.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.10.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.10.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.4","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.4","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.1","cabal-install-3.0"]}}
+      os: linux
 before_install:
   - HC=$(echo "/opt/$CC/bin/ghc" | sed 's/-/\//')
   - WITHCOMPILER="-w $HC"
diff --git a/fixtures/cabal.project.copy-fields.some.travis.yml b/fixtures/cabal.project.copy-fields.some.travis.yml
--- a/fixtures/cabal.project.copy-fields.some.travis.yml
+++ b/fixtures/cabal.project.copy-fields.some.travis.yml
@@ -4,7 +4,9 @@
 #
 # For more information, see https://github.com/haskell-CI/haskell-ci
 #
+version: ~> 1.0
 language: c
+os: linux
 dist: xenial
 git:
   # whether to recursively clone submodules
@@ -13,6 +15,7 @@
   directories:
     - $HOME/.cabal/packages
     - $HOME/.cabal/store
+    - $HOME/.hlint
 before_cache:
   - rm -fv $CABALHOME/packages/hackage.haskell.org/build-reports.log
   # remove files that are regenerated by 'cabal update'
@@ -22,50 +25,71 @@
   - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar
   - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar.idx
   - rm -rfv $CABALHOME/packages/head.hackage
-matrix:
+jobs:
   include:
     - compiler: ghc-8.8.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.8.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.8.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.5
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.5","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.5","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.4","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.4","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.4","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.4","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.2.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.2.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.2.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.2.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.2.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.2.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.0.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.0.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.0.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.0.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.0.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.0.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.10.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.10.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.10.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.4","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.4","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.1","cabal-install-3.0"]}}
+      os: linux
 before_install:
   - HC=$(echo "/opt/$CC/bin/ghc" | sed 's/-/\//')
   - WITHCOMPILER="-w $HC"
diff --git a/fixtures/cabal.project.empty-line.travis.yml b/fixtures/cabal.project.empty-line.travis.yml
--- a/fixtures/cabal.project.empty-line.travis.yml
+++ b/fixtures/cabal.project.empty-line.travis.yml
@@ -4,7 +4,9 @@
 #
 # For more information, see https://github.com/haskell-CI/haskell-ci
 #
+version: ~> 1.0
 language: c
+os: linux
 dist: xenial
 git:
   # whether to recursively clone submodules
@@ -13,6 +15,7 @@
   directories:
     - $HOME/.cabal/packages
     - $HOME/.cabal/store
+    - $HOME/.hlint
 before_cache:
   - rm -fv $CABALHOME/packages/hackage.haskell.org/build-reports.log
   # remove files that are regenerated by 'cabal update'
@@ -22,52 +25,74 @@
   - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar
   - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar.idx
   - rm -rfv $CABALHOME/packages/head.hackage
-matrix:
+jobs:
   include:
     - compiler: ghc-8.8.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.8.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.8.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.5
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.5","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.5","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.4","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.4","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.4","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.4","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.2.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.2.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.2.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.2.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.2.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.2.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.0.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.0.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.0.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.0.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.0.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.0.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.10.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.10.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.10.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.4","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.4","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-head
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-head","cabal-install-head"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-head","cabal-install-head"]}}
+      os: linux
   allow_failures:
     - compiler: ghc-head
 before_install:
diff --git a/fixtures/cabal.project.messy.travis.yml b/fixtures/cabal.project.messy.travis.yml
--- a/fixtures/cabal.project.messy.travis.yml
+++ b/fixtures/cabal.project.messy.travis.yml
@@ -4,7 +4,9 @@
 #
 # For more information, see https://github.com/haskell-CI/haskell-ci
 #
+version: ~> 1.0
 language: c
+os: linux
 dist: xenial
 git:
   # whether to recursively clone submodules
@@ -13,6 +15,7 @@
   directories:
     - $HOME/.cabal/packages
     - $HOME/.cabal/store
+    - $HOME/.hlint
 before_cache:
   - rm -fv $CABALHOME/packages/hackage.haskell.org/build-reports.log
   # remove files that are regenerated by 'cabal update'
@@ -22,52 +25,74 @@
   - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar
   - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar.idx
   - rm -rfv $CABALHOME/packages/head.hackage
-matrix:
+jobs:
   include:
     - compiler: ghc-8.8.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.8.1","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.8.1","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-8.6.5
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.5","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.5","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-8.6.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.4","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.4","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-8.6.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.3","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.3","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-8.6.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.2","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.2","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-8.6.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.1","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.1","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-8.4.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.4","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.4","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-8.4.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.3","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.3","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-8.4.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.2","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.2","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-8.4.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.1","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.1","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-8.2.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.2.2","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.2.2","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-8.2.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.2.1","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.2.1","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-8.0.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.0.2","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.0.2","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-8.0.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.0.1","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.0.1","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-7.10.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.3","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.3","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-7.10.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.2","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.2","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-7.10.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.1","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.1","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-7.8.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.4","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.4","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-7.8.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.3","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.3","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-7.8.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.2","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.2","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-7.8.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.1","cabal-install-3.0","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.1","cabal-install-3.0","fftw3-dev"]}}
+      os: linux
     - compiler: ghc-head
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-head","cabal-install-head","fftw3-dev"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-head","cabal-install-head","fftw3-dev"]}}
+      os: linux
   allow_failures:
     - compiler: ghc-head
 before_install:
diff --git a/fixtures/cabal.project.travis-patch.travis.yml b/fixtures/cabal.project.travis-patch.travis.yml
--- a/fixtures/cabal.project.travis-patch.travis.yml
+++ b/fixtures/cabal.project.travis-patch.travis.yml
@@ -4,7 +4,9 @@
 #
 # For more information, see https://github.com/haskell-CI/haskell-ci
 #
+version: ~> 1.0
 language: c
+os: linux
 dist: xenial
  git:
   # whether to recursively clone submodules
@@ -13,6 +15,7 @@
   directories:
     - $HOME/.cabal/packages
     - $HOME/.cabal/store
+    - $HOME/.hlint
 before_cache:
   - rm -fv $CABALHOME/packages/hackage.haskell.org/build-reports.log
   # remove files that are regenerated by 'cabal update'
@@ -22,50 +25,71 @@
   - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar
   - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar.idx
   - rm -rfv $CABALHOME/packages/head.hackage
-matrix:
+jobs:
   include:
     - compiler: ghc-8.8.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.8.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.8.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.5
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.5","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.5","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.4","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.4","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.6.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.4","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.4","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.4.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.2.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.2.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.2.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.2.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.2.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.2.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.0.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.0.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.0.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-8.0.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.0.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.0.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.10.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.10.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.10.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.10.1","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.4","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.4","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.3
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.3","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.3","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.2","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.2","cabal-install-3.0"]}}
+      os: linux
     - compiler: ghc-7.8.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.1","cabal-install-3.0"]}}
+      addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-7.8.1","cabal-install-3.0"]}}
+      os: linux
 before_install:
   - HC=$(echo "/opt/$CC/bin/ghc" | sed 's/-/\//')
   - WITHCOMPILER="-w $HC"
diff --git a/fixtures/haskell-ci.cabal b/fixtures/haskell-ci.cabal
deleted file mode 100644
--- a/fixtures/haskell-ci.cabal
+++ /dev/null
@@ -1,205 +0,0 @@
-cabal-version:      2.2
-name:               haskell-ci
-version:            0.6
-synopsis:           Cabal package script generator for Travis-CI
-description:
-  Script generator (@haskell-ci@) for [Travis-CI](https://travis-ci.org/) for continuous-integration testing of Haskell Cabal packages.
-  .
-  Included features (not limited to):
-  .
-  * Multiple GHC support
-  * Dependency caching
-  * cabal.project support (see [Nix-style local builds documentation](https://cabal.readthedocs.io/en/latest/nix-local-build-overview.html))
-  * Runs tests and builds benchmarks
-  * Generates Haddocks
-  * macOS (OSX) support
-  * GHCJS support
-  * building with specific constraints
-  .
-  === Quick Start Guide
-  .
-  Add a @tested-with@ line to your @.cabal@ file (e.g. @tested-with: GHC == 8.0.2 || == 8.2.2@) and then run @haskell-ci yourpackage.cabal -o .travis.yml@ to generate the Travis-CI job script.
-  .
-  See @haskell-ci --help@ for more information.
-
-homepage:           https://haskell-ci.rtfd.org/
-bug-reports:        https://github.com/haskell-CI/haskell-ci/issues
-license:            GPL-3.0-or-later
-license-file:       LICENSE
-author:             Herbert Valerio Riedel, Oleg Grenrus
-maintainer:         hvr@gnu.org
-category:           Development
-build-type:         Simple
-tested-with:        GHC ==8.2.2 || ==8.4.4 || ==8.6.5 || ==8.8.1
-extra-source-files:
-  CHANGELOG.md
-  fixtures/cabal.haskell-ci
-  fixtures/cabal.project.haskell-ci
-  fixtures/cabal.project.fail-versions
-  fixtures/cabal.project.fail-versions.stderr
-  fixtures/haskell-ci.cabal
-  fixtures/cabal.project.empty-line
-  fixtures/cabal.project.messy
-  fixtures/cabal.project.copy-fields.all
-  fixtures/cabal.project.copy-fields.some
-  fixtures/cabal.project.copy-fields.none
-  fixtures/haskell-ci.cabal.stderr
-  fixtures/cabal.project.empty-line.stderr
-  fixtures/cabal.project.messy.stderr
-  fixtures/cabal.project.copy-fields.all.stderr
-  fixtures/cabal.project.copy-fields.some.stderr
-  fixtures/cabal.project.copy-fields.none.stderr
-  fixtures/haskell-ci.cabal.travis.yml
-  fixtures/cabal.project.empty-line.travis.yml
-  fixtures/cabal.project.messy.travis.yml
-  fixtures/cabal.project.copy-fields.all.travis.yml
-  fixtures/cabal.project.copy-fields.some.travis.yml
-  fixtures/cabal.project.copy-fields.none.travis.yml
-  fixtures/cabal.project.travis-patch
-  fixtures/cabal.project.travis-patch.patch
-  fixtures/cabal.project.travis-patch.stderr
-  fixtures/cabal.project.travis-patch.travis.yml
-  fixtures/servant-client-core/*.cabal
-  fixtures/servant-client/*.cabal
-  fixtures/servant-docs/*.cabal
-  fixtures/servant-foreign/*.cabal
-  fixtures/servant-server/*.cabal
-  fixtures/servant/*.cabal
-  fixtures/doc/tutorial/tutorial.cabal
-
-source-repository head
-  type:     git
-  location: https://github.com/haskell-CI/haskell-ci.git
-
-flag ShellCheck
-  default: True
-  manual:  True
-
-library haskell-ci-internal
-  exposed-modules:
-    HaskellCI
-    HaskellCI.Cli
-    HaskellCI.Compiler
-    HaskellCI.Config
-    HaskellCI.Config.ConstraintSet
-    HaskellCI.Config.CopyFields
-    HaskellCI.Config.Doctest
-    HaskellCI.Config.Dump
-    HaskellCI.Config.Folds
-    HaskellCI.Config.HLint
-    HaskellCI.Config.Installed
-    HaskellCI.Config.Jobs
-    HaskellCI.Config.Ubuntu
-    HaskellCI.Diagnostics
-    HaskellCI.Glob
-    HaskellCI.Jobs
-    HaskellCI.List
-    HaskellCI.MonadErr
-    HaskellCI.Newtypes
-    HaskellCI.Optimization
-    HaskellCI.OptionsGrammar
-    HaskellCI.OptparseGrammar
-    HaskellCI.Package
-    HaskellCI.ParsecError
-    HaskellCI.ParsecUtils
-    HaskellCI.Prelude
-    HaskellCI.Project
-    HaskellCI.Sh
-    HaskellCI.ShVersionRange
-    HaskellCI.TestedWith
-    HaskellCI.Tools
-    HaskellCI.Travis
-    HaskellCI.Travis.Yaml
-    HaskellCI.YamlSyntax
-
-  ghc-options:        -Wall -Wcompat -Wnoncanonical-monad-instances
-
-  if impl(ghc <8.8)
-    ghc-options: -Wnoncanonical-monadfail-instances
-
-  hs-source-dirs:     src
-  default-extensions:
-    NoImplicitPrelude
-    BangPatterns
-    DeriveAnyClass
-    DeriveFoldable
-    DeriveFunctor
-    DeriveGeneric
-    DeriveTraversable
-    DerivingStrategies
-    GeneralizedNewtypeDeriving
-    ScopedTypeVariables
-
-  other-extensions:
-    CPP
-    NamedFieldPuns
-    OverloadedLabels
-    ViewPatterns
-
-  build-depends:
-    , base          >=4.10     && <4.14
-    , bytestring    ^>=0.10.8.1
-    , Cabal         ^>=3.0
-    , containers    ^>=0.5.7.1 || ^>=0.6.0.1
-    , deepseq       ^>=1.4.2.0
-    , directory     ^>=1.3.0.0
-    , filepath      ^>=1.4.1.1
-    , mtl           >=2.2.2
-    , parsec        ^>=3.1.13.0
-    , pretty        ^>=1.1.3.3
-    , process       ^>=1.4.3.0 || ^>=1.6.1.0
-    , text          ^>=1.2.3.0
-    , transformers  ^>=0.5.2.0
-
-  if !impl(ghc >=8.2)
-    build-depends: bifunctors ^>=5.5.4
-
-  -- other dependencies
-  build-depends:
-    , aeson                 ^>=1.4.2.0
-    , base-compat           ^>=0.11
-    , exceptions            ^>=0.10.0
-    , generic-lens          ^>=1.2.0.0
-    , HsYAML                ^>=0.2.0.0
-    , lattices              ^>=2
-    , microlens             ^>=0.4.10
-    , network-uri           ^>=2.6.1.0
-    , optparse-applicative  ^>=0.15
-    , temporary             ^>=1.3
-    , unordered-containers  ^>=0.2.10.0
-
-  default-language:   Haskell2010
-
-  -- ShellCheck. Would need newer transformers for older GHC
-  if (flag(shellcheck) && impl(ghc >=7.10 && <8.7))
-    build-depends: ShellCheck ==0.7.0
-
-executable haskell-ci
-  main-is:          Main.hs
-  hs-source-dirs:   cli
-  build-depends:
-    , base
-    , haskell-ci-internal
-
-  default-language: Haskell2010
-
-test-suite golden
-  type:             exitcode-stdio-1.0
-  main-is:          Tests.hs
-  hs-source-dirs:   test
-  build-depends:
-    , ansi-terminal        ^>=0.10
-    , base
-    , base-compat
-    , bytestring
-    , Diff                 ^>=0.4.0
-    , directory
-    , filepath
-    , haskell-ci-internal
-    , tasty                >=1.0     && <1.3
-    , tasty-golden         ^>=2.3.1.1
-    , transformers
-
-  -- inherited constraints via lib:haskell-ci
-  -- dependencies needing explicit constraints
-  default-language: Haskell2010
diff --git a/fixtures/haskell-ci.cabal.stderr b/fixtures/haskell-ci.cabal.stderr
deleted file mode 100644
--- a/fixtures/haskell-ci.cabal.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-*INFO* Generating Travis-CI config for testing for GHC versions: ghc-head 8.2.2 8.4.4 8.6.5 8.8.1
-*INFO* Also OSX jobs for: 8.4.4 8.6.5
diff --git a/fixtures/haskell-ci.cabal.travis.yml b/fixtures/haskell-ci.cabal.travis.yml
deleted file mode 100644
--- a/fixtures/haskell-ci.cabal.travis.yml
+++ /dev/null
@@ -1,211 +0,0 @@
-# This Travis job script has been generated by a script via
-#
-#   haskell-ci '--config=cabal.haskell-ci' 'cabal.project'
-#
-# For more information, see https://github.com/haskell-CI/haskell-ci
-#
-language: c
-dist: xenial
-git:
-  # whether to recursively clone submodules
-  submodules: false
-branches:
-  only:
-    - master
-cache:
-  directories:
-    - $HOME/.cabal/packages
-    - $HOME/.cabal/store
-    - $HOME/.ghc-install
-before_cache:
-  - rm -fv $CABALHOME/packages/hackage.haskell.org/build-reports.log
-  # remove files that are regenerated by 'cabal update'
-  - rm -fv $CABALHOME/packages/hackage.haskell.org/00-index.*
-  - rm -fv $CABALHOME/packages/hackage.haskell.org/*.json
-  - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.cache
-  - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar
-  - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar.idx
-  - rm -rfv $CABALHOME/packages/head.hackage
-matrix:
-  include:
-    - compiler: ghc-8.8.1
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.8.1","cabal-install-3.0"]}}
-    - compiler: ghc-8.6.5
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.5","cabal-install-3.0"]}}
-    - compiler: ghc-8.4.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.4","cabal-install-3.0"]}}
-    - compiler: ghc-8.2.2
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.2.2","cabal-install-3.0"]}}
-    - compiler: ghc-head
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-head","cabal-install-head"]}}
-    - compiler: ghc-8.6.5
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.5","cabal-install-3.0"]}}
-      os: osx
-    - compiler: ghc-8.4.4
-      addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.4","cabal-install-3.0"]}}
-      os: osx
-  allow_failures:
-    - compiler: ghc-head
-before_install:
-  - HC=$(echo "/opt/$CC/bin/ghc" | sed 's/-/\//')
-  - WITHCOMPILER="-w $HC"
-  - HADDOCK=$(echo "/opt/$CC/bin/haddock" | sed 's/-/\//')
-  - HCPKG="$HC-pkg"
-  - unset CC
-  - CABAL=/opt/ghc/bin/cabal
-  - CABALHOME=$HOME/.cabal
-  - export PATH="$CABALHOME/bin:$PATH"
-  - TOP=$(pwd)
-  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; brew upgrade python@3; curl https://haskell.futurice.com/haskell-on-macos.py | python3 - --make-dirs --install-dir=$HOME/.ghc-install --cabal-alias=head install cabal-install-head ${TRAVIS_COMPILER}; fi
-  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then HC=$HOME/.ghc-install/ghc/bin/$TRAVIS_COMPILER; WITHCOMPILER="-w $HC"; HCPKG=${HC/ghc/ghc-pkg}; CABAL=$HOME/.ghc-install/ghc/bin/cabal; fi
-  - "HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\\d+)\\.(\\d+)\\.(\\d+)(\\.(\\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')"
-  - echo $HCNUMVER
-  - CABAL="$CABAL -vnormal+nowrap+markoutput"
-  - set -o pipefail
-  - |
-    echo 'function blue(s) { printf "\033[0;34m" s "\033[0m " }'           >> .colorful.awk
-    echo 'BEGIN { state = "output"; }'                                     >> .colorful.awk
-    echo '/^-----BEGIN CABAL OUTPUT-----$/ { state = "cabal" }'            >> .colorful.awk
-    echo '/^-----END CABAL OUTPUT-----$/ { state = "output" }'             >> .colorful.awk
-    echo '!/^(-----BEGIN CABAL OUTPUT-----|-----END CABAL OUTPUT-----)/ {' >> .colorful.awk
-    echo '  if (state == "cabal") {'                                       >> .colorful.awk
-    echo '    print blue($0)'                                              >> .colorful.awk
-    echo '  } else {'                                                      >> .colorful.awk
-    echo '    print $0'                                                    >> .colorful.awk
-    echo '  }'                                                             >> .colorful.awk
-    echo '}'                                                               >> .colorful.awk
-  - cat .colorful.awk
-  - |
-    color_cabal_output () {
-      awk -f $TOP/.colorful.awk
-    }
-  - echo text | color_cabal_output
-install:
-  - ${CABAL} --version
-  - echo "$(${HC} --version) [$(${HC} --print-project-git-commit-id 2> /dev/null || echo '?')]"
-  - TEST=--enable-tests
-  - BENCH=--enable-benchmarks
-  - HEADHACKAGE=false
-  - if [ $HCNUMVER -gt 80801 ] ; then HEADHACKAGE=true ; fi
-  - rm -f $CABALHOME/config
-  - |
-    echo "verbose: normal +nowrap +markoutput"                                  >> $CABALHOME/config
-    echo "remote-build-reporting: anonymous"                                    >> $CABALHOME/config
-    echo "write-ghc-environment-files: always"                                  >> $CABALHOME/config
-    echo "remote-repo-cache: $CABALHOME/packages"                               >> $CABALHOME/config
-    echo "logs-dir:          $CABALHOME/logs"                                   >> $CABALHOME/config
-    echo "world-file:        $CABALHOME/world"                                  >> $CABALHOME/config
-    echo "extra-prog-path:   $CABALHOME/bin"                                    >> $CABALHOME/config
-    echo "symlink-bindir:    $CABALHOME/bin"                                    >> $CABALHOME/config
-    echo "installdir:        $CABALHOME/bin"                                    >> $CABALHOME/config
-    echo "build-summary:     $CABALHOME/logs/build.log"                         >> $CABALHOME/config
-    echo "store-dir:         $CABALHOME/store"                                  >> $CABALHOME/config
-    echo "install-dirs user"                                                    >> $CABALHOME/config
-    echo "  prefix: $CABALHOME"                                                 >> $CABALHOME/config
-    echo "repository hackage.haskell.org"                                       >> $CABALHOME/config
-    echo "  url: http://hackage.haskell.org/"                                   >> $CABALHOME/config
-    echo "  secure: True"                                                       >> $CABALHOME/config
-    echo "  key-threshold: 3"                                                   >> $CABALHOME/config
-    echo "  root-keys:"                                                         >> $CABALHOME/config
-    echo "    fe331502606802feac15e514d9b9ea83fee8b6ffef71335479a2e68d84adc6b0" >> $CABALHOME/config
-    echo "    1ea9ba32c526d1cc91ab5e5bd364ec5e9e8cb67179a471872f6e26f0ae773d42" >> $CABALHOME/config
-    echo "    2c6c3627bd6c982990239487f1abd02e08a02e6cf16edb105a8012d444d870c3" >> $CABALHOME/config
-    echo "    0a5c7ea47cd1b15f01f5f51a33adda7e655bc0f0b0615baa8e271f4c3351e21d" >> $CABALHOME/config
-    echo "    51f0161b906011b52c6613376b1ae937670da69322113a246a09f807c62f6921" >> $CABALHOME/config
-  - |
-    if $HEADHACKAGE; then
-    echo "allow-newer: $($HCPKG list --simple-output | sed -E 's/([a-zA-Z-]+)-[0-9.]+/*:\1/g')" >> $CABALHOME/config
-    echo "repository head.hackage.ghc.haskell.org"                                        >> $CABALHOME/config
-    echo "   url: https://ghc.gitlab.haskell.org/head.hackage/"                           >> $CABALHOME/config
-    echo "   secure: True"                                                                >> $CABALHOME/config
-    echo "   root-keys: 7541f32a4ccca4f97aea3b22f5e593ba2c0267546016b992dfadcd2fe944e55d" >> $CABALHOME/config
-    echo "              26021a13b401500c8eb2761ca95c61f2d625bfef951b939a8124ed12ecf07329" >> $CABALHOME/config
-    echo "              f76d08be13e9a61a377a85e2fb63f4c5435d40f8feb3e12eb05905edb8cdea89" >> $CABALHOME/config
-    echo "   key-threshold: 3"                                                            >> $CABALHOME/config
-    fi
-  - "echo 'jobs: 2' >> $CABALHOME/config"
-  - GHCJOBS=-j2
-  - |
-    echo "program-default-options"                >> $CABALHOME/config
-    echo "  ghc-options: $GHCJOBS +RTS -M6G -RTS" >> $CABALHOME/config
-  - cat $CABALHOME/config
-  - rm -fv cabal.project cabal.project.local cabal.project.freeze
-  - travis_retry ${CABAL} v2-update -v
-  - (cd /tmp && ${CABAL} v2-install $WITHCOMPILER -j2 doctest --constraint='doctest ==0.16.*' | color_cabal_output)
-  - if [ $HCNUMVER -ge 80800 ] && [ $HCNUMVER -lt 80802 ] ; then (cd /tmp && ${CABAL} v2-install $WITHCOMPILER -j2 hlint --constraint='hlint ==2.1.*' | color_cabal_output) ; fi
-  # Generate cabal.project
-  - rm -rf cabal.project cabal.project.local cabal.project.freeze
-  - touch cabal.project
-  - |
-    echo "packages: ." >> cabal.project
-  - |
-    echo "package haskell-ci"     >> cabal.project
-    echo "  ghc-options: -Werror" >> cabal.project
-    echo ""                       >> cabal.project
-    echo "keep-going: False"      >> cabal.project
-    echo ""                       >> cabal.project
-    echo "package bytestring"     >> cabal.project
-    echo "  tests: False"         >> cabal.project
-  - "for pkg in $($HCPKG list --simple-output); do echo $pkg | sed 's/-[^-]*$//' | (grep -vE -- '^(Cabal|haskell-ci)$' || true) | sed 's/^/constraints: /' | sed 's/$/ installed/' >> cabal.project.local; done"
-  - cat cabal.project || true
-  - cat cabal.project.local || true
-  - if [ -f "./configure.ac" ]; then (cd "." && autoreconf -i); fi
-  - ${CABAL} v2-freeze $WITHCOMPILER ${TEST} ${BENCH} | color_cabal_output
-  - "cat cabal.project.freeze | sed -E 's/^(constraints: *| *)//' | sed 's/any.//'"
-  - rm  cabal.project.freeze
-  - ${CABAL} v2-build $WITHCOMPILER ${TEST} ${BENCH} --dep -j2 all | color_cabal_output
-  - ${CABAL} v2-build $WITHCOMPILER --disable-tests --disable-benchmarks --dep -j2 all | color_cabal_output
-script:
-  - DISTDIR=$(mktemp -d /tmp/dist-test.XXXX)
-  # Packaging...
-  - ${CABAL} v2-sdist all | color_cabal_output
-  # Unpacking...
-  - mv dist-newstyle/sdist/*.tar.gz ${DISTDIR}/
-  - cd ${DISTDIR} || false
-  - find . -maxdepth 1 -type f -name '*.tar.gz' -exec tar -xvf '{}' \;
-  - find . -maxdepth 1 -type f -name '*.tar.gz' -exec rm       '{}' \;
-  - PKGDIR_haskell_ci="$(find . -maxdepth 1 -type d -regex '.*/haskell-ci-[0-9.]*')"
-  # Generate cabal.project
-  - rm -rf cabal.project cabal.project.local cabal.project.freeze
-  - touch cabal.project
-  - |
-    echo "packages: ${PKGDIR_haskell_ci}" >> cabal.project
-  - |
-    echo "package haskell-ci"     >> cabal.project
-    echo "  ghc-options: -Werror" >> cabal.project
-    echo ""                       >> cabal.project
-    echo "keep-going: False"      >> cabal.project
-    echo ""                       >> cabal.project
-    echo "package bytestring"     >> cabal.project
-    echo "  tests: False"         >> cabal.project
-  - "for pkg in $($HCPKG list --simple-output); do echo $pkg | sed 's/-[^-]*$//' | (grep -vE -- '^(Cabal|haskell-ci)$' || true) | sed 's/^/constraints: /' | sed 's/$/ installed/' >> cabal.project.local; done"
-  - cat cabal.project || true
-  - cat cabal.project.local || true
-  # Building...
-  # this builds all libraries and executables (without tests/benchmarks)
-  - ${CABAL} v2-build $WITHCOMPILER --disable-tests --disable-benchmarks all | color_cabal_output
-  # Building with tests and benchmarks...
-  # build & run tests, build benchmarks
-  - ${CABAL} v2-build $WITHCOMPILER ${TEST} ${BENCH} all | color_cabal_output
-  # Testing...
-  - ${CABAL} v2-test $WITHCOMPILER ${TEST} ${BENCH} all | color_cabal_output
-  # Doctest...
-  - (cd ${PKGDIR_haskell_ci} && doctest --fast -XNoImplicitPrelude -XBangPatterns -XDeriveAnyClass -XDeriveFoldable -XDeriveFunctor -XDeriveGeneric -XDeriveTraversable -XDerivingStrategies -XGeneralizedNewtypeDeriving -XScopedTypeVariables src)
-  # HLint..
-  - if [ $HCNUMVER -ge 80800 ] && [ $HCNUMVER -lt 80802 ] ; then (cd ${PKGDIR_haskell_ci} && hlint -h ${TOP}/.hlint.yaml -XNoImplicitPrelude -XBangPatterns -XDeriveAnyClass -XDeriveFoldable -XDeriveFunctor -XDeriveGeneric -XDeriveTraversable -XDerivingStrategies -XGeneralizedNewtypeDeriving -XScopedTypeVariables src) ; fi
-  - if [ $HCNUMVER -ge 80800 ] && [ $HCNUMVER -lt 80802 ] ; then (cd ${PKGDIR_haskell_ci} && hlint -h ${TOP}/.hlint.yaml cli) ; fi
-  # cabal check...
-  - (cd ${PKGDIR_haskell_ci} && ${CABAL} -vnormal check)
-  # Building without installed constraints for packages in global-db...
-  - rm -f cabal.project.local
-  - ${CABAL} v2-build $WITHCOMPILER --disable-tests --disable-benchmarks all | color_cabal_output
-  # Constraint sets
-  - rm -rf cabal.project.local
-  # Constraint set deepseq-1.4
-  - echo 'Constraint set deepseq-1.4' && echo -en 'travis_fold:start:constraint-sets-deepseq-1.4\\r'
-  - if [ $HCNUMVER -lt 80400 ] ; then ${CABAL} v2-build $WITHCOMPILER --disable-tests --disable-benchmarks --constraint='deepseq ==1.4.*' --constraint='binary installed' all | color_cabal_output ; fi
-  - if [ $HCNUMVER -lt 80400 ] ; then ${CABAL} v2-haddock $WITHCOMPILER --with-haddock $HADDOCK --disable-tests --disable-benchmarks --constraint='deepseq ==1.4.*' --constraint='binary installed' all | color_cabal_output ; fi
-  - echo -en 'travis_fold:end:constraint-sets-deepseq-1.4\\r'
-
-# REGENDATA ["--config=cabal.haskell-ci","cabal.project"]
-# EOF
diff --git a/haskell-ci.cabal b/haskell-ci.cabal
--- a/haskell-ci.cabal
+++ b/haskell-ci.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.2
 name:               haskell-ci
-version:            0.6
+version:            0.8
 synopsis:           Cabal package script generator for Travis-CI
 description:
   Script generator (@haskell-ci@) for [Travis-CI](https://travis-ci.org/) for continuous-integration testing of Haskell Cabal packages.
@@ -33,39 +33,38 @@
 tested-with:        GHC ==8.2.2 || ==8.4.4 || ==8.6.5 || ==8.8.1
 extra-source-files:
   CHANGELOG.md
-  fixtures/cabal.haskell-ci
-  fixtures/cabal.project.haskell-ci
-  fixtures/cabal.project.fail-versions
-  fixtures/cabal.project.fail-versions.stderr
-  fixtures/haskell-ci.cabal
-  fixtures/cabal.project.empty-line
-  fixtures/cabal.project.messy
+
+-- find fixtures -type f | sort
+extra-source-files:
   fixtures/cabal.project.copy-fields.all
-  fixtures/cabal.project.copy-fields.some
-  fixtures/cabal.project.copy-fields.none
-  fixtures/haskell-ci.cabal.stderr
-  fixtures/cabal.project.empty-line.stderr
-  fixtures/cabal.project.messy.stderr
   fixtures/cabal.project.copy-fields.all.stderr
-  fixtures/cabal.project.copy-fields.some.stderr
+  fixtures/cabal.project.copy-fields.all.travis.yml
+  fixtures/cabal.project.copy-fields.none
   fixtures/cabal.project.copy-fields.none.stderr
-  fixtures/haskell-ci.cabal.travis.yml
+  fixtures/cabal.project.copy-fields.none.travis.yml
+  fixtures/cabal.project.copy-fields.some
+  fixtures/cabal.project.copy-fields.some.stderr
+  fixtures/cabal.project.copy-fields.some.travis.yml
+  fixtures/cabal.project.empty-line
+  fixtures/cabal.project.empty-line.stderr
   fixtures/cabal.project.empty-line.travis.yml
+  fixtures/cabal.project.fail-versions
+  fixtures/cabal.project.fail-versions.stderr
+  fixtures/cabal.project.haskell-ci
+  fixtures/cabal.project.messy
+  fixtures/cabal.project.messy.stderr
   fixtures/cabal.project.messy.travis.yml
-  fixtures/cabal.project.copy-fields.all.travis.yml
-  fixtures/cabal.project.copy-fields.some.travis.yml
-  fixtures/cabal.project.copy-fields.none.travis.yml
   fixtures/cabal.project.travis-patch
   fixtures/cabal.project.travis-patch.patch
   fixtures/cabal.project.travis-patch.stderr
   fixtures/cabal.project.travis-patch.travis.yml
-  fixtures/servant-client-core/*.cabal
-  fixtures/servant-client/*.cabal
-  fixtures/servant-docs/*.cabal
-  fixtures/servant-foreign/*.cabal
-  fixtures/servant-server/*.cabal
-  fixtures/servant/*.cabal
   fixtures/doc/tutorial/tutorial.cabal
+  fixtures/servant-client-core/servant-client-core.cabal
+  fixtures/servant-client/servant-client.cabal
+  fixtures/servant-docs/servant-docs.cabal
+  fixtures/servant-foreign/servant-foreign.cabal
+  fixtures/servant-server/servant-server.cabal
+  fixtures/servant/servant.cabal
 
 source-repository head
   type:     git
@@ -76,6 +75,13 @@
   manual:  True
 
 library haskell-ci-internal
+  default-language:   Haskell2010
+  hs-source-dirs:     src
+  ghc-options:        -Wall -Wcompat -Wnoncanonical-monad-instances
+
+  if impl(ghc <8.8)
+    ghc-options: -Wnoncanonical-monadfail-instances
+
   exposed-modules:
     HaskellCI
     HaskellCI.Cli
@@ -91,19 +97,15 @@
     HaskellCI.Config.Jobs
     HaskellCI.Config.Ubuntu
     HaskellCI.Diagnostics
-    HaskellCI.Glob
     HaskellCI.Jobs
     HaskellCI.List
     HaskellCI.MonadErr
     HaskellCI.Newtypes
-    HaskellCI.Optimization
     HaskellCI.OptionsGrammar
     HaskellCI.OptparseGrammar
     HaskellCI.Package
-    HaskellCI.ParsecError
     HaskellCI.ParsecUtils
     HaskellCI.Prelude
-    HaskellCI.Project
     HaskellCI.Sh
     HaskellCI.ShVersionRange
     HaskellCI.TestedWith
@@ -112,12 +114,6 @@
     HaskellCI.Travis.Yaml
     HaskellCI.YamlSyntax
 
-  ghc-options:        -Wall -Wcompat -Wnoncanonical-monad-instances
-
-  if impl(ghc <8.8)
-    ghc-options: -Wnoncanonical-monadfail-instances
-
-  hs-source-dirs:     src
   default-extensions:
     NoImplicitPrelude
     BangPatterns
@@ -158,6 +154,7 @@
   build-depends:
     , aeson                 ^>=1.4.2.0
     , base-compat           ^>=0.11
+    , cabal-install-parsers ^>=0.1
     , exceptions            ^>=0.10.0
     , generic-lens          ^>=1.2.0.0
     , HsYAML                ^>=0.2.0.0
@@ -168,8 +165,6 @@
     , temporary             ^>=1.3
     , unordered-containers  ^>=0.2.10.0
 
-  default-language:   Haskell2010
-
   -- ShellCheck. Would need newer transformers for older GHC
   if (flag(shellcheck) && impl(ghc >=7.10 && <8.7))
     build-depends: ShellCheck ==0.7.0
@@ -184,22 +179,24 @@
   default-language: Haskell2010
 
 test-suite golden
+  default-language: Haskell2010
   type:             exitcode-stdio-1.0
   main-is:          Tests.hs
   hs-source-dirs:   test
+
+  -- inherited constraints via lib:haskell-ci
   build-depends:
-    , ansi-terminal        ^>=0.10
     , base
     , base-compat
     , bytestring
-    , Diff                 ^>=0.4.0
     , directory
     , filepath
     , haskell-ci-internal
-    , tasty                >=1.0     && <1.3
-    , tasty-golden         ^>=2.3.1.1
     , transformers
 
-  -- inherited constraints via lib:haskell-ci
   -- dependencies needing explicit constraints
-  default-language: Haskell2010
+  build-depends:
+    , ansi-terminal  ^>=0.10
+    , Diff           ^>=0.4.0
+    , tasty          >=1.0     && <1.3
+    , tasty-golden   ^>=2.3.1.1
diff --git a/src/HaskellCI.hs b/src/HaskellCI.hs
--- a/src/HaskellCI.hs
+++ b/src/HaskellCI.hs
@@ -20,18 +20,17 @@
 
 import HaskellCI.Prelude
 
-import Data.List                    (nubBy, sort, sortBy, (\\))
-import System.Directory             (canonicalizePath, doesDirectoryExist, doesFileExist, makeRelativeToCurrentDirectory, setCurrentDirectory)
-import System.Environment           (getArgs)
-import System.Exit                  (ExitCode (..), exitFailure)
-import System.FilePath.Posix        (takeDirectory, takeExtension, takeFileName, (</>))
-import System.IO                    (hClose, hFlush, hPutStr, hPutStrLn, stderr)
-import System.IO.Temp               (withSystemTempFile)
-import System.Process               (readProcessWithExitCode)
-import Text.ParserCombinators.ReadP (readP_to_S)
+import Data.List             (nubBy, sort, sortBy, (\\))
+import System.Directory      (canonicalizePath, doesFileExist, makeRelativeToCurrentDirectory, setCurrentDirectory)
+import System.Environment    (getArgs)
+import System.Exit           (ExitCode (..), exitFailure)
+import System.FilePath.Posix (takeDirectory, takeFileName)
+import System.IO             (hClose, hFlush, hPutStr, hPutStrLn, stderr)
+import System.IO.Temp        (withSystemTempFile)
+import System.Process        (readProcessWithExitCode)
 
-import Distribution.PackageDescription        (package, packageDescription, testedWith)
-import Distribution.PackageDescription.Parsec (readGenericPackageDescription)
+import Distribution.PackageDescription (GenericPackageDescription, package, packageDescription, testedWith)
+import Distribution.Simple.Utils       (fromUTF8BS)
 import Distribution.Text
 import Distribution.Version
 
@@ -43,15 +42,15 @@
 import qualified Distribution.Package  as Pkg
 import qualified Options.Applicative   as O
 
+import Cabal.Parse
+import Cabal.Project
 import HaskellCI.Cli
 import HaskellCI.Compiler
 import HaskellCI.Config
 import HaskellCI.Config.Dump
 import HaskellCI.Diagnostics
-import HaskellCI.Glob
 import HaskellCI.Jobs
 import HaskellCI.Package
-import HaskellCI.Project
 import HaskellCI.TestedWith
 import HaskellCI.Travis
 import HaskellCI.YamlSyntax
@@ -79,7 +78,7 @@
                     _                     -> defaultTravisPath
 
             -- read, and then change to the directory
-            contents <- readFile fp
+            contents <- fromUTF8BS <$> BS.readFile fp
             absFp <- canonicalizePath fp
             let dir = takeDirectory fp
             setCurrentDirectory dir
@@ -154,70 +153,22 @@
         | "cabal.project" `isPrefixOf` takeFileName path = Just path
         | otherwise = Nothing
 
-    getCabalFiles :: m (Project Void FilePath)
+    getCabalFiles :: m (Project URI Void (FilePath, GenericPackageDescription))
     getCabalFiles
-        | isNothing isCabalProject = return $ emptyProject & #prjPackages .~ [path]
+        | isNothing isCabalProject = do
+            e <- liftIO $ readPackagesOfProject (emptyProject & #prjPackages .~ [path])
+            either (putStrLnErr . renderParseError) return e
         | otherwise = do
             contents <- liftIO $ BS.readFile path
-            prj  <- either putStrLnErr return $ parseProjectFile path contents
-            prj' <- bitraverse findOptProjectPackage findProjectPackage prj
-            let (uris, pkgs) = partitionEithers $ concat $ prjPackages prj'
-            return prj'
-                { prjPackages    = pkgs ++ concat (prjOptPackages prj')
-                , prjOptPackages = []
-                , prjUriPackages = uris
-                }
-
-    rootdir = takeDirectory path
-
-    -- See findProjectPackages in cabal-install codebase
-    -- this is simple variant.
-    findProjectPackage :: String -> m [Either URI FilePath]
-    findProjectPackage pkglocstr = do
-        mfp <- fmap3 Right (checkisFileGlobPackage pkglocstr) `mplusMaybeT`
-               fmap3 Right (checkIsSingleFilePackage pkglocstr) `mplusMaybeT`
-               fmap2 (\uri -> [Left uri]) (return $ parseURI pkglocstr)
-        maybe (putStrLnErr $ "bad package location: " ++ pkglocstr) return mfp
-
-    fmap2 f = fmap (fmap f)
-    fmap3 f = fmap (fmap (fmap f))
-
-    findOptProjectPackage :: String -> m [FilePath]
-    findOptProjectPackage pkglocstr = do
-        mfp <- checkisFileGlobPackage pkglocstr `mplusMaybeT`
-               checkIsSingleFilePackage pkglocstr
-        maybe (return []) return mfp
-
-    checkIsSingleFilePackage pkglocstr = do
-        let abspath = rootdir </> pkglocstr
-        isFile <- liftIO $ doesFileExist abspath
-        isDir  <- liftIO $ doesDirectoryExist abspath
-        if | isFile && takeExtension pkglocstr == ".cabal" -> return (Just [abspath])
-           | isDir -> checkisFileGlobPackage (pkglocstr </> "*.cabal")
-           | otherwise -> return Nothing
-
-    -- if it looks like glob, glob
-    checkisFileGlobPackage pkglocstr =
-        case filter (null . snd) $ readP_to_S parseFilePathGlobRel pkglocstr of
-            [(g, "")] -> do
-                files <- liftIO $ expandRelGlob rootdir g
-                let files' = filter ((== ".cabal") . takeExtension) files
-                -- if nothing is matched, skip.
-                if null files' then return Nothing else return (Just files')
-            _         -> return Nothing
-
-    mplusMaybeT :: Monad m => m (Maybe a) -> m (Maybe a) -> m (Maybe a)
-    mplusMaybeT ma mb = do
-        mx <- ma
-        case mx of
-            Nothing -> mb
-            Just x  -> return (Just x)
+            prj0 <- either (putStrLnErr . renderParseError) return $ parseProject path contents
+            prj1 <- either (putStrLnErr . renderResolveError) return =<< liftIO (resolveProject path prj0)
+            either (putStrLnErr . renderParseError) return =<< liftIO (readPackagesOfProject prj1)
 
 genTravisFromConfigs
     :: (Monad m, MonadDiagnostics m)
     => [String]
     -> Config
-    -> Project Void Package
+    -> Project URI Void Package
     -> Set CompilerVersion
     -> m [String]
 genTravisFromConfigs argv config prj vs = do
@@ -248,7 +199,7 @@
         hFlush h
         for_ patches $ applyPatch fp
         hClose h
-        lines <$> readFile fp
+        lines . fromUTF8BS <$> BS.readFile fp
   where
     patches :: [FilePath]
     patches = cfgTravisPatches cfg
@@ -274,10 +225,8 @@
 
 configFromCabalFile
     :: (MonadIO m, MonadDiagnostics m)
-    => Config -> FilePath -> m Package
-configFromCabalFile cfg cabalFile = do
-    gpd <- liftIO $ readGenericPackageDescription maxBound cabalFile
-
+    => Config -> (FilePath, GenericPackageDescription) -> m Package
+configFromCabalFile cfg (cabalFile, gpd) = do
     let compilers = testedWith $ packageDescription gpd
         pkgNameStr = display $ Pkg.pkgName $ package $ packageDescription gpd
 
diff --git a/src/HaskellCI/Compiler.hs b/src/HaskellCI/Compiler.hs
--- a/src/HaskellCI/Compiler.hs
+++ b/src/HaskellCI/Compiler.hs
@@ -4,6 +4,7 @@
     CompilerVersion (..),
     maybeGHC,
     isGHCJS,
+    maybeGHCJS,
     previewGHC,
     -- * Compiler version range
     CompilerRange (..),
@@ -46,6 +47,10 @@
 isGHCJS :: CompilerVersion -> Bool
 isGHCJS (GHCJS _) = True
 isGHCJS _         = False
+
+maybeGHCJS :: CompilerVersion -> Maybe Version
+maybeGHCJS (GHCJS v) = Just v
+maybeGHCJS _         = Nothing
 
 -------------------------------------------------------------------------------
 -- CompilerRange
diff --git a/src/HaskellCI/Config.hs b/src/HaskellCI/Config.hs
--- a/src/HaskellCI/Config.hs
+++ b/src/HaskellCI/Config.hs
@@ -101,11 +101,12 @@
         , cfgDoctestFilterPkgs = []
         }
     , cfgHLint = HLintConfig
-        { cfgHLintEnabled = False
-        , cfgHLintJob     = HLintJobLatest
-        , cfgHLintYaml    = Nothing
-        , cfgHLintVersion = defaultHLintVersion
-        , cfgHLintOptions = []
+        { cfgHLintEnabled  = False
+        , cfgHLintJob      = HLintJobLatest
+        , cfgHLintYaml     = Nothing
+        , cfgHLintVersion  = defaultHLintVersion
+        , cfgHLintOptions  = []
+        , cfgHLintDownload = True
         }
     , cfgLocalGhcOptions = []
     , cfgConstraintSets  = []
diff --git a/src/HaskellCI/Config/HLint.hs b/src/HaskellCI/Config/HLint.hs
--- a/src/HaskellCI/Config/HLint.hs
+++ b/src/HaskellCI/Config/HLint.hs
@@ -16,16 +16,17 @@
 import HaskellCI.OptionsGrammar
 
 data HLintConfig = HLintConfig
-    { cfgHLintEnabled :: !Bool
-    , cfgHLintJob     :: !HLintJob
-    , cfgHLintYaml    :: !(Maybe FilePath)
-    , cfgHLintOptions :: [String]
-    , cfgHLintVersion :: !VersionRange
+    { cfgHLintEnabled  :: !Bool
+    , cfgHLintJob      :: !HLintJob
+    , cfgHLintYaml     :: !(Maybe FilePath)
+    , cfgHLintOptions  :: [String]
+    , cfgHLintVersion  :: !VersionRange
+    , cfgHLintDownload :: !Bool
     }
   deriving (Show, Generic)
 
 defaultHLintVersion :: VersionRange
-defaultHLintVersion = withinVersion (mkVersion [2,1])
+defaultHLintVersion = withinVersion (mkVersion [2,2])
 
 -------------------------------------------------------------------------------
 -- HLintJob
@@ -62,3 +63,5 @@
         ^^^ metahelp "OPTS" "Additional HLint options"
     <*> C.optionalFieldDef "hlint-version"                                     #cfgHLintVersion defaultHLintVersion
         ^^^ metahelp "RANGE" "HLint version"
+    <*> C.booleanFieldDef "hlint-download-binary"                              #cfgHLintDownload True
+        ^^^ help "Download HLint binary release"
diff --git a/src/HaskellCI/Glob.hs b/src/HaskellCI/Glob.hs
deleted file mode 100644
--- a/src/HaskellCI/Glob.hs
+++ /dev/null
@@ -1,153 +0,0 @@
-module HaskellCI.Glob where
-
-import HaskellCI.Prelude
-
-import Control.Applicative       as App ((<$>))
-import Control.Monad             (filterM, liftM2)
-import System.Directory          (doesDirectoryExist, getDirectoryContents)
-import System.FilePath.Posix     ((</>))
-import Text.ParserCombinators.ReadP
-
--------------------------------------------------------------------------------
--- Glob
--------------------------------------------------------------------------------
-
-{-
-
-Globbing code and grammar judiciously stolen from cabal-install:
-
-FilePathGlob    ::= FilePathRoot FilePathGlobRel
-FilePathRoot    ::= {- empty -}        # relative to cabal.project
-                  | "/"                # Unix root
-                  | [a-zA-Z] ":" [/\\] # Windows root
-                  | "~"                # home directory
-
-FilePathGlobRel ::= Glob "/"  FilePathGlobRel # Unix directory
-                  | Glob "\\" FilePathGlobRel # Windows directory
-                  | Glob         # file
-                  | {- empty -}  # trailing slash
-
-Glob      ::= GlobPiece *
-GlobPiece ::= "*"            # wildcard
-            | [^*{},/\\] *   # literal string
-            | "\\" [*{},]    # escaped reserved character
-            | "{" Glob "," ... "," Glob "}" # union (match any of these)
--}
-
-data FilePathGlob = FilePathGlob FilePathRoot FilePathGlobRel
-  deriving (Eq, Show)
-
-data FilePathGlobRel
-   = GlobDir  Glob FilePathGlobRel
-   | GlobFile Glob
-   | GlobDirTrailing -- trailing dir, a glob ending in '/'
-  deriving (Eq, Show)
-
--- | A single directory or file component of a globbed path
-type Glob = [GlobPiece]
-
--- | A piece of a globbing pattern
-data GlobPiece = WildCard
-               | Literal String
-               | Union [Glob]
-  deriving (Eq, Show)
-
-data FilePathRoot
-   = FilePathRelative
-   | FilePathRoot FilePath -- e.g. '/', 'c:\' or result of 'takeDrive'
-   | FilePathHomeDir
-  deriving (Eq, Show)
-
-parseFilePathGlobRel :: ReadP FilePathGlobRel
-parseFilePathGlobRel =
-      parseGlob >>= \globpieces ->
-          asDir globpieces
-      <++ asTDir globpieces
-      <++ asFile globpieces
-  where
-    asDir  glob = do dirSep
-                     GlobDir glob <$> parseFilePathGlobRel
-    asTDir glob = do dirSep
-                     return (GlobDir glob GlobDirTrailing)
-    asFile glob = return (GlobFile glob)
-
-    dirSep = void (char '/')
-         +++ (do _ <- char '\\'
-                 -- check this isn't an escape code
-                 following <- look
-                 case following of
-                   (c:_) | isGlobEscapedChar c -> pfail
-                   _                           -> return ())
-
-parseGlob :: ReadP Glob
-parseGlob = many1 parsePiece
-  where
-    parsePiece = literal +++ wildcard +++ union'
-
-    wildcard = char '*' >> return WildCard
-
-    union' = between (char '{') (char '}') $
-              fmap Union (sepBy1 parseGlob (char ','))
-
-    literal = Literal `fmap` litchars1
-
-    litchar = normal +++ escape
-
-    normal  = satisfy (\c -> not (isGlobEscapedChar c)
-                                && c /= '/' && c /= '\\')
-    escape  = char '\\' >> satisfy isGlobEscapedChar
-
-    litchars1 :: ReadP [Char]
-    litchars1 = liftM2 (:) litchar litchars
-
-    litchars :: ReadP [Char]
-    litchars = litchars1 <++ return []
-
-isGlobEscapedChar :: Char -> Bool
-isGlobEscapedChar '*'  = True
-isGlobEscapedChar '{'  = True
-isGlobEscapedChar '}'  = True
-isGlobEscapedChar ','  = True
-isGlobEscapedChar _    = False
-
-expandRelGlob :: MonadIO m => FilePath -> FilePathGlobRel -> m [FilePath]
-expandRelGlob root glob0 = liftIO $ go glob0 ""
-  where
-    go (GlobFile glob) dir = do
-      entries <- getDirectoryContents (root </> dir)
-      let files = filter (matchGlob glob) entries
-      return (map (dir </>) files)
-
-    go (GlobDir glob globPath) dir = do
-      entries <- getDirectoryContents (root </> dir)
-      subdirs <- filterM (\subdir -> doesDirectoryExist
-                                       (root </> dir </> subdir))
-               $ filter (matchGlob glob) entries
-      concat App.<$> mapM (\subdir -> go globPath (dir </> subdir)) subdirs
-
-    go GlobDirTrailing dir = return [dir]
-
-matchGlob :: Glob -> FilePath -> Bool
-matchGlob = goStart
-  where
-    -- From the man page, glob(7):
-    --   "If a filename starts with a '.', this character must be
-    --    matched explicitly."
-
-    go, goStart :: [GlobPiece] -> String -> Bool
-
-    goStart (WildCard:_) ('.':_)  = False
-    goStart (Union globs:rest) cs = any (\glob -> goStart (glob ++ rest) cs)
-                                        globs
-    goStart rest               cs = go rest cs
-
-    go []                 ""    = True
-    go (Literal lit:rest) cs
-      | Just cs' <- stripPrefix lit cs
-                                = go rest cs'
-      | otherwise               = False
-    go [WildCard]         ""    = True
-    go (WildCard:rest)   (c:cs) = go rest (c:cs) || go (WildCard:rest) cs
-    go (Union globs:rest)   cs  = any (\glob -> go (glob ++ rest) cs) globs
-    go []                (_:_)  = False
-    go (_:_)              ""    = False
diff --git a/src/HaskellCI/Optimization.hs b/src/HaskellCI/Optimization.hs
deleted file mode 100644
--- a/src/HaskellCI/Optimization.hs
+++ /dev/null
@@ -1,27 +0,0 @@
-module HaskellCI.Optimization where
-
-import HaskellCI.Prelude
-
-import qualified Distribution.Compat.CharParsing as C
-import qualified Distribution.Parsec             as C
-import qualified Distribution.Pretty             as C
-import qualified Text.PrettyPrint                as PP
-
-data Optimization
-    = OptimizationOn
-    | OptimizationOff
-    | OptimizationLevel Int
-  deriving (Eq, Show)
-
-instance C.Parsec Optimization where
-    parsec = boolean <|> numeric where
-        boolean = ite OptimizationOn OptimizationOff <$> C.parsec
-        numeric = OptimizationLevel <$> C.integral
-
-        ite t _ True  = t
-        ite _ f False = f
-
-instance C.Pretty Optimization where
-    pretty OptimizationOn        = C.pretty True
-    pretty OptimizationOff       = C.pretty False
-    pretty (OptimizationLevel l) = PP.int l
diff --git a/src/HaskellCI/ParsecError.hs b/src/HaskellCI/ParsecError.hs
deleted file mode 100644
--- a/src/HaskellCI/ParsecError.hs
+++ /dev/null
@@ -1,107 +0,0 @@
-module HaskellCI.ParsecError (
-    renderParseError,
-    ) where
-
-import Prelude ()
-import Prelude.Compat
-
-import Distribution.Parsec       (PError (..), PWarning (..), Position (..), showPos, zeroPos)
-import Distribution.Simple.Utils (fromUTF8BS)
-import System.FilePath           (normalise)
-
-import qualified Data.ByteString       as BS
-import qualified Data.ByteString.Char8 as BS8
-
--- | Render parse error highlighting the part of the input file.
-renderParseError
-    :: FilePath
-    -> BS.ByteString
-    -> [PError]
-    -> [PWarning]
-    -> String
-renderParseError filepath contents errors warnings
-    | null errors && null warnings = ""
-    | null errors = unlines $
-        ("Warnings encountered when parsing  file " <> filepath <> ":")
-        : renderedWarnings
-    | otherwise = unlines $
-        [ "Errors encountered when parsing file " <> filepath <> ":"
-        ]
-        ++ renderedErrors
-        ++ renderedWarnings
-  where
-    filepath' = normalise filepath
-
-    -- lines of the input file. 'lines' is taken, so they are called rows
-    -- contents, line number, whether it's empty line
-    rows :: [(String, Int, Bool)]
-    rows = zipWith f (BS8.lines contents) [1..] where
-        f bs i = let s = fromUTF8BS bs in (s, i, isEmptyOrComment s)
-
-    rowsZipper = listToZipper rows
-
-    isEmptyOrComment :: String -> Bool
-    isEmptyOrComment s = case dropWhile (== ' ') s of
-        ""          -> True   -- empty
-        ('-':'-':_) -> True   -- comment
-        _           -> False
-
-    renderedErrors   = concatMap renderError errors
-    renderedWarnings = concatMap renderWarning warnings
-
-    renderError :: PError -> [String]
-    renderError (PError pos@(Position row col) msg)
-        -- if position is 0:0, then it doesn't make sense to show input
-        -- looks like, Parsec errors have line-feed in them
-        | pos == zeroPos = msgs
-        | otherwise      = msgs ++ formatInput row col
-      where
-        msgs = [ "", filepath' ++ ":" ++ showPos pos ++ ": error:", trimLF msg, "" ]
-
-    renderWarning :: PWarning -> [String]
-    renderWarning (PWarning _ pos@(Position row col) msg)
-        | pos == zeroPos = msgs
-        | otherwise      = msgs ++ formatInput row col
-      where
-        msgs = [ "", filepath' ++ ":" ++ showPos pos ++ ": warning:", trimLF msg, "" ]
-
-    -- sometimes there are (especially trailing) newlines.
-    trimLF :: String -> String
-    trimLF = dropWhile (== '\n') . reverse . dropWhile (== '\n') . reverse
-
-    -- format line: prepend the given line number
-    formatInput :: Int -> Int -> [String]
-    formatInput row col = case advance (row - 1) rowsZipper of
-        Zipper xs ys -> before ++ after where
-            before = case span (\(_, _, b) -> b) xs of
-                (_, [])     -> []
-                (zs, z : _) -> map formatInputLine $ z : reverse zs
-
-            after  = case ys of
-                []        -> []
-                (z : _zs) ->
-                    [ formatInputLine z                             -- error line
-                    , "      | " ++ replicate (col - 1) ' ' ++ "^"  -- pointer: ^
-                    ]
-                    -- do we need rows after?
-                    -- ++ map formatInputLine (take 1 zs)           -- one row after
-
-    formatInputLine :: (String, Int, Bool) -> String
-    formatInputLine (str, row, _) = leftPadShow row ++ " | " ++ str
-
-    -- hopefully we don't need to work with over 99999 lines .cabal files
-    -- at that point small glitches in error messages are hopefully fine.
-    leftPadShow :: Int -> String
-    leftPadShow n = let s = show n in replicate (5 - length s) ' ' ++ s
-
-data Zipper a = Zipper [a] [a]
-
-listToZipper :: [a] -> Zipper a
-listToZipper = Zipper []
-
-advance :: Int -> Zipper a -> Zipper a
-advance n z@(Zipper xs ys)
-    | n <= 0 = z
-    | otherwise = case ys of
-        []      -> z
-        (y:ys') -> advance (n - 1) $ Zipper (y:xs) ys'
diff --git a/src/HaskellCI/ParsecUtils.hs b/src/HaskellCI/ParsecUtils.hs
--- a/src/HaskellCI/ParsecUtils.hs
+++ b/src/HaskellCI/ParsecUtils.hs
@@ -12,7 +12,7 @@
 import qualified Distribution.Parsec            as C
 import qualified Text.Parsec                    as P
 
-import HaskellCI.ParsecError
+import Cabal.Parse
 
 readAndParseFile
     :: ([C.Field C.Position] -> C.ParseResult a)  -- ^ File fields to final value parser
@@ -35,8 +35,8 @@
     run :: BS.ByteString -> C.ParseResult a -> IO a
     run bs r = case C.runParseResult r of
         (ws, Right x)      -> do
-            hPutStr stderr $ renderParseError fpath bs [] ws
+            hPutStr stderr $ renderParseError (ParseError fpath bs [] ws)
             return x
         (ws, Left (_, es)) -> do
-            hPutStr stderr $ renderParseError fpath bs es ws
+            hPutStr stderr $ renderParseError (ParseError fpath bs es ws)
             exitFailure
diff --git a/src/HaskellCI/Project.hs b/src/HaskellCI/Project.hs
deleted file mode 100644
--- a/src/HaskellCI/Project.hs
+++ /dev/null
@@ -1,97 +0,0 @@
-{-# LANGUAGE OverloadedLabels  #-}
-{-# LANGUAGE OverloadedStrings #-}
--- | Handling of @cabal.project@ file
-module HaskellCI.Project (
-    Project (..),
-    emptyProject,
-    parseProjectFile,
-    ) where
-
-import HaskellCI.Prelude
-
-import qualified Data.Map.Strict                              as M
-import qualified Distribution.CabalSpecVersion                as C
-import qualified Distribution.FieldGrammar                    as C
-import qualified Distribution.Fields                          as C
-import qualified Distribution.PackageDescription.FieldGrammar as C
-import qualified Distribution.Parsec                          as C
-import qualified Distribution.Parsec.Newtypes                 as C
-import qualified Distribution.Types.SourceRepo                as C
-
-import HaskellCI.Newtypes
-import HaskellCI.Optimization
-import HaskellCI.ParsecError
-
--- $setup
--- >>> :seti -XOverloadedStrings
-
-data Project b a = Project
-    { prjPackages     :: [a]
-    , prjOptPackages  :: [b]
-    , prjUriPackages  :: [URI]
-    , prjConstraints  :: [String]
-    , prjAllowNewer   :: [String]
-    , prjReorderGoals :: Bool
-    , prjMaxBackjumps :: Maybe Int
-    , prjOptimization :: Optimization
-    , prjSourceRepos  :: [C.SourceRepo]
-    , prjOrigFields   :: [C.PrettyField ()]
-    }
-  deriving (Functor, Foldable, Traversable, Generic)
-
-instance Bifunctor Project where bimap = bimapDefault
-instance Bifoldable Project where bifoldMap = bifoldMapDefault
-
-instance Bitraversable Project where
-    bitraverse f g prj = (\b a -> prj { prjPackages = a, prjOptPackages = b })
-        <$> traverse f (prjOptPackages prj)
-        <*> traverse g (prjPackages prj)
-
-emptyProject :: Project b a
-emptyProject = Project [] [] [] [] [] False Nothing OptimizationOn [] []
-
--- | Parse project file. Extracts only few fields.
---
--- >>> fmap prjPackages $ parseProjectFile "cabal.project" "packages: foo bar/*.cabal"
--- Right ["foo","bar/*.cabal"]
---
-parseProjectFile :: FilePath -> ByteString -> Either String (Project String String)
-parseProjectFile fp bs = do
-    fields0 <- either (Left . show) Right $ C.readFields bs
-    let (fields1, sections) = C.partitionFields fields0
-    let fields2 = M.filterWithKey (\k _ -> k `elem` knownFields) fields1
-    case C.runParseResult $ parse fields0 fields2 sections of
-        (_, Right x)       -> return x
-        (ws, Left (_, es)) -> Left $ renderParseError fp bs es ws
-  where
-    knownFields = C.fieldGrammarKnownFieldList $ grammar []
-
-    parse origFields fields sections = do
-        let prettyOrigFields = map void $ C.fromParsecFields $ filter notPackages origFields
-        prj <- C.parseFieldGrammar C.cabalSpecLatest fields $ grammar prettyOrigFields
-        foldr ($) prj <$> traverse parseSec (concat sections)
-
-    parseSec :: C.Section C.Position -> C.ParseResult (Project String String -> Project String String)
-    parseSec (C.MkSection (C.Name _pos name) [] fields) | name == "source-repository-package" = do
-        let fields' = fst $ C.partitionFields fields
-        repo <- C.parseFieldGrammar C.cabalSpecLatest fields' (C.sourceRepoFieldGrammar $ C.RepoKindUnknown "unused")
-        return $ over #prjSourceRepos (repo :)
-
-    parseSec _ = return id
-
-notPackages :: C.Field ann -> Bool
-notPackages (C.Field (C.Name _ "packages") _) = False
-notPackages _                                 = True
-
-grammar :: [C.PrettyField ()] -> C.ParsecFieldGrammar (Project String String) (Project String String)
-grammar origFields = Project
-    <$> C.monoidalFieldAla "packages"          (C.alaList' C.FSep PackageLocation) #prjPackages
-    <*> C.monoidalFieldAla "optional-packages" (C.alaList' C.FSep PackageLocation) #prjOptPackages
-    <*> pure []
-    <*> C.monoidalFieldAla "constraints"       (C.alaList' C.CommaVCat NoCommas)   #prjConstraints
-    <*> C.monoidalFieldAla "allow-newer"       (C.alaList' C.CommaVCat NoCommas)   #prjAllowNewer
-    <*> C.booleanFieldDef  "reorder-goals"                                         #prjReorderGoals False
-    <*> C.optionalFieldAla "max-backjumps"     Int'                                #prjMaxBackjumps
-    <*> C.optionalFieldDef "optimization"                                          #prjOptimization OptimizationOn
-    <*> pure []
-    <*> pure origFields
diff --git a/src/HaskellCI/TestedWith.hs b/src/HaskellCI/TestedWith.hs
--- a/src/HaskellCI/TestedWith.hs
+++ b/src/HaskellCI/TestedWith.hs
@@ -9,7 +9,6 @@
 import Control.Applicative  ((<|>))
 import Data.Generics.Labels ()
 import Data.List            (intercalate)
-import Data.Void            (Void)
 
 import qualified Data.Foldable                   as F
 import qualified Data.Set                        as S
@@ -18,9 +17,9 @@
 import qualified Distribution.Pretty             as C
 import qualified Text.PrettyPrint                as PP
 
+import Cabal.Project
 import HaskellCI.Compiler
 import HaskellCI.Package
-import HaskellCI.Project
 
 data TestedWithJobs
     = TestedWithUniform
@@ -41,14 +40,14 @@
 
 checkVersions
     :: TestedWithJobs
-    -> Project Void Package
-    -> Either [String] (S.Set CompilerVersion, Project Void Package)
+    -> Project a b Package
+    -> Either [String] (S.Set CompilerVersion, Project a b Package)
 checkVersions TestedWithUniform = checkVersionsUniform
 checkVersions TestedWithAny     = checkVersionsAny
 
 checkVersionsUniform
-    :: Project Void Package
-    -> Either [String] (S.Set CompilerVersion, Project Void Package)
+    :: Project a b Package
+    -> Either [String] (S.Set CompilerVersion, Project a b Package)
 checkVersionsUniform prj | null (prjPackages prj) = Left ["Error reading cabal file(s)!"]
 checkVersionsUniform prj = do
     let (errors, names) = F.foldl' collectConfig mempty prj
@@ -77,8 +76,8 @@
                     ] ++ intercalate "," missingVersions
 
 checkVersionsAny
-    :: Project Void Package
-    -> Either [String] (S.Set CompilerVersion, Project Void Package)
+    :: Project a b Package
+    -> Either [String] (S.Set CompilerVersion, Project a b Package)
 checkVersionsAny prj | null (prjPackages prj) = Left ["Error reading cabal file(s)!"]
 checkVersionsAny prj =
     Right (allVersions, prj)
diff --git a/src/HaskellCI/Travis.hs b/src/HaskellCI/Travis.hs
--- a/src/HaskellCI/Travis.hs
+++ b/src/HaskellCI/Travis.hs
@@ -31,6 +31,9 @@
 import qualified Distribution.Types.BuildInfo.Lens          as L
 import qualified Distribution.Types.PackageDescription.Lens as L
 
+import Cabal.Optimization
+import Cabal.Project
+import Cabal.SourceRepo
 import HaskellCI.Cli
 import HaskellCI.Compiler
 import HaskellCI.Config
@@ -45,9 +48,7 @@
 import HaskellCI.Jobs
 import HaskellCI.List
 import HaskellCI.MonadErr
-import HaskellCI.Optimization
 import HaskellCI.Package
-import HaskellCI.Project
 import HaskellCI.Sh
 import HaskellCI.ShVersionRange
 import HaskellCI.Tools
@@ -78,7 +79,7 @@
 makeTravis
     :: [String]
     -> Config
-    -> Project Void Package
+    -> Project URI Void Package
     -> JobVersions
     -> Either ShError Travis -- TODO: writer
 makeTravis argv Config {..} prj JobVersions {..} = do
@@ -104,22 +105,6 @@
             , "fi"
             ]
 
-        when (anyGHCJS || isBionic) $ sh $ unlines $ buildList $ do
-            let item' x = item $ "  " ++ x ++ ";"
-
-            item "if [ \"$TRAVIS_OS_NAME\" = \"linux\" ]; then"
-            when isBionic $ item' "sudo add-apt-repository -y ppa:hvr/ghc"
-            traverse_ item' $ forJob RangeGHCJS "sudo add-apt-repository -y ppa:hvr/ghcjs"
-            traverse_ item' $ forJob RangeGHCJS "curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key | sudo apt-key add -"
-            traverse_ item' $ forJob RangeGHCJS $ "sudo apt-add-repository 'https://deb.nodesource.com/node_8.x " ++ C.prettyShow cfgUbuntu  ++ " main'"
-            traverse_ item' $ forJob (boolToBoundedLattice isBionic \/ RangeGHCJS) "sudo apt-get update"
-            item' $ "sudo apt-get install $CC" ++
-                (if S.null cfgApt
-                then ""
-                else " " ++ unwords (S.toList cfgApt))
-            traverse_ item' $ forJob RangeGHCJS "sudo apt-get install -y nodejs cabal-install-3.0" -- TODO: select right `cabal-install` version.
-            item "fi"
-
         -- Adjust $HC
         sh "HC=$(echo \"/opt/$CC/bin/ghc\" | sed 's/-/\\//')"
         sh "WITHCOMPILER=\"-w $HC\""
@@ -128,11 +113,12 @@
 
         -- Needed to work around haskell/cabal#6214
         sh "HADDOCK=$(echo \"/opt/$CC/bin/haddock\" | sed 's/-/\\//')"
+        unless (null cfgOsx) $ do
+            sh $ "if [ \"$TRAVIS_OS_NAME\" = \"osx\" ]; then HADDOCK=$(echo $HADDOCK | sed \"s:^/opt:$HOME/.ghc-install:\"); fi"
 
         -- Hack: happy needs ghc. Let's install version matching GHCJS.
         -- At the moment, there is only GHCJS-8.4, so we install GHC-8.4.4
         when anyGHCJS $ do
-            shForJob RangeGHCJS $ "sudo apt-get install -y ghc-8.4.4"
             shForJob RangeGHCJS $ "PATH=\"/opt/ghc/8.4.4/bin:$PATH\""
 
         sh "HCPKG=\"$HC-pkg\""
@@ -147,7 +133,7 @@
         -- macOS installing
         let haskellOnMacos = "https://haskell.futurice.com/haskell-on-macos.py"
         unless (null cfgOsx) $ do
-            sh $ "if [ \"$TRAVIS_OS_NAME\" = \"osx\" ]; then brew update; brew upgrade python@3; curl " ++ haskellOnMacos ++ " | python3 - --make-dirs --install-dir=$HOME/.ghc-install --cabal-alias=head install cabal-install-head ${TRAVIS_COMPILER}; fi"
+            sh $ "if [ \"$TRAVIS_OS_NAME\" = \"osx\" ]; then curl " ++ haskellOnMacos ++ " | python3 - --make-dirs --install-dir=$HOME/.ghc-install --cabal-alias=head install cabal-install-head ${TRAVIS_COMPILER}; fi"
             sh' [2034,2039] "if [ \"$TRAVIS_OS_NAME\" = \"osx\" ]; then HC=$HOME/.ghc-install/ghc/bin/$TRAVIS_COMPILER; WITHCOMPILER=\"-w $HC\"; HCPKG=${HC/ghc/ghc-pkg}; CABAL=$HOME/.ghc-install/ghc/bin/cabal; fi"
         -- HCNUMVER, numeric HC version, e.g. ghc 7.8.4 is 70804 and 7.10.3 is 71003
         sh "HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\\d+)\\.(\\d+)\\.(\\d+)(\\.(\\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')"
@@ -273,9 +259,25 @@
         let hlintVersionConstraint
                 | C.isAnyVersion (cfgHLintVersion cfgHLint) = ""
                 | otherwise = " --constraint='hlint " ++ C.prettyShow (cfgHLintVersion cfgHLint) ++ "'"
-        when (cfgHLintEnabled cfgHLint) $ shForJob (hlintJobVersionRange versions cfgHeadHackage (cfgHLintJob cfgHLint)) $
-            cabalInTmp $ "v2-install $WITHCOMPILER -j2 hlint" ++ hlintVersionConstraint
+        when (cfgHLintEnabled cfgHLint) $ do
+            let forHLint = shForJob (hlintJobVersionRange versions cfgHeadHackage (cfgHLintJob cfgHLint))
+            if cfgHLintDownload cfgHLint
+            then do
+                -- install --dry-run and use perl regex magic to find a hlint version
+                -- -v is important
+                forHLint $ "HLINTVER=$(cd /tmp && (${CABAL} v2-install -v $WITHCOMPILER --dry-run hlint " ++ hlintVersionConstraint ++ " |  perl -ne 'if (/\\bhlint-(\\d+(\\.\\d+)*)\\b/) { print \"$1\"; last; }')); echo \"HLint version $HLINTVER\""
+                forHLint $ "if [ ! -e $HOME/.hlint/hlint-$HLINTVER/hlint ]; then " ++ unwords
+                    [ "echo \"Downloading HLint version $HLINTVER\";"
+                    , "mkdir -p $HOME/.hlint;"
+                    , "curl --write-out 'Status Code: %{http_code} Redirects: %{num_redirects} Total time: %{time_total} Total Dsize: %{size_download}\\n' --silent --location --output $HOME/.hlint/hlint-$HLINTVER.tar.gz \"https://github.com/ndmitchell/hlint/releases/download/v$HLINTVER/hlint-$HLINTVER-x86_64-linux.tar.gz\";"
+                    , "tar -xzv -f $HOME/.hlint/hlint-$HLINTVER.tar.gz -C $HOME/.hlint;"
+                    , "fi"
+                    ]
+                forHLint "mkdir -p $CABALHOME/bin && ln -sf \"$HOME/.hlint/hlint-$HLINTVER/hlint\" $CABALHOME/bin/hlint"
+                forHLint "hlint --version"
 
+            else forHLint $ cabalInTmp $ "v2-install $WITHCOMPILER -j2 hlint" ++ hlintVersionConstraint
+
         -- Install cabal-plan (for ghcjs tests)
         when (anyGHCJS && cfgGhcjsTests) $ do
             shForJob RangeGHCJS $ cabalInTmp "v2-install -w ghc-8.4.4 cabal-plan --constraint='cabal-plan ^>=0.6.0.0' --constraint='cabal-plan +exe'"
@@ -419,6 +421,7 @@
             for_ cfgConstraintSets $ \cs -> do
                 let name            = csName cs
                 let shForCs         = shForJob (Range (csGhcVersions cs))
+                let shForCs' r      = shForJob (Range (csGhcVersions cs) /\ r)
                 let testFlag        = if csTests cs then "--enable-tests" else "--disable-tests"
                 let benchFlag       = if csBenchmarks cs then "--enable-benchmarks" else "--disable-benchmarks"
                 let constraintFlags = map (\x ->  "--constraint='" ++ x ++ "'") (csConstraints cs)
@@ -427,8 +430,8 @@
                 foldedSh' FoldConstraintSets name ("Constraint set " ++ name) cfgFolds $ do
                     shForCs $ cabal $ "v2-build $WITHCOMPILER " ++ allFlags ++ " all"
                     when (csRunTests cs) $
-                        shForCs $ cabal $ "v2-test $WITHCOMPILER " ++ allFlags ++ " all"
-                    when (csHaddock cs) $
+                        shForCs' hasTests $ cabal $ "v2-test $WITHCOMPILER " ++ allFlags ++ " all"
+                    when (hasLibrary && csHaddock cs) $
                         shForCs $ cabal $ "v2-haddock $WITHCOMPILER " ++ withHaddock ++ " " ++ allFlags ++ " all"
 
     -- assemble travis configuration
@@ -442,6 +445,7 @@
             { tcDirectories = buildList $ when cfgCache $ do
                 item "$HOME/.cabal/packages"
                 item "$HOME/.cabal/store"
+                item "$HOME/.hlint"
                 -- on OSX ghc is installed in $HOME so we can cache it
                 -- independently of linux
                 when (cfgCache && not (null cfgOsx)) $ do
@@ -473,10 +477,26 @@
                         let cvs = dispCabalVersion $ correspondingCabalVersion cfgCabalInstallVersion gv
                         let gvs = dispGhcVersion gv
 
-                        -- GHCJS cannot be installed via apt plugin
-                        let addGvs | isGHCJS gv = id
-                                   | otherwise  = (gvs :)
+                        -- https://docs.travis-ci.com/user/installing-dependencies/#adding-apt-sources
+                        let hvrppa :: TravisAptSource
+                            hvrppa = TravisAptSourceLine ("deb http://ppa.launchpad.net/hvr/ghc/ubuntu " ++ C.prettyShow cfgUbuntu ++ " main") (Just "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286")
 
+                        let ghcjsAptSources :: [TravisAptSource]
+                            ghcjsAptSources = 
+                                [ TravisAptSourceLine ("deb http://ppa.launchpad.net/hvr/ghcjs/ubuntu " ++ C.prettyShow cfgUbuntu ++ " main") Nothing
+                                | isGHCJS gv
+                                ] ++
+                                [ TravisAptSourceLine ("deb https://deb.nodesource.com/node_8.x " ++ C.prettyShow cfgUbuntu ++ " main") (Just "https://deb.nodesource.com/gpgkey/nodesource.gpg.key")
+                                | isGHCJS gv && cfgUbuntu <= Xenial
+                                ]
+
+                        let ghcjsPackages :: [String]
+                            ghcjsPackages = case maybeGHCJS gv of
+                                Just v -> [ "ghc-" ++ C.prettyShow v', "nodejs" ] where
+                                    -- TODO: partial maximum
+                                    v' = maximum $ filter (`C.withinRange` C.withinVersion v) $ knownGhcVersions
+                                Nothing -> []
+
                         item TravisJob
                             { tjCompiler = gvs
                             , tjOS       = if osx then "osx" else "linux"
@@ -485,8 +505,8 @@
                                 _     -> Nothing
                             , tjAddons   = TravisAddons
                                 { taApt = TravisApt
-                                    { taPackages = addGvs $ ("cabal-install-" ++ cvs) : S.toList cfgApt
-                                    , taSources  = ["hvr-ghc"]
+                                    { taPackages = gvs : ("cabal-install-" ++ cvs) : ghcjsPackages ++ S.toList cfgApt
+                                    , taSources  = hvrppa : ghcjsAptSources
                                     }
 
                                 , taPostgres     = Nothing
@@ -519,7 +539,6 @@
     -- TODO: should this be part of MonadSh ?
     foldedSh label = foldedSh' label ""
 
-    isBionic = cfgUbuntu == Bionic
     anyGHCJS = any isGHCJS versions
 
     -- https://github.com/travis-ci/docs-travis-ci-com/issues/949#issuecomment-276755003
@@ -619,7 +638,7 @@
 
                 for_ (prjSourceRepos prj) $ \repo ->
                     item $ C.PrettySection () "source-repository-package" [] $
-                        C.prettyFieldGrammar C.cabalSpecLatest (C.sourceRepoFieldGrammar $ C.RepoKindUnknown "unused") repo
+                        C.prettyFieldGrammar C.cabalSpecLatest sourceRepositoryPackageGrammar (srpHoist toList repo)
 
         -- local ghc-options
         unless (null cfgLocalGhcOptions) $ for_ pkgs $ \Pkg{pkgName} -> do
@@ -728,7 +747,3 @@
 -- SC2129: Consider using { cmd1; cmd2; } >> file instead of individual redirects
 -- SC2016: Expressions don't expand in single quotes
 -- that's the point!
-
-boolToBoundedLattice :: BoundedLattice a => Bool -> a
-boolToBoundedLattice True = top
-boolToBoundedLattice False = bottom
diff --git a/src/HaskellCI/Travis/Yaml.hs b/src/HaskellCI/Travis/Yaml.hs
--- a/src/HaskellCI/Travis/Yaml.hs
+++ b/src/HaskellCI/Travis/Yaml.hs
@@ -85,10 +85,15 @@
 
 data TravisApt = TravisApt
     { taPackages :: [String]
-    , taSources  :: [String]
+    , taSources  :: [TravisAptSource]
     }
   deriving Show
 
+data TravisAptSource
+    = TravisAptSource String
+    | TravisAptSourceLine String (Maybe String) -- ^ sourceline with optional key
+  deriving Show
+
 newtype TravisAllowFailure = TravisAllowFailure
     { tafCompiler :: String
     }
@@ -145,7 +150,11 @@
 
 instance ToYaml Travis where
     toYaml Travis {..} = ykeyValuesFilt []
-        [ "language"       ~> fromString travisLanguage
+        -- version forces validation
+        -- https://blog.travis-ci.com/2019-10-24-build-config-validation
+        [ "version"        ~> fromString "~> 1.0"
+        , "language"       ~> fromString travisLanguage
+        , "os"             ~> fromString "linux"
         , "dist"           ~> fromString (showUbuntu travisUbuntu)
         , "git"            ~> toYaml travisGit
         , "branches"       ~> toYaml travisBranches
@@ -154,7 +163,7 @@
         , "addons"         ~> toYaml travisAddons
         , "cache"          ~> toYaml travisCache
         , "before_cache"   ~> shListToYaml travisBeforeCache
-        , "matrix"         ~> toYaml travisMatrix
+        , "jobs"           ~> toYaml travisMatrix
         , "before_install" ~> shListToYaml travisBeforeInstall
         , "install"        ~> shListToYaml travisInstall
         , "script"         ~> shListToYaml travisScript
@@ -199,11 +208,10 @@
 instance ToYaml TravisJob where
     toYaml TravisJob {..} = ykeyValuesFilt [] $ buildList $ do
         item $ "compiler" ~> fromString tjCompiler
-        item $ "addons" ~> toYaml (Aeson.toJSON tjAddons)
+        item $ "addons"   ~> toYaml (Aeson.toJSON tjAddons)
         for_ tjEnv $ \e ->
             item $ "env" ~> fromString e
-        unless (tjOS == "linux") $
-            item $ "os" ~> fromString tjOS
+        item $ "os" ~> fromString tjOS
 
 instance ToYaml TravisAllowFailure where
     toYaml TravisAllowFailure {..} = ykeyValuesFilt []
@@ -232,4 +240,14 @@
     toJSON TravisApt {..} = Aeson.object
         [ "packages" Aeson..= taPackages
         , "sources"  Aeson..= taSources
+        ]
+
+instance Aeson.ToJSON TravisAptSource where
+    toJSON (TravisAptSource s) = Aeson.toJSON s
+    toJSON (TravisAptSourceLine sl Nothing) = Aeson.object
+        [ "sourceline" Aeson..= sl
+        ]
+    toJSON (TravisAptSourceLine sl (Just key_url)) = Aeson.object
+        [ "sourceline" Aeson..= sl
+        , "key_url"    Aeson..= key_url
         ]
diff --git a/test/Tests.hs b/test/Tests.hs
--- a/test/Tests.hs
+++ b/test/Tests.hs
@@ -25,8 +25,7 @@
 main = do
     setCurrentDirectory "fixtures/"
     defaultMain $ testGroup "fixtures"
-        [ fixtureGoldenTest "haskell-ci.cabal"
-        , fixtureGoldenTest "cabal.project.empty-line"
+        [ fixtureGoldenTest "cabal.project.empty-line"
         , fixtureGoldenTest "cabal.project.fail-versions"
         , fixtureGoldenTest "cabal.project.messy"
         , fixtureGoldenTest "cabal.project.travis-patch"
