summaryrefslogtreecommitdiff
path: root/Tools/packageresolve.targets
blob: 65214b5a3b3f448139a12c515fc001504a36819b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <UsingTask TaskName="PrereleaseResolveNuGetPackageAssets" AssemblyFile="$(BuildToolsTaskDir)Microsoft.DotNet.Build.Tasks.dll"/>
  <UsingTask TaskName="ValidateProjectDependencyVersions" AssemblyFile="$(BuildToolsTaskDir)Microsoft.DotNet.Build.Tasks.dll"/>
  <UsingTask TaskName="IsRestoreRequired" AssemblyFile="$(BuildToolsTaskDir)Microsoft.DotNet.Build.Tasks.dll"/>

  <PropertyGroup>
    <ProjectJson Condition="'$(ProjectJson)' == '' and '$(ContainsPackageReferences)' == 'true'">$(MSBuildProjectFullPath)</ProjectJson>
    <RestoreOutputPath Condition="'$(RestoreOutputPath)' == ''">$(MSBuildProjectDirectory)</RestoreOutputPath>
    <RestoreOutputPath Condition="'$(ContainsPackageReferences)' != 'true' And '$(ProjectJson)' != ''">$([System.IO.Path]::GetDirectoryName('$(ProjectJson)'))/obj</RestoreOutputPath>
    <!-- SDK targets need this to be set in addition to RestoreOutputPath. See https://github.com/dotnet/sdk/issues/1057 -->
    <ProjectAssetsFile>$(RestoreOutputPath)/project.assets.json</ProjectAssetsFile>
    <ResolveNugetProjectFile Condition="'$(ResolveNugetProjectFile)' == ''">$(MSBuildProjectFullPath)</ResolveNugetProjectFile>
    <RestorePackages Condition="'$(RestorePackages)'!='false' and Exists('$(ProjectJson)') and '$(DesignTimeBuild)' != 'true'">true</RestorePackages>
    <PrereleaseResolveNuGetPackages Condition="'$(PrereleaseResolveNuGetPackages)'!='false' and Exists('$(ProjectJson)')">true</PrereleaseResolveNuGetPackages>

    <!--
        For now, prevent built-in task (if available) from running.
        More changes are needed to light up on their availability
        and use them instead of what we have here. See buildtools
        issue #192.
     -->
    <ResolveNugetPackages>false</ResolveNugetPackages>
  </PropertyGroup>

  <!-- Restoring packages during a background (designtime) build will cause VS 2015 (v14) to get into an endless loop of resolving references. -->
  <Target Name="RestorePackages"
          BeforeTargets="ResolveNuGetPackages;ValidatePackageVersions"
          Condition="'$(RestorePackages)'=='true' and !('$(VSDesignTimeBuild)'=='true' and '$(VisualStudioVersion)' >= '14.0')">

    <Error Condition="'$(DnuRestoreCommand)'=='' and Exists('$(ProjectJson)')" Text="RestorePackages target needs a predefined DnuRestoreCommand property set in order to restore $(ProjectJson)" />

    <IsRestoreRequired ProjectJsons="$(ProjectJson)" PackagesFolder="$(PackagesDir)">
      <Output TaskParameter="RestoreRequired" PropertyName="RestoreRequired" />
    </IsRestoreRequired>

    <PropertyGroup>
      <_RepoApiAdditionalRestoreArgs Condition="'$(DotNetRestoreSourcePropsPath)' != ''">/p:DotNetRestoreSourcePropsPath=$(DotNetRestoreSourcePropsPath)</_RepoApiAdditionalRestoreArgs>
      <_RepoApiAdditionalRestoreArgs Condition="'$(DotNetPackageVersionPropsPath)' != ''">$(_RepoApiAdditionalRestoreArgs) /p:DotNetPackageVersionPropsPath=$(DotNetPackageVersionPropsPath)</_RepoApiAdditionalRestoreArgs>
      <_RepoApiAdditionalRestoreArgs Condition="'$(DotNetBuildOffline)' != ''">$(_RepoApiAdditionalRestoreArgs) /p:DotNetBuildOffline=$(DotNetBuildOffline)</_RepoApiAdditionalRestoreArgs>
      <_RepoApiAdditionalRestoreArgs Condition="'$(EnablePackageRestoreLogger)' == 'true'">$(_RepoApiAdditionalRestoreArgs) /l:PackageRestoreLogger,$(MSBuildThisFileDirectory)Microsoft.DotNet.Build.Tasks.dll</_RepoApiAdditionalRestoreArgs>
      <AdditionalRestoreArgs Condition="'$(_RepoApiAdditionalRestoreArgs)' != ''">$(AdditionalRestoreArgs) $(_RepoApiAdditionalRestoreArgs)</AdditionalRestoreArgs>

      <_DnuRestoreCommandRidPortion Condition="'$(RidSpecificAssets)' == 'true'">-r $(NuGetRuntimeIdentifier)</_DnuRestoreCommandRidPortion>
      <_DnuRestoreCommandFull>$(DnuRestoreCommand) $(ProjectJson) /p:TargetGroup=$(TargetGroup) /p:ConfigurationGroup=$(ConfigurationGroup) /p:ArchGroup=$(ArchGroup) /p:OSGroup=$(OSGroup) /p:TargetFramework=$(NuGetTargetMonikerShort) $(_DnuRestoreCommandRidPortion) $(AdditionalRestoreArgs)</_DnuRestoreCommandFull>
    </PropertyGroup>
    <Exec Condition="Exists('$(ProjectJson)') AND '$(RestoreRequired)' == 'true' AND '$(EnablePackageRestoreLogger)' != 'true'" Command="$(_DnuRestoreCommandFull)" StandardOutputImportance="Low" CustomErrorRegularExpression="^Unable to locate .*" />
    <Exec Condition="Exists('$(ProjectJson)') AND '$(RestoreRequired)' == 'true' AND '$(EnablePackageRestoreLogger)' == 'true'" Command="$(_DnuRestoreCommandFull)" CustomErrorRegularExpression="^Unable to locate .*" />
    
    <!-- if lock file exists be sure to update timestamp otherwise we could get in a state of aways calling restore but the lock file not being updated -->
    <Touch Condition="Exists('$(ProjectAssetsFile)') AND '$(RestoreRequired)' == 'true'" Files="$(ProjectAssetsFile)" />
  </Target>

  <ItemGroup Condition="'$(ResolvePackages)'=='true' or '$(PrereleaseResolveNuGetPackages)'=='true'">
    <CustomAdditionalCompileInputs Condition="Exists('$(ProjectJson)')" Include="$(ProjectJson)" />
  </ItemGroup>
  <PropertyGroup>
    <ResolveAssemblyReferencesDependsOn>
      $(ResolveAssemblyReferencesDependsOn);
      ResolveNuGetPackages;
      ValidatePackageVersions;
    </ResolveAssemblyReferencesDependsOn>
  </PropertyGroup>

  <PropertyGroup>
    <!-- temporarily accept the old name NuGetTargetFrameworkMoniker until all projects are moved forward -->
    <NuGetTargetMoniker Condition="'$(NuGetTargetMoniker)' == ''">$(NuGetTargetFrameworkMoniker)</NuGetTargetMoniker>
    <UseTargetPlatformAsNuGetTargetMoniker Condition="'$(UseTargetPlatformAsNuGetTargetMoniker)' == '' AND '$(TargetFrameworkMoniker)' == '.NETCore,Version=v5.0'">true</UseTargetPlatformAsNuGetTargetMoniker>
    <NuGetTargetMoniker Condition="'$(NuGetTargetMoniker)' == '' AND '$(UseTargetPlatformAsNuGetTargetMoniker)' == 'true'">$(TargetPlatformIdentifier),Version=v$([System.Version]::Parse('$(TargetPlatformMinVersion)').ToString(3))</NuGetTargetMoniker>
    <NuGetTargetMoniker Condition="'$(NuGetTargetMoniker)' == '' AND '$(UseTargetPlatformAsNuGetTargetMoniker)' != 'true'">$(TargetFrameworkMoniker)</NuGetTargetMoniker>
    <BaseNuGetRuntimeIdentifier Condition="'$(BaseNuGetRuntimeIdentifier)' == '' and '$(TargetPlatformIdentifier)' == 'UAP'">win10</BaseNuGetRuntimeIdentifier>
    <BaseNuGetRuntimeIdentifier Condition="'$(BaseNuGetRuntimeIdentifier)' == ''">win</BaseNuGetRuntimeIdentifier>
    <CopyNuGetImplementations Condition="'$(CopyNuGetImplementations)' == '' and '$(OutputType)' != 'library' and ('$(OutputType)' != 'winmdobj' or '$(AppxPackage)' == 'true')">true</CopyNuGetImplementations>
  </PropertyGroup>

  <!-- If a RuntimeIndentifier wasn't already specified, let's go generate it -->
  <PropertyGroup Condition="'$(NuGetRuntimeIdentifier)' == '' and '$(CopyNuGetImplementations)' == 'true'">
    <_NuGetRuntimeIdentifierWithoutAot>$(BaseNuGetRuntimeIdentifier)-$(PlatformTarget.ToLower())</_NuGetRuntimeIdentifierWithoutAot>
    <NuGetRuntimeIdentifier>$(_NuGetRuntimeIdentifierWithoutAot)</NuGetRuntimeIdentifier>
    <NuGetRuntimeIdentifier Condition="'$(UseDotNetNativeToolchain)' == 'true'">$(_NuGetRuntimeIdentifierWithoutAot)-aot</NuGetRuntimeIdentifier>
  </PropertyGroup>

  <!-- Some projects want to explicitly use no runtime identifier, and do not want to receive any default value provided by other targets. -->
  <PropertyGroup Condition="'$(NuGetRuntimeIdentifier)' == 'None'">
    <NuGetRuntimeIdentifier></NuGetRuntimeIdentifier>
  </PropertyGroup>

  <Target Name="ResolveNuGetPackages"
          Condition="'$(PrereleaseResolveNuGetPackages)'=='true'"
          DependsOnTargets="$(ResolveNugetPackagesDependsOn)">

    <PrereleaseResolveNuGetPackageAssets Condition="Exists('$(ProjectAssetsFile)')"
                               AllowFallbackOnTargetSelection="true"
                               IncludeFrameworkReferences="false"
                               NuGetPackagesDirectory="$(PackagesDir)"
                               RuntimeIdentifier="$(NuGetRuntimeIdentifier)"
                               ProjectLanguage="$(Language)"
                               ProjectLockFile="$(ProjectAssetsFile)"
                               TargetMonikers="$(NuGetTargetMoniker)"
                               ProjectReferencesCreatingPackages="@(ProjectReference)">
      <Output TaskParameter="ResolvedAnalyzers" ItemName="Analyzer" />
      <Output TaskParameter="ResolvedReferences" ItemName="_ReferenceFromPackage" />
      <Output TaskParameter="ResolvedCopyLocalItems" ItemName="_ReferenceCopyLocalPathsFromPackage" />
      <Output TaskParameter="ReferencedPackages" ItemName="ReferencedNuGetPackages" />
    </PrereleaseResolveNuGetPackageAssets>

    <!-- We may have package references that we want to replace with project references -->
    <ItemGroup>
      <!-- Intersect project-refs with package-refs.
             Project refs may be in _ResolvedProjectReferencePaths or Reference items.
             Copy local may be in _ResolvedProjectReferencePaths or ReferenceCopyLocalPaths.
             Copy local items may also be in any item like Content but we currently don't strip those.-->
      <_ReferenceFileNamesToRemove Include="@(_ReferenceFromPackage)" Condition="'@(_ResolvedProjectReferencePaths->'%(FileName)%(Extension)')' == '%(FileName)%(Extension)'" />
      <_ReferenceFileNamesToRemove Include="@(_ReferenceFromPackage)" Condition="'@(Reference->'%(FileName)%(Extension)')' == '%(FileName)%(Extension)'" />

      <!-- If local copy is disabled remove all references, otherwise remove only project refrerences -->
      <_ReferenceCopyLocalPathsFileNamesToRemove Include="@(_ReferenceCopyLocalPathsFromPackage)" Condition="'$(DisableReferenceCopyLocal)' == 'true' OR '@(_ResolvedProjectReferencePaths->'%(FileName)%(Extension)')' == '%(FileName)%(Extension)'" />
      <_ReferenceCopyLocalPathsFileNamesToRemove Include="@(_ReferenceCopyLocalPathsFromPackage)" Condition="'$(DisableReferenceCopyLocal)' == 'true' OR '@(ReferenceCopyLocalPaths->'%(FileName)%(Extension)')' == '%(FileName)%(Extension)'" />

      <!-- strip from the resolved package output -->
      <_ReferenceFromPackage Remove="@(_ReferenceFileNamesToRemove)" />
      <_ReferenceCopyLocalPathsFromPackage Remove="@(_ReferenceCopyLocalPathsFileNamesToRemove)" />

      <!-- add the filtered resolved package output -->
      <Reference Include="@(_ReferenceFromPackage)" />
      <ReferenceCopyLocalPaths Include="@(_ReferenceCopyLocalPathsFromPackage)" />
    </ItemGroup>

    <Message Text="Excluding @(_ReferenceFileNamesToRemove);@(_ReferenceCopyLocalPathsFileNamesToRemove) from package references since the same file is provided by a project reference."
             Condition="'@(_ReferenceFileNamesToRemove)' != '' or '@(_ReferenceCopyLocalPathsFileNamesToRemove)' != ''"/>
  </Target>

  <Target Name="RemoveTransitiveCompileReferences"
          AfterTargets="ResolveNuGetPackages">
    <ItemGroup Condition="'$(OmitTransitiveCompileReferences)' == 'true'">
      <!-- get all references from nuget packages as ID so that we can substract the direct ref IDs-->
      <_ReferenceAsPackageId Include="@(Reference->'%(NuGetPackageId)')" Condition="'%(Reference.NuGetPackageId)' != ''">
        <OriginalIdentity>%(Identity)</OriginalIdentity>
      </_ReferenceAsPackageId>

      <!-- Indirect references are any references whose PackageId isn't in the direct reference set: ReferencedNuGetPackages -->
      <_IndirectReferenceAsPackageId Include="@(_ReferenceAsPackageId)" Exclude="@(ReferencedNuGetPackages)"/>

      <!-- Transform back to original -->
      <IndirectReference Include="@(_IndirectReferenceAsPackageId->'%(OriginalIdentity)')" />

      <Reference Remove="@(IndirectReference)"/>
    </ItemGroup>
  </Target>

  <Target Name="ValidatePackageVersions"
          Condition="'$(RestorePackages)'=='true' and '$(ValidatePackageVersions)'=='true' and Exists('$(ProjectJson)')">
    <ValidateProjectDependencyVersions ProjectJsons="$(ProjectJson)"
                                       ProhibitFloatingDependencies="$(ProhibitFloatingDependencies)"
                                       ValidationPatterns="@(ValidationPattern)" />
  </Target>

  <Target Name="FilterTargetingPackResolvedNugetPackages"
          Condition="'$(SkipFilterTargetingPackResolvedNugetPackages)' != 'true'"
          AfterTargets="ResolveNuGetPackages" >
    <PropertyGroup>
      <_TargetingPackPrefix>Microsoft.TargetingPack</_TargetingPackPrefix>
      <TargetingPackReferenceCoreAssembly Condition="'$(TargetingPackReferenceCoreAssembly)' == '' and '%(TargetingPackReference.Identity)' == 'System.Private.CoreLib'">System.Private.CoreLib</TargetingPackReferenceCoreAssembly>
      <TargetingPackReferenceCoreAssembly Condition="'$(TargetingPackReferenceCoreAssembly)' == ''">mscorlib</TargetingPackReferenceCoreAssembly>

      <!--
        S.P.CoreLib is generally architecture specific so disable the msbuild warning about
        referencing it from an MSIL project.
        -->
      <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch Condition="'$(TargetingPackReferenceCoreAssembly)' == 'System.Private.CoreLib'">None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
    </PropertyGroup>

    <!--
      Add the mscorlib and windows to the reference set by default to avoid a lot of duplication in projects
      They only act as a filter so if they aren't present in the packages references it will not impact anything.
    -->
    <ItemGroup Condition="'$(ExcludeDefaultTargetingPackReferences)' != 'true'">
      <TargetingPackReference Include="$(TargetingPackReferenceCoreAssembly)" Condition="'$(TargetingPackReferenceCoreAssembly)' != ''" />
      <TargetingPackReference Include="Windows" />
    </ItemGroup>

    <ItemGroup>
      <!-- Filter out all references coming out of the targeting pack packages except for TargetingPackReferences -->
      <ResolvedTargetingPackReference Include="@(Reference)"
        Condition="$([System.String]::new('%(Reference.NuGetPackageId)').StartsWith('$(_TargetingPackPrefix)'))" />
      <ResolvedTargetingPackReferenceFilename Include="@(ResolvedTargetingPackReference -> '%(Filename)')">
        <OriginalIdentity>%(Identity)</OriginalIdentity>
      </ResolvedTargetingPackReferenceFilename>
      <ResolvedTargetingPackReferenceFilename Remove="@(TargetingPackReference)" />
      <PackageReferencesToRemove Include="@(ResolvedTargetingPackReferenceFilename -> '%(OriginalIdentity)')" />
      <Reference Remove="@(PackageReferencesToRemove)" />

      <!-- Filter out the copy-local set of references coming from the targeting pack packages -->
      <PackageCopyLocalToRemove Include="@(ReferenceCopyLocalPaths)"
        Condition="$([System.String]::new('%(ReferenceCopyLocalPaths.NuGetPackageId)').StartsWith('$(_TargetingPackPrefix)'))" />
      <ReferenceCopyLocalPaths Remove="@(PackageCopyLocalToRemove)" />
    </ItemGroup>

    <Message Importance="Low"
             Text="Removed all ResolvedTagetingPackReferences that were not specified explicitly as a TargetingPackReference=[@(TargetingPackReference)]. PackageReferencesToRemove=[@(PackageReferencesToRemove)]." />
  </Target>
</Project>