Skip to content

Commit

Permalink
the bonnet is up and we're on bricks. Fix it. (qfpl#71)
Browse files Browse the repository at this point in the history
* Add shell.nix that includes sqlite.

previous shell environment didn't include an application that was necessary for
developing the application. Whoops.

This new shell.nix lets students add their own development tools if they want
to try something out. `ghcid` for example.

* Overhaul: New techniques, new exercises.

Remove hspec-wai dependencies, add waargonaut.

The aeson dependency has been replaced with waargonaut, and the exercises have
been updated to match. Some exercises have been removed.

Add the use of `finally` as a demonstration and reminder that we should be
cleaning up things like connections when an app is done.

Explain the purpose of the `runDB` function so that implementation makes more
sense to students as an exercise.

Add exercise to generalise the error type that is used in the `AppM` transformer
that they implement. This flows onto a later exercise where they reuse this type
to simplify a function that is not part of the core application. This also
allows for an easier introduction of `ExceptT` as an exercise later in the
course when `AppM` is no longer usable.

Add a startup error constructor as making the students add it isn't informative
when compared to the rest of the exercise.

* Remove all duplicate tests. Rebuild Level03.

Level03 has been changed entirely to be centered on writing tests for student
code. The tests are then to be updated by the students as they progress through
the course. There are no duplicated tests and there is a bit more incentive for
students to get in and get their hands dirty with respect to testing their own
work.

Still not sure what to do with doctests just yet. More documentation is required
for that.

* Remove Level03 exe and modules.

* Feedback driven development

* Add tighter bounds for lens.
* Add bounds for old-locale and contravariant.
* Realign some imports.
* Rename 'AppM'' to 'AppM' and 'AppM' to 'App'.
* Clean up an utterly misleading and out of date comment regarding configuration
  package choices. Revert to unremarkable statement about it being JSON.
* Remove redundant import of `Level02.Types` from `tests/Test.hs`.
* Add waargonaut to extra-deps in stack.yaml.
* Bump LTS in stack.yaml to 12.14.
* Fix typos.
* Improve wording, restructure some comments.

* Revert LTS bump, increase contravariant upper bound for GHC 8.6.1

* Try updated stack.yaml

* Update travis.yml:

Bump patch versions of GHC:

* 8.4.3 -> 8.4.4
* 8.6.1 -> 8.6.2

Drop Stack LTS:

6, 9, 10

Add Stack LTS:

11, 12

* Add fixes to help stack nightly builds on travis. Remove some comments in cabal file

* Remove LTS-11, add in-memory db notes to level04

* add workshop levels document for expansion

* Proofread changes.

* Try to use cached GHC downloads for stack on travis

* Remove install ghc flag from stack commands

* Last try to stop stack downloading its own GHC

* Revert stack travis changes. Attempt to pin appar version for 7.10.3.

* Drop support for GHC 7.10.3
  • Loading branch information
mankyKitty authored Dec 7, 2018
1 parent 95f268c commit b8921cd
Show file tree
Hide file tree
Showing 58 changed files with 1,104 additions and 1,947 deletions.
48 changes: 16 additions & 32 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ before_cache:

matrix:
include:
- env: BUILD=cabal
compiler: "ghc-7.10.3"
# - env: BUILD=cabal
# compiler: "ghc-7.10.3"
# env: TEST=--disable-tests BENCH=--disable-benchmarks
addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.4,ghc-7.10.3], sources: [hvr-ghc]}}
# addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.4,ghc-7.10.3], sources: [hvr-ghc]}}

- env: BUILD=cabal
compiler: "ghc-8.0.2"
Expand All @@ -46,30 +46,22 @@ matrix:
addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.4,ghc-8.2.2], sources: [hvr-ghc]}}

- env: BUILD=cabal
compiler: "ghc-8.4.3"
compiler: "ghc-8.4.4"
# env: TEST=--disable-tests BENCH=--disable-benchmarks
addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.4,ghc-8.4.3], sources: [hvr-ghc]}}
addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.4,ghc-8.4.4], sources: [hvr-ghc]}}
- env: BUILD=cabal
compiler: "ghc-8.6.1"
compiler: "ghc-8.6.2"
# env: TEST=--disable-tests BENCH=--disable-benchmarks
addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.4,ghc-8.6.1], sources: [hvr-ghc]}}
addons: {apt: {packages: [ghc-ppa-tools,cabal-install-2.4,ghc-8.6.2], sources: [hvr-ghc]}}

