Separate backend and frontend

This commit is contained in:
Mats Rauhala 2018-11-12 22:58:50 +02:00
parent e459a318bd
commit 8818b6f495
13 changed files with 264 additions and 28 deletions

View File

@ -8,4 +8,5 @@ before_script:
- mkdir -p ~/.config/nixpkgs - mkdir -p ~/.config/nixpkgs
script: script:
- nix-build ./release.nix -A backend --option trusted-public-keys "masser-ebook-manager.cachix.org-1:mtFSkQ2MO5MvjUpulZoFKjKUIa8g8CTcdPVuJaPKS1w= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" --option binary-caches "https://cache.nixos.org https://masser-ebook-manager.cachix.org" - nix-build ./release.nix --option trusted-public-keys "masser-ebook-manager.cachix.org-1:mtFSkQ2MO5MvjUpulZoFKjKUIa8g8CTcdPVuJaPKS1w= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" --option binary-caches "https://masser-ebook-manager.cachix.org https://cache.nixos.org" -A ghc.backend -A ghc.frontend
- nix-build ./release.nix --option trusted-public-keys "masser-ebook-manager.cachix.org-1:mtFSkQ2MO5MvjUpulZoFKjKUIa8g8CTcdPVuJaPKS1w= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" --option binary-caches "https://masser-ebook-manager.cachix.org https://cache.nixos.org" -A ghcjs.frontend

View File

