| 1 | # Nix shell expression for the oil shell (formatted with nixfmt)
 | 
| 2 | #   Note: run `nixfmt shell.nix` in nix-shell to reformat in-place
 | 
| 3 | #
 | 
| 4 | # By default fetch the most-recent 19.09 version of the stable NixOS release.
 | 
| 5 | # This should be fine, but if it causes trouble it can be pinned to ensure
 | 
| 6 | # everyone is running exactly the same versions.
 | 
| 7 | { nixpkgs ? fetchTarball "channel:nixos-19.09", dev ? "all", test ? "smoke"
 | 
| 8 | , cleanup ? true }:
 | 
| 9 | 
 | 
| 10 | let
 | 
| 11 |   # Import the package set.
 | 
| 12 |   pkgs = import nixpkgs { };
 | 
| 13 | 
 | 
| 14 |   # Added the following 3 declarations (and parameters/defaults above) to
 | 
| 15 |   # demonstrate how you could make the behavior a little configurable.
 | 
| 16 |   #
 | 
| 17 |   # By default, it will run:
 | 
| 18 |   # - "all" dev build (--argstr dev minimal or none to disable)
 | 
| 19 |   # - the "smoke" tests (--argstr test osh-all or none to disable)
 | 
| 20 |   # - and clean on exit (ex: --argstr cleanup none to disable)
 | 
| 21 |   build_oil = if dev == "none" then
 | 
| 22 |     "echo Skipping Oil build."
 | 
| 23 |   else ''
 | 
| 24 |     echo Building \'${dev}\' Oil.
 | 
| 25 |     "$PWD/build/py.sh" ${dev}
 | 
| 26 |   '';
 | 
| 27 |   test_oil = if test == "none" then
 | 
| 28 |     "echo Skipping Oil tests."
 | 
| 29 |   else ''
 | 
| 30 |     echo Running Oil \'${test}\' tests.
 | 
| 31 |     "$PWD/test/spec.sh" ${test}
 | 
| 32 |   '';
 | 
| 33 |   cleanup_oil = if cleanup == "none" then ''
 | 
| 34 |     echo "Note: nix-shell will *NOT* clean up Oil dev build on exit!"
 | 
| 35 |     trap 'echo "NOT cleaning up Oil dev build."' EXIT
 | 
| 36 |   '' else ''
 | 
| 37 |     echo "Note: nix-shell will clean up the dev build on exit."
 | 
| 38 |     trap 'echo "Cleaning up Oil dev build."; "$PWD/build/clean.sh"' EXIT
 | 
| 39 |   '';
 | 
| 40 | in with pkgs;
 | 
| 41 | 
 | 
| 42 | let
 | 
| 43 |   # Most of the items you listed in #513 are here now. I'm not sure what the
 | 
| 44 |   # remaining items here mean, so I'm not sure if they're covered.
 | 
| 45 |   #
 | 
| 46 |   # static analysis
 | 
| 47 |   #   mypy library for mycpp
 | 
| 48 |   # benchmarks
 | 
| 49 |   #   ocaml configure, etc. This is just source though.
 | 
| 50 |   # C deps
 | 
| 51 |   #   python headers for bootstrapping
 | 
| 52 |   # big one: Clang for ASAN and other sanitizers (even though GCC has some)
 | 
| 53 |   #   Clang for coverage too
 | 
| 54 | 
 | 
| 55 |   # nixpkgs: busybox linux only; no smoosh
 | 
| 56 |   # could append something like: ++ lib.optionals stdenv.isLinux [ busybox ]
 | 
| 57 |   spec_tests = [ bash dash mksh zsh busybox ];
 | 
| 58 | 
 | 
| 59 |   static_analysis = [
 | 
| 60 |     mypy # This is the Python 3 version
 | 
| 61 |     (python2.withPackages (ps: with ps; [ flake8 pyannotate ]))
 | 
| 62 |     # python3Packages.black # wink wink :)
 | 
| 63 |   ];
 | 
| 64 | 
 | 
| 65 |   binary = [ re2c ];
 | 
| 66 |   doctools = [ cmark ];
 | 