# The Stack builds. We can pass in arbitrary Stack arguments via the ARGS
# variable, such as using --stack-yaml to point to a different file.
- env: BUILD=stack ARGS=""
compiler: ": #stack default"
addons: {apt: {packages: [libgmp-dev]}}

- env: BUILD=stack ARGS="--resolver lts-6"
compiler: ": #stack 7.10.3"
addons: {apt: {packages: [libgmp-dev]}}

- env: BUILD=stack ARGS="--resolver lts-9"
compiler: ": #stack 8.0.2"
addons: {apt: {packages: [libgmp-dev]}}

- env: BUILD=stack ARGS="--resolver lts-10"
compiler: ": #stack 8.2.2"
- env: BUILD=stack ARGS="--resolver lts-12"
compiler: ": #stack 8.4.4"
addons: {apt: {packages: [libgmp-dev]}}

# Nightly builds are allowed to fail
Expand All @@ -82,25 +74,15 @@ matrix:
compiler: ": #stack default osx"
os: osx

# Travis includes an macOS which is incompatible with GHC 7.8.4
- env: BUILD=stack ARGS="--resolver lts-6"
compiler: ": #stack 7.10.3 osx"
os: osx

- env: BUILD=stack ARGS="--resolver lts-9"
compiler: ": #stack 8.0.2 osx"
os: osx

- env: BUILD=stack ARGS="--resolver lts-10"
compiler: ": #stack 8.2.2 osx"
- env: BUILD=stack ARGS="--resolver lts-12"
compiler: ": #stack 8.4.4 osx"
os: osx

- env: BUILD=stack ARGS="--resolver nightly"
compiler: ": #stack nightly osx"
os: osx

allow_failures:
#- env: BUILD=stack ARGS="--resolver lts-6"
- env: BUILD=stack ARGS="--resolver nightly"

before_install:
Expand Down Expand Up @@ -134,13 +116,15 @@ install:
- |
case "$BUILD" in
stack)
cabal --version
ghc --version
# Add in extra-deps for older snapshots, as necessary
stack --no-terminal --install-ghc $ARGS build --bench --dry-run || ( \
stack --no-terminal $ARGS build cabal-install && \
stack --no-terminal $ARGS --install-ghc build --bench --dry-run || ( \
stack --no-terminal $ARGS --install-ghc build cabal-install && \
stack --no-terminal $ARGS solver --update-config)
# Build the dependencies
stack --no-terminal --install-ghc $ARGS test --bench --only-dependencies
stack --no-terminal $ARGS test --bench --only-dependencies
;;
cabal)
cabal --version
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

<img src="https://i.imgur.com/0h9dFhl.png" height="200" width="320" />

This is a brand new course, so there are going to be rough edges. We invite
you to submit issues or pull requests if you find errors or have suggestions
on how to improve it.
This is a new course, so there are going to be rough edges. We invite you to
submit issues or pull requests if you find errors or have suggestions on how to
improve it.

This course is designed to be run in a class room with instructors, but we
would like to make it suitable for self-study as well. Although undertaking
Expand Down Expand Up @@ -123,8 +123,8 @@ instructions about what the goal is for that specific level.
* Level 06 : Add some flexible configuration
* Level 07 : ReaderT & refactoring

-- Coming Soon...
* Level 08 : (Bonus Round) Lenses & Refactoring
-- In Development...
* Level 08 : Lenses & "classy mtl" monad transformers

-- Maybe...
* Level 09 : Add session controls (login, logout) and a protected route. So we
Expand Down
56 changes: 11 additions & 45 deletions applied-fp-course.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ tested-with: GHC==8.6.1
, GHC==8.4.3
, GHC==8.2.2
, GHC==8.0.2
, GHC==7.10.3

source-repository head
type: git
Expand All @@ -60,8 +59,6 @@ library
Level01.Core
, Level02.Core
, Level02.Types
, Level03.Core
, Level03.Types
, Level04.Conf
, Level04.DB
, Level04.DB.Types
Expand Down Expand Up @@ -118,13 +115,17 @@ library
, bytestring == 0.10.*
, text == 1.2.*
, optparse-applicative >= 0.13 && < 0.15
, aeson == 1.*
, mtl == 2.2.*
, time >= 1.4 && < 1.10
, old-locale >= 1.0 && < 1.5
, contravariant >= 1.4 && < 1.6
, sqlite-simple == 0.4.*
, sqlite-simple-errors == 0.6.*
, semigroups == 0.18.*
, transformers >= 0.4 && < 0.6
, lens >= 4.15 && < 4.18
, waargonaut >= 0.4.2 && < 0.5
, attoparsec >= 0.13 && < 0.15

