Verified Commit 1032a015 authored by doshitan's avatar doshitan

Update nix page

parent 179a471e
......@@ -173,19 +173,51 @@ Package script dependencies:
#! /usr/bin/env nix-shell
#! nix-shell -i bash -p opusTools -p graphicsmagick -p file -p parallel -p flac
# do script things as normal
# do script things as normal, guaranteed the specified tools are available
```
Run Haskell as a script:
```bash
```haskell
#! /usr/bin/env nix-shell
#! nix-shell -i runghc -p "haskellPackages.ghcWithPackages (ps: with ps; [])"
main :: IO ()
main = putStrLn "Hello World!"
```
Pairs well with something like [turtle](https://hackage.haskell.org/package/turtle).
Pairs well with something like
[turtle](https://hackage.haskell.org/package/turtle), e.g.,
```haskell
#! /usr/bin/env nix-shell
#! nix-shell -i runghc -p "haskellPackages.ghcWithPackages (ps: with ps; [turtle])"
{-# LANGUAGE OverloadedStrings #-}
import Turtle
data Command = IncreaseVolume Int | DecreaseVolume Int deriving (Show)
parser :: Parser Command
parser
= fmap IncreaseVolume
(subcommand "up" "Turn the volume up"
(argInt "amount" "How much to increase the volume") )
<|> fmap DecreaseVolume
(subcommand "down" "Turn the volume down"
(argInt "amount" "How much to decrease the volume") )
main = do
x <- options "Volume adjuster" parser
case x of
IncreaseVolume n -> printf ("Increasing the volume by "%d%"\n") n
DecreaseVolume n -> printf ("Decreasing the volume by "%d%"\n") n
```
Write your bash scripts...in Haskell!
Example taken from the end of the last section of the [Turtle
tutorial](https://hackage.haskell.org/package/turtle-1.5.14/docs/Turtle-Tutorial.html#g:18).
# nix + direnv
......@@ -213,6 +245,24 @@ shell](https://github.com/direnv/direnv/wiki/Nix#persistent-shell-for-speeding-t
for nix with direnv.
# Language-specific things
Many languages have to tooling to automate packaging with nix, e.g.,
`cabal2nix`, `pypi2nix`, etc. For a more complete list see [the wiki
page](https://nixos.wiki/wiki/Language-specific_package_helpers).
This support is uneven across languages, largely dependent on how many nix users
there are who give their time to improve and maintain that languages
infrastructure. Some languages are also more or less hostile to packaging in the
nix way, some have more non-determinism or poor dependency
tracking/specification, which complicate making easy tooling for it.
[Chapter 9 of the nixpkgs
manual](https://nixos.org/nixpkgs/manual/#chap-language-support) has more
details on a numbers of different languages, development tips, troubleshooting,
etc.
# Haskell
The Haskell infrastructure in nix is extensive, the [section in the
......@@ -223,7 +273,7 @@ is a useful read.
## Basic dev environment
Probably the quickest way to get going developing a Haskell package is with
[haskellPackges.developPackage](https://github.com/NixOS/nixpkgs/blob/f3282c8d1e0ce6ba5d9f6aeddcfad51d879c7a4a/pkgs/development/haskell-modules/make-package-set.nix#L215):
[haskellPackages.developPackage](https://github.com/NixOS/nixpkgs/blob/f3282c8d1e0ce6ba5d9f6aeddcfad51d879c7a4a/pkgs/development/haskell-modules/make-package-set.nix#L215):
Have a cabal file for your project, then your `default.nix` can just be:
......@@ -254,6 +304,100 @@ There's a little more on this in [the
manual](https://nixos.org/nixpkgs/manual/#how-to-specify-source-overrides-for-your-haskell-package),
particularly for when you need to override a dependencies packaged version.
## Improved setup
While `haskellPackages.developPackage` is pretty easy, for any non-trivial
project, you are probably going to want a little more control over the shell
environment.
In your `default.nix`, extend the Haskell package set to include the project packages:
```{.nix caption="default.nix"}
{ pkgs ? import <nixpkgs> {} }:
let
haskellPackages = pkgs.haskellPackages.extend (pkgs.haskell.lib.packageSourceOverrides {
# your Haskell packages for the project
foo = ./foo;
bar = ./bar;
# for a simple project with only one package at the top-level, this might be
# baz = ./.;
# fetch free version 5.0.2 from Hackage instead of what is in `pkgs`,
# `packageSourceOverrides` wraps this in a `callHackage` call
free = "5.0.2";
});
in {
inherit pkgs haskellPackages;
# same as if we'd written:
# pkgs = pkgs;
# haskellPackages = haskellPackages;
# make the project package a top level attributes for easier building, e.g.,
# nix-build -A foo
#
# instead of
#
# nix-build -A haskellPackages.foo
foo = haskellPackages.foo;
bar = haskellPackages.bar;
}
```
Then utilize the `haskellPackages.shellFor` function to build a more
configurable development environment in your `shell.nix`:
```{.nix caption="shell.nix"}
let
project = import ./. {};
in
project.haskellPackages.shellFor {
# dependencies for the listed packages will all be available in the shell
packages = p: [p.foo p.bar];
# build a local hoogle database for all the dependencies of the given
# packages, the hoogle executable in the shell environment will be set to
# use it automatically
# withHoogle = true;
# list any other things you want available in the shell
buildInputs = [
project.haskellPackages.cabal-install
# project.haskellPackages.ghcid
# ...whatever other Haskell dev tools you need
# project.pkgs.niv
# project.pkgs.gnumake
# project.pkgs.terraform
# ...whatever other general dev tools you need
];
}
```
Adapted from [this
comment](https://www.reddit.com/r/haskell/comments/8fnlhq/little_tool_for_haskell_environment_with_nix/dy58z4a/).
This is a simplified example, just trying to get the basic idea across.
You can get fancier, automatically pickup the project packages from the
`cabal.project`, and such, see [this
gist](https://gist.github.com/codebje/000df013a2a4b7c10d6014d8bf7bccf3) for an
example.
See the documentation on
[haskellPackages.shellFor](https://github.com/NixOS/nixpkgs/blob/713a45ecf79a4b4c632819f1c898d3e66c77bdd2/pkgs/development/haskell-modules/make-package-set.nix#L253)
and
[haskell.lib.packageSourceOverrides](https://github.com/NixOS/nixpkgs/blob/713a45ecf79a4b4c632819f1c898d3e66c77bdd2/pkgs/development/haskell-modules/lib.nix#L43)
for more on what is actually going on.
# Learning Nix
<https://learnxinyminutes.com/docs/nix/>
<https://github.com/tazjin/nix-1p/blob/master/README.md>
<https://nixos.org/nixos/nix-pills/>
# Nix: Under the hood
......@@ -264,16 +408,88 @@ Good talk covering the basics of how nix works, simply.
# Test your NixOS config
https://twitter.com/IotaSamurai/status/1045220406792048640
```
nix repl '<nixpkgs/nixos>'
```
You can poke at your config without having to `nixos-rebuild`.
You can poke at your config without having to `nixos-rebuild`, with TAB
complete.
The `config` attribute holds your system config. `pkgs` allows you to look at
the packages in that version of the system.
<https://twitter.com/IotaSamurai/status/1045220406792048640>
<https://nixos.wiki/wiki/Nix-repl>
# NixOS options
There are a lot of configuration options supported by NixOS. The [options search
page on the website](https://nixos.org/nixos/options.html) is useful to find a)
if the thing you want to configure has been packaged as a service in NixOS and
b) what knobs you can turn for it.
One nice thing about the search tool is that it links directly to the source
file for the service, so you can inspect what is actually happening with the
option if you want to.
Note that currently, the website search tool only shows options for the latest
stable release, if you are living on the edge, you'll have to search nixpkgs
yourself, either grep a local copy of the repo, search GitHub, or use
`nixos-option`.
`nixos-option` evaluates your NixOS config and will display all the attributes
in a given attribute set available for it. For example:
```
nixos-option services.postgresql
```
Will show all the attributes you can set to configure the postgres service. It
unfortunately does not display the description when listing the attributes
(though hopefully is at least broadly clear in the name itself), but if you
specify a specific one, like:
```
nixos-option services.postgresql.dataDir
```
Then it will display more complete documentation for it, including the current
value in your configuration, the default, a description of what the option is
for, and a file path for module it's declared in.
The website search is nicer, but `nixos-option` works offline and can be helpful
as it does display the currently set value for *your* configuration. The repl is
usually better to explore your evaluated configuration, given it has TAB
complete, but sometimes `nixos-option` is more useful.
# Finding Nix packages
`nix search <name>` or <https://nixos.org/nixos/packages.html>
# Cheatsheet
The [NixOS
cheatsheet](https://nixos.wiki/index.php?title=Cheatsheet&useskin=vector) has a
bunch of stuff that is useful to look over, including a table comparing how you
would do something in Ubuntu and the equivalent command on NixOS.
It also has a bunch of short little snippets about how to do various things,
cross-compile a package, and other similar tasks.
# LaTeX
Arbitrary, one-off environments:
`nix-shell -E 'with import <nixpkgs> {}; mkShell { buildInputs = [(texlive.combine { inherit (pkgs.texlive) scheme-small standalone latexmk cm-super; })]; }'`
# Misc.
- <https://cachix.org/>
- <https://hercules-ci.com/>
- <https://nixery.dev/>
- <https://r13y.com/>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment