buildDotnetModule: fix structured attributes support
This change refactors internal hooks used by buildDotnetModule to support derivations with structured attributes. Note that this changes variable names that the internal hooks expect.
···69, disabledTests ? [ ]
70 # The project file to run unit tests against. This is usually referenced in the regular project file, but sometimes it needs to be manually set.
71 # It gets restored and build, but not installed. You may need to regenerate your nuget lockfile after setting this.
72-, testProjectFile ? ""
7374 # The type of build to perform. This is passed to `dotnet` with the `--configuration` flag. Possible values are `Release`, `Debug`, etc.
75, buildType ? "Release"
···88} @ args:
8990let
0000091 platforms =
92 if args ? meta.platforms
93 then lib.intersectLists args.meta.platforms dotnet-sdk.meta.platforms
94 else dotnet-sdk.meta.platforms;
9596 inherit (callPackage ./hooks {
97- inherit dotnet-sdk disabledTests nuget-source dotnet-runtime runtimeDeps buildType;
98- runtimeId =
99- if runtimeId != null
100- then runtimeId
101- else dotnetCorePackages.systemToDotnetRid stdenvNoCC.targetPlatform.system;
102 }) dotnetConfigureHook dotnetBuildHook dotnetCheckHook dotnetInstallHook dotnetFixupHook;
103104 localDeps =
···143 nugetDepsFile = _nugetDeps.sourceFile;
144in
145stdenvNoCC.mkDerivation (args // {
0000000000000146 nativeBuildInputs = args.nativeBuildInputs or [ ] ++ [
147 dotnetConfigureHook
148 dotnetBuildHook
···172 else [ ]));
173174 makeWrapperArgs = args.makeWrapperArgs or [ ] ++ [
175- "--prefix LD_LIBRARY_PATH : ${dotnet-sdk.icu}/lib"
176 ];
177178 # Stripping breaks the executable
···180181 # gappsWrapperArgs gets included when wrapping for dotnet, as to avoid double wrapping
182 dontWrapGApps = args.dontWrapGApps or true;
183-184- inherit selfContainedBuild useAppHost useDotnetFromEnv;
185186 # propagate the runtime sandbox profile since the contents apply to published
187 # executables
···267 --no-cache \
268 --force \
269 ${lib.optionalString (!enableParallelBuilding) "--disable-parallel"} \
270- ${lib.optionalString (flags != []) (toString flags)}
271 }
272273- declare -a projectFiles=( ${toString (lib.toList projectFile)} )
274- declare -a testProjectFiles=( ${toString (lib.toList testProjectFile)} )
275276 export DOTNET_NOLOGO=1
277 export DOTNET_CLI_TELEMETRY_OPTOUT=1
···69, disabledTests ? [ ]
70 # The project file to run unit tests against. This is usually referenced in the regular project file, but sometimes it needs to be manually set.
71 # It gets restored and build, but not installed. You may need to regenerate your nuget lockfile after setting this.
72+, testProjectFile ? null
7374 # The type of build to perform. This is passed to `dotnet` with the `--configuration` flag. Possible values are `Release`, `Debug`, etc.
75, buildType ? "Release"
···88} @ args:
8990let
91+ projectFiles =
92+ lib.optionals (projectFile != null) (lib.toList projectFile);
93+ testProjectFiles =
94+ lib.optionals (testProjectFile != null) (lib.toList testProjectFile);
95+96 platforms =
97 if args ? meta.platforms
98 then lib.intersectLists args.meta.platforms dotnet-sdk.meta.platforms
99 else dotnet-sdk.meta.platforms;
100101 inherit (callPackage ./hooks {
102+ inherit dotnet-sdk dotnet-runtime;
0000103 }) dotnetConfigureHook dotnetBuildHook dotnetCheckHook dotnetInstallHook dotnetFixupHook;
104105 localDeps =
···144 nugetDepsFile = _nugetDeps.sourceFile;
145in
146stdenvNoCC.mkDerivation (args // {
147+ dotnetInstallPath = installPath;
148+ dotnetExecutables = executables;
149+ dotnetBuildType = buildType;
150+ dotnetProjectFiles = projectFiles;
151+ dotnetTestProjectFiles = testProjectFiles;
152+ dotnetDisabledTests = disabledTests;
153+ dotnetRuntimeId = runtimeId;
154+ nugetSource = nuget-source;
155+ dotnetRuntimeDeps = map lib.getLib runtimeDeps;
156+ dotnetSelfContainedBuild = selfContainedBuild;
157+ dotnetUseAppHost = useAppHost;
158+ inherit useDotnetFromEnv;
159+160 nativeBuildInputs = args.nativeBuildInputs or [ ] ++ [
161 dotnetConfigureHook
162 dotnetBuildHook
···186 else [ ]));
187188 makeWrapperArgs = args.makeWrapperArgs or [ ] ++ [
189+ "--prefix" "LD_LIBRARY_PATH" ":" "${dotnet-sdk.icu}/lib"
190 ];
191192 # Stripping breaks the executable
···194195 # gappsWrapperArgs gets included when wrapping for dotnet, as to avoid double wrapping
196 dontWrapGApps = args.dontWrapGApps or true;
00197198 # propagate the runtime sandbox profile since the contents apply to published
199 # executables
···279 --no-cache \
280 --force \
281 ${lib.optionalString (!enableParallelBuilding) "--disable-parallel"} \
282+ ${lib.escapeShellArgs flags}
283 }
284285+ declare -a projectFiles=( ${lib.escapeShellArgs projectFiles} )
286+ declare -a testProjectFiles=( ${lib.escapeShellArgs testProjectFiles} )
287288 export DOTNET_NOLOGO=1
289 export DOTNET_CLI_TELEMETRY_OPTOUT=1
···1-# inherit arguments from derivation
2-dotnetTestFlags=( ${dotnetTestFlags[@]-} )
3-4dotnetCheckHook() {
5 echo "Executing dotnetCheckHook"
67 runHook preCheck
89- if [ "${disabledTests-}" ]; then
10- local -r disabledTestsFlag="--filter @disabledTests@"
00000000000000000000011 fi
1213- if [ "${enableParallelBuilding-}" ]; then
0000000014 local -r maxCpuFlag="$NIX_BUILD_CORES"
15 else
16 local -r maxCpuFlag="1"
17 fi
1819- for project in ${testProjectFile[@]-${projectFile[@]}}; do
20- runtimeIdFlags=()
21- if [[ "$project" == *.csproj ]]; then
22- runtimeIdFlags=("--runtime @runtimeId@")
023 fi
2425- LD_LIBRARY_PATH="@libraryPath@" \
26- dotnet test "$project" \
27- -maxcpucount:$maxCpuFlag \
28 -p:ContinuousIntegrationBuild=true \
29 -p:Deterministic=true \
30- --configuration "@buildType@" \
31 --no-build \
32 --logger "console;verbosity=normal" \
33- ${disabledTestsFlag-} \
34- ${runtimeIdFlags[@]} \
35- "${dotnetTestFlags[@]}" \
36- "${dotnetFlags[@]}"
37 done
3839 runHook postCheck
···0001dotnetCheckHook() {
2 echo "Executing dotnetCheckHook"
34 runHook preCheck
56+ local -r hostRuntimeId=@runtimeId@
7+ local -r dotnetBuildType="${dotnetBuildType-Release}"
8+ local -r dotnetRuntimeId="${dotnetRuntimeId-$hostRuntimeId}"
9+10+ if [[ -n $__structuredAttrs ]]; then
11+ local dotnetProjectFilesArray=( "${dotnetProjectFiles[@]}" )
12+ local dotnetTestProjectFilesArray=( "${dotnetTestProjectFiles[@]}" )
13+ local dotnetTestFlagsArray=( "${dotnetTestFlags[@]}" )
14+ local dotnetDisabledTestsArray=( "${dotnetDisabledTests[@]}" )
15+ local dotnetRuntimeDepsArray=( "${dotnetRuntimeDeps[@]}" )
16+ else
17+ local dotnetProjectFilesArray=($dotnetProjectFiles)
18+ local dotnetTestProjectFilesArray=($dotnetTestProjectFiles)
19+ local dotnetTestFlagsArray=($dotnetTestFlags)
20+ local dotnetDisabledTestsArray=($dotnetDisabledTests)
21+ local dotnetRuntimeDepsArray=($dotnetRuntimeDeps)
22+ fi
23+24+ if (( ${#dotnetDisabledTestsArray[@]} > 0 )); then
25+ local disabledTestsFilters=("${dotnetDisabledTestsArray[@]/#/FullyQualifiedName!=}")
26+ local OLDIFS="$IFS" IFS='&'
27+ dotnetTestFlagsArray+=("--filter:${disabledTestsFilters[*]//,/%2C}")
28+ IFS="$OLDIFS"
29 fi
3031+ local libraryPath="${LD_LIBRARY_PATH-}"
32+ if (( ${#dotnetRuntimeDepsArray[@]} > 0 )); then
33+ local libraryPathArray=("${dotnetRuntimeDepsArray[@]/%//lib}")
34+ local OLDIFS="$IFS" IFS=':'
35+ libraryPath="${libraryPathArray[*]}${libraryPath:+':'}$libraryPath"
36+ IFS="$OLDIFS"
37+ fi
38+39+ if [[ -n ${enableParallelBuilding-} ]]; then
40 local -r maxCpuFlag="$NIX_BUILD_CORES"
41 else
42 local -r maxCpuFlag="1"
43 fi
4445+ local projectFile
46+ for projectFile in "${dotnetTestProjectFilesArray[@]-${dotnetProjectFilesArray[@]}}"; do
47+ local runtimeIdFlagsArray=()
48+ if [[ $projectFile == *.csproj ]]; then
49+ runtimeIdFlagsArray=("--runtime" "$dotnetRuntimeId")
50 fi
5152+ LD_LIBRARY_PATH=$libraryPath \
53+ dotnet test "$projectFile" \
54+ -maxcpucount:"$maxCpuFlag" \
55 -p:ContinuousIntegrationBuild=true \
56 -p:Deterministic=true \
57+ --configuration "$dotnetBuildType" \
58 --no-build \
59 --logger "console;verbosity=normal" \
60+ "${runtimeIdFlagsArray[@]}" \
61+ "${dotnetTestFlagsArray[@]}" \
62+ "${dotnetFlagsArray[@]}"
063 done
6465 runHook postCheck
···1-declare -a projectFile testProjectFile
2-3-# Inherit arguments from derivation
4-dotnetFlags=( ${dotnetFlags[@]-} )
5-dotnetRestoreFlags=( ${dotnetRestoreFlags[@]-} )
6-7dotnetConfigureHook() {
8 echo "Executing dotnetConfigureHook"
910 runHook preConfigure
1112- if [ -z "${enableParallelBuilding-}" ]; then
000000000000000000000000000000013 local -r parallelFlag="--disable-parallel"
14 fi
1516 dotnetRestore() {
17- local -r project="${1-}"
18- dotnet restore ${project-} \
19 -p:ContinuousIntegrationBuild=true \
20 -p:Deterministic=true \
21- --runtime "@runtimeId@" \
22- --source "@nugetSource@/lib" \
23 ${parallelFlag-} \
24- ${dotnetRestoreFlags[@]} \
25- ${dotnetFlags[@]}
26 }
2728 # Generate a NuGet.config file to make sure everything,
29 # including things like <Sdk /> dependencies, is restored from the proper source
30-cat <<EOF > "./NuGet.config"
31<?xml version="1.0" encoding="utf-8"?>
32<configuration>
33 <packageSources>
34 <clear />
35- <add key="nugetSource" value="@nugetSource@/lib" />
36 </packageSources>
37</configuration>
38EOF
3940- # Patch paket.dependencies and paket.lock (if found) to use the proper source. This ensures
41- # paket restore works correctly
42- # We use + instead of / in sed to avoid problems with slashes
43- find -name paket.dependencies -exec sed -i 's+source .*+source @nugetSource@/lib+g' {} \;
44- find -name paket.lock -exec sed -i 's+remote:.*+remote: @nugetSource@/lib+g' {} \;
004546- dotnet tool restore --add-source "@nugetSource@/lib"
4748- (( "${#projectFile[@]}" == 0 )) && dotnetRestore
00000000004950- for project in ${projectFile[@]} ${testProjectFile[@]-}; do
51- dotnetRestore "$project"
52- done
005354 echo "Fixing up native binaries..."
55 # Find all native binaries and nuget libraries, and fix them up,
56 # by setting the proper interpreter and rpath to some commonly used libraries
057 for binary in $(find "$HOME/.nuget/packages/" -type f -executable); do
58 if patchelf --print-interpreter "$binary" >/dev/null 2>/dev/null; then
59 echo "Found binary: $binary, fixing it up..."
60- patchelf --set-interpreter "$(cat "@dynamicLinker@")" "$binary"
6162 # This makes sure that if the binary requires some specific runtime dependencies, it can find it.
63 # This fixes dotnet-built binaries like crossgen2
···68 --add-needed libssl.so \
69 "$binary"
7071- patchelf --set-rpath "@libPath@" "$binary"
72 fi
73 done
74
···0000001dotnetConfigureHook() {
2 echo "Executing dotnetConfigureHook"
34 runHook preConfigure
56+ if [[ -z ${nugetSource-} ]]; then
7+ echo
8+ echo "ERROR: no dependencies were specified"
9+ echo 'Hint: set `nugetSource` if using these hooks individually. If this is happening with `buildDotnetModule`, please open an issue.'
10+ echo
11+12+ exit 1
13+ fi
14+15+ local nugetSourceSedQuoted="${nugetSource//[\/\\&$'\n']/\\&}"
16+ local nugetSourceXMLQuoted="$nugetSource"
17+ nugetSourceXMLQuoted="${nugetSource//&/\&}"
18+ nugetSourceXMLQuoted="${nugetSourceXMLQuoted//\"/\"}"
19+20+ local -r hostRuntimeId=@runtimeId@
21+ local -r dynamicLinker=@dynamicLinker@
22+ local -r libPath=@libPath@
23+ local -r dotnetRuntimeId="${dotnetRuntimeId-$hostRuntimeId}"
24+25+ if [[ -n $__structuredAttrs ]]; then
26+ local dotnetProjectFilesArray=( "${dotnetProjectFiles[@]}" )
27+ local dotnetTestProjectFilesArray=( "${dotnetTestProjectFiles[@]}" )
28+ local dotnetFlagsArray=( "${dotnetFlags[@]}" )
29+ local dotnetRestoreFlagsArray=( "${dotnetRestoreFlags[@]}" )
30+ else
31+ local dotnetProjectFilesArray=($dotnetProjectFiles)
32+ local dotnetTestProjectFilesArray=($dotnetTestProjectFiles)
33+ local dotnetFlagsArray=($dotnetFlags)
34+ local dotnetRestoreFlagsArray=($dotnetRestoreFlags)
35+ fi
36+37+ if [[ -z ${enableParallelBuilding-} ]]; then
38 local -r parallelFlag="--disable-parallel"
39 fi
4041 dotnetRestore() {
42+ local -r projectFile="${1-}"
43+ dotnet restore ${1+"$projectFile"} \
44 -p:ContinuousIntegrationBuild=true \
45 -p:Deterministic=true \
46+ --runtime "$dotnetRuntimeId" \
47+ --source "$nugetSource/lib" \
48 ${parallelFlag-} \
49+ "${dotnetRestoreFlagsArray[@]}" \
50+ "${dotnetFlagsArray[@]}"
51 }
5253 # Generate a NuGet.config file to make sure everything,
54 # including things like <Sdk /> dependencies, is restored from the proper source
55+ cat >NuGet.config <<EOF
56<?xml version="1.0" encoding="utf-8"?>
57<configuration>
58 <packageSources>
59 <clear />
60+ <add key="nugetSource" value="$nugetSourceXMLQuoted/lib" />
61 </packageSources>
62</configuration>
63EOF
6465+ # Patch paket.dependencies and paket.lock (if found) to use the proper
66+ # source. This ensures paket restore works correctly. Note that the
67+ # nugetSourceSedQuoted abomination below safely escapes nugetSource string
68+ # for use as a sed replacement string to avoid issues with slashes and other
69+ # special characters ('&', '\\' and '\n').
70+ find -name paket.dependencies -exec sed -i "s/source .*/source $nugetSourceSedQuoted\/lib/g" {} \;
71+ find -name paket.lock -exec sed -i "s/remote:.*/remote: $nugetSourceSedQuoted\/lib/g" {} \;
7273+ dotnet tool restore --add-source "$nugetSource/lib"
7475+ # dotnetGlobalTool is set in buildDotnetGlobalTool to patch dependencies but
76+ # avoid other project-specific logic. This is a hack, but the old behavior
77+ # is worse as it relied on a bug: setting projectFile to an empty string
78+ # made the hooks actually skip all project-specific logic. It’s hard to keep
79+ # backwards compatibility with this odd behavior now since we are using
80+ # arrays, so instead we just pass a variable to indicate that we don’t have
81+ # projects.
82+ if [[ -z ${dotnetGlobalTool-} ]]; then
83+ if (( ${#dotnetProjectFilesArray[@]} == 0 )); then
84+ dotnetRestore
85+ fi
8687+ local projectFile
88+ for projectFile in "${dotnetProjectFilesArray[@]}" "${dotnetTestProjectFilesArray[@]}"; do
89+ dotnetRestore "$projectFile"
90+ done
91+ fi
9293 echo "Fixing up native binaries..."
94 # Find all native binaries and nuget libraries, and fix them up,
95 # by setting the proper interpreter and rpath to some commonly used libraries
96+ local binary
97 for binary in $(find "$HOME/.nuget/packages/" -type f -executable); do
98 if patchelf --print-interpreter "$binary" >/dev/null 2>/dev/null; then
99 echo "Found binary: $binary, fixing it up..."
100+ patchelf --set-interpreter "$(cat "$dynamicLinker")" "$binary"
101102 # This makes sure that if the binary requires some specific runtime dependencies, it can find it.
103 # This fixes dotnet-built binaries like crossgen2
···108 --add-needed libssl.so \
109 "$binary"
110111+ patchelf --set-rpath "$libPath" "$binary"
112 fi
113 done
114
···1-# Inherit arguments from the derivation
2-declare -a derivationMakeWrapperArgs="( ${makeWrapperArgs-} )"
3-makeWrapperArgs=( "${derivationMakeWrapperArgs[@]}" )
4-5# First argument is the executable you want to wrap,
6# the second is the destination for the wrapper.
7wrapDotnetProgram() {
8- local dotnetRootFlags=()
00000000000000000000910- if [ ! "${selfContainedBuild-}" ]; then
11- if [ "${useDotnetFromEnv-}" ]; then
00000000012 # if dotnet CLI is available, set DOTNET_ROOT based on it. Otherwise set to default .NET runtime
13- dotnetRootFlags+=("--run" 'command -v dotnet &>/dev/null && export DOTNET_ROOT="$(@dirname@ "$(@realpath@ "$(@which@ dotnet)")")" || export DOTNET_ROOT="@dotnetRuntime@"')
14- dotnetRootFlags+=("--suffix" "PATH" ":" "@dotnetRuntime@/bin")
0015 else
16- dotnetRootFlags+=("--set" "DOTNET_ROOT" "@dotnetRuntime@")
17- dotnetRootFlags+=("--prefix" "PATH" ":" "@dotnetRuntime@/bin")
18 fi
19 fi
2021 makeWrapper "$1" "$2" \
22- --suffix "LD_LIBRARY_PATH" : "@runtimeDeps@" \
23- "${dotnetRootFlags[@]}" \
24 "${gappsWrapperArgs[@]}" \
25- "${makeWrapperArgs[@]}"
2627 echo "installed wrapper to "$2""
28}
···30dotnetFixupHook() {
31 echo "Executing dotnetFixupPhase"
3233- # check if executables is declared (including empty values, in which case we generate no executables)
34- if declare -p executables &>/dev/null; then
35- for executable in ${executables[@]}; do
36- path="${installPath-$out/lib/$pname}/$executable"
000000000003738 if test -x "$path"; then
39- wrapDotnetProgram "$path" "$out/bin/$(basename "$executable")"
40 else
41 echo "Specified binary \"$executable\" is either not an executable or does not exist!"
42 echo "Looked in $path"
···45 done
46 else
47 while IFS= read -d '' executable; do
48- wrapDotnetProgram "$executable" "$out/bin/$(basename "$executable")" \;
49- done < <(find "${installPath-$out/lib/$pname}" ! -name "*.dll" -executable -type f -print0)
050 fi
5152 echo "Finished dotnetFixupPhase"
···00001# First argument is the executable you want to wrap,
2# the second is the destination for the wrapper.
3wrapDotnetProgram() {
4+ local -r dotnetRuntime=@dotnetRuntime@
5+ local -r wrapperPath=@wrapperPath@
6+7+ local -r dotnetFromEnvScript='dotnetFromEnv() {
8+ local dotnetPath
9+ if command -v dotnet 2>&1 >/dev/null; then
10+ dotnetPath=$(which dotnet) && \
11+ dotnetPath=$(realpath "$dotnetPath") && \
12+ dotnetPath=$(dirname "$dotnetPath") && \
13+ export DOTNET_ROOT="$dotnetPath"
14+ fi
15+}
16+dotnetFromEnv'
17+18+ if [[ -n $__structuredAttrs ]]; then
19+ local -r dotnetRuntimeDepsArray=( "${dotnetRuntimeDeps[@]}" )
20+ local -r makeWrapperArgsArray=( "${makeWrapperArgs[@]}" )
21+ else
22+ local -r dotnetRuntimeDepsArray=($dotnetRuntimeDeps)
23+ local -r makeWrapperArgsArray=($makeWrapperArgs)
24+ fi
2526+ local dotnetRuntimeDepsFlags=()
27+ if (( ${#dotnetRuntimeDepsArray[@]} > 0 )); then
28+ local libraryPathArray=("${dotnetRuntimeDepsArray[@]/%//lib}")
29+ local OLDIFS="$IFS" IFS=':'
30+ dotnetRuntimeDepsFlags+=("--suffix" "LD_LIBRARY_PATH" ":" "${libraryPathArray[*]}")
31+ IFS="$OLDIFS"
32+ fi
33+34+ local dotnetRootFlagsArray=()
35+ if [[ -z ${dotnetSelfContainedBuild-} ]]; then
36+ if [[ -n ${useDotnetFromEnv-} ]]; then
37 # if dotnet CLI is available, set DOTNET_ROOT based on it. Otherwise set to default .NET runtime
38+ dotnetRootFlagsArray+=("--suffix" "PATH" ":" "$wrapperPath")
39+ dotnetRootFlagsArray+=("--run" "$dotnetFromEnvScript")
40+ dotnetRootFlagsArray+=("--set-default" "DOTNET_ROOT" "$dotnetRuntime")
41+ dotnetRootFlagsArray+=("--suffix" "PATH" ":" "$dotnetRuntime/bin")
42 else
43+ dotnetRootFlagsArray+=("--set" "DOTNET_ROOT" "$dotnetRuntime")
44+ dotnetRootFlagsArray+=("--prefix" "PATH" ":" "$dotnetRuntime/bin")
45 fi
46 fi
4748 makeWrapper "$1" "$2" \
49+ "${dotnetRuntimeDepsFlags[@]}" \
50+ "${dotnetRootFlagsArray[@]}" \
51 "${gappsWrapperArgs[@]}" \
52+ "${makeWrapperArgsArray[@]}"
5354 echo "installed wrapper to "$2""
55}
···57dotnetFixupHook() {
58 echo "Executing dotnetFixupPhase"
5960+ local -r dotnetInstallPath="${dotnetInstallPath-$out/lib/$pname}"
61+62+ local executable executableBasename
63+64+ # check if dotnetExecutables is declared (including empty values, in which case we generate no executables)
65+ if declare -p dotnetExecutables &>/dev/null; then
66+ if [[ -n $__structuredAttrs ]]; then
67+ local dotnetExecutablesArray=( "${dotnetExecutables[@]}" )
68+ else
69+ local dotnetExecutablesArray=($dotnetExecutables)
70+ fi
71+ for executable in "${dotnetExecutablesArray[@]}"; do
72+ executableBasename=$(basename "$executable")
73+74+ local path="$dotnetInstallPath/$executable"
7576 if test -x "$path"; then
77+ wrapDotnetProgram "$path" "$out/bin/$executableBasename"
78 else
79 echo "Specified binary \"$executable\" is either not an executable or does not exist!"
80 echo "Looked in $path"
···83 done
84 else
85 while IFS= read -d '' executable; do
86+ executableBasename=$(basename "$executable")
87+ wrapDotnetProgram "$executable" "$out/bin/$executableBasename" \;
88+ done < <(find "$dotnetInstallPath" ! -name "*.dll" -executable -type f -print0)
89 fi
9091 echo "Finished dotnetFixupPhase"
···1+# This file was automatically generated by passthru.fetch-deps.
2+# Please dont edit it manually, your changes might get overwritten!
3+4+{ fetchNuGet }: [
5+]
···1+# This file was automatically generated by passthru.fetch-deps.
2+# Please dont edit it manually, your changes might get overwritten!
3+4+{ fetchNuGet }: [
5+]