From 93a35c06bc8983b3a36900c39dec6b36ab9b9fdd Mon Sep 17 00:00:00 2001 From: Pavel Anpin Date: Fri, 22 Nov 2024 09:11:43 -0300 Subject: [PATCH] add dotnet kernel for C# and F# --- README.md | 1 + examples/dotnet/csharp/default.nix | 10 ++ examples/dotnet/csharp/test.ipynb | 166 ++++++++++++++++++++++++++ examples/dotnet/csharp/test.py | 13 ++ examples/dotnet/fsharp/default.nix | 11 ++ examples/dotnet/fsharp/test.ipynb | 158 ++++++++++++++++++++++++ examples/dotnet/fsharp/test.py | 13 ++ modules/default.nix | 1 + modules/kernels/dotnet/default.nix | 88 ++++++++++++++ modules/kernels/dotnet/logo-64x64.png | Bin 0 -> 1131 bytes modules/kernels/dotnet/package.nix | 27 +++++ 11 files changed, 488 insertions(+) create mode 100644 examples/dotnet/csharp/default.nix create mode 100644 examples/dotnet/csharp/test.ipynb create mode 100644 examples/dotnet/csharp/test.py create mode 100644 examples/dotnet/fsharp/default.nix create mode 100644 examples/dotnet/fsharp/test.ipynb create mode 100644 examples/dotnet/fsharp/test.py create mode 100644 modules/kernels/dotnet/default.nix create mode 100644 modules/kernels/dotnet/logo-64x64.png create mode 100644 modules/kernels/dotnet/package.nix diff --git a/README.md b/README.md index b734516d..1e4b2024 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ +

