From 3752605627e1fab4fc9298c7f1eb60b963ac8e9a Mon Sep 17 00:00:00 2001 From: Raymond Gauthier Date: Sat, 10 Oct 2020 17:46:58 -0400 Subject: [PATCH] vscode-exts/ms-dotnettools-csharp: Init at 1.23.2 Including PR fixes as suggested by: - Sandro --- pkgs/misc/vscode-extensions/default.nix | 2 + .../ms-dotnettools-csharp/default.nix | 143 ++++++++++++++++ .../rt-deps-bin-srcs.json | 37 +++++ .../ms-dotnettools-csharp/update-bin-srcs | 25 +++ .../update-bin-srcs-lib.sh | 154 ++++++++++++++++++ 5 files changed, 361 insertions(+) create mode 100644 pkgs/misc/vscode-extensions/ms-dotnettools-csharp/default.nix create mode 100644 pkgs/misc/vscode-extensions/ms-dotnettools-csharp/rt-deps-bin-srcs.json create mode 100755 pkgs/misc/vscode-extensions/ms-dotnettools-csharp/update-bin-srcs create mode 100755 pkgs/misc/vscode-extensions/ms-dotnettools-csharp/update-bin-srcs-lib.sh diff --git a/pkgs/misc/vscode-extensions/default.nix b/pkgs/misc/vscode-extensions/default.nix index bc00f82f19b..d1bbba0b953 100644 --- a/pkgs/misc/vscode-extensions/default.nix +++ b/pkgs/misc/vscode-extensions/default.nix @@ -141,6 +141,8 @@ let }; }; + ms-dotnettools.csharp = callPackage ./ms-dotnettools-csharp { }; + ms-kubernetes-tools.vscode-kubernetes-tools = buildVscodeMarketplaceExtension { mktplcRef = { name = "vscode-kubernetes-tools"; diff --git a/pkgs/misc/vscode-extensions/ms-dotnettools-csharp/default.nix b/pkgs/misc/vscode-extensions/ms-dotnettools-csharp/default.nix new file mode 100644 index 00000000000..a7b0e17ecbf --- /dev/null +++ b/pkgs/misc/vscode-extensions/ms-dotnettools-csharp/default.nix @@ -0,0 +1,143 @@ +{ lib +, fetchurl +, vscode-utils +, unzip +, patchelf +, makeWrapper +, icu +, stdenv +, openssl +, mono6 +}: + +let + # Get as close as possible as the `package.json` required version. + # This is what drives omnisharp. + mono = mono6; + + rtDepsSrcsFromJson = builtins.fromJSON (builtins.readFile ./rt-deps-bin-srcs.json); + + rtDepsBinSrcs = builtins.mapAttrs (k: v: + let + # E.g: "OmniSharp-x86_64-linux" + kSplit = builtins.split "(-)" k; + name = builtins.elemAt kSplit 0; + arch = builtins.elemAt kSplit 2; + platform = builtins.elemAt kSplit 4; + in + { + inherit name arch platform; + installPath = v.installPath; + binaries = v.binaries; + bin-src = fetchurl { + urls = v.urls; + inherit (v) sha256; + }; + } + ) + rtDepsSrcsFromJson; + + arch = "x86_64"; + platform = "linux"; + + rtDepBinSrcByName = bSrcName: + rtDepsBinSrcs."${bSrcName}-${arch}-${platform}"; + + omnisharp = rtDepBinSrcByName "OmniSharp"; + vsdbg = rtDepBinSrcByName "Debugger"; + razor = rtDepBinSrcByName "Razor"; +in + +vscode-utils.buildVscodeMarketplaceExtension { + mktplcRef = { + name = "csharp"; + publisher = "ms-dotnettools"; + version = "1.23.2"; + sha256 = "0ydaiy8jfd1bj50bqiaz5wbl7r6qwmbz9b29bydimq0rdjgapaar"; + }; + + nativeBuildInputs = [ + unzip + patchelf + makeWrapper + ]; + + postPatch = '' + declare ext_unique_id + # See below as to why we cannot take the whole basename. + ext_unique_id="$(basename "$out" | head -c 32)" + + # Fix 'Unable to connect to debuggerEventsPipeName .. exceeds the maximum length 107.' when + # attempting to launch a specific test in debug mode. The extension attemps to open + # a pipe in extension dir which would fail anyway. We change to target file path + # to a path in tmp dir with a short name based on the unique part of the nix store path. + # This is however a brittle patch as we're working on minified code. + # Hence the attempt to only hold on stable names. + # However, this really would better be fixed upstream. + sed -i \ + -E -e 's/(this\._pipePath=[a-zA-Z0-9_]+\.join\()([a-zA-Z0-9_]+\.getExtensionPath\(\)[^,]*,)/\1require("os").tmpdir(), "'"$ext_unique_id"'"\+/g' \ + "$PWD/dist/extension.js" + + unzip_to() { + declare src_zip="''${1?}" + declare target_dir="''${2?}" + mkdir -p "$target_dir" + if unzip "$src_zip" -d "$target_dir"; then + true + elif [[ "1" -eq "$?" ]]; then + 1>&2 echo "WARNING: unzip('$?' -> skipped files)." + else + 1>&2 echo "ERROR: unzip('$?')." + fi + } + + patchelf_add_icu_as_needed() { + declare elf="''${1?}" + declare icu_major_v="${ + with builtins; head (splitVersion (parseDrvName icu.name).version)}" + + for icu_lib in icui18n icuuc icudata; do + patchelf --add-needed "lib''${icu_lib}.so.$icu_major_v" "$elf" + done + } + + patchelf_common() { + declare elf="''${1?}" + + patchelf_add_icu_as_needed "$elf" + patchelf --add-needed "libssl.so" "$elf" + patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \ + --set-rpath "${lib.makeLibraryPath [ stdenv.cc.cc openssl.out icu.out ]}:\$ORIGIN" \ + "$elf" + } + + declare omnisharp_dir="$PWD/${omnisharp.installPath}" + unzip_to "${omnisharp.bin-src}" "$omnisharp_dir" + rm "$omnisharp_dir/bin/mono" + ln -s -T "${mono6}/bin/mono" "$omnisharp_dir/bin/mono" + chmod a+x "$omnisharp_dir/run" + touch "$omnisharp_dir/install.Lock" + + declare vsdbg_dir="$PWD/${vsdbg.installPath}" + unzip_to "${vsdbg.bin-src}" "$vsdbg_dir" + chmod a+x "$vsdbg_dir/vsdbg-ui" + chmod a+x "$vsdbg_dir/vsdbg" + touch "$vsdbg_dir/install.complete" + touch "$vsdbg_dir/install.Lock" + patchelf_common "$vsdbg_dir/vsdbg" + patchelf_common "$vsdbg_dir/vsdbg-ui" + + declare razor_dir="$PWD/${razor.installPath}" + unzip_to "${razor.bin-src}" "$razor_dir" + chmod a+x "$razor_dir/rzls" + touch "$razor_dir/install.Lock" + patchelf_common "$razor_dir/rzls" + ''; + + meta = with lib; { + description = "C# for Visual Studio Code (powered by OmniSharp)"; + license = licenses.mit; + maintainers = [ maintainers.jraygauthier ]; + platforms = [ "x86_64-linux" ]; + }; +} diff --git a/pkgs/misc/vscode-extensions/ms-dotnettools-csharp/rt-deps-bin-srcs.json b/pkgs/misc/vscode-extensions/ms-dotnettools-csharp/rt-deps-bin-srcs.json new file mode 100644 index 00000000000..91ee056efc1 --- /dev/null +++ b/pkgs/misc/vscode-extensions/ms-dotnettools-csharp/rt-deps-bin-srcs.json @@ -0,0 +1,37 @@ +{ + "OmniSharp-x86_64-linux": { + "installPath": ".omnisharp/1.37.1", + "binaries": [ + "./mono.linux-x86_64", + "./run" + ], + "urls": [ + "https://download.visualstudio.microsoft.com/download/pr/46933d64-075c-4f9f-b205-da4a839e2e3c/4bba2c3f40106056b53721c164ff86fa/omnisharp-linux-x64-1.37.1.zip", + "https://roslynomnisharp.blob.core.windows.net/releases/1.37.1/omnisharp-linux-x64-1.37.1.zip" + ], + "sha256": "0yzxkbq0fyq2bv0s7qmycxl0w54lla0vykg1a5lpv9j38k062vvz" + }, + "Debugger-x86_64-linux": { + "installPath": ".debugger", + "binaries": [ + "./vsdbg-ui", + "./vsdbg" + ], + "urls": [ + "https://download.visualstudio.microsoft.com/download/pr/292d2e01-fb93-455f-a6b3-76cddad4f1ef/2e9b8bc5431d8f6c56025e76eaabbdff/coreclr-debug-linux-x64.zip", + "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-22-2/coreclr-debug-linux-x64.zip" + ], + "sha256": "1lhyjq6g6lc1b4n4z57g0ssr5msqgsmrl8yli8j9ah5s3jq1lrda" + }, + "Razor-x86_64-linux": { + "installPath": ".razor", + "binaries": [ + "./rzls" + ], + "urls": [ + "https://download.visualstudio.microsoft.com/download/pr/757f5246-2b09-43fe-9a8d-840cfd15092b/2b6d8eee0470acf725c1c7a09f8b6475/razorlanguageserver-linux-x64-6.0.0-alpha.1.20418.9.zip", + "https://razorvscodetest.blob.core.windows.net/languageserver/RazorLanguageServer-linux-x64-6.0.0-alpha.1.20418.9.zip" + ], + "sha256": "1hksxq867anb9h040497phszq64f6krg4a46w0xqrm6crj8znqr5" + } +} diff --git a/pkgs/misc/vscode-extensions/ms-dotnettools-csharp/update-bin-srcs b/pkgs/misc/vscode-extensions/ms-dotnettools-csharp/update-bin-srcs new file mode 100755 index 00000000000..ecd7efba05d --- /dev/null +++ b/pkgs/misc/vscode-extensions/ms-dotnettools-csharp/update-bin-srcs @@ -0,0 +1,25 @@ +#!/usr/bin/env nix-shell +#!nix-shell -I nixpkgs=../../../.. -i bash -p curl jq unzip +set -euf -o pipefail + +declare scriptDir +scriptDir=$(cd "$(dirname "$0")"; pwd) +1>&2 echo "scriptDir='$scriptDir'" + +. "$scriptDir/update-bin-srcs-lib.sh" + +declare extPublisher="ms-dotnettools" +declare extName="csharp" +declare defaultExtVersion="1.23.2" +declare extVersion="${1:-$defaultExtVersion}" + +formatExtRuntimeDeps \ + "$extPublisher" "$extName" "$extVersion" \ + | computeAndAttachExtRtDepsChecksums \ + | jqStreamToJson \ + | tee "$scriptDir/rt-deps-bin-srcs.json" \ + | jq '.' + +# TODO: Unfortunatly no simple json to nix implementation available. +# This would allow us to dump to './rt-deps-bin-srcs.nix' instead. +# jsonToNix diff --git a/pkgs/misc/vscode-extensions/ms-dotnettools-csharp/update-bin-srcs-lib.sh b/pkgs/misc/vscode-extensions/ms-dotnettools-csharp/update-bin-srcs-lib.sh new file mode 100755 index 00000000000..ad494a37908 --- /dev/null +++ b/pkgs/misc/vscode-extensions/ms-dotnettools-csharp/update-bin-srcs-lib.sh @@ -0,0 +1,154 @@ +#!/usr/bin/env bash + +prefetchExtensionZip() { + declare publisher="${1?}" + declare name="${2?}" + declare version="${3?}" + + 1>&2 echo + 1>&2 echo "------------- Downloading extension ---------------" + + declare extZipStoreName="${publisher}-${name}.zip" + declare extUrl="https://${publisher}.gallery.vsassets.io/_apis/public/gallery/publisher/${publisher}/extension/${name}/${version}/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage"; + 1>&2 echo "extUrl='$extUrl'" + declare nixPrefetchArgs=( --name "$extZipStoreName" --print-path "$extUrl" ) + + 1>&2 printf "$ nix-prefetch-url" + 1>&2 printf " %q" "${nixPrefetchArgs[@]}" + 1>&2 printf " 2> /dev/null\n" + declare zipShaWStorePath + zipShaWStorePath=$(nix-prefetch-url "${nixPrefetchArgs[@]}" 2> /dev/null) + + 1>&2 echo "zipShaWStorePath='$zipShaWStorePath'" + echo "$zipShaWStorePath" +} + + +prefetchExtensionUnpacked() { + declare publisher="${1?}" + declare name="${2?}" + declare version="${3?}" + + declare zipShaWStorePath + zipShaWStorePath="$(prefetchExtensionZip "$publisher" "$name" "$version")" + + declare zipStorePath + zipStorePath="$(echo "$zipShaWStorePath" | tail -n1)" + 1>&2 echo "zipStorePath='$zipStorePath'" + + function rm_tmpdir() { + 1>&2 printf "rm -rf -- %q\n" "$tmpDir" + rm -rf -- "$tmpDir" + unset tmpDir + trap - INT TERM HUP EXIT + } + function make_trapped_tmpdir() { + tmpDir=$(mktemp -d) + trap rm_tmpdir INT TERM HUP EXIT + } + + 1>&2 echo + 1>&2 echo "------------- Unpacking extension ---------------" + + make_trapped_tmpdir + declare unzipArgs=( -q -d "$tmpDir" "$zipStorePath" ) + 1>&2 printf "$ unzip" + 1>&2 printf " %q" "${unzipArgs[@]}" + 1>&2 printf "\n" + unzip "${unzipArgs[@]}" + + declare unpackedStoreName="${publisher}-${name}" + + declare unpackedStorePath + unpackedStorePath="$(nix add-to-store -n "$unpackedStoreName" "$tmpDir")" + declare unpackedSha256 + unpackedSha256="$(nix hash-path --base32 --type sha256 "$unpackedStorePath")" + 1>&2 echo "unpackedStorePath='$unpackedStorePath'" + 1>&2 echo "unpackedSha256='$unpackedSha256'" + + rm_tmpdir + + echo "$unpackedSha256" + echo "$unpackedStorePath" +} + + +prefetchExtensionJson() { + declare publisher="${1?}" + declare name="${2?}" + declare version="${3?}" + + declare unpackedShaWStorePath + unpackedShaWStorePath="$(prefetchExtensionUnpacked "$publisher" "$name" "$version")" + + declare unpackedStorePath + unpackedStorePath="$(echo "$unpackedShaWStorePath" | tail -n1)" + 1>&2 echo "unpackedStorePath='$unpackedStorePath'" + + declare jsonShaWStorePath + jsonShaWStorePath=$(nix-prefetch-url --print-path "file://${unpackedStorePath}/extension/package.json" 2> /dev/null) + + 1>&2 echo "jsonShaWStorePath='$jsonShaWStorePath'" + echo "$jsonShaWStorePath" +} + + +formatExtRuntimeDeps() { + declare publisher="${1?}" + declare name="${2?}" + declare version="${3?}" + + declare jsonShaWStorePath + jsonShaWStorePath="$(prefetchExtensionJson "$publisher" "$name" "$version")" + + declare jsonStorePath + jsonStorePath="$(echo "$jsonShaWStorePath" | tail -n1)" + 1>&2 echo "jsonStorePath='$jsonStorePath'" + + declare jqQuery + jqQuery=$(cat <<'EOF' +.runtimeDependencies \ +| map(select(.platforms[] | in({"linux": null}))) \ +| map(select(.architectures[] | in({"x86_64": null}))) \ +| .[] | {(.id + "-" + (.architectures[0]) + "-" + (.platforms[0])): \ +{installPath, binaries, urls: [.url, .fallbackUrl]}} +EOF +) + + 1>&2 printf "$ cat %q | jq '%s'\n" "$jsonStorePath" "$jqQuery" + cat "$jsonStorePath" | jq "$jqQuery" +} + + +computeExtRtDepChecksum() { + declare rtDepJsonObject="${1?}" + declare url + url="$(echo "$rtDepJsonObject" | jq -j '.[].urls[0]')" + declare sha256 + 1>&2 printf "$ nix-prefetch-url '%s'\n" "$url" + sha256="$(nix-prefetch-url "$url")" + 1>&2 echo "$sha256" + echo "$sha256" +} + + +computeAndAttachExtRtDepsChecksums() { + while read -r rtDepJsonObject; do + declare sha256 + sha256="$(computeExtRtDepChecksum "$rtDepJsonObject")" + echo "$rtDepJsonObject" | jq --arg sha256 "$sha256" '.[].sha256 = $sha256' + done < <(cat - | jq -c '.') +} + + +jqStreamToJson() { + cat - | jq --slurp '. | add' +} + + +jsonToNix() { + # TODO: Replacing this non functional stuff with a proper json to nix + # implementation would allow us to produce a 'rt-deps-bin-srcs.nix' file instead. + false + cat - | sed -E -e 's/": /" = /g' -e 's/,$/;/g' -e 's/ }$/ };/g' -e 's/ ]$/ ];/g' +}