1# shellcheck shell=bash disable=SC2154
2export MSBUILDALWAYSOVERWRITEREADONLYFILES=1
3export MSBUILDTERMINALLOGGER=false
4
5declare -Ag _nugetInputs
6
7addNugetInputs() {
8 if [[ -d $1/share/nuget ]]; then
9 _nugetInputs[$1]=1
10 fi
11}
12
13addEnvHooks "$targetOffset" addNugetInputs
14
15_linkPackages() {
16 local -r src="$1"
17 local -r dest="$2"
18 local dir
19 local x
20
21 (
22 shopt -s nullglob
23 for x in "$src"/*/*; do
24 dir=$dest/$(basename "$(dirname "$x")")
25 mkdir -p "$dir"
26 ln -s "$x" "$dir"/
27 done
28 )
29}
30
31configureNuget() {
32 runHook preConfigureNuGet
33
34 local nugetTemp x
35
36 nugetTemp="$(mktemp -dt nuget.XXXXXX)"
37 # trailing slash required here:
38 # Microsoft.Managed.Core.targets(236,5): error : SourceRoot paths are required to end with a slash or backslash: '/build/.nuget-temp/packages'
39 # also e.g. from avalonia:
40 # <EmbeddedResource Include="$(NuGetPackageRoot)sourcelink/1.1.0/tools/pdbstr.exe" />
41 export NUGET_PACKAGES=$nugetTemp/packages/
42 export NUGET_FALLBACK_PACKAGES=$nugetTemp/fallback/
43 nugetSource=$nugetTemp/source
44 mkdir -p "${NUGET_PACKAGES%/}" "${NUGET_FALLBACK_PACKAGES%/}" "$nugetSource"
45
46 for x in "${!_nugetInputs[@]}"; do
47 if [[ -d $x/share/nuget/packages ]]; then
48 _linkPackages "$x/share/nuget/packages" "${NUGET_FALLBACK_PACKAGES%/}"
49 fi
50
51 if [[ -d $x/share/nuget/source ]]; then
52 _linkPackages "$x/share/nuget/source" "$nugetSource"
53 fi
54 done
55
56 if [[ -f .config/dotnet-tools.json
57 || -f dotnet-tools.json ]]; then
58 : ${linkNugetPackages=1}
59 fi
60
61 if [[ -z ${keepNugetConfig-} && -f paket.dependencies ]]; then
62 sed -i "s:source .*:source $nugetSource:" paket.dependencies
63 sed -i "s:remote\:.*:remote\: $nugetSource:" paket.lock
64
65 : ${linkNuGetPackagesAndSources=1}
66 fi
67
68 if [[ -n ${linkNuGetPackagesAndSources-} ]]; then
69 for x in "${!_nugetInputs[@]}"; do
70 if [[ -d $x/share/nuget/source ]]; then
71 @lndir@/bin/lndir -silent "$x/share/nuget/packages" "${NUGET_PACKAGES%/}"
72 @lndir@/bin/lndir -silent "$x/share/nuget/source" "${NUGET_PACKAGES%/}"
73 fi
74 done
75 elif [[ -n ${linkNugetPackages-} ]]; then
76 for x in "${!_nugetInputs[@]}"; do
77 if [[ -d $x/share/nuget/packages ]]; then
78 _linkPackages "$x/share/nuget/packages" "${NUGET_PACKAGES%/}"
79 fi
80 done
81 fi
82
83 # create a root nuget.config if one doesn't exist
84 local rootConfig
85 rootConfig=$(find . -maxdepth 1 -iname nuget.config -print -quit)
86 if [[ -z $rootConfig ]]; then
87 dotnet new nugetconfig
88 rootConfig=nuget.config
89 fi
90
91 (
92 shopt -s nullglob
93
94 local -a xmlConfigArgs=() xmlRootConfigArgs=()
95
96 local -ra xmlSourceConfigArgs=(
97 -s /configuration -t elem -n packageSources
98 -d '/configuration/packageSources[position() != 1]'
99 -s /configuration/packageSources -t elem -n __new
100 -i /configuration/packageSources/__new -t attr -n key -v _nix
101 -i /configuration/packageSources/__new -t attr -n value -v "$nugetSource"
102 -r /configuration/packageSources/__new -v add)
103
104 if [[ -n ${keepNugetConfig-} ]] &&
105 ! @xmlstarlet@/bin/xmlstarlet select -t -i "/configuration/packageSources/clear" -nl "$rootConfig" &&
106 ! @xmlstarlet@/bin/xmlstarlet select -t -i "/configuration/packageSources/add[@value='https://api.nuget.org/v3/index.json' or @key='nuget.org']" -nl "$rootConfig"; then
107 dotnet nuget add source https://api.nuget.org/v3/index.json --name nuget.org --configfile "$rootConfig"
108 fi
109
110 if [[ -z ${keepNugetConfig-} ]]; then
111 xmlConfigArgs+=(-d '//configuration/*')
112 xmlRootConfigArgs+=("${xmlSourceConfigArgs[@]}")
113 else
114 if [[ -n ${mapNuGetDependencies-} ]]; then
115 xmlConfigArgs+=(
116 -s /configuration -t elem -n __tmp
117 # If there's no packageSourceMapping, we need to add * patterns for
118 # all the sources, else they won't be used.
119 -u \$prev -x ../packageSources/add
120 -d '/configuration/__tmp/add/@*[name() != "key"]'
121 -r /configuration/__tmp/add -v packageSource
122 -s /configuration/__tmp/packageSource -t elem -n package
123 -i \$prev -t attr -n pattern -v \*
124 -r /configuration/__tmp -v packageSourceMapping
125 -d '/configuration/packageSourceMapping[position() != 1]'
126 "${xmlSourceConfigArgs[@]}"
127 # add package source mappings from all existing patterns to _nix
128 # this ensures _nix is always considered
129 -s /configuration/packageSourceMapping -t elem -n packageSource
130 -u \$prev -x ../packageSource/package
131 -i \$prev -t attr -n key -v _nix)
132
133 cd "$nugetSource"
134 local id
135 for id in *; do
136 id=${id,,}
137 xmlConfigArgs+=(
138 # unmap any fully-qualified patterns that exist, so they
139 # can't be used, using a horrific method for
140 # case-insensitivity in xpath1
141 -d "/configuration/packageSourceMapping/packageSource/package[translate(@pattern, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = ${id@Q}]"
142 -s '/configuration/packageSourceMapping/packageSource[@key="_nix"]' -t elem -n package
143 -i \$prev -t attr -n pattern -v "$id")
144 done
145 cd - > /dev/null
146 else
147 xmlConfigArgs+=(
148 "${xmlSourceConfigArgs[@]}"
149 # add package source mappings from all existing patterns to _nix
150 # this ensures _nix is always considered
151 -s /configuration/packageSourceMapping -t elem -n packageSource
152 -u \$prev -x '../packageSource/package'
153 -i \$prev -t attr -n key -v _nix
154 # delete empty _nix mapping
155 -d '/configuration/packageSourceMapping/packageSource[@key="_nix" and not(*)]')
156 fi
157 fi
158
159 # try to stop the global config from having any effect
160 if [[ -z ${keepNugetConfig-} || -z ${allowGlobalNuGetConfig-} ]]; then
161 local -ar configSections=(
162 config
163 bindingRedirects
164 packageRestore
165 solution
166 packageSources
167 auditSources
168 apikeys
169 disabledPackageSources
170 activePackageSource
171 fallbackPackageFolders
172 packageSourceMapping
173 packageManagement)
174
175 for section in "${configSections[@]}"; do
176 xmlRootConfigArgs+=(
177 -s /configuration -t elem -n "$section"
178 # hacky way of ensuring we use existing sections when they exist
179 -d "/configuration/$section[position() != 1]"
180 # hacky way of adding to the start of a possibly empty element
181 -s "/configuration/$section" -t elem -n __unused
182 -i "/configuration/$section/*[1]" -t elem -n clear
183 -d "/configuration/$section/__unused"
184 # delete consecutive clears
185 # these actually cause nuget tools to fail in some cases
186 -d "/configuration/$section/clear[position() = 2 and name() = \"clear\"]")
187 done
188 fi
189
190 find . \( -iname nuget.config \) -print0 | while IFS= read -rd "" config; do
191 local dir isRoot=
192
193 dir=$(dirname "$config")
194 [[ $dir != . ]] || isRoot=1
195
196 @xmlstarlet@/bin/xmlstarlet \
197 ed --inplace \
198 "${xmlConfigArgs[@]}" \
199 ${isRoot:+"${xmlRootConfigArgs[@]}"} \
200 "$config"
201 done
202 )
203
204 runHook postConfigureNuGet
205}
206
207if [[ -z ${dontConfigureNuget-} ]]; then
208 appendToVar preConfigurePhases configureNuget
209fi