This repository provides a Nix-based framework for the definition of diff --git a/examples/dotnet/csharp/default.nix b/examples/dotnet/csharp/default.nix new file mode 100644 index 00000000..bea7e4eb --- /dev/null +++ b/examples/dotnet/csharp/default.nix @@ -0,0 +1,10 @@ +{ + self, + system, + pkgs, + ... +}: { + kernel.dotnet.csharp-example = { + enable = true; + }; +} diff --git a/examples/dotnet/csharp/test.ipynb b/examples/dotnet/csharp/test.ipynb new file mode 100644 index 00000000..e554d67d --- /dev/null +++ b/examples/dotnet/csharp/test.ipynb @@ -0,0 +1,166 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "d13cad64-62c0-4b87-b8ef-0242658baa0f", + "metadata": { + "vscode": { + "languageId": "rust" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\r\n", + "
\r\n", + " \r\n", + " \r\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "hello world\n" + ] + } + ], + "source": [ + "var b = new[] { \"hello\", \"world\" }; \n", + "Console.WriteLine(string.Join(\" \", b));" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5082b04d-1edd-4a81-8462-fa571311cd33", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "dotnet-csharp-example kernel", + "language": "dotnet", + "name": "dotnet-csharp-example" + }, + "language_info": { + "file_extension": ".cs", + "mimetype": "text/x-csharp", + "name": "C#", + "pygments_lexer": "csharp", + "version": "12.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/dotnet/csharp/test.py b/examples/dotnet/csharp/test.py new file mode 100644 index 00000000..ae658c50 --- /dev/null +++ b/examples/dotnet/csharp/test.py @@ -0,0 +1,13 @@ +import os +from testbook import testbook + +current_dir = os.path.dirname(os.path.abspath(__file__)) + +@testbook(f'{current_dir}/test.ipynb', execute=True, kernel_name="dotnet-csharp-example") +def test_nb(tb): + result = tb.cell_output_text(0) + assert result == 'hello world' + +if __name__ == '__main__': + test_nb() + diff --git a/examples/dotnet/fsharp/default.nix b/examples/dotnet/fsharp/default.nix new file mode 100644 index 00000000..7b8f029e --- /dev/null +++ b/examples/dotnet/fsharp/default.nix @@ -0,0 +1,11 @@ +{ + self, + system, + pkgs, + ... +}: { + kernel.dotnet.fsharp-example = { + enable = true; + language = "fsharp"; + }; +} diff --git a/examples/dotnet/fsharp/test.ipynb b/examples/dotnet/fsharp/test.ipynb new file mode 100644 index 00000000..ea91ba19 --- /dev/null +++ b/examples/dotnet/fsharp/test.ipynb @@ -0,0 +1,158 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "d13cad64-62c0-4b87-b8ef-0242658baa0f", + "metadata": { + "vscode": { + "languageId": "rust" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\r\n", + "
\r\n", + " \r\n", + " \r\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10]" + ] + } + ], + "source": [ + "let m = [0 .. 10]\n", + "printf \"%A\" m" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "dotnet-fsharp-example kernel", + "language": "dotnet", + "name": "dotnet-fsharp-example" + }, + "language_info": { + "file_extension": ".fs", + "mimetype": "text/x-fsharp", + "name": "F#", + "pygments_lexer": "fsharp", + "version": "8.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/dotnet/fsharp/test.py b/examples/dotnet/fsharp/test.py new file mode 100644 index 00000000..10638915 --- /dev/null +++ b/examples/dotnet/fsharp/test.py @@ -0,0 +1,13 @@ +import os +from testbook import testbook + +current_dir = os.path.dirname(os.path.abspath(__file__)) + +@testbook(f'{current_dir}/test.ipynb', execute=True, kernel_name="dotnet-fsharp-example") +def test_nb(tb): + result = tb.cell_output_text(0) + assert result == '[0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10]' + +if __name__ == '__main__': + test_nb() + diff --git a/modules/default.nix b/modules/default.nix index d8005955..23600f85 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -84,6 +84,7 @@ in { ./../modules/kernels/scala ./../modules/kernels/typescript ./../modules/kernels/zsh + ./../modules/kernels/dotnet ]; # TODO: add kernels #++ map (name: ./. + "/../modules/kernels/${name}/module.nix") (builtins.attrNames (builtins.readDir ./../modules/kernels)); diff --git a/modules/kernels/dotnet/default.nix b/modules/kernels/dotnet/default.nix new file mode 100644 index 00000000..46dbbc58 --- /dev/null +++ b/modules/kernels/dotnet/default.nix @@ -0,0 +1,88 @@ +{ + self, + system, + config, + lib, + mkKernel, + ... +}: let + inherit (lib) types; + + kernelName = "dotnet"; + kernelOptions = { + config, + name, + ... + }: let + dotnet-interactive = + config.nixpkgs.callPackage ./package.nix { + }; + + requiredRuntimePackages = [ + config.nixpkgs.dotnet-sdk_9 + dotnet-interactive + ]; + args = {inherit self system lib config name kernelName requiredRuntimePackages;}; + kernelModule = import ./../../kernel.nix args; + kernelFunc = { + self, + system, + # custom arguments + pkgs ? self.inputs.nixpkgs.legacyPackages.${system}, + name ? "dotnet", + displayName ? "dotnet", + requiredRuntimePackages ? with pkgs; [dotnet-sdk_8 dotnet-interactive], + runtimePackages ? [], + extraKernelSpc, + language ? "csharp", + }: + { + inherit name displayName; + language = "dotnet"; + argv = [ + "${dotnet-interactive}/bin/dotnet-interactive" + "jupyter" + "{connection_file}" + "--default-kernel" + "${language}" + ]; + codemirrorMode = "dotnet"; + logo64 = ./logo-64x64.png; + } + // extraKernelSpc; + in { + options = + { + language = lib.mkOption { + type = lib.types.enum ["csharp" "fsharp"]; + default = "csharp"; + description = lib.mdDoc '' + Language flavour of dotnet-interactive kernel + ''; + }; + } + // kernelModule.options; + + config = lib.mkIf config.enable { + build = mkKernel (kernelFunc config.kernelArgs); + kernelArgs = + { + inherit (config) language; + } + // kernelModule.kernelArgs; + }; + }; +in { + options.kernel.${kernelName} = lib.mkOption { + type = types.attrsOf (types.submodule kernelOptions); + default = {}; + example = lib.literalExpression '' + { + kernel.${kernelName}."example".enable = true; + } + ''; + description = lib.mdDoc '' + A ${kernelName} kernel for IPython. + ''; + }; +} diff --git a/modules/kernels/dotnet/logo-64x64.png b/modules/kernels/dotnet/logo-64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..0ff8255cd315d01dc20f5289e421c437a2860b9a GIT binary patch literal 1131 zcmV-x1eE)UP)004R> z004l5008;`004mK004C`008P>0026e000+ooVrmw0005?P)t-sQ7hC?Db!FZ)K@ds zWklI#McHFP*itRjRWH?KLfKn4*HbOjW<=RxKG;(()nY){WJB3iFx5^d(|=>%=i>S6 z=KAB^_J&cpNT=lb8+ z_iatvPAAiaYvKL<|NsC0(#Z5(I@fPd-16}JrdgPFI26f@k2Njp&bd zA z)%Nr7{C!~GUp&{IiRb?P|4}T|WkcE5&h^E)@me<4TsYUy#q-F#@y5FG$GY*sv+!(8 z+j(2w`S<;hc;kFu->8-8{rvuWUfzRf;G>S{u%7GN)Am#@)w-+hyRGhbS>3*`@4c_@ zTR7LOn(Dl*?!2zL@Ok@b3c$WeXNk5!s@}OO{etw!GXYsHpT-Rru0WuUN_cE#Nh)5NlV9*4dgm zTuZ^f4o%hdL1Obe^HSaMiBycix9_PRf}g+o x6mem{Q{6U~44%ZF><=Vg@~@CcBofL0uD002ovPDHLkV1k^TcrgF~ literal 0 HcmV?d00001 diff --git a/modules/kernels/dotnet/package.nix b/modules/kernels/dotnet/package.nix new file mode 100644 index 00000000..2b99bf55 --- /dev/null +++ b/modules/kernels/dotnet/package.nix @@ -0,0 +1,27 @@ +{ + lib, + buildDotnetGlobalTool, + dotnetCorePackages, +}: let + inherit (dotnetCorePackages) sdk_8_0; +in + buildDotnetGlobalTool rec { + pname = "Microsoft.dotnet-interactive"; + version = "1.0.556801"; + + nugetSha256 = "sha256-tABt/DltggX85SZaaZK7ZP+L3EqxEh0fZ1pfB4MOtxk="; + + dotnet-sdk = sdk_8_0; + dotnet-runtime = sdk_8_0; + executables = "dotnet-interactive"; + + meta = with lib; { + description = ".NET Interactive"; + mainProgram = "dotnet-interactive"; + homepage = "https://github.com/dotnet/interactive"; + changelog = "https://github.com/dotnet/interactive/releases/tag/v${version}"; + license = licenses.mit; + platforms = platforms.linux ++ platforms.windows ++ platforms.darwin; + maintainers = with maintainers; [anpin]; + }; + }