Skip to content

Instantly share code, notes, and snippets.

@o1lo01ol1o
Last active November 7, 2018 05:33
Show Gist options
  • Select an option

  • Save o1lo01ol1o/3c74676b35806e5fc84577c169edfa75 to your computer and use it in GitHub Desktop.

Select an option

Save o1lo01ol1o/3c74676b35806e5fc84577c169edfa75 to your computer and use it in GitHub Desktop.
Axiom and Reflex project skeleton

Axiom via Nix

Get Nix

https://nixos.org/nix/

Review the reflex-dom project-development documentation

https://github.com/reflex-frp/reflex-platform/blob/develop/docs/project-development.md

We're piggy-backing off reflex-platforms nix infrastructure because it provides a working, cached, environment in which to develop with GHCJS. We'll be using GHC(JS) 8.4.
Most reflex-platform projects split the codebase into code needed to be compiled on GHC (backend project), code needed to be compiled by GHCJS (frontend project) and code shared between the two (common project). For simplicity, and because axiom can be compiled by either compiler, we just define one frontend project in our default.nix. More scalable projects would also follow the tripartate project structure.

So create a project as defined above in the project-development.md with only definitions for a "frontend" project. Then put the above default.nix in the base directory and nix-build to pull the requisit packages.

The haskell-ide-engine has some support for nix projects here. Once you've run nix-build ., you can add support for GHC 8.4 to your environment by following the readme. Once installed, you can enter the compiler shell of your choice with nix-shell -A shells.ghc8_4 or nix-shell -A shells.ghcjs8_4 and from there, launching an editor ((spac)emacs / vs code) inside the shell with support for hie should pick up the correct executables and packages and give you nice development experience.

See the default.nix and reflext-platforms's project function for how the various attributes in the nix expression are defined.

Building

./build will run the needed cabal commands in their respective shells.

Running

The cabal commands will put binaries under dist-newstyle and dist-ghcjs respectively. To run these, the rename the ghcjs binary to out.jsexe and put it in a static/ directory in the same location as the ghc binary:

.
├── frontend
└── static
    └── out.jsexe

Then run the axiom app as usual, eg: ./frontend -p start/localhost/8080

Note: if you're running services in transient-universe that rely on the monitor or executor executables, you may need to execute ./frontend -p start/localhost/8080 from within nix-shell -A shells.ghc8_4 to allow nix to see those paths. Derivation coming soon.

JSaddle

Requires supporting the jsaddle api in axiom

IOS; Android

Requires more work in axiom to support these architectures.

#!/bin/bash
sh ./build-ghc
sh ./build-ghcjs
#!/usr/bin/env bash
set -eu -o pipefail
nix-shell -A shells.ghc8_4 --run ' cabal --project-file=cabal.project new-build all;'
#!/usr/bin/env bash
set -eu -o pipefail
nix-shell -A shells.ghcjs8_4 --run '
cabal --project-file=cabal-ghcjs.project --builddir=dist-ghcjs new-build all;'
# default.nix
{}:
(import (builtins.fetchGit {
url = git://github.com/reflex-frp/reflex-platform;
rev = "a721a268120908c9902a8b20509e6983b7088161";
}) {}).project ({ pkgs, ... }:
{
packages = {
frontend = ./frontend;
# common = ./common;
# backend = ./backend; # it's better to split code into only those needed by each compiler to minimize ifdefs in code. Currently haskell-ide-engine doesn't yet support cabal.project files and thuse won't be able to locate the modules in across cabal projects. This should be supported soon, though.
};
shells = { # Other valid versions are 8_2 and 8_0 ymmv.
ghc8_4 = ["frontend"];
ghcjs8_4 = ["frontend"];
};
overrides = self: super: {
transient-universe-tls = self.callCabal2nix "transient-universe-tls" (pkgs.fetchFromGitHub {
owner = "transient-haskell";
repo = "transient-universe-tls";
rev = "e91c2bd615e1cffd06cf4704590f7bd3e404ba1a";
sha256 = "0bj3vh5laxbmdj5qlb7fqwb8jrcppsywa089wk27ix0srspxv38k";
fetchSubmodules = true;
}) {};
transient-universe =
let checked = self.callCabal2nix "transient-universe" (pkgs.fetchFromGitHub {
owner = "transient-haskell";
repo = "transient-universe";
rev = "11f089dcc0b94afc49a09d20627f467d9a41fa4b";
sha256 = "0zih5d0m8js6nqzg4l6zhsx7n6ykgrzghmvnz2hyhzin1jcrhl77";
fetchSubmodules = true;
}) {};
in (pkgs.haskell.lib.dontHaddock (pkgs.haskell.lib.dontCheck checked)) ;
transient =
let checked = self.callCabal2nix "transient" (pkgs.fetchFromGitHub {
owner = "transient-haskell";
repo = "transient";
rev = "b98af612cc7e1137ac003301d0bb169d25a3c2c8";
sha256 = "15lhqh296rglssy9z3xq8z3ivq0nj2j3s8caj6cwb1s4p4akfiin";
fetchSubmodules = true;
}) {};
in (pkgs.haskell.lib.dontHaddock (pkgs.haskell.lib.dontCheck checked));
ghcjs-perch = self.callCabal2nix "ghcjs-perch" (pkgs.fetchFromGitHub {
owner = "transient-haskell";
repo = "ghcjs-perch";
rev = "ae74f6b96f037ba1193206b075875755f43913a6";
sha256 = "00zrz0j22kjb9c8wxs07fipsbfxm5m3cmb0mnjawkv3f5xzq7gkc";
fetchSubmodules = true;
}) {};
axiom = self.callCabal2nix "axiom" (pkgs.fetchFromGitHub {
owner = "transient-haskell";
repo = "axiom";
rev = "7fde62df5fe052c5d50bd258e0764122d86c3b3b";
sha256 = "0mzj64305pj2qj2cp4lkx65vznm4rrjamra200l3523gmcp0ypnd";
fetchSubmodules = true;
}) {};
};
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment