Skip to content

Commit 919235a

Browse files
V4 fork (#148)
* Big V4 Update. PS1/XDT ==> MSBuild migration. * Fix preview versioning. * Rev to 4.1-rtm
1 parent 6b67ad9 commit 919235a

16 files changed

Lines changed: 251 additions & 570 deletions

README.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@ Please see the blog [Enabling the .NET Compiler Platform (“Roslyn”) in ASP.N
55
for an introduction to Microsoft.CodeDom.Providers.DotNetCompilerPlatform.
66

77
## Updates
8+
+ #### Version 4.1.0 (preview1)
9+
- #### Refreshed current compilers
10+
In keeping with the new versioning scheme for this project, the version has been revved to 4.1 to match the version of the compilers included.
11+
12+
- #### No more old compilers
13+
Stop carrying old versions of compilers. If you upgrade to get new compilers, you get new compilers. The old compilers that might carry references to binaries that get flagged in security scans even though the binaries don't get copied to the ouput directory... they just won't be included in the package anymore.
14+
15+
- #### .Net >= 4.7.2
16+
As a result of not keeping older compilers packaged in this project, we can no longer support versions before 4.7.2 because compiler versions 3.0 and newer only support 4.7.2+.
17+
18+
- #### Drop install.ps1, Rely more on msbuild
19+
Nuget has moved on from install.ps1. We had one foot in the msbuild camp before, and one foot still in the install.ps1 camp. Time to just jump in with both feet. See the 'RoslynRegisterInConfig' setting description below.
20+
821
+ #### Version 3.11.0 (preview1)
922
- #### Refreshed compilers
1023
In keeping with the new versioning scheme for this project, the version has been revved to 3.11 to match the version of the compilers included.
@@ -46,13 +59,28 @@ for an introduction to Microsoft.CodeDom.Providers.DotNetCompilerPlatform.
4659
Generally, command-line options for the codedom compilers can be specified using the `compilerOptions` attribute of the compiler when it is registered in configuration. There are however, a handful of options for controlling some behaviors of this package that are not command-line options. These options fall into two broad categories and can be set as follows:
4760

4861
### Build-time Options
49-
+ **Specify the path to copy Roslyn compiler at build time** - When building projects, target files included by the Microsoft.CodeDom.Providers.DotNetCompilerPlatform nupkg will copy appropriate Roslyn compiler into bin\roslyn folder. With this setting, you can specify a custom path from which the build process will copy the Roslyn compiler, rather than using one of the pre-packaged Roslyn compilers.
62+
+ **(V2) Specify the path to copy Roslyn compiler at build time** - When building projects, target files included by the Microsoft.CodeDom.Providers.DotNetCompilerPlatform nupkg will copy appropriate Roslyn compiler into bin\roslyn folder. With this setting, you can specify a custom path from which the build process will copy the Roslyn compiler, rather than using one of the pre-packaged Roslyn compilers.
5063

5164
**Setting name** - RoslynToolPath
5265

5366
**How to use it** - ```msbuild mysolution.sln /t:build /p:RoslynToolPath="[Roslyn compiler folder full path]"```
5467

5568
**Use case** - In 2.0.0 version, Microsoft.CodeDom.Providers.DotNetCompilerPlatform nupkg removes the dependency on Microsoft.Net.Compilers nupkg. Instead, it embeds one version of Roslyn compiler inside the nupkg. It's possible that the embeded version of Roslyn compiler is not the one you want, so through this setting you can specify a version of Roslyn compiler at build time which will be copied to bin\roslyn folder.
69+
70+
+ **(V4) Skip copying Roslyn compiler at build time** - When building projects, target files will copy the appropriate binaries specified by the 'RoslynToolPath' setting described above and copy them into the project output for runtime use. This copy step can be skipped by using this project setting.
71+
72+
**Setting name** - RoslynCopyToOutDir
73+
74+
**How to use it** - ```msbuild mysolution.sln /t:build /p:RoslynCopyToOutDir="[true|false]"```
75+
76+
+ **(V4) Don't modify config at build time** - CodeDom providers are not magically picked up from referenced assemblies. They must be explicitly registered in config in order to be used. Prior to the Version 4 update, all modifications to config were performed via powershell scripts included in the nuget package. This powershell method worked with 'packages.config' apps, but does not work with 'PackageReference' apps. As more applications move towards the preferred 'PackageReference' way of doing things, we have updated our method of config registration to be an msbuild task instead of a powershell install script. We take care not to stomp over existing settings. But this step gets checked/performed on every build now instead of just on package install. Use this setting to skip the config update.
77+
78+
**Setting name** - RoslynRegisterInConfig
79+
80+
**How to use it** - ```msbuild mysolution.sln /t:build /p:RoslynRegisterInConfig="[true|false]"```
81+
82+
**Use case** - This config-manipulation step happens on ever build. (Even designer builds.) We take care to be as non-invasive as possible, but if you want us to stay entirely hands-off and update your config registrations manually, this setting enables that.
83+
5684
### Run-time Options
5785
+ **Specify the path to load Roslyn compiler at runtime** - When asp.net compiles the views at runtime or precompile time(using aspnet_compiler to precompile the web app), Microsoft.CodeDom.Providers.DotNetCompilerPlatform needs a path to load Roslyn compiler. This setting can be used to specify this loading path.
5886

RoslynCodeProviderTest/CommonCodeDomProviderTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ public void AssemblyVersion(CodeDomProvider provider)
1919
{
2020
var ver = provider.GetType().Assembly.GetName().Version;
2121

22-
Assert.Equal(3, ver.Major);
23-
Assert.Equal(11, ver.Minor);
22+
Assert.Equal(4, ver.Major);
23+
Assert.Equal(1, ver.Minor);
2424
}
2525

2626
public void FileExtension(CodeDomProvider provider, string extension) {
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.IO;
7+
using System.Net;
8+
using System.Xml;
9+
using Microsoft.Build.Framework;
10+
using Microsoft.Build.Utilities;
11+
12+
namespace DotNetCompilerPlatformTasks
13+
{
14+
public class UpdateCompilerConfigRecord : Task
15+
{
16+
[Required]
17+
public string ConfigFile { get; set; }
18+
[Required]
19+
public string Extension { get; set; }
20+
[Required]
21+
public string Language { get; set; }
22+
[Required]
23+
public string WarningLevel { get; set; }
24+
[Required]
25+
public string Options { get; set; }
26+
[Required]
27+
public string CompilerType { get; set; }
28+
29+
private readonly string singleTab = " ";
30+
31+
32+
public override bool Execute()
33+
{
34+
try
35+
{
36+
XmlDocument config = new XmlDocument() { PreserveWhitespace = true };
37+
config.Load(ConfigFile);
38+
39+
// Look for existing 'compiler' record first. Keying on 'extension' is a little dubious since that attribute can
40+
// technically be a ';' separated list of extensions... but it's what we always seemed to do in the past.
41+
XmlNode compiler = config.SelectSingleNode($"/configuration/system.codedom/compilers/compiler[@extension='{Extension}']");
42+
43+
// Create the 'compiler' record if not found.
44+
if (compiler == null)
45+
{
46+
string indent = "";
47+
XmlElement e = CreateElement(config, "system.codedom/compilers", "compiler", ref indent);
48+
e.SetAttribute("language", Language);
49+
e.SetAttribute("extension", Extension);
50+
e.SetAttribute("warningLevel", WarningLevel);
51+
e.SetAttribute("compilerOptions", Options);
52+
e.SetAttribute("type", CompilerType);
53+
54+
// Add a 'providerOption' to not do ASP.Net "magic" within the codedom provider if not working on web.config
55+
if (!ConfigFile.EndsWith("web.config", System.StringComparison.InvariantCultureIgnoreCase))
56+
{
57+
XmlElement pOpt = CreateIndentedElement(e, "providerOption", indent + singleTab);
58+
pOpt.SetAttribute("name", "UseAspNetSettings");
59+
pOpt.SetAttribute("value", "false");
60+
}
61+
62+
config.Save(ConfigFile);
63+
return true;
64+
}
65+
66+
// Otherwise, leave the existing compiler alone - including any 'providerOptions' - except...
67+
// Ensure the 'type' value is current.
68+
var typeAttr = compiler.Attributes["type"];
69+
if (typeAttr == null || string.Compare(typeAttr.Value, CompilerType, System.StringComparison.InvariantCultureIgnoreCase) != 0)
70+
{
71+
typeAttr = config.CreateAttribute("type");
72+
typeAttr.Value = CompilerType;
73+
compiler.Attributes.SetNamedItem(typeAttr);
74+
config.Save(ConfigFile);
75+
}
76+
}
77+
catch (Exception e)
78+
{
79+
Log.LogErrorFromException(e);
80+
return false;
81+
}
82+
83+
return true;
84+
}
85+
86+
private XmlElement CreateElement(XmlDocument doc, string path, string name, ref string indent)
87+
{
88+
XmlElement current = doc.DocumentElement;
89+
90+
foreach (var partName in path.Trim('/').Split('/'))
91+
{
92+
if (string.IsNullOrWhiteSpace(partName))
93+
continue;
94+
95+
current = (current.SelectSingleNode(partName) as XmlElement) ?? CreateIndentedElement(current, partName, indent);
96+
indent += singleTab;
97+
}
98+
99+
return CreateIndentedElement(current, name, indent);
100+
}
101+
102+
private XmlElement CreateIndentedElement(XmlNode parent, string name, string indent)
103+
{
104+
if (!parent.HasChildNodes)
105+
parent.AppendChild(parent.OwnerDocument.CreateWhitespace(Environment.NewLine + indent + singleTab));
106+
else
107+
parent.AppendChild(parent.OwnerDocument.CreateWhitespace(singleTab));
108+
109+
XmlElement e = parent.AppendChild(parent.OwnerDocument.CreateElement(name)) as XmlElement;
110+
parent.AppendChild(parent.OwnerDocument.CreateWhitespace(Environment.NewLine + indent));
111+
return e;
112+
}
113+
}
114+
}

src/Packages/Microsoft.CodeDom.Providers.DotNetCompilerPlatform/Microsoft.CodeDom.Providers.DotNetCompilerPlatform.nuproj

Lines changed: 6 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@
1010
<ItemGroup>
1111
<NuGetContent Include="$(AssemblyName).dll">
1212
<Source>$(AssemblyPath)</Source>
13-
<Destination>lib\net462</Destination>
13+
<Destination>lib\net472</Destination>
1414
</NuGetContent>
1515
<NuGetContent Include="$(AssemblyName).xml">
1616
<Source>$(OutputPath)</Source>
17-
<Destination>lib\net462</Destination>
17+
<Destination>lib\net472</Destination>
1818
</NuGetContent>
1919
<NuGetContent Include="$(AssemblyName).pdb" Condition="'$(NuGetPackSymbols)' == 'true'">
2020
<Source>$(OutputPath)</Source>
21-
<Destination>lib\net462</Destination>
21+
<Destination>lib\net472</Destination>
2222
</NuGetContent>
2323
<NuGetContentProject Include="$(RepositoryRoot)\src\$(MSBuildProjectName)\$(MSBuildProjectName).csproj" Condition="'$(NuGetPackSymbols)' == 'true'" />
2424
<NuGetContent Include="DotNetCompilerPlatformTasks.dll">
@@ -29,72 +29,17 @@
2929
<Source>$(OutputPath)</Source>
3030
<Destination>tasks</Destination>
3131
</NuGetContent>
32-
<NuGetContent Include="Content\config.install.xdt">
33-
<Destination>content\net462\app.config.install.xdt</Destination>
34-
</NuGetContent>
35-
<NuGetContent Include="Content\config.install.xdt">
36-
<Destination>content\net462\web.config.install.xdt</Destination>
37-
</NuGetContent>
38-
<NuGetContent Include="Content\config.uninstall.xdt">
39-
<Destination>content\net462\app.config.uninstall.xdt</Destination>
40-
</NuGetContent>
41-
<NuGetContent Include="Content\config.uninstall.xdt">
42-
<Destination>content\net462\web.config.uninstall.xdt</Destination>
43-
</NuGetContent>
44-
<NuGetContent Include="Content\config.install.xdt">
45-
<Destination>content\net472\app.config.install.xdt</Destination>
46-
</NuGetContent>
47-
<NuGetContent Include="Content\config.install.xdt">
48-
<Destination>content\net472\web.config.install.xdt</Destination>
49-
</NuGetContent>
50-
<NuGetContent Include="Content\config.uninstall.xdt">
51-
<Destination>content\net472\app.config.uninstall.xdt</Destination>
52-
</NuGetContent>
53-
<NuGetContent Include="Content\config.uninstall.xdt">
54-
<Destination>content\net472\web.config.uninstall.xdt</Destination>
55-
</NuGetContent>
56-
<NuGetContent Include="build\*">
57-
<Destination>build\net472</Destination>
58-
</NuGetContent>
59-
<NuGetContent Include="build\*">
60-
<Destination>build\net462</Destination>
61-
</NuGetContent>
62-
<NuGetContent Include="build\net46\*">
63-
<Destination>build\net462</Destination>
64-
</NuGetContent>
65-
<NuGetContent Include="build\net472\*">
32+
<NuGetContent Include="build.pp\*">
6633
<Destination>build\net472</Destination>
6734
</NuGetContent>
68-
<NuGetContent Include="tools\*.ps1" Condition="'$(SignAssembly)' != 'true'">
69-
<Destination>tools</Destination>
70-
</NuGetContent>
71-
<NuGetContent Include="tools\signed\*.ps1" Condition="'$(SignAssembly)' == 'true'">
72-
<Destination>tools</Destination>
73-
</NuGetContent>
74-
<NuGetContent Include="tools\$(LocalRoslyn46FolderName)\*">
75-
<Destination>tools\$(LocalRoslyn46FolderName)</Destination>
76-
</NuGetContent>
77-
<NuGetContent Include="tools\$(LocalRoslyn472FolderName)\*">
78-
<Destination>tools\$(LocalRoslyn472FolderName)</Destination>
35+
<NuGetContent Include="tools\$(LocalRoslynFolderName)\*">
36+
<Destination>tools\$(LocalRoslynFolderName)</Destination>
7937
</NuGetContent>
8038
<NuGetContent Include="..\icons\*">
8139
<Destination>icons</Destination>
8240
</NuGetContent>
8341
</ItemGroup>
8442
<Import Project="$(RepositoryRoot)Tools\NuGetProj.targets"/>
85-
<Target Name="SignPowerShellScript" Condition=" '$(SignAssembly)' == 'true' " AfterTargets="BeforeBuild">
86-
<ItemGroup>
87-
<OriginalScriptFiles Include="$(MSBuildThisFileDirectory)\tools\*.ps1" />
88-
</ItemGroup>
89-
<Copy SourceFiles="@(OriginalScriptFiles)" DestinationFolder="$(MSBuildThisFileDirectory)\tools\signed" SkipUnchangedFiles="true" />
90-
<ItemGroup>
91-
<ScriptFilesToSign Include="$(MSBuildThisFileDirectory)\tools\signed\*.ps1">
92-
<Authenticode>Microsoft400</Authenticode>
93-
</ScriptFilesToSign>
94-
</ItemGroup>
95-
<SignFiles Files="@(ScriptFilesToSign)" Type="$(SignType)" BinariesDirectory="$(MSBuildThisFileDirectory)\tools\signed"
96-
IntermediatesDirectory="$(MSBuildThisFileDirectory)\tools" ESRPSigning="$(ESRPSigning)" UseBearerToken="$(UseBearerToken)" />
97-
</Target>
9843
<Target Name="AfterBuild">
9944
<PropertyGroup>
10045
<OutDir>$(PackageOutputDir)</OutDir>

src/Packages/Microsoft.CodeDom.Providers.DotNetCompilerPlatform/build/Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2-
<Import Project="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.Extensions.targets"/>
32

43
<PropertyGroup>
54
<RoslynCopyToOutDir Condition="$(RoslynCopyToOutDir) == ''">true</RoslynCopyToOutDir>
5+
<RoslynRegisterInConfig Condition="$(RoslynRegisterInConfig) == ''">true</RoslynRegisterInConfig>
6+
<RoslynToolPath Condition="'$(RoslynToolPath)' == ''">$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\..\$roslynToolPath$'))</RoslynToolPath>
67
</PropertyGroup>
7-
8-
<Target Name="SetRoslynCompilerFiles" DependsOnTargets="LocateRoslynCompilerFiles">
8+
9+
<Target Name="SetRoslynCompilerFiles" >
910
<Message Text="Using Roslyn from '$(RoslynToolPath)' folder" />
1011
<ItemGroup>
1112
<RoslynCompilerFiles Include="$(RoslynToolPath)\*">
@@ -37,14 +38,29 @@
3738
</PropertyGroup>
3839
</Target>
3940

40-
<Target Name="CopyRoslynCompilerFilesToOutputDirectory" AfterTargets="CopyFilesToOutputDirectory" DependsOnTargets="LocateRoslynToolsDestinationFolder;SetRoslynCompilerFiles" Condition="$(RoslynCopyToOutDir) == 'true'">
41+
<Target Name="CopyRoslynCompilerFilesToOutputDirectory" AfterTargets="CopyFilesToOutputDirectory" DependsOnTargets="LocateRoslynToolsDestinationFolder;SetRoslynCompilerFiles" Condition="$(RoslynCopyToOutDir) == 'true'">
4142
<Copy SourceFiles="@(RoslynCompilerFiles)" DestinationFolder="$(RoslynToolsDestinationFolder)" ContinueOnError="true" SkipUnchangedFiles="true" Retries="0" />
4243
<ItemGroup Condition="'$(MSBuildLastTaskResult)' == 'True'" >
4344
<FileWrites Include="$(RoslynToolsDestinationFolder)\*" />
4445
</ItemGroup>
4546
</Target>
4647

47-
<Target Name="CheckIfShouldKillVBCSCompiler" DependsOnTargets="LocateRoslynCompilerFiles;LocateRoslynToolsDestinationFolder">
48+
<Target Name="UpdateRoslynCompilersInConfigFile" BeforeTargets="ResolveAssemblyReferences" Condition="$(RoslynRegisterInConfig) == 'true'">
49+
<UpdateCompilerConfigRecord ConfigFile="web.config" Extension=".cs" Language="c#;cs;csharp" WarningLevel="4" Options="/langversion:default /nowarn:1659;1699;1701;612;618"
50+
CompilerType="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, $compilerPlatformFQAN$"
51+
Condition="Exists('web.config')" />
52+
<UpdateCompilerConfigRecord ConfigFile="web.config" Extension=".vb" Language="vb;vbs;visualbasic;vbscript" WarningLevel="4" Options="/langversion:default /nowarn:41008,40000,40008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+"
53+
CompilerType="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, $compilerPlatformFQAN$"
54+
Condition="Exists('web.config')" />
55+
<UpdateCompilerConfigRecord ConfigFile="App.config" Extension=".cs" Language="c#;cs;csharp" WarningLevel="4" Options="/langversion:default /nowarn:1659;1699;1701"
56+
CompilerType="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, $compilerPlatformFQAN$"
57+
Condition="Exists('App.config')" />
58+
<UpdateCompilerConfigRecord ConfigFile="App.config" Extension=".vb" Language="vb;vbs;visualbasic;vbscript" WarningLevel="4" Options="/langversion:default /nowarn:41008 /optionInfer+"
59+
CompilerType="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, $compilerPlatformFQAN$"
60+
Condition="Exists('App.config')" />
61+
</Target>
62+
63+
<Target Name="CheckIfShouldKillVBCSCompiler" DependsOnTargets="LocateRoslynToolsDestinationFolder">
4864
<CheckIfVBCSCompilerWillOverride src="$(RoslynToolPath)\VBCSCompiler.exe" dest="$(RoslynToolsDestinationFolder)\VBCSCompiler.exe">
4965
<Output TaskParameter="WillOverride" PropertyName="ShouldKillVBCSCompiler" />
5066
</CheckIfVBCSCompilerWillOverride>
@@ -60,5 +76,6 @@
6076

6177
<UsingTask TaskName="KillProcess" AssemblyFile="..\..\tasks\DotNetCompilerPlatformTasks.dll" />
6278
<UsingTask TaskName="CheckIfVBCSCompilerWillOverride" AssemblyFile="..\..\tasks\DotNetCompilerPlatformTasks.dll" />
79+
<UsingTask TaskName="UpdateCompilerConfigRecord" AssemblyFile="..\..\tasks\DotNetCompilerPlatformTasks.dll" />
6380

6481
</Project>

src/Packages/Microsoft.CodeDom.Providers.DotNetCompilerPlatform/build/net46/Microsoft.CodeDom.Providers.DotNetCompilerPlatform.Extensions.targets

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/Packages/Microsoft.CodeDom.Providers.DotNetCompilerPlatform/build/net472/Microsoft.CodeDom.Providers.DotNetCompilerPlatform.Extensions.targets

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)