From 92ec21106806ad341609844e78616b8b23be387f Mon Sep 17 00:00:00 2001 From: Peter Becich Date: Mon, 6 Sep 2021 16:00:37 -0700 Subject: [PATCH 1/3] basic GitHub Actions --- .github/workflows/ci.yml | 62 ++++++++++++++++++++++++++++++++++++++++ README.md | 1 + 2 files changed, 63 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..106b8adc8 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,62 @@ +# modified from https://github.com/jgm/pandoc/blob/master/.github/workflows/ci.yml +name: CI + +on: + push: + branches: + - '**' + paths-ignore: [] + pull_request: + paths-ignore: [] + +jobs: + linux: + + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + versions: + - ghc: '8.6.5' + cabal: '3.4' + steps: + - uses: actions/checkout@v2 + + # need to install older cabal/ghc versions from ppa repository + + - name: Install recent cabal/ghc + uses: haskell/actions/setup@v1 + with: + ghc-version: ${{ matrix.versions.ghc }} + cabal-version: ${{ matrix.versions.cabal }} + + # declare/restore cached things + # caching doesn't work for scheduled runs yet + # https://github.com/actions/cache/issues/63 + + - name: Cache cabal global package db + id: cabal-global + uses: actions/cache@v2 + with: + path: | + ~/.cabal + key: ${{ runner.os }}-${{ matrix.versions.ghc }}-${{ matrix.versions.cabal }}-cabal-global-${{ hashFiles('cabal.project') }} + + - name: Cache cabal work + id: cabal-local + uses: actions/cache@v2 + with: + path: | + dist-newstyle + key: ${{ runner.os }}-${{ matrix.versions.ghc }}-${{ matrix.versions.cabal }}-cabal-local + + - name: Install dependencies + run: | + cabal update + cabal build all --dependencies-only --enable-tests --disable-optimization + - name: Build + run: | + cabal build all --enable-tests --disable-optimization 2>&1 | tee build.log + # - name: Test # needs GHCJS + # run: | + # cabal test all --disable-optimization diff --git a/README.md b/README.md index 8c98f3547..c127b74f7 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ CodeWorld ========= [![Build Status](https://travis-ci.org/google/codeworld.svg?branch=master)](https://travis-ci.org/google/codeworld) +[![Build status](https://github.com/google/codeworld/actions/workflows/ci.yml/badge.svg)](https://github.com/google/codeworld/actions/workflows/ci.yml) CodeWorld is an educational environment using Haskell. It provides a simple mathematical model for geometric figures, animations, and interactive and From 4324b5ff4711c3ae1c52ee0c9e7d6b370de805be Mon Sep 17 00:00:00 2001 From: Peter Becich Date: Sun, 12 Sep 2021 22:13:21 -0700 Subject: [PATCH 2/3] GHC 8.10.7 and Nix support using https://github.com/input-output-hk/haskell.nix --- .github/workflows/ci.yml | 2 +- cabal.project | 3 + codeworld-api/codeworld-api.cabal | 8 +- codeworld-base/src/Parameter.hs | 2 +- codeworld-compiler/codeworld-compiler.cabal | 8 +- .../src/CodeWorld/Compile/Framework.hs | 93 ++++++++-- .../CodeWorld/Compile/Requirements/Eval.hs | 27 ++- .../CodeWorld/Compile/Requirements/Matcher.hs | 3 +- .../src/CodeWorld/Compile/Stages.hs | 2 +- .../codeworld-error-sanitizer.cabal | 6 +- .../codeworld-requirements.cabal | 2 +- codeworld-server/codeworld-server.cabal | 2 +- default.nix | 15 ++ nix/sources.json | 38 ++++ nix/sources.nix | 174 ++++++++++++++++++ 15 files changed, 353 insertions(+), 32 deletions(-) create mode 100644 default.nix create mode 100644 nix/sources.json create mode 100644 nix/sources.nix diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 106b8adc8..7f670039c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: fail-fast: false matrix: versions: - - ghc: '8.6.5' + - ghc: '8.10.7' cabal: '3.4' steps: - uses: actions/checkout@v2 diff --git a/cabal.project b/cabal.project index 9466eccf8..91d2e63b0 100644 --- a/cabal.project +++ b/cabal.project @@ -10,3 +10,6 @@ packages: codeworld-server/ codeworld-base/ funblocks-client/ + +constraints: + ghcjs-dom ==0.9.* diff --git a/codeworld-api/codeworld-api.cabal b/codeworld-api/codeworld-api.cabal index a7f731030..658c38730 100644 --- a/codeworld-api/codeworld-api.cabal +++ b/codeworld-api/codeworld-api.cabal @@ -61,7 +61,7 @@ Library mtl >= 2.2.1 && < 2.3, random >= 1.1 && < 1.2, ref-tf >= 0.4 && < 0.5, - reflex >= 0.6.3 && < 0.7, + reflex >= 0.6.3, template-haskell >= 2.8 && < 2.18, text >= 1.2.2 && < 1.3, time >= 1.8 && < 2.0, @@ -73,7 +73,7 @@ Library ghcjs-prim, codeworld-game-api, codeworld-prediction, - ghcjs-dom >= 0.9 && < 0.9.4, + ghcjs-dom >= 0.9, transformers else Build-depends: blank-canvas >= 0.6 && < 0.8, @@ -122,7 +122,7 @@ Test-suite unit-tests mtl >= 2.2.1 && < 2.3, random >= 1.1 && < 1.2, ref-tf >= 0.4 && < 0.5, - reflex >= 0.6.3 && < 0.7, + reflex >= 0.6.3, template-haskell >= 2.8 && < 2.18, text >= 1.2.2 && < 1.3, time >= 1.8 && < 2.0, @@ -134,7 +134,7 @@ Test-suite unit-tests ghcjs-prim, codeworld-game-api, codeworld-prediction, - ghcjs-dom >= 0.9 && < 0.9.4, + ghcjs-dom >= 0.9, transformers else Build-depends: blank-canvas >= 0.6 && < 0.8, diff --git a/codeworld-base/src/Parameter.hs b/codeworld-base/src/Parameter.hs index cf5e0ae4e..e69d4279e 100644 --- a/codeworld-base/src/Parameter.hs +++ b/codeworld-base/src/Parameter.hs @@ -44,7 +44,7 @@ import qualified CodeWorld.Parameter as CW import Internal.Picture import Internal.Text import Prelude -import "base" Prelude ((.), map) +import "base" Prelude (map, (.)) -- | A drawing that depends on parameters. The first argument is a -- list of parameters. The second is a picture, which depends on the diff --git a/codeworld-compiler/codeworld-compiler.cabal b/codeworld-compiler/codeworld-compiler.cabal index 75ed47614..1868ff44d 100644 --- a/codeworld-compiler/codeworld-compiler.cabal +++ b/codeworld-compiler/codeworld-compiler.cabal @@ -54,16 +54,18 @@ Library directory, exceptions, filepath, - ghc == 8.6.5, - ghc-boot-th == 8.6.5, + ghc == 8.10.*, + ghc-boot, + ghc-boot-th == 8.10.*, + ghc-lib-parser, hashable, haskell-src-exts >= 1.20, megaparsec >= 7.0.0 && < 8.0.0, memory, mtl, process, + regex-base, regex-tdfa, - regex-tdfa-text, split, syb, temporary, diff --git a/codeworld-compiler/src/CodeWorld/Compile/Framework.hs b/codeworld-compiler/src/CodeWorld/Compile/Framework.hs index d7e4d417b..5d1c7bc7c 100644 --- a/codeworld-compiler/src/CodeWorld/Compile/Framework.hs +++ b/codeworld-compiler/src/CodeWorld/Compile/Framework.hs @@ -56,16 +56,22 @@ import qualified "ghc" FastString as GHC import qualified "ghc" Fingerprint as GHC import qualified "ghc-boot-th" GHC.LanguageExtensions.Type as GHC import qualified "ghc" HeaderInfo as GHC -import qualified "ghc" HsExtension as GHC -import qualified "ghc" HsSyn as GHC +import qualified "ghc" GHC.Hs.Extension as GHC +import qualified "ghc" GHC.Hs as GHC +import qualified "ghc" RdrHsSyn as GHC +import qualified "ghc" TcHsSyn as GHC import qualified "ghc" HscTypes as GHC import Language.Haskell.Exts import qualified "ghc" Lexer as GHC +import qualified "ghc" Fingerprint as GHC import qualified "ghc" Module as GHC import qualified "ghc" Outputable as GHC import qualified "ghc" Panic as GHC import qualified "ghc" Parser as GHC -import qualified "ghc" Platform as GHC +import qualified "ghc" GhcNameVersion as GHC +import qualified "ghc" FileSettings as GHC +import qualified "ghc" ToolSettings as GHC +import qualified "ghc-boot" GHC.Platform as GHC import qualified "ghc" SrcLoc as GHC import qualified "ghc" StringBuffer as GHC import System.Directory @@ -305,32 +311,95 @@ ghcParseCode extraExts src = do state = GHC.mkPState dflagsWithPragmas buffer location return $ case GHC.unP GHC.parseModule state of GHC.POk _ (GHC.L _ mod) -> GHCParsed mod - GHC.PFailed _ _ _ -> GHCNoParse + GHC.PFailed _ -> GHCNoParse fakeDynFlags :: GHC.DynFlags fakeDynFlags = GHC.defaultDynFlags fakeSettings fakeLlvmConfig +fakePlatformMisc :: GHC.PlatformMisc +fakePlatformMisc = GHC.PlatformMisc + mempty + mempty + GHC.IntegerSimple + False + False + False + mempty + False + False + False + False + False + False + mempty + +fakeToolSettings :: GHC.ToolSettings +fakeToolSettings = GHC.ToolSettings + True + True + True + True + True + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + (GHC.Fingerprint (read mempty) (read mempty)) + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + mempty + fakeSettings :: GHC.Settings fakeSettings = GHC.Settings - { GHC.sProgramName = "ghcjs", - GHC.sProjectVersion = GHC.cProjectVersion, + { GHC.sGhcNameVersion = GHC.GhcNameVersion "foo" "foo", + GHC.sFileSettings = GHC.FileSettings mempty mempty Nothing mempty mempty mempty, + GHC.sToolSettings = fakeToolSettings, GHC.sTargetPlatform = GHC.Platform - { GHC.platformWordSize = 8, - GHC.platformOS = GHC.OSUnknown, - GHC.platformUnregisterised = True + { GHC.platformWordSize = GHC.PW8, + GHC.platformMini = GHC.PlatformMini GHC.ArchX86_64 GHC.OSUnknown, + GHC.platformUnregisterised = True, + GHC.platformHasGnuNonexecStack = True, + GHC.platformIsCrossCompiling = True, + GHC.platformHasSubsectionsViaSymbols = True }, GHC.sPlatformConstants = GHC.PlatformConstants { GHC.pc_DYNAMIC_BY_DEFAULT = False, GHC.pc_WORD_SIZE = 8 }, - GHC.sOpt_P_fingerprint = GHC.fingerprint0 + GHC.sPlatformMisc = fakePlatformMisc } -fakeLlvmConfig :: (GHC.LlvmTargets, GHC.LlvmPasses) -fakeLlvmConfig = ([], []) +fakeLlvmConfig :: GHC.LlvmConfig +fakeLlvmConfig = GHC.LlvmConfig mempty mempty parsePragmasIntoDynFlags :: GHC.DynFlags -> diff --git a/codeworld-compiler/src/CodeWorld/Compile/Requirements/Eval.hs b/codeworld-compiler/src/CodeWorld/Compile/Requirements/Eval.hs index 4c5ece3db..489c1acd9 100644 --- a/codeworld-compiler/src/CodeWorld/Compile/Requirements/Eval.hs +++ b/codeworld-compiler/src/CodeWorld/Compile/Requirements/Eval.hs @@ -40,7 +40,27 @@ import Data.Hashable import Data.List import qualified Data.Text as T import Data.Void -import "ghc" HsSyn +import "ghc" GHC.Hs + ( GRHS (..), + GRHSs (..), + GhcPs, + GhciLStmt, + HsBind, + HsBindLR (..), + HsExpr (HsApp, HsLet, HsPar, HsVar), + HsModule (..), + ImportDecl, + LHsDecl, + LHsExpr, + LMatch, + Match (..), + MatchGroup (..), + Sig (TypeSig), + pprFunBind, + pprPatBind, + ) +import "ghc" GHC.Hs.Decls +import "ghc" GHC.Hs.Pat import qualified Language.Haskell.Exts as Exts import "ghc" Outputable import "ghc" SrcLoc @@ -192,8 +212,9 @@ checkRule (AllOf rules) = do return (concat <$> results) checkRule (AnyOf rules) = do results <- sequence <$> mapM checkRule rules - return $ (<$> results) $ \errs -> - if any null errs then [] else ["No alternatives succeeded."] + return $ + (<$> results) $ \errs -> + if any null errs then [] else ["No alternatives succeeded."] checkRule (NotThis rule) = do result <- checkRule rule case result of diff --git a/codeworld-compiler/src/CodeWorld/Compile/Requirements/Matcher.hs b/codeworld-compiler/src/CodeWorld/Compile/Requirements/Matcher.hs index c159b3bab..a3725150b 100644 --- a/codeworld-compiler/src/CodeWorld/Compile/Requirements/Matcher.hs +++ b/codeworld-compiler/src/CodeWorld/Compile/Requirements/Matcher.hs @@ -26,7 +26,8 @@ import Data.Generics import Data.Generics.Twins import Data.List import Data.Maybe -import "ghc" HsSyn +import "ghc" RdrHsSyn +import "ghc" GHC.Hs import "ghc" OccName import "ghc" RdrName import "ghc" SrcLoc diff --git a/codeworld-compiler/src/CodeWorld/Compile/Stages.hs b/codeworld-compiler/src/CodeWorld/Compile/Stages.hs index 30f3464d7..805d5afde 100644 --- a/codeworld-compiler/src/CodeWorld/Compile/Stages.hs +++ b/codeworld-compiler/src/CodeWorld/Compile/Stages.hs @@ -47,7 +47,7 @@ import Data.Monoid import Data.Text (Text, unpack) import Data.Text.Encoding (decodeUtf8) import qualified "ghc" FastString as GHC -import qualified "ghc" HsSyn as GHC +import qualified "ghc" GHC.Hs as GHC import Language.Haskell.Exts import qualified "ghc" Module as GHC import qualified "ghc" OccName as GHC diff --git a/codeworld-error-sanitizer/codeworld-error-sanitizer.cabal b/codeworld-error-sanitizer/codeworld-error-sanitizer.cabal index 95ad875b1..8940b32f7 100644 --- a/codeworld-error-sanitizer/codeworld-error-sanitizer.cabal +++ b/codeworld-error-sanitizer/codeworld-error-sanitizer.cabal @@ -25,8 +25,7 @@ Library else Build-depends: array, regex-base, - regex-tdfa, - regex-tdfa-text + regex-tdfa Default-language: Haskell2010 Exposed: True @@ -49,7 +48,6 @@ Test-suite unit-tests else Build-depends: array, regex-base, - regex-tdfa, - regex-tdfa-text + regex-tdfa Default-language: Haskell2010 diff --git a/codeworld-requirements/codeworld-requirements.cabal b/codeworld-requirements/codeworld-requirements.cabal index 3337ab1ed..f2c09c324 100644 --- a/codeworld-requirements/codeworld-requirements.cabal +++ b/codeworld-requirements/codeworld-requirements.cabal @@ -36,8 +36,8 @@ library haskell-src-exts >= 1.20, mtl, process, + regex-base, regex-tdfa, - regex-tdfa-text, syb, temporary, text, diff --git a/codeworld-server/codeworld-server.cabal b/codeworld-server/codeworld-server.cabal index 035e6a683..d9cb09fd9 100644 --- a/codeworld-server/codeworld-server.cabal +++ b/codeworld-server/codeworld-server.cabal @@ -39,7 +39,7 @@ Executable codeworld-server fast-logger, filelock, filepath, - haskell-src-exts < 1.21, + haskell-src-exts, http-conduit, lifted-base, memory, diff --git a/default.nix b/default.nix new file mode 100644 index 000000000..ad9b47618 --- /dev/null +++ b/default.nix @@ -0,0 +1,15 @@ +# https://input-output-hk.github.io/haskell.nix/tutorials/getting-started/ +let + sources = import ./nix/sources.nix {}; + haskellNix = import sources.haskellNix {}; + pkgs = import + haskellNix.sources.nixpkgs-2009 + haskellNix.nixpkgsArgs; +in pkgs.pkgsCross.ghcjs.haskell-nix.project { + projectFileName = "cabal.project"; + src = pkgs.haskell-nix.haskellLib.cleanGit { + name = "haskell-nix-project"; + src = ./.; + }; + compiler-nix-name = "ghc8107"; +} diff --git a/nix/sources.json b/nix/sources.json new file mode 100644 index 000000000..03e9f4806 --- /dev/null +++ b/nix/sources.json @@ -0,0 +1,38 @@ +{ + "haskellNix": { + "branch": "master", + "description": "Alternative Haskell Infrastructure for Nixpkgs", + "homepage": "https://input-output-hk.github.io/haskell.nix", + "owner": "input-output-hk", + "repo": "haskell.nix", + "rev": "ebadbf04a966820cd27a504a439370276539572e", + "sha256": "1i6fv2xx9rmcl9qfaqr374dgwqcra79pjjj3rr7zccrdmlfl05wb", + "type": "tarball", + "url": "https://github.com/input-output-hk/haskell.nix/archive/ebadbf04a966820cd27a504a439370276539572e.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + }, + "niv": { + "branch": "master", + "description": "Easy dependency management for Nix projects", + "homepage": "https://github.com/nmattia/niv", + "owner": "nmattia", + "repo": "niv", + "rev": "e0ca65c81a2d7a4d82a189f1e23a48d59ad42070", + "sha256": "1pq9nh1d8nn3xvbdny8fafzw87mj7gsmp6pxkdl65w2g18rmcmzx", + "type": "tarball", + "url": "https://github.com/nmattia/niv/archive/e0ca65c81a2d7a4d82a189f1e23a48d59ad42070.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + }, + "nixpkgs": { + "branch": "release-20.03", + "description": "Nix Packages collection", + "homepage": "", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "eb73405ecceb1dc505b7cbbd234f8f94165e2696", + "sha256": "06k21wbyhhvq2f1xczszh3c2934p0m02by3l2ixvd6nkwrqklax7", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/eb73405ecceb1dc505b7cbbd234f8f94165e2696.tar.gz", + "url_template": "https://github.com///archive/.tar.gz" + } +} diff --git a/nix/sources.nix b/nix/sources.nix new file mode 100644 index 000000000..1938409dd --- /dev/null +++ b/nix/sources.nix @@ -0,0 +1,174 @@ +# This file has been generated by Niv. + +let + + # + # The fetchers. fetch_ fetches specs of type . + # + + 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 + 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 = 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; + + fetch_builtin-tarball = name: throw + ''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`. + $ niv modify ${name} -a type=tarball -a builtin=true''; + + fetch_builtin-url = name: throw + ''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`. + $ niv modify ${name} -a type=file -a builtin=true''; + + # + # 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: system: + let + sourcesNixpkgs = + import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) { inherit system; }; + hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath; + hasThisAsNixpkgsPath = == ./.; + in + if builtins.hasAttr "nixpkgs" sources + then sourcesNixpkgs + else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then + import {} + else + abort + '' + Please specify either (through -I or NIX_PATH=nixpkgs=...) or + add a package called "nixpkgs" to your sources.json. + ''; + + # The actual fetching function. + fetch = pkgs: name: spec: + + 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 name spec + else if spec.type == "tarball" then fetch_tarball pkgs name 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 + else + abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}"; + + # If the environment variable NIV_OVERRIDE_${name} is set, then use + # the path directly as opposed to the fetched source. + replace = name: drv: + 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 + # 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 + + # a Nix version of mapAttrs if the built-in doesn't exist + mapAttrs = builtins.mapAttrs or ( + f: set: with builtins; + listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set)) + ); + + # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295 + range = first: last: if first > last then [] else builtins.genList (n: first + n) (last - first + 1); + + # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257 + stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1)); + + # 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 ? null, sha256 }@attrs: + let + inherit (builtins) lessThan nixVersion fetchTarball; + in + if lessThan nixVersion "1.12" then + 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, name ? null, sha256 }@attrs: + let + inherit (builtins) lessThan nixVersion fetchurl; + in + if lessThan nixVersion "1.12" then + fetchurl ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; })) + else + fetchurl attrs; + + # Create the final "sources" from the config + mkSources = config: + mapAttrs ( + name: spec: + if builtins.hasAttr "outPath" spec + then abort + "The values in sources.json should not have an 'outPath' attribute" + else + spec // { outPath = replace name (fetch config.pkgs name spec); } + ) config.sources; + + # The "config" used by the fetchers + mkConfig = + { sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null + , sources ? if isNull sourcesFile then {} else builtins.fromJSON (builtins.readFile sourcesFile) + , system ? builtins.currentSystem + , pkgs ? mkPkgs sources system + }: rec { + # The sources, i.e. the attribute set of spec name to spec + inherit sources; + + # The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers + inherit pkgs; + }; + +in +mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); } From 72a26128a72a3cc756fa0141ccf05918df59ff32 Mon Sep 17 00:00:00 2001 From: Peter Becich Date: Sun, 12 Sep 2021 22:53:28 -0700 Subject: [PATCH 3/3] GitHub Actions with Nix --- .github/workflows/{ci.yml => Cabal.yml} | 2 +- .github/workflows/Nix.yml | 27 +++++++++++++++++++++++++ README.md | 3 ++- nix/sources.json | 6 +++--- 4 files changed, 33 insertions(+), 5 deletions(-) rename .github/workflows/{ci.yml => Cabal.yml} (99%) create mode 100644 .github/workflows/Nix.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/Cabal.yml similarity index 99% rename from .github/workflows/ci.yml rename to .github/workflows/Cabal.yml index 7f670039c..817bb977e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/Cabal.yml @@ -1,5 +1,5 @@ # modified from https://github.com/jgm/pandoc/blob/master/.github/workflows/ci.yml -name: CI +name: Cabal on: push: diff --git a/.github/workflows/Nix.yml b/.github/workflows/Nix.yml new file mode 100644 index 000000000..6201fc704 --- /dev/null +++ b/.github/workflows/Nix.yml @@ -0,0 +1,27 @@ +name: Nix + +on: + push: + branches: + - '**' + paths-ignore: [] + pull_request: + paths-ignore: [] + +jobs: + linux: + + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + steps: + - uses: actions/checkout@v2 + + # https://github.com/marketplace/actions/install-nix + - name: Install Nix + uses: cachix/install-nix-action@v14 + with: + extra_nix_config: | + trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= + substituters = https://hydra.iohk.io https://cache.nixos.org/ + - run: nix-build diff --git a/README.md b/README.md index c127b74f7..b24c33101 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,8 @@ CodeWorld ========= [![Build Status](https://travis-ci.org/google/codeworld.svg?branch=master)](https://travis-ci.org/google/codeworld) -[![Build status](https://github.com/google/codeworld/actions/workflows/ci.yml/badge.svg)](https://github.com/google/codeworld/actions/workflows/ci.yml) +[![Build status](https://github.com/google/codeworld/actions/workflows/Cabal.yml/badge.svg)](https://github.com/google/codeworld/actions/workflows/Cabal.yml) +[![Build status](https://github.com/google/codeworld/actions/workflows/Nix.yml/badge.svg)](https://github.com/google/codeworld/actions/workflows/Nix.yml) CodeWorld is an educational environment using Haskell. It provides a simple mathematical model for geometric figures, animations, and interactive and diff --git a/nix/sources.json b/nix/sources.json index 03e9f4806..eab41c286 100644 --- a/nix/sources.json +++ b/nix/sources.json @@ -5,10 +5,10 @@ "homepage": "https://input-output-hk.github.io/haskell.nix", "owner": "input-output-hk", "repo": "haskell.nix", - "rev": "ebadbf04a966820cd27a504a439370276539572e", - "sha256": "1i6fv2xx9rmcl9qfaqr374dgwqcra79pjjj3rr7zccrdmlfl05wb", + "rev": "903bdfe655b644690d4b4c6ca4adf55be95377f8", + "sha256": "1skdd228mjcji3k4rkf9n4kwjgvm7kd9r4bakd4lc2igqxv0nzjr", "type": "tarball", - "url": "https://github.com/input-output-hk/haskell.nix/archive/ebadbf04a966820cd27a504a439370276539572e.tar.gz", + "url": "https://github.com/input-output-hk/haskell.nix/archive/903bdfe655b644690d4b4c6ca4adf55be95377f8.tar.gz", "url_template": "https://github.com///archive/.tar.gz" }, "niv": {