Code Monkey home page Code Monkey logo

devx's Introduction

The Developer Experience Shell

This repo contains a nix develop shell for haskell. Its primary purpose is to help get a development shell for haskell quickly and across multiple operating systems (and architectures).

It requires nix to be installed.

Once you have nix installed you can check that everything is working correctly:

  • Make sure to add experimental-features = nix-command flakes and accept-flake-config = true lines to $XDG_CONFIG_HOME/nix/nix.conf file ;
  • Make sure your $USER is trusted nix show-config | grep trusted-users, otherwise add it to /etc/nix/nix.conf and restart nix-daemon ;
  • Make sure the nix-daemon is running using systemctl status nix-daemon (if your OS is systemd-based).

Once you have nix, (linux, macOS, windows WSL) you can use

nix develop github:input-output-hk/devx#ghc96 --no-write-lock-file --refresh

to obtain a haskell evelopment shell for GHC 8.10.7 including cabal-install, as well as hls and hlint. If you are on macOS on an apple silicon chip (M1, M2, ...), and want to switch between Intel (x86_64) and Apple Silicon (aarch64), you can do this by simply passing the corresponding --system argument:

nix develop github:input-output-hk/devx#ghc810 --no-write-lock-file --refresh --system x86_64-darwin

or

nix develop github:input-output-hk/devx#ghc810 --no-write-lock-file --refresh --system aarch64-darwin

direnv integration

If you use direnv, you can integrate this shell by creating an .envrc file with the following content:

# https://github.com/nix-community/nix-direnv A fast, persistent use_nix/use_flake implementation for direnv:
if ! has nix_direnv_version || ! nix_direnv_version 2.3.0; then
  source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.3.0/direnvrc" "sha256-Dmd+j63L84wuzgyjITIfSxSD57Tx7v51DMxVZOsiUD8="
fi
# https://github.com/input-output-hk/devx Slightly opinionated shared GitHub Action for Cardano-Haskell projects 
use flake "github:input-output-hk/devx#ghc810-iog"

Refer to direnv and devx guide for more information.

VSCode DevContainer / GitHub CodeSpace support

To make this developer shell available in VSCode DevContainer or GitHub CodeSpace, simply add a file named .devcontainer/devcontainer.json with the following content:

{
   "image":"ghcr.io/input-output-hk/devx-devcontainer:ghc810-iog",
   "customizations":{
      "vscode":{
         "extensions":[
            "haskell.haskell"
         ],
         "settings":{
            "haskell.manageHLS":"PATH"
         }
      }
   }
}

This configuration will work immediately in GitHub CodeSpace! For local VSCode DevContainer, you need Docker and the VSCode extension. For guidance on this, you can follow the Microsoft tutorial.

It's also advise to enable GitHub CodeSpace prebuilds in your repository settings, follow the instructions provided in the GitHub documentation. This will significantly enhance your development experience by reducing the setup time when opening a new CodeSpace.

List of images available: ghc810-iog, ghc96-iog, ghc810-js-iog, ghc96-js-iog, ghc810-windows-iog, ghc96-windows-iog

Compilers and Flavours

There are multiple compilers available, and usually the latest for each series from 8.10 to 9.6 (a slight delay between the official release announcement and the compiler showing up in the devx shell is expected due to integration work necessary). The current available ones are: ghc810, ghc90, ghc92,ghc94, and ghc96 (these are the same ones as in haskell.nix and may contain patches for defects in the official releases).

Flavours