@ -1,27 +1,27 @@
{-# Language DataKinds #-} {-# LANGUAGE DataKinds #-}
{-# Language TypeFamilies #-} {-# LANGUAGE DeriveGeneric #-}
{-# Language TypeOperators #-} {-# LANGUAGE FlexibleInstances #-}
{-# Language NoImplicitPrelude #-} {-# LANGUAGE MultiParamTypeClasses #-}
{-# Language MultiParamTypeClasses #-} {-# LANGUAGE NoImplicitPrelude #-}
{-# Language OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# Language TemplateHaskell #-} {-# LANGUAGE QuasiQuotes #-}
{-# Language QuasiQuotes #-} {-# LANGUAGE RecordWildCards #-}
{-# Language RecordWildCards #-} {-# LANGUAGE TemplateHaskell #-}
{-# Language DeriveGeneric #-} {-# LANGUAGE TypeFamilies #-}
{-# Language FlexibleInstances #-} {-# LANGUAGE TypeOperators #-}
module API (API, handler) where module API (API, handler) where
import Servant import Servant
import Servant.HTML.Lucid (HTML) import Servant.HTML.Lucid (HTML)
import Types import Types
import View import View
import qualified API.Users as Users import qualified API.Books as Books
import qualified API.Channels as Channels import qualified API.Catalogue as Catalogue
import qualified API.Books as Books import qualified API.Channels as Channels
import qualified API.Catalogue as Catalogue import qualified API.Users as Users
data Index = Index data Index = Index

View File

@ -1,12 +1,59 @@
{ nixpkgs, haskellPackages }: { nixpkgs, haskellPackages }:
let
miso = nixpkgs.fetchFromGitHub {
owner = "dmjio";
repo = "miso";
rev = "630e823dd40a434b73124e12b229a79d9fefb01d";
sha256 = "046gdp3ah2lsipfcy89rh20mn08xbhcgrj549v8zzy69j33xjm2l";
};
miso-jsaddle = super: if haskellPackages.ghc.isGhcjs or false then (super.callPackage (miso + "/miso-ghcjs.nix") {}) else (super.callPackage (miso + "/miso-ghc-jsaddle.nix") {});
dontCheck = nixpkgs.haskell.lib.dontCheck;
in
(import ./project.nix nixpkgs) { (import ./project.nix nixpkgs) {
haskellPackages = haskellPackages;
packages = { packages = {
common = ./common; common = ./common;
backend = ./backend; backend = ./backend;
frontend = ./frontend;
}; };
overrides = self: super: { overrides = self: super: {
generic-lens = nixpkgs.haskell.lib.dontCheck super.generic-lens; generic-lens = nixpkgs.haskell.lib.dontCheck super.generic-lens;
miso = miso-jsaddle super;
# doctest = null; # Not compilable with ghcjs
# comonad = dontCheck super.comonad;
# Glob = dontCheck super.Glob;
# SHA = dontCheck super.SHA;
# iproute = dontCheck super.iproute;
# semigroupoids = dontCheck super.semigroupoids;
# wai-app-static = dontCheck super.wai-app-static;
# attoparsec = dontCheck super.attoparsec;
# http-date = dontCheck super.http-date;
# lens = dontCheck super.lens;
# unix-time = dontCheck super.unix-time;
# http-types = dontCheck super.http-types;
# servant = dontCheck super.servant;
# servant-server = dontCheck super.servant-server;
# servant-auth-docs = dontCheck super.servant-auth-docs;
# lens-aeson = dontCheck super.lens-aeson;
# word8 = dontCheck super.word8;
# http2 = dontCheck super.http2;
# wai-extra = dontCheck super.wai-extra;
# pgp-wordlist = dontCheck super.pgp-wordlist;
# prettyprinter = dontCheck super.prettyprinter;
# unliftio = dontCheck super.unliftio;
# prettyprinter-ansi-terminal = dontCheck super.prettyprinter-ansi-terminal;
# distributive = dontCheck super.distributive;
# genvalidity-property = dontCheck super.genvalidity-property;
# genvalidity-hspec = dontCheck super.genvalidity-hspec;
# genvalidity = dontCheck super.genvalidity;
# megaparsec = dontCheck super.megaparsec;
# ncurses = null;
# haskeline = super.callHackage "haskeline" "0.7.4.2" {};
# terminfo = super.callHackage "terminfo" "0.4.1.1" {};
}; };
tools = with haskellPackages; [ tools = with haskellPackages; [
ghcid ghcid

5
frontend/ChangeLog.md Normal file
View File

@ -0,0 +1,5 @@
# Revision history for frontend
## 0.1.0.0 -- YYYY-mm-dd
* First version. Released on an unsuspecting world.

30
frontend/LICENSE Normal file
View File

@ -0,0 +1,30 @@
Copyright (c) 2018, Mats Rauhala
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Mats Rauhala nor the names of other
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

2
frontend/Setup.hs Normal file
View File

@ -0,0 +1,2 @@
import Distribution.Simple
main = defaultMain

27
frontend/frontend.cabal Normal file
View File

@ -0,0 +1,27 @@
-- Initial frontend.cabal generated by cabal init. For further
-- documentation, see http://haskell.org/cabal/users-guide/
name: frontend
version: 0.1.0.0
-- synopsis:
-- description:
license: BSD3
license-file: LICENSE
author: Mats Rauhala
maintainer: mats.rauhala@iki.fi
-- copyright:
category: Web
build-type: Simple
extra-source-files: ChangeLog.md
cabal-version: >=1.10
executable frontend
main-is: Main.hs
-- other-modules:
-- other-extensions:
build-depends: base >=4.11 && <4.12
, miso
, jsaddle-warp
, mtl
hs-source-dirs: src
default-language: Haskell2010

41
frontend/src/Main.hs Normal file
View File

@ -0,0 +1,41 @@
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Main where
import Control.Monad.Trans (liftIO)
import Language.Javascript.JSaddle.Warp
import Miso
import Miso.String
data Action = Add
| Subtract
| SayHello
| NoOp
newtype Model = Model Int deriving (Eq, Num, ToMisoString)
updateModel :: Action -> Model -> Effect Action Model
updateModel Add m = noEff (m + 1)
updateModel Subtract m = noEff (m - 1)
updateModel SayHello m = m <# (liftIO (putStrLn "Hello world") >> pure NoOp)
updateModel NoOp m = noEff m
viewModel :: Model -> View Action
viewModel x =
div_ [] [ button_ [ onClick Add ] [ text "+" ]
, text (ms x)
, button_ [ onClick Subtract ] [ text "-" ]
]
main :: IO ()
main = run 8081 $ startApp App{..}
where
model = Model 0
initialAction = SayHello
update = updateModel
view = viewModel
subs = []
events = defaultEvents
mountPoint = Nothing

16
ghcjs.patch Normal file
View File

@ -0,0 +1,16 @@
diff --git a/lib/boot/shims/src/string.js b/lib/boot/shims/src/string.js
index d82f75a..f16e55a 100644
--- a/lib/boot/shims/src/string.js
+++ b/lib/boot/shims/src/string.js
@@ -780,11 +780,7 @@ function h$throwJSException(e) {
// adding the Exception dictionary
var strVal = e.toString() + '\n' + Array.prototype.join.call(e.stack, '\n');
var someE = MK_SOMEEXCEPTION(HS_JSEXCEPTION_EXCEPTION,
-#ifdef GHCJS_PROF
- MK_JSEXCEPTION(MK_JSVAL(e), h$toHsString(strVal), h$CCS_SYSTEM))
-#else
MK_JSEXCEPTION(MK_JSVAL(e), h$toHsString(strVal))
-#endif
);
return h$throw(someE, true);
}

14
jsaddle-warp-ghcjs.nix Normal file
View File

@ -0,0 +1,14 @@
{ mkDerivation, base, fetchgit, stdenv }:
mkDerivation {
pname = "jsaddle-warp";
version = "0.9.5.0";
src = fetchgit {
url = "https://github.com/ghcjs/jsaddle.git";
rev = "34fe7d61b3f387b81aa748294ac8d993243f53b4";
sha256 = "0qdh5qdk23vcp1yp910zgw2hs4zpbx9ig25xgaax0iwj2m1ifh5x";
};
postUnpack = "sourceRoot+=/jsaddle-warp; echo source root reset to $sourceRoot";
libraryHaskellDepends = [ base ];
description = "Interface for JavaScript that works with GHCJS and GHC";
license = stdenv.lib.licenses.mit;
}

View File

@ -1,7 +1,7 @@
{ {
"url": "https://github.com/nixos/nixpkgs.git", "url": "https://github.com/nixos/nixpkgs.git",
"rev": "e0d250e5cf6d179e1ccc775472d89718f61fcfd1", "rev": "4507926b80c6b8f73053775ffee17f6781c7e7c8",
"date": "2018-01-08T11:52:28+01:00", "date": "2018-01-08T11:52:28+01:00",
"sha256": "1iqpjz4czcpghbv924a5h4jvfmj6c8q6sl3b1z7blz3mi740aivs", "sha256": "068v9xh7d8klk62p2qwr76fyfqfh1bp08xc12x138g5q6pg6yfzb",
"fetchSubmodules": true "fetchSubmodules": true
} }

View File

@ -6,7 +6,8 @@ let
in in
{ packages { haskellPackages
, packages
, overrides ? _ : _ : {} , overrides ? _ : _ : {}
, tools ? [] , tools ? []
}: }:
@ -17,12 +18,12 @@ let
(self: super: mapAttrs (name: path: self.callCabal2nix name path {}) packages) (self: super: mapAttrs (name: path: self.callCabal2nix name path {}) packages)
overrides overrides
]; ];
haskellPackages = nixpkgs.haskellPackages.override { overrides = overrides'; }; haskellPackages' = haskellPackages.extend overrides';
packages' = mapAttrs (name: _: haskellPackages."${name}") packages; packages' = mapAttrs (name: _: haskellPackages'."${name}") packages;
mkShell = name: pkg: mkShell = name: pkg:
let let
n = "${name}-shell"; n = "${name}-shell";
deps = haskellPackages.ghcWithHoogle (pkgs: pkg.buildInputs ++ pkg.propagatedBuildInputs); deps = haskellPackages'.ghcWithHoogle (pkgs: pkg.buildInputs ++ pkg.propagatedBuildInputs);
in in
{ {
name = "${n}"; name = "${n}";

View File

@ -2,14 +2,66 @@
let let
jsaddle = nixpkgs.fetchFromGitHub {
owner = "ghcjs";
repo = "jsaddle";
rev = "34fe7d61b3f387b81aa748294ac8d993243f53b4";
sha256 = "0qdh5qdk23vcp1yp910zgw2hs4zpbx9ig25xgaax0iwj2m1ifh5x";
};
config = {
packageOverrides = pkgs: with pkgs.haskell.lib; with pkgs.lib; {
haskell = pkgs.haskell // {
packages = pkgs.haskell.packages // {
ghccustom = pkgs.haskell.packages.ghc843.override {
overrides = self: super: {
jsaddle-warp = dontCheck (super.callPackage (jsaddle + "/jsaddle-warp") {});
# jsaddle-warp = super.callPackage ./jsaddle-warp-ghcjs.nix {};
jsaddle = dontCheck (super.callPackage (jsaddle + "/jsaddle") {});
};
};
ghcjscustom = pkgs.haskell.packages.ghcjs84.override {
overrides = self: super: {
doctest = null;
directory-tree = dontCheck (super.directory-tree);
http-types = dontCheck (super.http-types);
tasty-quickcheck = dontCheck (super.tasty-quickcheck);
scientific = dontCheck (super.scientific);
servant = dontCheck (super.servant);
jsaddle-warp = super.callPackage ./jsaddle-warp-ghcjs.nix {};
ghc = overrideDerivation (super.ghc.override {
ghcjsSrc = pkgs.fetchgit {
url = "https://github.com/ghcjs/ghcjs.git";
rev = "dc190b1bb2453cfa484124e9f335ee3cad1492f7";
sha256 = "0dh52gj0f3700zfyrhisy44b6y9p1bsawwrmd5pllpdyw21zd9lw";
fetchSubmodules = true;
};
}) (drv: { patches = (drv.patches or []) ++ [ ./ghcjs.patch ]; });
};
};
};
};
};
};
pinnedVersion = nixpkgs.lib.importJSON ./nixpkgs-version.json; pinnedVersion = nixpkgs.lib.importJSON ./nixpkgs-version.json;
pinnedPkgs = import (nixpkgs.fetchFromGitHub { pinnedPkgs = import (nixpkgs.fetchFromGitHub {
owner = "NixOS"; owner = "NixOS";
repo = "nixpkgs"; repo = "nixpkgs";
inherit (pinnedVersion) rev sha256; inherit (pinnedVersion) rev sha256;
}) {}; }) { inherit config; };
ghc = import ./default.nix { nixpkgs = pinnedPkgs; haskellPackages = pinnedPkgs.haskell.packages.ghccustom; };
ghcjs = import ./default.nix { nixpkgs = pinnedPkgs; haskellPackages = pinnedPkgs.haskell.packages.ghcjscustom; };
inherit (pinnedPkgs) pkgs; inherit (pinnedPkgs) pkgs;
in in
import ./default.nix { nixpkgs = pinnedPkgs; haskellPackages = pinnedPkgs.haskellPackages; } {
inherit ghc ghcjs;
deps = pkgs.buildEnv {
name = "deps";
paths = [
(pkgs.haskell.packages.ghccustom.ghcWithPackages (_: ghc.backend.buildInputs ++ ghc.backend.propagatedBuildInputs))
(pkgs.haskell.packages.ghcjscustom.ghcWithPackages (_: ghcjs.frontend.buildInputs ++ ghcjs.frontend.propagatedBuildInputs))
];
buildInputs = [ ];
};
}