diff --git a/.github/workflows/ci-cachix.yml b/.github/workflows/ci-cachix.yml new file mode 100644 index 00000000..39051677 --- /dev/null +++ b/.github/workflows/ci-cachix.yml @@ -0,0 +1,37 @@ +name: Builds, lints, tests in nix + +on: [push, pull_request] + +jobs: + flake: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + - name: Install nix + uses: cachix/install-nix-action@v17 + with: + nix_path: nixpkgs=channel:nixos-unstable + - name: Use cachix + uses: cachix/cachix-action@v10 + with: + name: quantified-uncertainty + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + - name: Check that lang lints + run: nix build .#lang-lint + - name: Check that components lints + run: nix build .#components-lint + - name: Check that website lints + run: nix build .#docusaurus-lint + - name: Check that vscode extension lints + run: nix build .#vscode-lint + + - name: Check that lang bundles + run: nix build .#lang-bundle + - name: Check all lang tests + run: nix build .#lang-test + - name: Check that components builds + run: nix build .#components + - name: Check that components bundles + run: nix build .#components-bundle diff --git a/.gitignore b/.gitignore index 5b48f91c..0a2d50fe 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ yarn-error.log **/.sync.ffs_db .direnv .log +result diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..fcadffff --- /dev/null +++ b/flake.lock @@ -0,0 +1,79 @@ +{ + "nodes": { + "flake-utils": { + "locked": { + "lastModified": 1659877975, + "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "locked": { + "lastModified": 1659877975, + "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gentype": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1660630689, + "narHash": "sha256-oM21qcr+VtI69GIm56UDy6oGiupq2GkZDIaKXWWnM8k=", + "owner": "quinn-dougherty", + "repo": "genType", + "rev": "c2a022cfec32b5a61d575205daa93416a9a9309c", + "type": "github" + }, + "original": { + "owner": "quinn-dougherty", + "repo": "genType", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1661617163, + "narHash": "sha256-NN9Ky47j8ohgPhA9JZyfkYIbbAo6RJkGz+7h8/exVpE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "0ba2543f8c855d7be8e90ef6c8dc89c1617e8a08", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-22.05", + "type": "indirect" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "gentype": "gentype", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..fa8efa59 --- /dev/null +++ b/flake.nix @@ -0,0 +1,95 @@ +{ + description = "Squiggle CI"; + + inputs = { + nixpkgs.url = "nixpkgs/nixos-22.05"; + gentype = { + url = github:quinn-dougherty/genType; + inputs.nixpkgs.follows = "nixpkgs"; + }; + flake-utils = { + url = github:numtide/flake-utils; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { self, nixpkgs, gentype, flake-utils }: + let + version = builtins.substring 0 8 self.lastModifiedDate; + overlays = [ + (final: prev: { + # set the node version here + nodejs = prev.nodejs-18_x; + # The override is the only way to get it into mkYarnModules + }) + ]; + + commonFn = pkgs: { + buildInputs = with pkgs; [ nodejs yarn ]; + prettier = with pkgs.nodePackages; [ prettier ]; + which = [ pkgs.which ]; + }; + gentypeOutputFn = pkgs: gentype.outputs.packages.${pkgs.system}.default; + langFn = { pkgs, ... }: + # Probably doesn't work on i686-linux + import ./nix/squiggle-lang.nix { + inherit pkgs commonFn gentypeOutputFn; + }; + componentsFn = { pkgs, ... }: + import ./nix/squiggle-components.nix { + inherit pkgs commonFn langFn; + }; + websiteFn = { pkgs, ... }: + import ./nix/squiggle-website.nix { + inherit pkgs commonFn langFn componentsFn; + }; + vscodeextFn = { pkgs, ... }: + import ./nix/squiggle-vscode.nix { + inherit pkgs commonFn langFn componentsFn; + }; + + # local machines + localFlakeOutputs = { pkgs, ... }: + let + lang = langFn pkgs; + components = componentsFn pkgs; + website = websiteFn pkgs; + vscodeext = vscodeextFn pkgs; + in { + # validating + checks = flake-utils.lib.flattenTree { + lang-lint = lang.lint; + lang-test = lang.test; + components-lint = components.lint; + docusaurus-lint = website.lint; + }; + # building + packages = flake-utils.lib.flattenTree { + default = components.build; + lang-bundle = lang.bundle; + lang-test = lang.test; + components = components.build; + components-bundle = components.bundle; + + # Lint + lang-lint = lang.lint; + components-lint = components.lint; + docusaurus-lint = website.lint; + vscode-lint = vscodeext.lint; + }; + + # developing + devShells = flake-utils.lib.flattenTree { + default = + (import ./nix/shell.nix { inherit pkgs; }).shell; + }; + }; + in flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { + inherit system; + overlays = overlays; + }; + + in localFlakeOutputs pkgs); +} diff --git a/nix/README.md b/nix/README.md new file mode 100644 index 00000000..cadf6b82 --- /dev/null +++ b/nix/README.md @@ -0,0 +1 @@ +Visit `quantified-uncertainty.cachix.org` for information about how to add our binary cache to your local dev environment. diff --git a/nix/shell.nix b/nix/shell.nix new file mode 100644 index 00000000..16c20eab --- /dev/null +++ b/nix/shell.nix @@ -0,0 +1,21 @@ +{ pkgs }: +with pkgs; { + shell = mkShell { + name = "SQUIGGLE_yarn-wasm-devshell"; + buildInputs = [ + wasm-pack + cargo + yarn + nodejs + nodePackages.ts-node + rustup + pkg-config + libressl + nixfmt + rustfmt + wasmtime + binaryen + wasm-bindgen-cli + ]; + }; +} diff --git a/nix/squiggle-components.nix b/nix/squiggle-components.nix new file mode 100644 index 00000000..3a01641f --- /dev/null +++ b/nix/squiggle-components.nix @@ -0,0 +1,75 @@ +{ pkgs, commonFn, langFn }: + +rec { + common = commonFn pkgs; + lang = langFn pkgs; + componentsPackageJson = let + raw = pkgs.lib.importJSON ../packages/components/package.json; + modified = + pkgs.lib.recursiveUpdate raw { dependencies.react-dom = "^18.2.0"; }; + packageJsonString = builtins.toJSON modified; + in pkgs.writeText "packages/components/patched-package.json" + packageJsonString; + yarn-source = pkgs.mkYarnPackage { + name = "squiggle-components_yarnsource"; + buildInputs = common.buildInputs; + src = ../packages/components; + packageJSON = componentsPackageJson; + yarnLock = ../yarn.lock; + packageResolutions."@quri/squiggle-lang" = lang.build; + }; + lint = pkgs.stdenv.mkDerivation { + name = "squiggle-components-lint"; + src = ../packages/components; + buildInputs = common.buildInputs ++ common.prettier; + buildPhase = "yarn lint"; + installPhase = "mkdir -p $out"; + }; + build = pkgs.stdenv.mkDerivation { + name = "squiggle-components-build"; + src = yarn-source + "/libexec/@quri/squiggle-components"; + buildInputs = common.buildInputs; + buildPhase = '' + cp -r node_modules/@quri/squiggle-lang deps/@quri + pushd deps/@quri/squiggle-components + + yarn --offline build:cjs + yarn --offline build:css + popd + ''; + installPhase = '' + mkdir -p $out + + # annoying hack because permissions on transitive dependencies later on + mv deps/@quri/squiggle-components/node_modules deps/@quri/squiggle-components/NODE_MODULES + mv node_modules deps/@quri/squiggle-components + + # patching .gitignore so flake keeps build artefacts + sed -i /dist/d deps/@quri/squiggle-components/.gitignore + cp -r deps/@quri/squiggle-components/. $out + ''; + }; + bundle = pkgs.stdenv.mkDerivation { + name = "squiggle-components-bundle"; + src = yarn-source + "/libexec/@quri/squiggle-components"; + buildInputs = common.buildInputs; + buildPhase = '' + cp -r node_modules/@quri/squiggle-lang deps/@quri + pushd deps/@quri/squiggle-components + + yarn --offline bundle + popd + ''; + installPhase = '' + mkdir -p $out + + # annoying hack because permissions on transitive dependencies later on + mv deps/@quri/squiggle-components/node_modules deps/@quri/squiggle-components/NODE_MODULES + mv node_modules deps/@quri/squiggle-components + + # patching .gitignore so flake keeps build artefacts + sed -i /dist/d deps/@quri/squiggle-components/.gitignore + cp -r deps/@quri/squiggle-components/. $out + ''; + }; +} diff --git a/nix/squiggle-lang.nix b/nix/squiggle-lang.nix new file mode 100644 index 00000000..e7ad21ee --- /dev/null +++ b/nix/squiggle-lang.nix @@ -0,0 +1,116 @@ +{ pkgs, commonFn, gentypeOutputFn }: + +rec { + common = commonFn pkgs; + yarn-source = pkgs.mkYarnPackage { + name = "squiggle-lang_yarnsource"; + src = ../packages/squiggle-lang; + packageJSON = ../packages/squiggle-lang/package.json; + yarnLock = ../yarn.lock; + pkgConfig = { + rescript = { + buildInputs = common.which ++ (if pkgs.system != "i686-linux" then [ pkgs.gcc_multi ] else []); + postInstall = '' + echo "PATCHELF'ING RESCRIPT EXECUTABLES (INCL NINJA)" + # Patching interpreter for linux/*.exe's + THE_LD=$(patchelf --print-interpreter $(which mkdir)) + patchelf --set-interpreter $THE_LD linux/*.exe && echo "- patched interpreter for linux/*.exe's" + + # Replacing needed shared library for linux/ninja.exe + THE_SO=$(find /nix/store/*/lib64 -name libstdc++.so.6 | head -n 1) + patchelf --replace-needed libstdc++.so.6 $THE_SO linux/ninja.exe && echo "- replaced needed for linux/ninja.exe" + ''; + }; + bisect_ppx = { + buildInputs = common.which; + postInstall = '' + echo "PATCHELF'ING BISECT_PPX EXECUTABLE" + THE_LD=$(patchelf --print-interpreter $(which mkdir)) + patchelf --set-interpreter $THE_LD bin/linux/ppx + patchelf --set-interpreter $THE_LD bin/linux/bisect-ppx-report + cp bin/linux/ppx ppx + ''; + }; + gentype = { + postInstall = '' + mv gentype.exe ELFLESS-gentype.exe + cp ${gentypeOutputFn pkgs}/src/GenType.exe gentype.exe + ''; + }; + }; + }; + lint = pkgs.stdenv.mkDerivation { + name = "squiggle-lang-lint"; + src = yarn-source + "/libexec/@quri/squiggle-lang/deps/@quri/squiggle-lang"; + buildInputs = common.buildInputs ++ common.prettier; + buildPhase = '' + yarn lint:prettier + yarn lint:rescript + ''; + installPhase = "mkdir -p $out"; + }; + build = pkgs.stdenv.mkDerivation { + name = "squiggle-lang-build"; + # `peggy` is in the `node_modules` that's adjacent to `deps`. + src = yarn-source + "/libexec/@quri/squiggle-lang"; + buildInputs = common.buildInputs; + buildPhase = '' + # so that the path to ppx doesn't need to be patched. + mv node_modules deps + + pushd deps/@quri/squiggle-lang + yarn --offline build:peggy + yarn --offline build:rescript + yarn --offline build:typescript + + # custom gitignore so that the flake keeps build artefacts + mv .gitignore GITIGNORE + sed -i /Reducer_Peggy_GeneratedParser.js/d GITIGNORE + sed -i /\*.bs.js/d GITIGNORE + sed -i /\*.gen.ts/d GITIGNORE + sed -i /\*.gen.tsx/d GITIGNORE + sed -i /\*.gen.js/d GITIGNORE + sed -i /helpers.js/d GITIGNORE + + popd + ''; + installPhase = '' + mkdir -p $out + # mkdir -p $out/node_modules + mv deps/@quri/squiggle-lang/GITIGNORE deps/@quri/squiggle-lang/.gitignore + + # annoying hack because permissions on transitive dependencies later on + mv deps/@quri/squiggle-lang/node_modules deps/@quri/squiggle-lang/NODE_MODULES + mv deps/node_modules deps/@quri/squiggle-lang + + # the proper install phase + cp -r deps/@quri/squiggle-lang/. $out + ''; + }; + test = pkgs.stdenv.mkDerivation { + name = "squiggle-lang-test"; + src = build; + buildInputs = common.buildInputs; + buildPhase = '' + yarn --offline test + ''; + installPhase = '' + mkdir -p $out + cp -r . $out + ''; + }; + bundle = pkgs.stdenv.mkDerivation { + name = "squiggle-lang-bundle"; + src = test; + buildInputs = common.buildInputs; + buildPhase = '' + yarn --offline bundle + ''; + installPhase = '' + mkdir -p $out + cp -r dist $out + cp *.json $out/dist + ''; + }; + +} diff --git a/nix/squiggle-vscode.nix b/nix/squiggle-vscode.nix new file mode 100644 index 00000000..433d6caa --- /dev/null +++ b/nix/squiggle-vscode.nix @@ -0,0 +1,23 @@ +{ pkgs, commonFn, langFn, componentsFn }: + +rec { + common = commonFn pkgs; + lang = langFn pkgs; + components = componentsFn pkgs; + + yarn-source = pkgs.mkYarnPackage { + name = "squiggle-vscodeext_yarnsource"; + src = ../packages/vscode-ext; + packageJson = ../packages/vscode-ext/package.json; + yarnLock = ../yarn.lock; + packageResolutions."@quri/squiggle-lang" = lang.build; + packageResolutions."@quri/squiggle-components" = components.build; + }; + lint = pkgs.stdenv.mkDerivation { + name = "squiggle-vscode-lint"; + buildInputs = common.buildInputs ++ common.prettier; + src = ../packages/vscode-ext; # yarn-source + "/libexec/vscode-squiggle/deps/vscode-squiggle"; + buildPhase = "prettier --check ."; + installPhase = "mkdir -p $out"; + }; +} diff --git a/nix/squiggle-website.nix b/nix/squiggle-website.nix new file mode 100644 index 00000000..a3ee1856 --- /dev/null +++ b/nix/squiggle-website.nix @@ -0,0 +1,30 @@ +{ pkgs, commonFn, langFn, componentsFn }: + +rec { + common = commonFn pkgs; +# lang = langFn pkgs; +# components = componentsFn pkgs; +# websitePackageJson = let +# raw = pkgs.lib.importJSON ../packages/website/package.json; +# modified = pkgs.lib.recursiveUpdate raw { +# dependencies.postcss-import = "^14.1.0"; +# dependencies.tailwindcss = "^3.1.8"; +# }; +# packageJsonString = builtins.toJSON modified; +# in pkgs.writeText "packages/website/patched-package.json" packageJsonString; +# yarn-source = pkgs.mkYarnPackage { +# name = "squiggle-website_yarnsource"; +# src = ../packages/website; +# packageJSON = websitePackageJson; +# yarnLock = ../yarn.lock; +# packageResolutions."@quri/squiggle-lang" = lang.build; +# packageResolutions."@quri/squiggle-components" = components.build; +# }; + lint = pkgs.stdenv.mkDerivation { + name = "squiggle-website-lint"; + buildInputs = common.buildInputs ++ common.prettier; + src = ../packages/website; + buildPhase = "yarn lint"; + installPhase = "mkdir -p $out"; + }; +} diff --git a/nixos.sh b/nixos.sh index 91aa754f..8acff5f4 100755 --- a/nixos.sh +++ b/nixos.sh @@ -13,6 +13,6 @@ theLd=$(patchelf --print-interpreter $(which mkdir)) patchelf --set-interpreter $theLd ./node_modules/gentype/gentype.exe patchelf --set-interpreter $theLd ./node_modules/rescript/linux/*.exe patchelf --set-interpreter $theLd ./node_modules/bisect_ppx/ppx -patchelf --set-interpreter $theLd ./node_moduels/bisect_ppx/bisect-ppx-report -theSo=$(find /nix/store/*$fhsShellName*/lib64 -name libstdc++.so.6 | grep $fhsShellName | head -n 1) +patchelf --set-interpreter $theLd ./node_modules/bisect_ppx/bisect-ppx-report +theSo=$(find /nix/store/*$fhsShellName*/lib64 -name libstdc++.so.6 | head -n 1) patchelf --replace-needed libstdc++.so.6 $theSo ./node_modules/rescript/linux/ninja.exe diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index a94197f8..73db9a42 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -51,6 +51,7 @@ "@glennsl/rescript-jest": "^0.9.0", "@istanbuljs/nyc-config-typescript": "^1.0.2", "@types/jest": "^27.5.0", + "@types/lodash": "^4.14.182", "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", "bisect_ppx": "^2.7.1", "chalk": "^5.0.1", diff --git a/packages/vscode-ext/.prettierignore b/packages/vscode-ext/.prettierignore new file mode 100644 index 00000000..ea5daaf6 --- /dev/null +++ b/packages/vscode-ext/.prettierignore @@ -0,0 +1,3 @@ +out +dist +**/*.d.ts diff --git a/packages/vscode-ext/package.json b/packages/vscode-ext/package.json index 73ca9dd6..8fa973fa 100644 --- a/packages/vscode-ext/package.json +++ b/packages/vscode-ext/package.json @@ -143,4 +143,4 @@ "vscode-languageserver-textdocument": "^1.0.5", "@quri/squiggle-lang": "^0.2.11" } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index acdc5bf0..5dbab7c4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4696,7 +4696,7 @@ resolved "https://registry.yarnpkg.com/@types/katex/-/katex-0.11.1.tgz#34de04477dcf79e2ef6c8d23b41a3d81f9ebeaf5" integrity sha512-DUlIj2nk0YnJdlWgsFuVKcX27MLW0KbKmGVoUHmFr+74FYYNUDAaj9ZqTADvsbE8rfxuVmSFc7KczYn5Y09ozg== -"@types/lodash@^4.14.167", "@types/lodash@^4.14.175", "@types/lodash@^4.14.184": +"@types/lodash@^4.14.167", "@types/lodash@^4.14.175", "@types/lodash@^4.14.182", "@types/lodash@^4.14.184": version "4.14.184" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.184.tgz#23f96cd2a21a28e106dc24d825d4aa966de7a9fe" integrity sha512-RoZphVtHbxPZizt4IcILciSWiC6dcn+eZ8oX9IWEYfDMcocdd42f7NPI6fQj+6zI8y4E0L7gu2pcZKLGTRaV9Q==