There are various flavours available as suffixes to the compiler names (e.g. #ghc810-minimal-iog).

Flavour Description Example Included
empty General Haskell Dev #ghc810 ghc, cabal-install, hls, hlint
-iog IOG Haskell Dev #ghc810 adds sodium-vrf, blst, secp256k1, R, postgresql
-minimal Only GHC, and Cabal #ghc810-minimal drops hls, hlint
-static Building static binaries #ghc810-static static haskell cross compiler
-js JavaScript Cross Compiler #ghc810-js javascript haskell cross compiler
-windows Windows Cross Compiler #ghc810-windows windows haskell cross compiler

these can then be comined following this schema:

#ghc<ver>[-js|-windows|-static][-minimal][-iog]

For example

nix develop github:input-output-hk/devx#ghc810-windows-minimal-iog --no-write-lock-file --refresh

would provide a development shell with a windows cross compiler as well as cabal, and the IOG specific libraries, but no Haskell Language Server (hls), and no HLint.

A full list of all available devShells can be see with:

nix flake show github:input-output-hk/devx

devx's People

Contributors

andreabedini avatar angerman avatar erikd avatar hamishmack avatar newhoggy avatar yvan-sraka avatar zeme-wana avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

devx's Issues

`$CABAL_PROJECT_LOCAL_TEMPLATE` broken & inconvenient to use

When entering the nix shell, the following message is shown:

 Quirks:
	if you have the zlib, HsOpenSSL, or digest package in your dependency tree, please make sure to
	echo "$CABAL_PROJECT_LOCAL_TEMPLATE" > cabal.project.local

Firstly, the content of the $CABAL_PROJECT_LOCAL_TEMPLATE is broken as it's missing newlines / carriage returns. Thus adding it to cabal.project.local with the provided instruction result in a build failure as cabal chokes on it.

Second, it is actually inconvenient to use for two reasons:

  1. On a local setup, this may conflict with a local cabal.project.local and sadly, because the extra-lib referenced in this variable are paths on the nix store, we can't really get around by 'hard coding' them in the cabal.project.local since they may change on a new index-state or constraints solving.

  2. The fact it is stored in an environment variable which only exists from within the nix-shell is annoying. It prevents using it in combination with --command for example since escaping doesn't work. For similar reason, when used from within a Makefile it gets in the way pretty quickly.

Possible / suggested resolution: to address (1) and (2), I'd be more convenient to have a one-time command to run that would output the extra cabal constraints on stdout or to a file for a given dependency set. This way, this operation can be done as part of a configuration step and need not to rely on environment variables.

HLS broken in `-static`?

HLS, which isn’t included in the -minimal devShell flavor, seems broken in the -static one:

last 10 log lines:
> dist/build/haskell-language-server/haskell-language-server-tmp/Main.o(.data+0x5a8): error: undefined reference to 'stg_SRT_4_info'
> dist/build/haskell-language-server/haskell-language-server-tmp/Main.o(.data+0x5b0): error: undefined reference to 'haskellzmlanguagezmserverzm1zi8zi0zi0zm1o58ZZky230r7vv4t7Fs4cA_IdeziArguments_getArguments1_closure'
> dist/build/haskell-language-server/haskell-language-server-tmp/Main.o(.data+0x5d8): error: undefined reference to 'stg_SRT_4_info'
> dist/build/haskell-language-server/haskell-language-server-tmp/Main.o(.data+0x5e0): error: undefined reference to 'base_GHCziIOziHandleziFD_stderr_closure'
> dist/build/haskell-language-server/haskell-language-server-tmp/Main.o(.data+0x5e8): error: undefined reference to 'ghcidezm1zi8zi0zi0zmDnn6Vml4mofDkXelX4I3Y_DevelopmentziIDEziTypesziLogger_makeDefaultHandleRecorder_closure'
> dist/build/haskell-language-server/haskell-language-server-tmp/Main.o(.data+0x630): error: undefined reference to 'base_GHCziTopHandler_runMainIO1_closure'
> /build/ghc176_0/ghc_4.o:ghc_3.c:function main: error: undefined reference to 'defaultRtsConfig'
> /build/ghc176_0/ghc_4.o:ghc_3.c:function main: error: undefined reference to 'hs_main'
> collect2: error: ld returned 1 exit status
> `x86_64-unknown-linux-musl-cc' failed in phase `Linker'. (Exit code: 1)

error: 1 dependencies of derivation 'haskell-language-server-exe-haskell-language-server-1.9.1.0.drv' failed to build

Build failed using the following command:
nix develop github:input-output-hk/devx#ghc8107 --no-write-lock-file --refresh

trace: No index state specified for cabal-install, using the latest index state that we know about (2023-03-25T00:00:00Z)!
trace: No index state specified for haskell-language-server, using the latest index state that we know about (2023-03-25T00:00:00Z)!
trace: No index state specified for hlint, using the latest index state that we know about (2023-03-25T00:00:00Z)!
error: builder for '/nix/store/6sfkiisgk19xl7j0f7ryrv9a1wxzdxwb-ghcide-lib-ghcide-1.9.1.0.drv' failed with exit code 1;
       last 10 log lines:
       >            prepd_expr <- corePrepExpr dflags hsc_env tidy_expr
       >            ....
       >     |
       > 272 |                        (icInteractiveModule (hsc_IC hsc_env)) prepd_expr
       >     |                                                               ^^^^^^^^^^
       > [57 of 73] Compiling Development.IDE.Core.Service ( src/Development/IDE/Core/Service.hs, dist/build/Development/IDE/Core/Service.o, dist/build/Development/IDE/Core/Service.dyn_o )
       > [58 of 73] Compiling Development.IDE.LSP.Notifications ( src/Development/IDE/LSP/Notifications.hs, dist/build/Development/IDE/LSP/Notifications.o, dist/build/Development/IDE/LSP/Notifications.dyn_o )
       > [59 of 73] Compiling Development.IDE.Core.Actions ( src/Development/IDE/Core/Actions.hs, dist/build/Development/IDE/Core/Actions.o, dist/build/Development/IDE/Core/Actions.dyn_o )
       > [68 of 73] Compiling Generics.SYB.GHC ( src/Generics/SYB/GHC.hs, dist/build/Generics/SYB/GHC.o, dist/build/Generics/SYB/GHC.dyn_o )
       > [69 of 73] Compiling Text.Fuzzy.Parallel ( src/Text/Fuzzy/Parallel.hs, dist/build/Text/Fuzzy/Parallel.o, dist/build/Text/Fuzzy/Parallel.dyn_o )
       For full logs, run 'nix log /nix/store/6sfkiisgk19xl7j0f7ryrv9a1wxzdxwb-ghcide-lib-ghcide-1.9.1.0.drv'.
error: 1 dependencies of derivation '/nix/store/3ml4i7a3f94s1b5qlj711v9jq6mqvr2f-haskell-language-server-exe-haskell-language-server-1.9.1.0.drv' failed to build
error: 1 dependencies of derivation '/nix/store/y6v80y3504wgn5yw2nfazgibmxxw83dh-nix-shell-env.drv' failed to build
@nix { "action": "setPhase", "phase": "unpackPhase" }
unpacking sources
unpacking source archive /nix/store/h7lf6qy8maqskizinckw85y9y7ab791i-ghcide-1.9.1.0.tar.gz
source root is ghcide-1.9.1.0
setting SOURCE_DATE_EPOCH to timestamp 1000000000 of file ghcide-1.9.1.0/test/src/Development/IDE/Test.hs
@nix { "action": "setPhase", "phase": "patchPhase" }
patching sources
'/build/.attr-0h9ydb7s8pfhl5kfs3rmmwnmpi49yyiw7jgr5dpw9rmvv8sy0f2b' -> 'ghcide.cabal'
@nix { "action": "setPhase", "phase": "configurePhase" }
configuring
Configure flags:
--prefix=/nix/store/rarisc9aswsi6yf171b6sx2y7ra9mhvw-ghcide-lib-ghcide-1.9.1.0 lib:ghcide --package-db=clear --package-db=/nix/store/n>
Configuring library for ghcide-1.9.1.0..
@nix { "action": "setPhase", "phase": "buildPhase" }
building
Preprocessing library for ghcide-1.9.1.0..
Building library for ghcide-1.9.1.0..
[ 1 of 73] Compiling Control.Concurrent.Strict ( src/Control/Concurrent/Strict.hs, dist/build/Control/Concurrent/Strict.o, dist/build/>
[ 2 of 73] Compiling Development.IDE.Core.Debouncer ( src/Development/IDE/Core/Debouncer.hs, dist/build/Development/IDE/Core/Debouncer>
[ 3 of 73] Compiling Development.IDE.Core.FileUtils ( src/Development/IDE/Core/FileUtils.hs, dist/build/Development/IDE/Core/FileUtils>
[ 4 of 73] Compiling Development.IDE.Core.PositionMapping ( src/Development/IDE/Core/PositionMapping.hs, dist/build/Development/IDE/Co>
[ 5 of 73] Compiling Development.IDE.GHC.Compat.Core ( src/Development/IDE/GHC/Compat/Core.hs, dist/build/Development/IDE/GHC/Compat/C>

src/Development/IDE/GHC/Compat/Core.hs:404:5: warning: [-Wduplicate-exports]
    ‘defaultFixity’ is exported by ‘module BasicTypes’ and ‘defaultFixity’
    |
404 |     module BasicTypes,
    |     ^^^^^^^^^^^^^^^^^

[DevX bootstrap] Benchmark the speed download of the `devx` closure

When using GHA to turn iohk/devx into a shell to run, e.g. cabal update, cabal build, we take a lot of time downloading stuff.

A lot of this time comes down to nix sequentially downloading a lot of data. We should build the store and export/import it instead to speed this up.

nix path-info --closure-size --human-readable $(nix print-dev-env --json .#ghc8107-static-minimal | jq -r .variables.out.value)

… will give us something like 2.5G. That's a lot.

We can also enter the shell using

$ nix print-dev-env .#ghc8107-static-minimal > env.sh
$ bash --rcfile env.sh

(e.g. instead of nix develop).

We could pre-build the closure (e.g. from result), and store that as a zstd compressed archive:

nix-store --export $(nix-store -qR result) | zstd -z8T8 > out.zstd

And then re-import this as the first step in GHAs after setting up nix.

See for example this GHA: https://github.com/angerman/x/blob/c559ae0429bb69829a9c9cae8c21ab777461aaf2/.github/workflows/main.yml#L23-L66, which doesn't work properly yet (nix still ends up downloading stuff when trying to enter the shell; maybe this can be eliminated with the env.sh idea from above).

JS shell: invalid flags

In the JS shell:

nix develop github:input-output-hk/devx#ghc810-js-minimal-iog --no-write-lock-file --refresh

we have:

env | grep NIX_CABAL_FLAGS
NIX_CABAL_FLAGS=--with-ghc=javascript-unknown-ghcjs-ghc --with-ghc-pkg=javascript-unknown-ghcjs-ghc-pkg --with-hsc2hs=javascript-unknown-ghcjs-hsc2hs

Two issues:

  • ghcjs is built with prefix "js-unknown-ghcjs", not "javascript-unknown-ghcjs" (while the latter is correct for the JS backend)
  • "--ghcjs" isn't passed to cabal (only required for ghcjs, not for the JS backend)

[DevX boostrap] cut down closure size of iohk/devx

We should analyse the size of the closure needed for:

nix develop "github:input-output-hk/devx#ghc8107"

… and similar (also --minimal).

And then figure out why they are too large and what could (or should) be dropped.

Inconsistency in compiler versions in the README

All commands reference ghc810, except for the first one which references ghc96.

The accompanying text also talks about GHC 8.10:

[...] to obtain a haskell evelopment shell for GHC 8.10.7 including [...]

[macOS] Add package/sign/notarise script

Signing and notarisation needs keys, and likely needs to be done on some separate machine.
The best would be if we had a script that could be copied alongside some files and then shipped
to the target machine, where running it would provide some minor UI to select the signing key,
and notarisation credentials; do the signing and then provide the artefact (stapled?) to be shipped somewhere.

[ci] hydra

Should add this to hydra, so that we get the compilers and everything pre-built.

Cabal build not locating installed packages

I've created a development environment using the following command:

nix develop github:input-output-hk/devx#ghc92 --no-write-lock-file --refresh

But after installing packages my project is dependent on using cabal install ... and try to build my project, it gives an error that points to the package not existing.

Indeed, when I ran ghc-pkg list, the package isn't listed there, but in the $CABAL_DIR/packages/hackage... folder, the installed package is there.

Any help would be appreciated.

[devx] enable merge queues

We want to ensure that hydra has run prior to GHA. The idea here is to use merge queue. GHA's only run on main.
However hydra would run on the merge-queue branch, and thus ensure that all the hydra artifacts are built beforehand.

Add sentinel job

We often need to know if all jobs have been built. Currently we don't at best we could check for hydra-statuses and ensure that no pending ones are left. That's fairly unergonomic.

https://determinate.systems/posts/hydra-deployment-source-of-truth might help with the aggregate job. The question is whether or not that aggregate job ends up pulling all the constituents onto the aggregate building machine.

main vs development branch

As we are now having more and more users, we need to be a bit more cautious about breaking main.

As such I suggest we start having a develop branch, and make main highly protected. Only merge to main when an extended CI suite has passed from develop?

@hamishmack @yvan-sraka @andreabedini thoughts?

`trusted-users` allows running commands as root without password (in `README.md`)

Adding a user to trusted-users essentially gives them passwordless root access when used in combination with post-build-hook (which users can add at will). This is especially problematic if accept-flake-config = true; is added to nix.conf, because it will allow any flake build unauthenticated root access.

I believe the only reason trusted-users is being used is to set up binary caches -- if this is the case, we should add instructions on setting up binary caches in a different way.

N.B.: cachix currently recommends adding your user as a trusted-user to set up the binary cache. A similar issue has been raised on that repo here. This means that there will most likely be a new "best practice" recommendation from cachix, which this repo should ostensibly follow.

Improve DevX readme

It should have a table and explain the differences between the different -xxx extensions.

Support more GHC versions?

Do we agree on the only 3 GHC versions currently offered by input-output-hk/devx are only ghc8107, ghc902, and ghc925?

That’s the only 3 versions that show up when I inspect devShell.x86_64-linux on

nix repl --extra-experimental-features 'flakes repl-flake' 'github:input-output-hk/devx'

[ci] add ci logic

We should have CI that ensure we can build a trival (and maybe not so trivial) application with all compiler selections, on the supported Operating Systems. Some that come to mind are

  • node
  • db-sync
  • wallet

[DevX] Smoke tests for generic shells

To properly ensure all our environments work. Maybe we should build

  • cardano-node
  • db-sync
  • wallet
  • Marlowe

If we can build the leaf nodes, anything in-between should also work. I believe.

[engineering blog] devx / devx action / devx codespace

We should write a engineering.iog.io article about the devx repo that covers:

  • motivation (why do we care at all?)
  • basic haskell.nix understanding
  • usage as GitHub action (example)
  • nix usage of devx (example)
  • usage of the devx CodeSpaces (example)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.