diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index d99c5f59ba..11a35a804c 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -27,7 +27,7 @@ jobs: submodules: true - uses: cachix/install-nix-action@v12 with: - nix_path: nixpkgs=channel:nixos-20.03 + nix_path: nixpkgs=channel:nixos-unstable - uses: cachix/cachix-action@v8 with: name: haskell-language-server diff --git a/nix/default.nix b/nix/default.nix index 480c81ff0f..b4ad84068d 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -2,20 +2,27 @@ let nix-pre-commit-hooks = (import (builtins.fetchTarball "https://github.com/cachix/pre-commit-hooks.nix/tarball/master/" + "/nix/") { sources = sources; }).packages; overlay = _self: pkgs: - let sharedOverrides = { - overrides = _self: super: { - mkDerivation = args: super.mkDerivation (args // - { - # skip running tests for Hackage packages - doCheck = args.pname == "ghcide" || args.pname == "haskell-language-server"; - # relax upper bounds - jailbreak = args.pname != "jailbreak-cabal"; - }); - }; - }; - gitignoreSource = (import sources.gitignore { inherit (pkgs) lib; }).gitignoreSource; - extended = haskellPackages: - haskellPackages.extend (pkgs.haskell.lib.packageSourceOverrides { + let + sharedOverrides = { + overrides = _self: super: { + # we override mkDerivation here to apply the following + # tweak to each haskell package: + # if the package is broken, then we disable its check and relax the cabal bounds; + # otherwise, we leave it unchanged. + # hopefully, this could fix packages marked as broken by nix due to check failures + # or the build failure because of tight cabal bounds + mkDerivation = args: + let + broken = args.broken or false; + check = args.doCheck or true; + jailbreak = args.jailbreak or false; + in super.mkDerivation (args // { + jailbreak = if broken then true else jailbreak; + doCheck = if broken then false else check; + }); + }; + }; + ourSources = { haskell-language-server = gitignoreSource ../.; ghcide = gitignoreSource ../ghcide; shake-bench = gitignoreSource ../shake-bench; @@ -30,10 +37,26 @@ let hls-retrie-plugin = gitignoreSource ../plugins/hls-retrie-plugin; hls-splice-plugin = gitignoreSource ../plugins/hls-splice-plugin; hls-tactics-plugin = gitignoreSource ../plugins/hls-tactics-plugin; - }); + }; + gitignoreSource = (import sources.gitignore { inherit (pkgs) lib; }).gitignoreSource; + extended = haskellPackages: + haskellPackages.extend (pkgs.haskell.lib.packageSourceOverrides ourSources); in { inherit gitignoreSource; + inherit ourSources; + + # tracy-0.7.6 is broken on macOS + tracy = pkgs.tracy.overrideAttrs (_old: rec { + version = "0.7.5"; + src = pkgs.fetchFromGitHub { + owner = "wolfpld"; + repo = "tracy"; + rev = "v${version}"; + sha256 = "0qfb30k6a8vi8vn65vv927wd9nynwwvc9crbmi7a55kp20hzg06r"; + }; + }); + ourHaskell = pkgs.haskell // { packages = pkgs.haskell.packages // { # relax upper bounds on ghc 8.10.x versions (and skip running tests) diff --git a/nix/sources.json b/nix/sources.json index e87f2e692e..210fcffde3 100644 --- a/nix/sources.json +++ b/nix/sources.json @@ -5,10 +5,10 @@ "homepage": "", "owner": "hercules-ci", "repo": "gitignore", - "rev": "c4662e662462e7bf3c2a968483478a665d00e717", - "sha256": "1npnx0h6bd0d7ql93ka7azhj40zgjp815fw2r6smg8ch9p7mzdlx", + "rev": "211907489e9f198594c0eb0ca9256a1949c9d412", + "sha256": "06j7wpvj54khw0z10fjyi31kpafkr6hi1k0di13k1xp8kywvfyx8", "type": "tarball", - "url": "https://github.com/hercules-ci/gitignore/archive/c4662e662462e7bf3c2a968483478a665d00e717.tar.gz", + "url": "https://github.com/hercules-ci/gitignore/archive/211907489e9f198594c0eb0ca9256a1949c9d412.tar.gz", "url_template": "https://github.com///archive/.tar.gz" }, "niv": { @@ -17,22 +17,22 @@ "homepage": "https://github.com/nmattia/niv", "owner": "nmattia", "repo": "niv", - "rev": "89ae775e9dfc2571f912156dd2f8627e14d4d507", - "sha256": "0ssw6byyn79fpyzswi28s5b85x66xh4xsfhmcfl5mkdxxpmyy0ns", + "rev": "af958e8057f345ee1aca714c1247ef3ba1c15f5e", + "sha256": "1qjavxabbrsh73yck5dcq8jggvh3r2jkbr6b5nlz5d9yrqm9255n", "type": "tarball", - "url": "https://github.com/nmattia/niv/archive/89ae775e9dfc2571f912156dd2f8627e14d4d507.tar.gz", + "url": "https://github.com/nmattia/niv/archive/af958e8057f345ee1aca714c1247ef3ba1c15f5e.tar.gz", "url_template": "https://github.com///archive/.tar.gz" }, "nixpkgs": { - "branch": "haskell-updates", + "branch": "nixpkgs-unstable", "description": "A read-only mirror of NixOS/nixpkgs tracking the released channels. Send issues and PRs to", "homepage": "https://github.com/NixOS/nixpkgs", "owner": "NixOS", "repo": "nixpkgs", - "rev": "8911c99c2f1bf44210be7ff35314430f02f0f33d", - "sha256": "06mi91yxidjyyrc7q5dbi1j8bxi2iird0ivqcnb4kiglpw0ivpkr", + "rev": "c5147860e23ed75ce9d40298c66b416c00be1167", + "sha256": "104mw4rfbzyrfkxq468dlk38drrjx92dgyvkazgci67a6cx3n6nx", "type": "tarball", - "url": "https://github.com/NixOS/nixpkgs/archive/8911c99c2f1bf44210be7ff35314430f02f0f33d.tar.gz", + "url": "https://github.com/NixOS/nixpkgs/archive/c5147860e23ed75ce9d40298c66b416c00be1167.tar.gz", "url_template": "https://github.com///archive/.tar.gz" } } diff --git a/nix/sources.nix b/nix/sources.nix index b64b8f821a..1938409ddd 100644 --- a/nix/sources.nix +++ b/nix/sources.nix @@ -6,25 +6,33 @@ let # The fetchers. fetch_ fetches specs of type . # - fetch_file = pkgs: spec: - if spec.builtin or true then - builtins_fetchurl { inherit (spec) url sha256; } - else - pkgs.fetchurl { inherit (spec) url sha256; }; + fetch_file = pkgs: name: spec: + let + name' = sanitizeName name + "-src"; + in + if spec.builtin or true then + builtins_fetchurl { inherit (spec) url sha256; name = name'; } + else + pkgs.fetchurl { inherit (spec) url sha256; name = name'; }; fetch_tarball = pkgs: name: spec: let - ok = str: ! builtins.isNull (builtins.match "[a-zA-Z0-9+-._?=]" str); - # sanitize the name, though nix will still fail if name starts with period - name' = stringAsChars (x: if ! ok x then "-" else x) "${name}-src"; + name' = sanitizeName name + "-src"; in if spec.builtin or true then builtins_fetchTarball { name = name'; inherit (spec) url sha256; } else pkgs.fetchzip { name = name'; inherit (spec) url sha256; }; - fetch_git = spec: - builtins.fetchGit { url = spec.repo; inherit (spec) rev ref; }; + fetch_git = name: spec: + let + ref = + if spec ? ref then spec.ref else + if spec ? branch then "refs/heads/${spec.branch}" else + if spec ? tag then "refs/tags/${spec.tag}" else + abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!"; + in + builtins.fetchGit { url = spec.repo; inherit (spec) rev; inherit ref; }; fetch_local = spec: spec.path; @@ -40,11 +48,21 @@ let # Various helpers # + # https://github.com/NixOS/nixpkgs/pull/83241/files#diff-c6f540a4f3bfa4b0e8b6bafd4cd54e8bR695 + sanitizeName = name: + ( + concatMapStrings (s: if builtins.isList s then "-" else s) + ( + builtins.split "[^[:alnum:]+._?=-]+" + ((x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0) name) + ) + ); + # The set of packages used when specs are fetched using non-builtins. - mkPkgs = sources: + mkPkgs = sources: system: let sourcesNixpkgs = - import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) {}; + import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) { inherit system; }; hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath; hasThisAsNixpkgsPath = == ./.; in @@ -64,9 +82,9 @@ let if ! builtins.hasAttr "type" spec then abort "ERROR: niv spec ${name} does not have a 'type' attribute" - else if spec.type == "file" then fetch_file pkgs spec + else if spec.type == "file" then fetch_file pkgs name spec else if spec.type == "tarball" then fetch_tarball pkgs name spec - else if spec.type == "git" then fetch_git spec + else if spec.type == "git" then fetch_git name spec else if spec.type == "local" then fetch_local spec else if spec.type == "builtin-tarball" then fetch_builtin-tarball name else if spec.type == "builtin-url" then fetch_builtin-url name @@ -80,7 +98,10 @@ let saneName = stringAsChars (c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name; ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}"; in - if ersatz == "" then drv else ersatz; + if ersatz == "" then drv else + # this turns the string into an actual Nix path (for both absolute and + # relative paths) + if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}"; # Ports of functions for older nix versions @@ -98,25 +119,29 @@ let # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269 stringAsChars = f: s: concatStrings (map f (stringToCharacters s)); + concatMapStrings = f: list: concatStrings (map f list); concatStrings = builtins.concatStringsSep ""; + # https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331 + optionalAttrs = cond: as: if cond then as else {}; + # fetchTarball version that is compatible between all the versions of Nix - builtins_fetchTarball = { url, name, sha256 }@attrs: + builtins_fetchTarball = { url, name ? null, sha256 }@attrs: let inherit (builtins) lessThan nixVersion fetchTarball; in if lessThan nixVersion "1.12" then - fetchTarball { inherit name url; } + fetchTarball ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; })) else fetchTarball attrs; # fetchurl version that is compatible between all the versions of Nix - builtins_fetchurl = { url, sha256 }@attrs: + builtins_fetchurl = { url, name ? null, sha256 }@attrs: let inherit (builtins) lessThan nixVersion fetchurl; in if lessThan nixVersion "1.12" then - fetchurl { inherit url; } + fetchurl ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; })) else fetchurl attrs; @@ -135,7 +160,8 @@ let mkConfig = { sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null , sources ? if isNull sourcesFile then {} else builtins.fromJSON (builtins.readFile sourcesFile) - , pkgs ? mkPkgs sources + , system ? builtins.currentSystem + , pkgs ? mkPkgs sources system }: rec { # The sources, i.e. the attribute set of spec name to spec inherit sources; diff --git a/shell.nix b/shell.nix index 74fc01ba22..ef8b0a039d 100644 --- a/shell.nix +++ b/shell.nix @@ -4,9 +4,7 @@ # Maintaining this file: # # - Bump the nixpkgs version using `niv update nixpkgs` -# - To edit the set of local packages: -# 1. Declare them in nix/default.nix -# 2. Edit the list of packages below +# - Edit `ourSources` (in nix/default.nix) to update the set of local packages # # For more details: https://github.com/NixOS/nixpkgs/blob/20.03/pkgs/development/haskell-modules/make-package-set.nix#L256 @@ -24,21 +22,7 @@ let defaultCompiler = "ghc" + lib.replaceStrings ["."] [""] haskellPackages.ghc. then ourHaskell.packages.${defaultCompiler} else ourHaskell.packages.${compiler}; - packages = p: [ p.haskell-language-server - p.ghcide - p.shake-bench - p.hie-compat - p.hls-plugin-api - p.hls-brittany-plugin - p.hls-class-plugin - p.hls-haddock-comments-plugin - p.hls-eval-plugin - p.hls-explicit-imports-plugin - p.hls-hlint-plugin - p.hls-retrie-plugin - p.hls-splice-plugin - p.hls-tactics-plugin - ]; + packages = p: with builtins; map (name: p.${name}) (attrNames ourSources); isSupported = compiler == "default" || compiler == defaultCompiler; in