| 67 |   c_deps = [ readline ];
 | 
| 68 | 
 | 
| 69 |   shell_deps = [
 | 
| 70 |     gawk
 | 
| 71 |     time
 | 
| 72 |     # additional command dependencies I found as I went
 | 
| 73 |     # guessing they go here...
 | 
| 74 |     # run with nix-shell --pure to make missing deps easier to find!
 | 
| 75 |     file
 | 
| 76 |     git
 | 
| 77 |     hostname
 | 
| 78 |     which
 | 
| 79 |   ];
 | 
| 80 | 
 | 
| 81 |   nix_deps = [
 | 
| 82 |     nixfmt # `nixfmt shell.nix` to format in place
 | 
| 83 |   ];
 | 
| 84 | 
 | 
| 85 |   # Create a shell with packages we need.
 | 
| 86 | in mkShell rec {
 | 
| 87 | 
 | 
| 88 |   buildInputs = c_deps ++ binary ++ spec_tests ++ static_analysis ++ doctools
 | 
| 89 |     ++ shell_deps ++ nix_deps ++ doctools;
 | 
| 90 | 
 | 
| 91 |   # Not sure if this is "right" (for nix, other platforms, etc.)
 | 
| 92 |   # doctools/cmark.py hardcoded /usr/local/lib/libcmark.so, and it looks
 | 
| 93 |   # like Nix has as much trouble with load_library as you have. For a
 | 
| 94 |   # "build" I think we'd use a patchPhase to replace the hard path
 | 
| 95 |   # in cmark.py with the correct one. Since we can't patch the source here
 | 
| 96 |   # I'm hacking an env in here and in cmark.py. Hopefully others will
 | 
| 97 |   # weigh in if there's a better way to handle this.
 | 
| 98 |   #
 | 
| 99 |   # Note: Nix automatically adds identifiers declared here to the environment!
 | 
| 100 |   _NIX_SHELL_LIBCMARK = "${cmark}/lib/libcmark${stdenv.hostPlatform.extensions.sharedLibrary}";
 | 
| 101 | 
 | 
| 102 |   # Need nix to relax before it'll link against a local file.
 | 
| 103 |   NIX_ENFORCE_PURITY = 0;
 | 
| 104 | 
 | 
| 105 |   # Note: failing spec test with either of these LOCALE_ARCHIVE settings.
 | 
| 106 |   #
 | 
| 107 |   # $ test/spec.sh oil-options -r 0 -v
 | 
| 108 |   # if libc.fnmatch(pat_val.s, to_match):
 | 
| 109 |   #  SystemError: Invalid locale for LC_CTYPE
 | 
| 110 |   LOCALE_ARCHIVE =
 | 
| 111 |     if stdenv.isLinux then "${glibcLocales}/lib/locale/locale-archive" else "";
 | 
| 112 | 
 | 
| 113 |   # a different option:
 | 
| 114 |   # LOCALE_ARCHIVE = lib.optionalString (stdenv.hostPlatform.libc == "glibc") "${glibcLocales}/lib/locale/locale-archive";
 | 
| 115 | 
 | 
| 116 |   # do setup work you want to do every time you enter the shell
 | 
| 117 |   # Here are a few ideas that made sense to me:
 | 
| 118 |   shellHook = ''
 | 
| 119 |     if [[ ! -a "$PWD/py-yajl/setup.py" ]]; then
 | 
| 120 |       git submodule update --init --recursive
 | 
| 121 |     fi
 | 
| 122 | 
 | 
| 123 |     if [[ ! -a "$PWD/libc.so" ]]; then
 | 
| 124 |       ${build_oil}
 | 
| 125 |       ${test_oil}
 | 
| 126 |     else
 | 
| 127 |       echo "Dev build already exists. If you made changes, run:"
 | 
| 128 |       echo "    'build/clean.sh' and "
 | 
| 129 |       echo "    'build/py.sh all' or 'build/py.sh minimal'"
 | 
| 130 |     fi
 | 
| 131 | 
 | 
| 132 |     ${cleanup_oil}
 | 
| 133 |   '';
 | 
| 134 | }
 |