-- Directories containing source files.
hs-source-dirs: src
Expand All @@ -139,59 +140,35 @@ test-suite app-fp-tests
hs-source-dirs: tests
main-is: Test.hs

other-modules: Level03Tests
, Level04Tests
, Level05Tests
, Level06Tests
, Level07Tests

, Helpers

build-depends: base >= 4.8 && <4.13
, applied-fp-course
, wai == 3.2.*
, wai-extra == 3.0.*
, http-types >= 0.9 && < 0.13
, tasty >= 0.8 && < 1.2
, tasty-hunit >= 0.9 && < 0.11
, hspec >= 2.2 && < 3.0
, hspec-wai >= 0.6 && < 0.10
, tasty-wai >= 0.1 && < 0.2
, bytestring == 0.10.*
, text == 1.2.*
, mtl == 2.2.*
, semigroups == 0.18.*
, transformers >= 0.4 && < 0.6
, mmorph

-- [Challenge] Packages
, hedgehog >= 0.6 && < 0.7
, tasty-hedgehog >= 0.2 && < 0.3

test-suite doctests
-- Base language which the package is written in.
default-language: Haskell2010
type: exitcode-stdio-1.0

other-modules: Level04Tests
, Level05Tests
, Level06Tests
, Level07Tests
, Helpers

ghc-options: -threaded
main-is: doctests.hs
hs-source-dirs: tests
build-depends: base >= 4.8 && <4.13
, applied-fp-course
, mtl == 2.2.*
, hspec >= 2.2 && < 3.0
, hspec-wai >= 0.6 && < 0.10
, doctest >= 0.11 && < 0.17
, semigroups == 0.18.*
, tasty >= 0.8 && < 1.2
, tasty-hunit >= 0.9 && < 0.11
, bytestring == 0.10.*
, wai == 3.2.*
, wai-extra == 3.0.*
, http-types >= 0.9 && < 0.13
, transformers >= 0.4 && < 0.6
, mmorph
, applied-fp-course

-- Level Executables
executable level01-exe
Expand All @@ -216,17 +193,6 @@ executable level02-exe
-- Base language which the package is written in.
default-language: Haskell2010

executable level03-exe
-- .hs or .lhs file containing the Main module.
main-is: Level03.hs
-- Directories containing source files.
hs-source-dirs: exe
-- Other library packages from which modules are imported.
build-depends: base >=4.8 && <4.13
, applied-fp-course
-- Base language which the package is written in.
default-language: Haskell2010

executable level04-exe
-- .hs or .lhs file containing the Main module.
main-is: Level04.hs
Expand Down
21 changes: 12 additions & 9 deletions applied-fp-course.nix
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{ mkDerivation, aeson, base, bytestring, doctest, hspec, hspec-wai
, http-types, mtl, optparse-applicative, semigroups, sqlite-simple
, sqlite-simple-errors, stdenv, tasty, tasty-hunit, text, time
, transformers, wai, wai-extra, warp, mmorph
{ mkDerivation, attoparsec, base, bytestring, contravariant
, doctest, hedgehog, http-types, lens, mtl, old-locale
, optparse-applicative, semigroups, sqlite-simple
, sqlite-simple-errors, stdenv, tasty, tasty-hedgehog, tasty-hunit
, tasty-wai, text, time, transformers, waargonaut, wai, wai-extra
, warp
}:
mkDerivation {
pname = "applied-fp-course";
Expand All @@ -10,14 +12,15 @@ mkDerivation {
isLibrary = true;
isExecutable = true;
libraryHaskellDepends = [
aeson base bytestring http-types mtl optparse-applicative
semigroups sqlite-simple sqlite-simple-errors text time
transformers wai warp
attoparsec base bytestring contravariant http-types lens mtl
old-locale optparse-applicative semigroups sqlite-simple
sqlite-simple-errors text time transformers waargonaut wai warp
];
executableHaskellDepends = [ base ];
testHaskellDepends = [
base bytestring doctest hspec hspec-wai http-types mtl tasty
tasty-hunit text wai wai-extra mmorph
base bytestring doctest hedgehog http-types mtl semigroups tasty
tasty-hedgehog tasty-hunit tasty-wai text transformers wai
wai-extra
];
description = "Simplest of web apps for educational purposes";
license = stdenv.lib.licenses.bsd3;
Expand Down
20 changes: 18 additions & 2 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,23 @@ let
then pkgs.haskellPackages
else pkgs.haskell.packages.${compiler};

drv = haskellPackages.callPackage ./applied-fp-course.nix {};
sources = {
tasty-wai = import ./nix/tasty-wai.nix;
waarg = import ./nix/waargonaut.nix;
};

waarg-deps = import "${sources.waarg}/waargonaut-deps.nix";

modifiedHaskellPackages = haskellPackages.override (old: {
overrides = pkgs.lib.composeExtensions
(old.overrides or (_: _: {}))
(self: super: (waarg-deps pkgs self super) // {
tasty-wai = self.callCabal2nix "tasty-wai" sources.tasty-wai {};
waargonaut = self.callCabal2nix "waargonaut" sources.waarg {};
});
});

drv = modifiedHaskellPackages.callPackage ./applied-fp-course.nix {};

in
if pkgs.lib.inNixShell then drv.env else drv
drv
9 changes: 0 additions & 9 deletions exe/Level03.hs

This file was deleted.

2 changes: 1 addition & 1 deletion exe/Level06.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ import qualified Level06.Core as Core
-- executable. So our ``exe/Main.hs`` is a straightforward and unremarkable
-- affair.
main :: IO ()
main = Core.runApp
main = Core.runApplication
2 changes: 1 addition & 1 deletion exe/Level07.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ import qualified Level07.Core as Core
-- executable. So our ``exe/Main.hs`` is a straightforward and unremarkable
-- affair.
main :: IO ()
main = Core.runApp
main = Core.runApplication
7 changes: 7 additions & 0 deletions nix/tasty-wai.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"url": "https://github.com/qfpl/tasty-wai",
"rev": "17ae906f318a222eb30a22b6b334399a0ca436a9",
"date": "2018-12-04T14:31:04+10:00",
"sha256": "16j3qbpwxbl4n2pvck91k6gz2541pkfdpxn4l47nf1s9jx9yaa7f",
"fetchSubmodules": true
}
13 changes: 13 additions & 0 deletions nix/tasty-wai.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
let
initialNixpkgs = import <nixpkgs> {};

sources = rec {
tasty-wai-pinned = initialNixpkgs.pkgs.lib.importJSON ./tasty-wai.json;
tasty-wai = initialNixpkgs.pkgs.fetchFromGitHub {
owner = "qfpl";
repo = "tasty-wai";
inherit (tasty-wai-pinned) rev sha256;
};
};
in
sources.tasty-wai
7 changes: 7 additions & 0 deletions nix/waargonaut.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"url": "https://github.com/qfpl/waargonaut",
"rev": "7d868c5ca568797345cee762a499488227238b1f",
"date": "2018-11-29T12:55:15+10:00",
"sha256": "1hr0iyzcamgknsx4830rzvfxy6ykslnalfvbxb6k7h8ywkd2zzc2",
"fetchSubmodules": true
}
13 changes: 13 additions & 0 deletions nix/waargonaut.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
let
initialNixpkgs = import <nixpkgs> {};

sources = rec {
waargonaut-pinned = initialNixpkgs.pkgs.lib.importJSON ./waargonaut.json;
waargonaut = initialNixpkgs.pkgs.fetchFromGitHub {
owner = "qfpl";
repo = "waargonaut";
inherit (waargonaut-pinned) rev sha256;
};
};
in
sources.waargonaut
25 changes: 25 additions & 0 deletions shell.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{ nixpkgs ? import <nixpkgs> {}
, compiler ? "default"
}:
let
inherit (nixpkgs) pkgs;

# Grab our course derivation
course = import ./. { inherit nixpkgs compiler; };

# Override the basic derivation so we can have a more fully feature
# environment for hacking on the course material
courseDevEnv = (pkgs.haskell.lib.addBuildTools course
[ # Include the SQLite Database application
nixpkgs.sqlite

# 'ghcid' auto reloading tool
nixpkgs.haskellPackages.ghcid
]
# We don't want nix to build the thing, we want the environment so we can
# build the thing.
).env;

in
# Fly, my pretties!
courseDevEnv
Loading

0 comments on commit b8921cd

Please sign in to comment.