diff --git a/.gitignore b/.gitignore
index b620a468b..3f156e9b9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,8 @@
### Repo-specific things ###
+# Test results
+*-testResults.xml
+
# NuGet keeps dropping
Library/
diff --git a/Microsoft.DotNet.Cli.sln b/Microsoft.DotNet.Cli.sln
index be6d49846..ce13bb1b6 100644
--- a/Microsoft.DotNet.Cli.sln
+++ b/Microsoft.DotNet.Cli.sln
@@ -37,15 +37,7 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "EndToEnd", "test\EndToEnd\E
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Tools.Test.Utilities", "test\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Test.Utilities.xproj", "{E4F46EAB-B5A5-4E60-9B9D-40A1FADBF45C}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestApp", "TestAssets\TestProjects\TestApp\TestApp.xproj", "{58808BBC-371E-47D6-A3D0-4902145EDA4E}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestAppWithArgs", "TestAssets\TestProjects\TestAppWithArgs\TestAppWithArgs.xproj", "{DA8E0E9E-A6D6-4583-864C-8F40465E3A48}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestAppWithContents", "TestAssets\TestProjects\TestAppWithContents\TestAppWithContents.xproj", "{0138CB8F-4AA9-4029-A21E-C07C30F425BA}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestLibrary", "TestAssets\TestProjects\TestLibrary\TestLibrary.xproj", "{947DD232-8D9B-4B78-9C6A-94F807D2DD58}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestProjectToProjectDependencies", "TestAssets\TestProjects\TestProjectToProjectDependencies\TestProjectToProjectDependencies.xproj", "{947DD232-8D9B-4B78-9C6A-94F807D22222}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestProjects", "TestProjects", "{713CBFBB-5392-438D-B766-A9A585EF1BB8}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet", "src\dotnet\dotnet.xproj", "{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}"
EndProject
@@ -58,14 +50,23 @@ EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-projectmodel-server.Tests", "test\dotnet-projectmodel-server.Tests\dotnet-projectmodel-server.Tests.xproj", "{11C77123-E4DA-499F-8900-80C88C2C69F2}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Files", "src\Microsoft.DotNet.Files\Microsoft.DotNet.Files.xproj", "{D521DD9F-0614-4929-93B4-D8FA5682C174}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{88278B81-7649-45DC-8A6A-D3A645C5AFC3}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestAssets", "TestAssets", "{82BD2E61-326D-4EA4-A1C1-93A565573C81}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-cli-build", "scripts\dotnet-cli-build\dotnet-cli-build.xproj", "{D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Cli.Utils.Tests", "test\Microsoft.DotNet.Cli.Utils.Tests\Microsoft.DotNet.Cli.Utils.Tests.xproj", "{09C52F96-EFDD-4448-95EC-6D362DD60BAA}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Cli.Build.Framework", "scripts\Microsoft.DotNet.Cli.Build.Framework\Microsoft.DotNet.Cli.Build.Framework.xproj", "{49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Compiler.Common.Tests", "test\Microsoft.DotNet.Compiler.Common.Tests\Microsoft.DotNet.Compiler.Common.Tests.xproj", "{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-compile.UnitTests", "test\dotnet-compile.UnitTests\dotnet-compile.UnitTests.xproj", "{920B71D8-62DA-4F5E-8A26-926C113F1D97}"
EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.TestFramework", "src\Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.xproj", "{0724ED7C-56E3-4604-9970-25E600611383}"
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestApp", "TestAssets\TestProjects\TestApp\TestApp.xproj", "{58808BBC-371E-47D6-A3D0-4902145EDA4E}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestAppWithArgs", "TestAssets\TestProjects\TestAppWithArgs\TestAppWithArgs.xproj", "{DA8E0E9E-A6D6-4583-864C-8F40465E3A48}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestAppWithContents", "TestAssets\TestProjects\TestAppWithContents\TestAppWithContents.xproj", "{0138CB8F-4AA9-4029-A21E-C07C30F425BA}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestLibrary", "TestAssets\TestProjects\TestLibrary\TestLibrary.xproj", "{947DD232-8D9B-4B78-9C6A-94F807D2DD58}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "TestProjectToProjectDependencies", "TestAssets\TestProjects\TestProjectToProjectDependencies\TestProjectToProjectDependencies.xproj", "{947DD232-8D9B-4B78-9C6A-94F807D22222}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -255,86 +256,6 @@ Global
{E4F46EAB-B5A5-4E60-9B9D-40A1FADBF45C}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{E4F46EAB-B5A5-4E60-9B9D-40A1FADBF45C}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{E4F46EAB-B5A5-4E60-9B9D-40A1FADBF45C}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
- {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|x64.ActiveCfg = Debug|Any CPU
- {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|x64.Build.0 = Debug|Any CPU
- {58808BBC-371E-47D6-A3D0-4902145EDA4E}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
- {58808BBC-371E-47D6-A3D0-4902145EDA4E}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
- {58808BBC-371E-47D6-A3D0-4902145EDA4E}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
- {58808BBC-371E-47D6-A3D0-4902145EDA4E}.MinSizeRel|x64.Build.0 = Debug|Any CPU
- {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|Any CPU.Build.0 = Release|Any CPU
- {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|x64.ActiveCfg = Release|Any CPU
- {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|x64.Build.0 = Release|Any CPU
- {58808BBC-371E-47D6-A3D0-4902145EDA4E}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
- {58808BBC-371E-47D6-A3D0-4902145EDA4E}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
- {58808BBC-371E-47D6-A3D0-4902145EDA4E}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
- {58808BBC-371E-47D6-A3D0-4902145EDA4E}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
- {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Debug|x64.ActiveCfg = Debug|Any CPU
- {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Debug|x64.Build.0 = Debug|Any CPU
- {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
- {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
- {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
- {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.MinSizeRel|x64.Build.0 = Debug|Any CPU
- {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Release|Any CPU.Build.0 = Release|Any CPU
- {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Release|x64.ActiveCfg = Release|Any CPU
- {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Release|x64.Build.0 = Release|Any CPU
- {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
- {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
- {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
- {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
- {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Debug|x64.ActiveCfg = Debug|Any CPU
- {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Debug|x64.Build.0 = Debug|Any CPU
- {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
- {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
- {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
- {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.MinSizeRel|x64.Build.0 = Debug|Any CPU
- {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Release|Any CPU.Build.0 = Release|Any CPU
- {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Release|x64.ActiveCfg = Release|Any CPU
- {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Release|x64.Build.0 = Release|Any CPU
- {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
- {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
- {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
- {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Debug|x64.ActiveCfg = Debug|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Debug|x64.Build.0 = Debug|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.MinSizeRel|x64.Build.0 = Debug|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Release|Any CPU.Build.0 = Release|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Release|x64.ActiveCfg = Release|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Release|x64.Build.0 = Release|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D22222}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D22222}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D22222}.Debug|x64.ActiveCfg = Debug|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D22222}.Debug|x64.Build.0 = Debug|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D22222}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D22222}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D22222}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D22222}.MinSizeRel|x64.Build.0 = Debug|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D22222}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D22222}.Release|Any CPU.Build.0 = Release|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D22222}.Release|x64.ActiveCfg = Release|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D22222}.Release|x64.Build.0 = Release|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D22222}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D22222}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D22222}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
- {947DD232-8D9B-4B78-9C6A-94F807D22222}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -431,6 +352,102 @@ Global
{D521DD9F-0614-4929-93B4-D8FA5682C174}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{D521DD9F-0614-4929-93B4-D8FA5682C174}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{D521DD9F-0614-4929-93B4-D8FA5682C174}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
+ {920B71D8-62DA-4F5E-8A26-926C113F1D97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {920B71D8-62DA-4F5E-8A26-926C113F1D97}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {920B71D8-62DA-4F5E-8A26-926C113F1D97}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {920B71D8-62DA-4F5E-8A26-926C113F1D97}.Debug|x64.Build.0 = Debug|Any CPU
+ {920B71D8-62DA-4F5E-8A26-926C113F1D97}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
+ {920B71D8-62DA-4F5E-8A26-926C113F1D97}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
+ {920B71D8-62DA-4F5E-8A26-926C113F1D97}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
+ {920B71D8-62DA-4F5E-8A26-926C113F1D97}.MinSizeRel|x64.Build.0 = Debug|Any CPU
+ {920B71D8-62DA-4F5E-8A26-926C113F1D97}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {920B71D8-62DA-4F5E-8A26-926C113F1D97}.Release|Any CPU.Build.0 = Release|Any CPU
+ {920B71D8-62DA-4F5E-8A26-926C113F1D97}.Release|x64.ActiveCfg = Release|Any CPU
+ {920B71D8-62DA-4F5E-8A26-926C113F1D97}.Release|x64.Build.0 = Release|Any CPU
+ {920B71D8-62DA-4F5E-8A26-926C113F1D97}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
+ {920B71D8-62DA-4F5E-8A26-926C113F1D97}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
+ {920B71D8-62DA-4F5E-8A26-926C113F1D97}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
+ {920B71D8-62DA-4F5E-8A26-926C113F1D97}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
+ {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Debug|x64.Build.0 = Debug|Any CPU
+ {58808BBC-371E-47D6-A3D0-4902145EDA4E}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
+ {58808BBC-371E-47D6-A3D0-4902145EDA4E}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
+ {58808BBC-371E-47D6-A3D0-4902145EDA4E}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
+ {58808BBC-371E-47D6-A3D0-4902145EDA4E}.MinSizeRel|x64.Build.0 = Debug|Any CPU
+ {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|x64.ActiveCfg = Release|Any CPU
+ {58808BBC-371E-47D6-A3D0-4902145EDA4E}.Release|x64.Build.0 = Release|Any CPU
+ {58808BBC-371E-47D6-A3D0-4902145EDA4E}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
+ {58808BBC-371E-47D6-A3D0-4902145EDA4E}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
+ {58808BBC-371E-47D6-A3D0-4902145EDA4E}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
+ {58808BBC-371E-47D6-A3D0-4902145EDA4E}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
+ {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Debug|x64.Build.0 = Debug|Any CPU
+ {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
+ {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
+ {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
+ {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.MinSizeRel|x64.Build.0 = Debug|Any CPU
+ {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Release|x64.ActiveCfg = Release|Any CPU
+ {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.Release|x64.Build.0 = Release|Any CPU
+ {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
+ {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
+ {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
+ {DA8E0E9E-A6D6-4583-864C-8F40465E3A48}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
+ {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Debug|x64.Build.0 = Debug|Any CPU
+ {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
+ {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
+ {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
+ {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.MinSizeRel|x64.Build.0 = Debug|Any CPU
+ {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Release|x64.ActiveCfg = Release|Any CPU
+ {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.Release|x64.Build.0 = Release|Any CPU
+ {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
+ {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
+ {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
+ {0138CB8F-4AA9-4029-A21E-C07C30F425BA}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Debug|x64.Build.0 = Debug|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.MinSizeRel|x64.Build.0 = Debug|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Release|Any CPU.Build.0 = Release|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Release|x64.ActiveCfg = Release|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.Release|x64.Build.0 = Release|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D2DD58}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D22222}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D22222}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D22222}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D22222}.Debug|x64.Build.0 = Debug|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D22222}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D22222}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D22222}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D22222}.MinSizeRel|x64.Build.0 = Debug|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D22222}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D22222}.Release|Any CPU.Build.0 = Release|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D22222}.Release|x64.ActiveCfg = Release|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D22222}.Release|x64.Build.0 = Release|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D22222}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D22222}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D22222}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
+ {947DD232-8D9B-4B78-9C6A-94F807D22222}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{09C52F96-EFDD-4448-95EC-6D362DD60BAA}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -463,22 +480,38 @@ Global
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
- {0724ED7C-56E3-4604-9970-25E600611383}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0724ED7C-56E3-4604-9970-25E600611383}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0724ED7C-56E3-4604-9970-25E600611383}.Debug|x64.ActiveCfg = Debug|Any CPU
- {0724ED7C-56E3-4604-9970-25E600611383}.Debug|x64.Build.0 = Debug|Any CPU
- {0724ED7C-56E3-4604-9970-25E600611383}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
- {0724ED7C-56E3-4604-9970-25E600611383}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
- {0724ED7C-56E3-4604-9970-25E600611383}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
- {0724ED7C-56E3-4604-9970-25E600611383}.MinSizeRel|x64.Build.0 = Debug|Any CPU
- {0724ED7C-56E3-4604-9970-25E600611383}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0724ED7C-56E3-4604-9970-25E600611383}.Release|Any CPU.Build.0 = Release|Any CPU
- {0724ED7C-56E3-4604-9970-25E600611383}.Release|x64.ActiveCfg = Release|Any CPU
- {0724ED7C-56E3-4604-9970-25E600611383}.Release|x64.Build.0 = Release|Any CPU
- {0724ED7C-56E3-4604-9970-25E600611383}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
- {0724ED7C-56E3-4604-9970-25E600611383}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
- {0724ED7C-56E3-4604-9970-25E600611383}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
- {0724ED7C-56E3-4604-9970-25E600611383}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
+ {D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Debug|x64.Build.0 = Debug|Any CPU
+ {D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
+ {D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
+ {D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
+ {D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.MinSizeRel|x64.Build.0 = Debug|Any CPU
+ {D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Release|x64.ActiveCfg = Release|Any CPU
+ {D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.Release|x64.Build.0 = Release|Any CPU
+ {D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
+ {D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
+ {D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
+ {D7B9695D-23EB-4EA8-B8AB-707A0092E1D5}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
+ {49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Debug|x64.Build.0 = Debug|Any CPU
+ {49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
+ {49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
+ {49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
+ {49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.MinSizeRel|x64.Build.0 = Debug|Any CPU
+ {49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Release|x64.ActiveCfg = Release|Any CPU
+ {49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.Release|x64.Build.0 = Release|Any CPU
+ {49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
+ {49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
+ {49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
+ {49BEB486-AB5A-4416-91EA-8CD34ABB0C9D}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -495,19 +528,22 @@ Global
{688870C8-9843-4F9E-8576-D39290AD0F25} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
{65741CB1-8AEE-4C66-8198-10A7EA0E4258} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
{E4F46EAB-B5A5-4E60-9B9D-40A1FADBF45C} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
- {58808BBC-371E-47D6-A3D0-4902145EDA4E} = {82BD2E61-326D-4EA4-A1C1-93A565573C81}
- {DA8E0E9E-A6D6-4583-864C-8F40465E3A48} = {82BD2E61-326D-4EA4-A1C1-93A565573C81}
- {0138CB8F-4AA9-4029-A21E-C07C30F425BA} = {82BD2E61-326D-4EA4-A1C1-93A565573C81}
- {947DD232-8D9B-4B78-9C6A-94F807D2DD58} = {82BD2E61-326D-4EA4-A1C1-93A565573C81}
- {947DD232-8D9B-4B78-9C6A-94F807D22222} = {82BD2E61-326D-4EA4-A1C1-93A565573C81}
+ {713CBFBB-5392-438D-B766-A9A585EF1BB8} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
{60CF7E6C-D6C8-439D-B7B7-D8A27E29BE2C} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
{833FFEE1-7EED-4F51-8DFD-946D48833333} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
{833FFEE1-7EED-4F51-8DFD-946D48893D6E} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
{386D412C-003C-47B1-8258-0E35865CB7C4} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
{11C77123-E4DA-499F-8900-80C88C2C69F2} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
{D521DD9F-0614-4929-93B4-D8FA5682C174} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
+ {920B71D8-62DA-4F5E-8A26-926C113F1D97} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
+ {58808BBC-371E-47D6-A3D0-4902145EDA4E} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
+ {DA8E0E9E-A6D6-4583-864C-8F40465E3A48} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
+ {0138CB8F-4AA9-4029-A21E-C07C30F425BA} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
+ {947DD232-8D9B-4B78-9C6A-94F807D2DD58} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
+ {947DD232-8D9B-4B78-9C6A-94F807D22222} = {713CBFBB-5392-438D-B766-A9A585EF1BB8}
{09C52F96-EFDD-4448-95EC-6D362DD60BAA} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
{44E7D1AC-DCF1-4A18-9C22-F09E6BB302B5} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
- {0724ED7C-56E3-4604-9970-25E600611383} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
+ {D7B9695D-23EB-4EA8-B8AB-707A0092E1D5} = {88278B81-7649-45DC-8A6A-D3A645C5AFC3}
+ {49BEB486-AB5A-4416-91EA-8CD34ABB0C9D} = {88278B81-7649-45DC-8A6A-D3A645C5AFC3}
EndGlobalSection
EndGlobal
diff --git a/TestAssets/TestProjects/TestAppCompilationContext/TestApp/project.json b/TestAssets/TestProjects/TestAppCompilationContext/TestApp/project.json
index 6b317abf2..dcc22edfe 100644
--- a/TestAssets/TestProjects/TestAppCompilationContext/TestApp/project.json
+++ b/TestAssets/TestProjects/TestAppCompilationContext/TestApp/project.json
@@ -13,10 +13,5 @@
"frameworks": {
"dnxcore50": { }
- },
-
- "scripts": {
- "prepublish" : ["echo prepublish_output ?%publish:ProjectPath%? ?%publish:Configuration%? ?%publish:OutputPath%? ?%publish:Framework%? ?%publish:Runtime%?"],
- "postpublish" : ["echo postpublish_output ?%publish:ProjectPath%? ?%publish:Configuration%? ?%publish:OutputPath%? ?%publish:Framework%? ?%publish:Runtime%?"]
}
}
diff --git a/TestAssets/TestProjects/TestAppWithLibrary/TestApp/project.json b/TestAssets/TestProjects/TestAppWithLibrary/TestApp/project.json
index 51b830d57..64ba761af 100644
--- a/TestAssets/TestProjects/TestAppWithLibrary/TestApp/project.json
+++ b/TestAssets/TestProjects/TestAppWithLibrary/TestApp/project.json
@@ -13,10 +13,5 @@
"frameworks": {
"dnxcore50": { }
- },
-
- "scripts": {
- "prepublish" : ["echo prepublish_output ?%publish:ProjectPath%? ?%publish:Configuration%? ?%publish:OutputPath%? ?%publish:Framework%? ?%publish:Runtime%?"],
- "postpublish" : ["echo postpublish_output ?%publish:ProjectPath%? ?%publish:Configuration%? ?%publish:OutputPath%? ?%publish:Framework%? ?%publish:Runtime%?"]
}
}
diff --git a/TestAssets/TestProjects/TestAppWithScripts/Program.cs b/TestAssets/TestProjects/TestAppWithScripts/Program.cs
new file mode 100644
index 000000000..7bcd4fbd3
--- /dev/null
+++ b/TestAssets/TestProjects/TestAppWithScripts/Program.cs
@@ -0,0 +1,17 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Diagnostics;
+
+namespace TestApp
+{
+ public class Program
+ {
+ public static int Main(string[] args)
+ {
+ Console.WriteLine("Hello World");
+ return 0;
+ }
+ }
+}
diff --git a/TestAssets/TestProjects/TestAppWithScripts/TestApp.xproj b/TestAssets/TestProjects/TestAppWithScripts/TestApp.xproj
new file mode 100644
index 000000000..4cef17daa
--- /dev/null
+++ b/TestAssets/TestProjects/TestAppWithScripts/TestApp.xproj
@@ -0,0 +1,20 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+
+ 58808bbc-371e-47d6-a3d0-4902145eda4e
+ TestApp
+ ..\..\artifacts\obj\$(MSBuildProjectName)
+ ..\..\artifacts\bin\$(MSBuildProjectName)\
+
+
+
+ 2.0
+
+
+
diff --git a/TestAssets/TestProjects/TestAppWithScripts/echoscript.cmd b/TestAssets/TestProjects/TestAppWithScripts/echoscript.cmd
new file mode 100644
index 000000000..a996a370f
--- /dev/null
+++ b/TestAssets/TestProjects/TestAppWithScripts/echoscript.cmd
@@ -0,0 +1,2 @@
+@echo off
+echo %*
\ No newline at end of file
diff --git a/TestAssets/TestProjects/TestAppWithScripts/echoscript.sh b/TestAssets/TestProjects/TestAppWithScripts/echoscript.sh
new file mode 100755
index 000000000..778a035de
--- /dev/null
+++ b/TestAssets/TestProjects/TestAppWithScripts/echoscript.sh
@@ -0,0 +1,2 @@
+#!/usr/bin/env sh
+echo $@
\ No newline at end of file
diff --git a/TestAssets/TestProjects/TestAppWithScripts/project.json b/TestAssets/TestProjects/TestAppWithScripts/project.json
new file mode 100644
index 000000000..8df726e4d
--- /dev/null
+++ b/TestAssets/TestProjects/TestAppWithScripts/project.json
@@ -0,0 +1,22 @@
+{
+ "version": "1.0.0-*",
+ "compilationOptions": {
+ "emitEntryPoint": true
+ },
+
+ "dependencies": {
+ "NETStandard.Library": "1.0.0-rc2-23811"
+ },
+
+ "frameworks": {
+ "dnxcore50": { }
+ },
+
+ "scripts": {
+ "prepublish" : ["echoscript prepublish_output ?%publish:ProjectPath%? ?%publish:Configuration%? ?%publish:OutputPath%? ?%publish:TargetFramework%? ?%publish:Runtime%?"],
+ "postpublish" : ["echoscript postpublish_output ?%publish:ProjectPath%? ?%publish:Configuration%? ?%publish:OutputPath%? ?%publish:TargetFramework%? ?%publish:Runtime%?"],
+
+ "precompile" : ["echoscript precompile_output ?%compile:ProjectPath%? ?%compile:Configuration%? ?%compile:OutputPath%? ?%compile:TargetFramework%? ?%compile:Runtime%?"],
+ "postcompile" : ["echoscript postcompile_output ?%compile:ProjectPath%? ?%compile:Configuration%? ?%compile:OutputPath%? ?%compile:TargetFramework%? ?%compile:Runtime%?"]
+ }
+}
diff --git a/branchinfo.txt b/branchinfo.txt
new file mode 100644
index 000000000..7ac005498
--- /dev/null
+++ b/branchinfo.txt
@@ -0,0 +1,7 @@
+# This is a file containing environment variables specific to this branch
+# Any line that is not blank and does not start with '#' is interpreted as a variable to set
+# Each line is expected to be in the format "[Name]=[Value]".
+MAJOR_VERSION=1
+MINOR_VERSION=0
+PATCH_VERSION=0
+RELEASE_SUFFIX=beta
diff --git a/build.cmd b/build.cmd
index 9b72ee74b..615538658 100644
--- a/build.cmd
+++ b/build.cmd
@@ -6,4 +6,4 @@ REM Licensed under the MIT license. See LICENSE file in the project root for ful
REM Crossgen Workaround
set ComPlus_ReadyToRun=0
-powershell -NoProfile -NoLogo -Command "%~dp0scripts\build\build.ps1 %*; exit $LastExitCode;"
+powershell -NoProfile -NoLogo -Command "%~dp0scripts\run-build.ps1 %*; exit $LastExitCode;"
diff --git a/build.sh b/build.sh
index 36895885b..fb885b57b 100755
--- a/build.sh
+++ b/build.sh
@@ -16,26 +16,9 @@ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symli
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-source "$DIR/scripts/common/_common.sh"
-source "$REPOROOT/scripts/build/process-args.sh"
-
-# splitting build from package is required to work around dotnet/coreclr#2215
-# once that is fixed, we should remove the NOPACKAGE flag and do the full build either in
-# or out of docker.
+# Check if we need to build in docker
if [ ! -z "$BUILD_IN_DOCKER" ]; then
- export BUILD_COMMAND=". /opt/code/scripts/build/process-args.sh $@ ; . /opt/code/scripts/build/build.sh"
- $REPOROOT/scripts/docker/dockerbuild.sh
+ $DIR/scripts/dockerbuild.sh "$@"
else
- $REPOROOT/scripts/build/build.sh
-fi
-
-if [ ! -z "$NOPACKAGE" ]; then
- header "Skipping packaging"
-else
- if [ ! -z "$PACKAGE_IN_DOCKER" ]; then
- export BUILD_COMMAND="/opt/code/scripts/package/package.sh"
- $REPOROOT/scripts/docker/dockerbuild.sh
- else
- $REPOROOT/scripts/package/package.sh
- fi
+ $DIR/scripts/run-build.sh "$@"
fi
diff --git a/netci.groovy b/netci.groovy
index a617fa11d..49d474f8a 100644
--- a/netci.groovy
+++ b/netci.groovy
@@ -6,19 +6,14 @@
import jobs.generation.Utilities;
def project = GithubProject
+def branch = GithubBranchName
def osList = ['Ubuntu', 'OSX', 'Windows_NT', 'CentOS7.1']
-def machineLabelMap = ['Ubuntu':'ubuntu-doc',
- 'OSX':'mac',
- 'Windows_NT':'windows',
- 'CentOS7.1' : 'centos-71']
-
def static getBuildJobName(def configuration, def os) {
return configuration.toLowerCase() + '_' + os.toLowerCase()
}
-
[true, false].each { isPR ->
['Debug', 'Release'].each { configuration ->
osList.each { os ->
@@ -28,7 +23,6 @@ def static getBuildJobName(def configuration, def os) {
// Calculate job name
def jobName = getBuildJobName(configuration, os)
def buildCommand = '';
- def postBuildCommand = '';
// Calculate the build command
if (os == 'Windows_NT') {
@@ -40,7 +34,6 @@ def static getBuildJobName(def configuration, def os) {
def newJob = job(Utilities.getFullJobName(project, jobName, isPR)) {
// Set the label.
- label(machineLabelMap[os])
steps {
if (os == 'Windows_NT') {
// Batch
@@ -49,26 +42,15 @@ def static getBuildJobName(def configuration, def os) {
else {
// Shell
shell(buildCommand)
-
- // Post Build Cleanup
- publishers {
- postBuildScripts {
- steps {
- shell(postBuildCommand)
- }
- onlyIfBuildSucceeds(false)
- }
- }
-
}
}
}
-
- Utilities.standardJobSetup(newJob, project, isPR)
+ Utilities.setMachineAffinity(newJob, os, 'latest-or-auto')
+ Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
Utilities.addXUnitDotNETResults(newJob, '**/*-testResults.xml')
if (isPR) {
- Utilities.addGithubPRTrigger(newJob, "${os} ${configuration} Build")
+ Utilities.addGithubPRTriggerForBranch(newJob, branch, "${os} ${configuration} Build")
}
else {
Utilities.addGithubPushTrigger(newJob)
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/AnsiColorExtensions.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/AnsiColorExtensions.cs
new file mode 100644
index 000000000..874fc7608
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/AnsiColorExtensions.cs
@@ -0,0 +1,52 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ public static class AnsiColorExtensions
+ {
+ public static string Black(this string text)
+ {
+ return "\x1B[30m" + text + "\x1B[39m";
+ }
+
+ public static string Red(this string text)
+ {
+ return "\x1B[31m" + text + "\x1B[39m";
+ }
+ public static string Green(this string text)
+ {
+ return "\x1B[32m" + text + "\x1B[39m";
+ }
+
+ public static string Yellow(this string text)
+ {
+ return "\x1B[33m" + text + "\x1B[39m";
+ }
+
+ public static string Blue(this string text)
+ {
+ return "\x1B[34m" + text + "\x1B[39m";
+ }
+
+ public static string Magenta(this string text)
+ {
+ return "\x1B[35m" + text + "\x1B[39m";
+ }
+
+ public static string Cyan(this string text)
+ {
+ return "\x1B[36m" + text + "\x1B[39m";
+ }
+
+ public static string White(this string text)
+ {
+ return "\x1B[37m" + text + "\x1B[39m";
+ }
+
+ public static string Bold(this string text)
+ {
+ return "\x1B[1m" + text + "\x1B[22m";
+ }
+ }
+}
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/AnsiConsole.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/AnsiConsole.cs
new file mode 100644
index 000000000..8458eb629
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/AnsiConsole.cs
@@ -0,0 +1,143 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.IO;
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ public class AnsiConsole
+ {
+ private AnsiConsole(TextWriter writer, bool useConsoleColor)
+ {
+ Writer = writer;
+
+ _useConsoleColor = useConsoleColor;
+ if (_useConsoleColor)
+ {
+ OriginalForegroundColor = Console.ForegroundColor;
+ }
+ }
+
+ private int _boldRecursion;
+ private bool _useConsoleColor;
+
+ public static AnsiConsole GetOutput(bool useConsoleColor)
+ {
+ return new AnsiConsole(Console.Out, useConsoleColor);
+ }
+
+ public static AnsiConsole GetError(bool useConsoleColor)
+ {
+ return new AnsiConsole(Console.Error, useConsoleColor);
+ }
+
+ public TextWriter Writer { get; }
+
+ public ConsoleColor OriginalForegroundColor { get; }
+
+ private void SetColor(ConsoleColor color)
+ {
+ Console.ForegroundColor = (ConsoleColor)(((int)Console.ForegroundColor & 0x08) | ((int)color & 0x07));
+ }
+
+ private void SetBold(bool bold)
+ {
+ _boldRecursion += bold ? 1 : -1;
+ if (_boldRecursion > 1 || (_boldRecursion == 1 && !bold))
+ {
+ return;
+ }
+
+ Console.ForegroundColor = (ConsoleColor)((int)Console.ForegroundColor ^ 0x08);
+ }
+
+ public void WriteLine(string message)
+ {
+ if (!_useConsoleColor)
+ {
+ Writer.WriteLine(message);
+ return;
+ }
+
+ var escapeScan = 0;
+ for (;;)
+ {
+ var escapeIndex = message.IndexOf("\x1b[", escapeScan);
+ if (escapeIndex == -1)
+ {
+ var text = message.Substring(escapeScan);
+ Writer.Write(text);
+ break;
+ }
+ else
+ {
+ var startIndex = escapeIndex + 2;
+ var endIndex = startIndex;
+ while (endIndex != message.Length &&
+ message[endIndex] >= 0x20 &&
+ message[endIndex] <= 0x3f)
+ {
+ endIndex += 1;
+ }
+
+ var text = message.Substring(escapeScan, escapeIndex - escapeScan);
+ Writer.Write(text);
+ if (endIndex == message.Length)
+ {
+ break;
+ }
+
+ switch (message[endIndex])
+ {
+ case 'm':
+ int value;
+ if (int.TryParse(message.Substring(startIndex, endIndex - startIndex), out value))
+ {
+ switch (value)
+ {
+ case 1:
+ SetBold(true);
+ break;
+ case 22:
+ SetBold(false);
+ break;
+ case 30:
+ SetColor(ConsoleColor.Black);
+ break;
+ case 31:
+ SetColor(ConsoleColor.Red);
+ break;
+ case 32:
+ SetColor(ConsoleColor.Green);
+ break;
+ case 33:
+ SetColor(ConsoleColor.Yellow);
+ break;
+ case 34:
+ SetColor(ConsoleColor.Blue);
+ break;
+ case 35:
+ SetColor(ConsoleColor.Magenta);
+ break;
+ case 36:
+ SetColor(ConsoleColor.Cyan);
+ break;
+ case 37:
+ SetColor(ConsoleColor.Gray);
+ break;
+ case 39:
+ SetColor(OriginalForegroundColor);
+ break;
+ }
+ }
+ break;
+ }
+
+ escapeScan = endIndex + 1;
+ }
+ }
+ Writer.WriteLine();
+ }
+ }
+}
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/ArgumentEscaper.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/ArgumentEscaper.cs
new file mode 100644
index 000000000..7b1958057
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/ArgumentEscaper.cs
@@ -0,0 +1,206 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ public static class ArgumentEscaper
+ {
+ ///
+ /// Undo the processing which took place to create string[] args in Main,
+ /// so that the next process will receive the same string[] args
+ ///
+ /// See here for more info:
+ /// http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
+ ///
+ ///
+ ///
+ public static string EscapeAndConcatenateArgArrayForProcessStart(IEnumerable args)
+ {
+ return string.Join(" ", EscapeArgArray(args));
+ }
+
+ ///
+ /// Undo the processing which took place to create string[] args in Main,
+ /// so that the next process will receive the same string[] args
+ ///
+ /// See here for more info:
+ /// http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
+ ///
+ ///
+ ///
+ public static string EscapeAndConcatenateArgArrayForCmdProcessStart(IEnumerable args)
+ {
+ return string.Join(" ", EscapeArgArrayForCmd(args));
+ }
+
+ ///
+ /// Undo the processing which took place to create string[] args in Main,
+ /// so that the next process will receive the same string[] args
+ ///
+ /// See here for more info:
+ /// http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
+ ///
+ ///
+ ///
+ private static IEnumerable EscapeArgArray(IEnumerable args)
+ {
+ var escapedArgs = new List();
+
+ foreach (var arg in args)
+ {
+ escapedArgs.Add(EscapeArg(arg));
+ }
+
+ return escapedArgs;
+ }
+
+ ///
+ /// This prefixes every character with the '^' character to force cmd to
+ /// interpret the argument string literally. An alternative option would
+ /// be to do this only for cmd metacharacters.
+ ///
+ /// See here for more info:
+ /// http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
+ ///
+ ///
+ ///
+ private static IEnumerable EscapeArgArrayForCmd(IEnumerable arguments)
+ {
+ var escapedArgs = new List();
+
+ foreach (var arg in arguments)
+ {
+ escapedArgs.Add(EscapeArgForCmd(arg));
+ }
+
+ return escapedArgs;
+ }
+
+ private static string EscapeArg(string arg)
+ {
+ var sb = new StringBuilder();
+
+ var quoted = ShouldSurroundWithQuotes(arg);
+ if (quoted) sb.Append("\"");
+
+ for (int i = 0; i < arg.Length; ++i)
+ {
+ var backslashCount = 0;
+
+ // Consume All Backslashes
+ while (i < arg.Length && arg[i] == '\\')
+ {
+ backslashCount++;
+ i++;
+ }
+
+ // Escape any backslashes at the end of the arg
+ // This ensures the outside quote is interpreted as
+ // an argument delimiter
+ if (i == arg.Length)
+ {
+ sb.Append('\\', 2 * backslashCount);
+ }
+
+ // Escape any preceding backslashes and the quote
+ else if (arg[i] == '"')
+ {
+ sb.Append('\\', (2 * backslashCount) + 1);
+ sb.Append('"');
+ }
+
+ // Output any consumed backslashes and the character
+ else
+ {
+ sb.Append('\\', backslashCount);
+ sb.Append(arg[i]);
+ }
+ }
+
+ if (quoted) sb.Append("\"");
+
+ return sb.ToString();
+ }
+
+ ///
+ /// Prepare as single argument to
+ /// roundtrip properly through cmd.
+ ///
+ /// This prefixes every character with the '^' character to force cmd to
+ /// interpret the argument string literally. An alternative option would
+ /// be to do this only for cmd metacharacters.
+ ///
+ /// See here for more info:
+ /// http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
+ ///
+ ///
+ ///
+ private static string EscapeArgForCmd(string argument)
+ {
+ var sb = new StringBuilder();
+
+ var quoted = ShouldSurroundWithQuotes(argument);
+
+ if (quoted) sb.Append("^\"");
+
+ foreach (var character in argument)
+ {
+
+ if (character == '"')
+ {
+
+ sb.Append('^');
+ sb.Append('"');
+ sb.Append('^');
+ sb.Append(character);
+ }
+ else
+ {
+ sb.Append("^");
+ sb.Append(character);
+ }
+ }
+
+ if (quoted) sb.Append("^\"");
+
+ return sb.ToString();
+ }
+
+ ///
+ /// Prepare as single argument to
+ /// roundtrip properly through cmd.
+ ///
+ /// This prefixes every character with the '^' character to force cmd to
+ /// interpret the argument string literally. An alternative option would
+ /// be to do this only for cmd metacharacters.
+ ///
+ /// See here for more info:
+ /// http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
+ ///
+ ///
+ ///
+ internal static bool ShouldSurroundWithQuotes(string argument)
+ {
+ // Don't quote already quoted strings
+ if (argument.StartsWith("\"", StringComparison.Ordinal) &&
+ argument.EndsWith("\"", StringComparison.Ordinal))
+ {
+ return false;
+ }
+
+ // Only quote if whitespace exists in the string
+ if (argument.Contains(" ") || argument.Contains("\t") || argument.Contains("\n"))
+ {
+ return true;
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildContext.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildContext.cs
new file mode 100644
index 000000000..312fdd6ce
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildContext.cs
@@ -0,0 +1,132 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ public class BuildContext
+ {
+ private IDictionary _completedTargets = new Dictionary(StringComparer.OrdinalIgnoreCase);
+
+ public static readonly string DefaultTarget = "Default";
+
+ private int _maxTargetLen;
+ private Stack _targetStack = new Stack();
+
+ public IDictionary Targets { get; }
+
+ public IDictionary Properties = new Dictionary();
+
+ public string BuildDirectory { get; }
+
+ public object this[string name]
+ {
+ get { return Properties.ContainsKey(name) ? Properties[name] : null; }
+ set { Properties[name] = value; }
+ }
+
+ public BuildContext(IDictionary targets, string buildDirectory)
+ {
+ Targets = targets;
+ BuildDirectory = buildDirectory;
+ _maxTargetLen = targets.Values.Select(t => t.Name.Length).Max();
+ }
+
+ public BuildTargetResult RunTarget(string name) => RunTarget(name, force: false);
+
+ public BuildTargetResult RunTarget(string name, bool force)
+ {
+ BuildTarget target;
+ if (!Targets.TryGetValue(name, out target))
+ {
+ Reporter.Verbose.WriteLine($"Skipping undefined target: {name}");
+ }
+
+ // Check if it's been completed
+ BuildTargetResult result;
+ if (!force && _completedTargets.TryGetValue(name, out result))
+ {
+ Reporter.Verbose.WriteLine($"Skipping completed target: {target.Name}");
+ return result;
+ }
+
+
+ // It hasn't, or we're forcing, so run it
+ result = ExecTarget(target);
+ _completedTargets[target.Name] = result;
+ return result;
+ }
+
+ public void Verbose(string message)
+ {
+ Reporter.Output.WriteLine("trace".White() + $": {message}");
+ }
+
+ public void Info(string message)
+ {
+ Reporter.Output.WriteLine("info ".Green() + $": {message}");
+ }
+
+ public void Warn(string message)
+ {
+ Reporter.Output.WriteLine("warn ".Yellow() + $": {message}");
+ }
+
+ public void Error(string message)
+ {
+ Reporter.Error.WriteLine("error".Red().Bold() + $": {message}");
+ }
+
+ private BuildTargetResult ExecTarget(BuildTarget target)
+ {
+ var sectionName = $"{target.Name.PadRight(_maxTargetLen + 2).Yellow()} ({target.Source.White()})";
+ BuildReporter.BeginSection("TARGET", sectionName);
+
+ BuildTargetResult result;
+
+ // Run the dependencies
+ var dependencyResults = new Dictionary();
+ var failedDependencyResult = RunDependencies(target, dependencyResults);
+ if (failedDependencyResult != null)
+ {
+ result = failedDependencyResult;
+ }
+ else if (target.Body != null)
+ {
+ try
+ {
+ result = target.Body(new BuildTargetContext(this, target, dependencyResults));
+ }
+ catch (Exception ex)
+ {
+ result = new BuildTargetResult(target, success: false, exception: ex);
+ }
+ }
+ else
+ {
+ result = new BuildTargetResult(target, success: true);
+ }
+ BuildReporter.EndSection("TARGET", sectionName, result.Success);
+
+ return result;
+ }
+
+ private BuildTargetResult RunDependencies(BuildTarget target, Dictionary dependencyResults)
+ {
+ BuildTargetResult result = null;
+ foreach (var dependency in target.Dependencies)
+ {
+ result = RunTarget(dependency);
+ dependencyResults[dependency] = result;
+
+ if (!result.Success)
+ {
+ return result;
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildFailureException.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildFailureException.cs
new file mode 100644
index 000000000..665c0243a
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildFailureException.cs
@@ -0,0 +1,42 @@
+using System;
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ public class BuildFailureException : Exception
+ {
+ public BuildTarget Target { get; }
+
+ public BuildFailureException()
+ {
+ }
+
+ public BuildFailureException(BuildTarget target) : base($"The '{target.Name}' target failed")
+ {
+ Target = target;
+ }
+
+ public BuildFailureException(BuildTarget target, Exception innerException) : base($"The '{target.Name}' target failed", innerException)
+ {
+ Target = target;
+ }
+
+ public BuildFailureException(string message) : base(message)
+ {
+ }
+
+ public BuildFailureException(string message, BuildTarget target) : base(message)
+ {
+ Target = target;
+ }
+
+ public BuildFailureException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
+
+ public BuildFailureException(string message, Exception innerException, BuildTarget target) : base(message, innerException)
+ {
+ Target = target;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildHelpers.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildHelpers.cs
new file mode 100644
index 000000000..cb7aa8ede
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildHelpers.cs
@@ -0,0 +1,42 @@
+using System.Collections.Generic;
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ public static class BuildHelpers
+ {
+ public static int ExecInSilent(string workingDirectory, string command, params string[] args) => ExecInSilent(workingDirectory, command, (IEnumerable)args);
+ public static int ExecInSilent(string workingDirectory, string command, IEnumerable args) => ExecCore(command, args, workingDirectory, silent: true);
+
+ public static int ExecIn(string workingDirectory, string command, params string[] args) => ExecIn(workingDirectory, command, (IEnumerable)args);
+ public static int ExecIn(string workingDirectory, string command, IEnumerable args) => ExecCore(command, args, workingDirectory, silent: false);
+
+ public static int ExecSilent(string command, params string[] args) => ExecSilent(command, (IEnumerable)args);
+ public static int ExecSilent(string command, IEnumerable args) => ExecCore(command, args, workingDirectory: null, silent: true);
+
+ public static int Exec(string command, params string[] args) => Exec(command, (IEnumerable)args);
+ public static int Exec(string command, IEnumerable args) => ExecCore(command, args, workingDirectory: null, silent: false);
+
+ public static Command Cmd(string command, params string[] args) => Cmd(command, (IEnumerable)args);
+ public static Command Cmd(string command, IEnumerable args)
+ {
+ return Command.Create(command, args);
+ }
+
+ internal static int ExecCore(string command, IEnumerable args, string workingDirectory, bool silent)
+ {
+ var cmd = Cmd(command, args);
+ if(!string.IsNullOrEmpty(workingDirectory))
+ {
+ cmd.WorkingDirectory(workingDirectory);
+ }
+ if(silent)
+ {
+ cmd.CaptureStdErr().CaptureStdOut();
+ }
+ var result = cmd.Execute();
+
+ result.EnsureSuccessful();
+ return result.ExitCode;
+ }
+ }
+}
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildReporter.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildReporter.cs
new file mode 100644
index 000000000..bbefb7cf6
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildReporter.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ public static class BuildReporter
+ {
+ public static void BeginSection(string type, string name)
+ {
+ Reporter.Output.WriteLine($"[{type.PadRight(10)} >]".Green() + $" [....] [{DateTime.Now:O}]".Blue() + $" {name}");
+ }
+
+ public static void EndSection(string type, string name, bool success)
+ {
+ var header = $"[{type.PadRight(10)} <]";
+ if(success)
+ {
+ header = header.Green();
+ }
+ else
+ {
+ header = header.Red();
+ }
+ var successString = success ? " OK " : "FAIL";
+ Reporter.Output.WriteLine(header + $" [{successString}] [{DateTime.Now:O}]".Blue() + $" {name}");
+ }
+ }
+}
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildSetup.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildSetup.cs
new file mode 100644
index 000000000..34eb86afa
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildSetup.cs
@@ -0,0 +1,148 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ public class BuildSetup
+ {
+ private Dictionary _targets = new Dictionary();
+
+ public IList _overrides = new List();
+
+ public string ProductName { get; }
+
+ public BuildSetup(string productName)
+ {
+ ProductName = productName;
+ }
+
+ public static BuildSetup Create(string productName)
+ {
+ return new BuildSetup(productName);
+ }
+
+ public BuildSetup UseTargets(IEnumerable targets)
+ {
+ foreach (var target in targets)
+ {
+ BuildTarget previousTarget;
+ if (_targets.TryGetValue(target.Name, out previousTarget))
+ {
+ _overrides.Add(new TargetOverride(target.Name, previousTarget.Source, target.Source));
+ }
+ _targets[target.Name] = target;
+ }
+ return this;
+ }
+
+ public BuildSetup UseAllTargetsFromAssembly()
+ {
+ var asm = typeof(T).GetTypeInfo().Assembly;
+ return UseTargets(asm.GetExportedTypes().SelectMany(t => CollectTargets(t)));
+ }
+
+ public BuildSetup UseTargetsFrom()
+ {
+ return UseTargets(CollectTargets(typeof(T)));
+ }
+
+ public int Run(string[] args)
+ {
+ DebugHelper.HandleDebugSwitch(ref args);
+
+ var targets = new[] { BuildContext.DefaultTarget };
+ if(args.Length > 0)
+ {
+ targets = args;
+ }
+
+ Reporter.Output.WriteBanner($"Building {ProductName}");
+
+ if (_overrides.Any())
+ {
+ foreach (var targetOverride in _overrides)
+ {
+ Reporter.Verbose.WriteLine($"Target {targetOverride.Name} from {targetOverride.OriginalSource} was overridden in {targetOverride.OverrideSource}".Black());
+ }
+ }
+
+ var context = new BuildContext(_targets, Directory.GetCurrentDirectory());
+ BuildTargetResult result = null;
+ try
+ {
+ foreach (var target in targets)
+ {
+ result = context.RunTarget(target);
+ if(!result.Success)
+ {
+ break;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Reporter.Error.WriteLine(ex.ToString().Red());
+ return 1;
+ }
+
+ if(result != null && !result.Success)
+ {
+ Reporter.Error.WriteLine($"Build failed: {result.ErrorMessage}".Red());
+ return 1;
+ }
+ else
+ {
+ Reporter.Output.WriteLine("Build succeeded".Green());
+ return 0;
+ }
+ }
+
+ private static IEnumerable CollectTargets(Type typ)
+ {
+ return from m in typ.GetMethods()
+ let attr = m.GetCustomAttribute()
+ where attr != null
+ select CreateTarget(m, attr);
+ }
+
+ private static BuildTarget CreateTarget(MethodInfo m, TargetAttribute attr)
+ {
+ return new BuildTarget(
+ attr.Name ?? m.Name,
+ $"{m.DeclaringType.FullName}.{m.Name}",
+ attr.Dependencies,
+ (Func)m.CreateDelegate(typeof(Func)));
+ }
+
+ private string GenerateSourceString(string file, int? line, string member)
+ {
+ if (!string.IsNullOrEmpty(file) && line != null)
+ {
+ return $"{file}:{line}";
+ }
+ else if (!string.IsNullOrEmpty(member))
+ {
+ return member;
+ }
+ return string.Empty;
+ }
+
+ public class TargetOverride
+ {
+ public string Name { get; }
+ public string OriginalSource { get; }
+ public string OverrideSource { get; }
+
+ public TargetOverride(string name, string originalSource, string overrideSource)
+ {
+ Name = name;
+ OriginalSource = originalSource;
+ OverrideSource = overrideSource;
+ }
+ }
+ }
+}
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildTarget.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildTarget.cs
new file mode 100644
index 000000000..303e0ae66
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildTarget.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ public class BuildTarget
+ {
+ public string Name { get; }
+ public string Source { get; }
+ public IEnumerable Dependencies { get; }
+ public Func Body { get; }
+
+ public BuildTarget(string name, string source) : this(name, source, Enumerable.Empty(), null) { }
+ public BuildTarget(string name, string source, IEnumerable dependencies) : this(name, source, dependencies, null) { }
+ public BuildTarget(string name, string source, IEnumerable dependencies, Func body)
+ {
+ Name = name;
+ Source = source;
+ Dependencies = dependencies;
+ Body = body;
+ }
+ }
+}
\ No newline at end of file
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildTargetContext.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildTargetContext.cs
new file mode 100644
index 000000000..376234dc2
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildTargetContext.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ public class BuildTargetContext
+ {
+ private IDictionary _dependencyResults;
+
+ public BuildContext BuildContext { get; }
+ public BuildTarget Target { get; }
+
+ public BuildTargetContext(BuildContext buildContext, BuildTarget target, IDictionary dependencyResults)
+ {
+ BuildContext = buildContext;
+ Target = target;
+ _dependencyResults = dependencyResults;
+ }
+
+ public BuildTargetResult Success()
+ {
+ return new BuildTargetResult(Target, success: true);
+ }
+
+ public BuildTargetResult Failed() => Failed(errorMessage: string.Empty);
+
+ public BuildTargetResult Failed(string errorMessage)
+ {
+ return new BuildTargetResult(Target, success: false, errorMessage: errorMessage);
+ }
+
+ public void Info(string message) => BuildContext.Info(message);
+ public void Warn(string message) => BuildContext.Warn(message);
+ public void Error(string message) => BuildContext.Error(message);
+ public void Verbose(string message) => BuildContext.Verbose(message);
+ }
+}
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildTargetResult.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildTargetResult.cs
new file mode 100644
index 000000000..cadf74a03
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/BuildTargetResult.cs
@@ -0,0 +1,41 @@
+using System;
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ public class BuildTargetResult
+ {
+ public BuildTarget Target { get; }
+ public bool Success { get; }
+ public string ErrorMessage { get; }
+ public Exception Exception { get; }
+
+ public BuildTargetResult(BuildTarget target, bool success) : this(target, success, errorMessage: string.Empty) { }
+
+ public BuildTargetResult(BuildTarget target, bool success, Exception exception) : this(target, success, exception.ToString())
+ {
+ Exception = exception;
+ }
+
+ public BuildTargetResult(BuildTarget target, bool success, string errorMessage)
+ {
+ Target = target;
+ Success = success;
+ ErrorMessage = errorMessage;
+ }
+
+ public void EnsureSuccessful()
+ {
+ if(!Success)
+ {
+ if(string.IsNullOrEmpty(ErrorMessage))
+ {
+ throw new BuildFailureException(Target, Exception);
+ }
+ else
+ {
+ throw new BuildFailureException(ErrorMessage, Exception, Target);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/Command.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/Command.cs
new file mode 100644
index 000000000..625b3f776
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/Command.cs
@@ -0,0 +1,327 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ public class Command
+ {
+ private Process _process;
+
+ private StringWriter _stdOutCapture;
+ private StringWriter _stdErrCapture;
+
+ private Action _stdOutForward;
+ private Action _stdErrForward;
+
+ private Action _stdOutHandler;
+ private Action _stdErrHandler;
+
+ private bool _running = false;
+
+ private Command(string executable, string args)
+ {
+ // Set the things we need
+ var psi = new ProcessStartInfo()
+ {
+ FileName = executable,
+ Arguments = args
+ };
+
+ _process = new Process()
+ {
+ StartInfo = psi
+ };
+ }
+
+ public static Command Create(string executable, params string[] args)
+ {
+ return Create(executable, ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(args));
+ }
+
+ public static Command Create(string executable, IEnumerable args)
+ {
+ return Create(executable, ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(args));
+ }
+
+ public static Command Create(string executable, string args)
+ {
+ ResolveExecutablePath(ref executable, ref args);
+
+ return new Command(executable, args);
+ }
+
+ private static void ResolveExecutablePath(ref string executable, ref string args)
+ {
+ foreach (string suffix in Constants.RunnableSuffixes)
+ {
+ var fullExecutable = Path.GetFullPath(Path.Combine(
+ AppContext.BaseDirectory, executable + suffix));
+
+ if (File.Exists(fullExecutable))
+ {
+ executable = fullExecutable;
+
+ // In priority order we've found the best runnable extension, so break.
+ break;
+ }
+ }
+
+ // On Windows, we want to avoid using "cmd" if possible (it mangles the colors, and a bunch of other things)
+ // So, do a quick path search to see if we can just directly invoke it
+ var useCmd = ShouldUseCmd(executable);
+
+ if (useCmd)
+ {
+ var comSpec = System.Environment.GetEnvironmentVariable("ComSpec");
+
+ // cmd doesn't like "foo.exe ", so we need to ensure that if
+ // args is empty, we just run "foo.exe"
+ if (!string.IsNullOrEmpty(args))
+ {
+ executable = (executable + " " + args).Replace("\"", "\\\"");
+ }
+ args = $"/C \"{executable}\"";
+ executable = comSpec;
+ }
+ }
+
+ private static bool ShouldUseCmd(string executable)
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ var extension = Path.GetExtension(executable);
+ if (!string.IsNullOrEmpty(extension))
+ {
+ return !string.Equals(extension, ".exe", StringComparison.Ordinal);
+ }
+ else if (executable.Contains(Path.DirectorySeparatorChar))
+ {
+ // It's a relative path without an extension
+ if (File.Exists(executable + ".exe"))
+ {
+ // It refers to an exe!
+ return false;
+ }
+ }
+ else
+ {
+ // Search the path to see if we can find it
+ foreach (var path in System.Environment.GetEnvironmentVariable("PATH").Split(Path.PathSeparator))
+ {
+ var candidate = Path.Combine(path, executable + ".exe");
+ if (File.Exists(candidate))
+ {
+ // We found an exe!
+ return false;
+ }
+ }
+ }
+
+ // It's a non-exe :(
+ return true;
+ }
+
+ // Non-windows never uses cmd
+ return false;
+ }
+
+ public Command Environment(IDictionary env)
+ {
+ foreach(var item in env)
+ {
+ _process.StartInfo.Environment[item.Key] = item.Value;
+ }
+ return this;
+ }
+
+ public CommandResult Execute()
+ {
+ ThrowIfRunning();
+ _running = true;
+
+ if (_process.StartInfo.RedirectStandardOutput)
+ {
+ _process.OutputDataReceived += (sender, args) =>
+ {
+ ProcessData(args.Data, _stdOutCapture, _stdOutForward, _stdOutHandler);
+ };
+ }
+
+ if (_process.StartInfo.RedirectStandardError)
+ {
+ _process.ErrorDataReceived += (sender, args) =>
+ {
+ ProcessData(args.Data, _stdErrCapture, _stdErrForward, _stdErrHandler);
+ };
+ }
+
+ _process.EnableRaisingEvents = true;
+
+ var sw = Stopwatch.StartNew();
+ BuildReporter.BeginSection("EXEC", FormatProcessInfo(_process.StartInfo));
+
+ _process.Start();
+
+ if (_process.StartInfo.RedirectStandardOutput)
+ {
+ _process.BeginOutputReadLine();
+ }
+
+ if (_process.StartInfo.RedirectStandardError)
+ {
+ _process.BeginErrorReadLine();
+ }
+
+ _process.WaitForExit();
+
+ var exitCode = _process.ExitCode;
+
+ var message = $"{FormatProcessInfo(_process.StartInfo)} exited with {exitCode}";
+ if (exitCode == 0)
+ {
+ BuildReporter.EndSection("EXEC", message.Green(), success: true);
+ }
+ else
+ {
+ BuildReporter.EndSection("EXEC", message.Red().Bold(), success: false);
+ }
+
+ return new CommandResult(
+ _process.StartInfo,
+ exitCode,
+ _stdOutCapture?.GetStringBuilder()?.ToString(),
+ _stdErrCapture?.GetStringBuilder()?.ToString());
+ }
+
+ public Command WorkingDirectory(string projectDirectory)
+ {
+ _process.StartInfo.WorkingDirectory = projectDirectory;
+ return this;
+ }
+
+ public Command EnvironmentVariable(string name, string value)
+ {
+ _process.StartInfo.Environment[name] = value;
+ return this;
+ }
+
+ public Command CaptureStdOut()
+ {
+ ThrowIfRunning();
+ _process.StartInfo.RedirectStandardOutput = true;
+ _stdOutCapture = new StringWriter();
+ return this;
+ }
+
+ public Command CaptureStdErr()
+ {
+ ThrowIfRunning();
+ _process.StartInfo.RedirectStandardError = true;
+ _stdErrCapture = new StringWriter();
+ return this;
+ }
+
+ public Command ForwardStdOut(TextWriter to = null)
+ {
+ ThrowIfRunning();
+ _process.StartInfo.RedirectStandardOutput = true;
+ if (to == null)
+ {
+ _stdOutForward = Reporter.Output.WriteLine;
+ }
+ else
+ {
+ _stdOutForward = to.WriteLine;
+ }
+ return this;
+ }
+
+ public Command ForwardStdErr(TextWriter to = null)
+ {
+ ThrowIfRunning();
+ _process.StartInfo.RedirectStandardError = true;
+ if (to == null)
+ {
+ _stdErrForward = Reporter.Error.WriteLine;
+ }
+ else
+ {
+ _stdErrForward = to.WriteLine;
+ }
+ return this;
+ }
+
+ public Command OnOutputLine(Action handler)
+ {
+ ThrowIfRunning();
+ _process.StartInfo.RedirectStandardOutput = true;
+ if (_stdOutHandler != null)
+ {
+ throw new InvalidOperationException("Already handling stdout!");
+ }
+ _stdOutHandler = handler;
+ return this;
+ }
+
+ public Command OnErrorLine(Action handler)
+ {
+ ThrowIfRunning();
+ _process.StartInfo.RedirectStandardError = true;
+ if (_stdErrHandler != null)
+ {
+ throw new InvalidOperationException("Already handling stderr!");
+ }
+ _stdErrHandler = handler;
+ return this;
+ }
+
+ private string FormatProcessInfo(ProcessStartInfo info)
+ {
+ if (string.IsNullOrWhiteSpace(info.Arguments))
+ {
+ return info.FileName;
+ }
+
+ return info.FileName + " " + info.Arguments;
+ }
+
+ private void ThrowIfRunning([CallerMemberName] string memberName = null)
+ {
+ if (_running)
+ {
+ throw new InvalidOperationException($"Unable to invoke {memberName} after the command has been run");
+ }
+ }
+
+ private void ProcessData(string data, StringWriter capture, Action forward, Action handler)
+ {
+ if (data == null)
+ {
+ return;
+ }
+
+ if (capture != null)
+ {
+ capture.WriteLine(data);
+ }
+
+ if (forward != null)
+ {
+ forward(data);
+ }
+
+ if (handler != null)
+ {
+ handler(data);
+ }
+ }
+ }
+}
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/CommandResult.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/CommandResult.cs
new file mode 100644
index 000000000..6630a857b
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/CommandResult.cs
@@ -0,0 +1,34 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Diagnostics;
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ public struct CommandResult
+ {
+ public static readonly CommandResult Empty = new CommandResult();
+
+ public ProcessStartInfo StartInfo { get; }
+ public int ExitCode { get; }
+ public string StdOut { get; }
+ public string StdErr { get; }
+
+ public CommandResult(ProcessStartInfo startInfo, int exitCode, string stdOut, string stdErr)
+ {
+ StartInfo = startInfo;
+ ExitCode = exitCode;
+ StdOut = stdOut;
+ StdErr = stdErr;
+ }
+
+ public void EnsureSuccessful()
+ {
+ if(ExitCode != 0)
+ {
+ throw new BuildFailureException($"Command failed with exit code {ExitCode}: {StartInfo.FileName} {StartInfo.Arguments}");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/Constants.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/Constants.cs
new file mode 100644
index 000000000..66bbb9000
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/Constants.cs
@@ -0,0 +1,23 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Runtime.InteropServices;
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ public static class Constants
+ {
+ //public static readonly string ProjectFileName = "project.json";
+ public static readonly string ExeSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : string.Empty;
+
+ // Priority order of runnable suffixes to look for and run
+ public static readonly string[] RunnableSuffixes = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
+ ? new string[] { ".exe", ".cmd", ".bat" }
+ : new string[] { string.Empty };
+
+ public static readonly string DynamicLibPrefix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "" : "lib";
+
+ public static readonly string DynamicLibSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".dll" :
+ RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? ".dylib" : ".so";
+ }
+}
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/DebugHelper.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/DebugHelper.cs
new file mode 100644
index 000000000..988e15f8d
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/DebugHelper.cs
@@ -0,0 +1,29 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ public static class DebugHelper
+ {
+ [Conditional("DEBUG")]
+ public static void HandleDebugSwitch(ref string[] args)
+ {
+ if (args.Length > 0 && string.Equals("--debug", args[0], StringComparison.OrdinalIgnoreCase))
+ {
+ args = args.Skip(1).ToArray();
+ WaitForDebugger();
+ }
+ }
+
+ private static void WaitForDebugger()
+ {
+ Console.WriteLine("Waiting for debugger to attach. Press ENTER to continue");
+ Console.WriteLine($"Process ID: {Process.GetCurrentProcess().Id}");
+ Console.ReadLine();
+ }
+ }
+}
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/Microsoft.DotNet.Cli.Build.Framework.xproj b/scripts/Microsoft.DotNet.Cli.Build.Framework/Microsoft.DotNet.Cli.Build.Framework.xproj
new file mode 100644
index 000000000..26f7e55e4
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/Microsoft.DotNet.Cli.Build.Framework.xproj
@@ -0,0 +1,19 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ 49beb486-ab5a-4416-91ea-8cd34abb0c9d
+ Microsoft.DotNet.Cli.Build.Framework
+ ..\..\artifacts\obj\$(MSBuildProjectName)
+ ..\..\artifacts\bin\$(MSBuildProjectName)\
+
+
+
+ 2.0
+
+
+
\ No newline at end of file
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/Reporter.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/Reporter.cs
new file mode 100644
index 000000000..766ddf764
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/Reporter.cs
@@ -0,0 +1,65 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ // Stupid-simple console manager
+ internal class Reporter
+ {
+ private static readonly Reporter Null = new Reporter(console: null);
+ private static object _lock = new object();
+
+ private readonly AnsiConsole _console;
+
+ private Reporter(AnsiConsole console)
+ {
+ _console = console;
+ }
+
+ public static Reporter Output { get; } = Create(AnsiConsole.GetOutput);
+ public static Reporter Error { get; } = Create(AnsiConsole.GetOutput);
+ public static Reporter Verbose { get; } = Create(AnsiConsole.GetOutput);
+
+ public static Reporter Create(Func getter)
+ {
+ var stripColors = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ||
+ string.Equals(Environment.GetEnvironmentVariable("NO_COLOR"), "1");
+ return new Reporter(getter(stripColors));
+ }
+
+ public void WriteLine(string message)
+ {
+ lock (_lock)
+ {
+ _console?.WriteLine(message);
+ }
+ }
+
+ public void WriteLine()
+ {
+ lock (_lock)
+ {
+ _console?.Writer?.WriteLine();
+ }
+ }
+
+ public void Write(string message)
+ {
+ lock (_lock)
+ {
+ _console?.Writer?.Write(message);
+ }
+ }
+
+ public void WriteBanner(string content)
+ {
+ string border = new string('*', content.Length + 6);
+ WriteLine($@"{border}
+* {content} *
+{border}".Green());
+ }
+ }
+}
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/StandardGoals.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/StandardGoals.cs
new file mode 100644
index 000000000..c22ac967a
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/StandardGoals.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ public static class StandardGoals
+ {
+ public static BuildSetup UseStandardGoals(this BuildSetup self)
+ {
+ return self.UseTargets(new[]
+ {
+ new BuildTarget("Default", "Standard Goals", new [] { "Prepare", "Compile", "Test", "Publish" }),
+ new BuildTarget("Prepare", "Standard Goals"),
+ new BuildTarget("Compile", "Standard Goals"),
+ new BuildTarget("Test", "Standard Goals"),
+ new BuildTarget("Publish", "Standard Goals")
+ });
+ }
+ }
+}
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/TargetAttribute.cs b/scripts/Microsoft.DotNet.Cli.Build.Framework/TargetAttribute.cs
new file mode 100644
index 000000000..6cc6771fc
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/TargetAttribute.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Microsoft.DotNet.Cli.Build.Framework
+{
+ [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
+ public class TargetAttribute : Attribute
+ {
+ public string Name { get; set; }
+ public IEnumerable Dependencies { get; }
+
+ public TargetAttribute()
+ {
+ Dependencies = Enumerable.Empty();
+ }
+
+ // Attributes can only use constants, so a comma-separated string is better :)
+ public TargetAttribute(params string[] dependencies)
+ {
+ Dependencies = dependencies;
+ }
+ }
+}
\ No newline at end of file
diff --git a/scripts/Microsoft.DotNet.Cli.Build.Framework/project.json b/scripts/Microsoft.DotNet.Cli.Build.Framework/project.json
new file mode 100644
index 000000000..dd887545d
--- /dev/null
+++ b/scripts/Microsoft.DotNet.Cli.Build.Framework/project.json
@@ -0,0 +1,12 @@
+{
+ "version": "1.0.0-*",
+
+ "dependencies": {
+ "NETStandard.Library": "1.0.0-rc2-23811",
+ "System.Diagnostics.Process": "4.1.0-rc2-23811"
+ },
+
+ "frameworks": {
+ "dnxcore50": { }
+ }
+}
diff --git a/scripts/build/build.ps1 b/scripts/build/build.ps1
deleted file mode 100644
index c302e0378..000000000
--- a/scripts/build/build.ps1
+++ /dev/null
@@ -1,56 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-param(
- [string]$Configuration="Debug",
- [switch]$Offline,
- [switch]$NoPackage)
-
-$ErrorActionPreference="Stop"
-
-. "$PSScriptRoot\..\common\_common.ps1"
-
-. "$RepoRoot\scripts\build\generate-version.ps1"
-
-_ "$RepoRoot\scripts\clean\clear-nuget-cache.ps1"
-
-header "Building dotnet tools version $($env:DOTNET_CLI_VERSION) - $Configuration"
-header "Checking Pre-Reqs"
-
-_ "$RepoRoot\scripts\test\check-prereqs.ps1"
-
-header "Restoring Tools and Packages"
-
-if ($Offline){
- info "Skipping Tools and Packages dowlnoad: Offline build"
-}
-else {
- _ "$RepoRoot\scripts\obtain\install-tools.ps1"
-}
-
-header "Cleaning out .ni's from Stage0"
-rm "$RepoRoot\.dotnet_stage0\**\*.ni.*"
-
-_ "$RepoRoot\scripts\build\restore-packages.ps1"
-
-header "Compiling"
-_ "$RepoRoot\scripts\compile\compile.ps1" @("$Configuration")
-
-header "Setting Stage2 as PATH and DOTNET_TOOLS"
-setPathAndHome "$Stage2Dir"
-
-header "Testing"
-_ "$RepoRoot\scripts\test\test.ps1"
-
-header "Validating Dependencies"
-_ "$RepoRoot\scripts\test\validate-dependencies.ps1"
-
-if ($NoPackage){
- info "Skipping Packaging"
- exit 0
-}
-else {
- _ "$RepoRoot\scripts\package\package.ps1"
-}
diff --git a/scripts/build/build.sh b/scripts/build/build.sh
deleted file mode 100755
index 362f7c531..000000000
--- a/scripts/build/build.sh
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-# Set OFFLINE environment variable to build offline
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-
-source "$REPOROOT/scripts/build/generate-version.sh"
-
-"$REPOROOT/scripts/clean/clear-nuget-cache.sh"
-
-header "Building dotnet tools version $DOTNET_CLI_VERSION - $CONFIGURATION"
-header "Checking Pre-Reqs"
-
-$REPOROOT/scripts/test/check-prereqs.sh
-
-header "Adjusting file descriptors limit, if necessary"
-# Increases the file descriptors limit for this bash. It prevents an issue we were hitting during restore
-FILE_DESCRIPTOR_LIMIT=$( ulimit -n )
-if [ $FILE_DESCRIPTOR_LIMIT -lt 1024 ]
-then
- info "Increasing file description limit to 1024"
- ulimit -n 1024
-fi
-
-header "Restoring Tools and Packages"
-
-if [ ! -z "$OFFLINE" ]; then
- info "Skipping Tools and Package Download: Offline build"
-else
- $REPOROOT/scripts/obtain/install-tools.sh
-fi
-
-header "Cleaning out .ni's from Stage0"
-find ".dotnet_stage0" -name '*.ni.*' -delete
-
-$REPOROOT/scripts/build/restore-packages.sh
-
-header "Compiling"
-$REPOROOT/scripts/compile/compile.sh
-
-header "Setting Stage2 as PATH, DOTNET_HOME, and DOTNET_TOOLS"
-export DOTNET_HOME=$STAGE2_DIR && export DOTNET_TOOLS=$STAGE2DIR && export PATH=$STAGE2_DIR/bin:$PATH
-
-header "Testing"
-$REPOROOT/scripts/test/test.sh
-
-header "Validating Dependencies"
-$REPOROOT/scripts/test/validate-dependencies.sh
diff --git a/scripts/build/build_appdeps.ps1 b/scripts/build/build_appdeps.ps1
deleted file mode 100644
index f2fd8d5bc..000000000
--- a/scripts/build/build_appdeps.ps1
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-param(
- [Parameter(Mandatory=$true)][string]$RepoRoot,
- [Parameter(Mandatory=$true)][string]$OutputDir)
-
-$appdepBinDir = "$OutputDir\bin\appdepsdk"
-
-If (Test-Path $appdepBinDir){
- rmdir -Force -Rec $appdepBinDir
-}
-
-mkdir -Force "$appdepBinDir"
-
-ls "$env:NUGET_PACKAGES\toolchain.win7-x64.Microsoft.DotNet.AppDep\1.0.5-prerelease-00001\*" | foreach {
- copy -Rec $_ "$appdepBinDir"
-}
diff --git a/scripts/build/build_appdeps.sh b/scripts/build/build_appdeps.sh
deleted file mode 100755
index 3c47986bb..000000000
--- a/scripts/build/build_appdeps.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-
-# Always recalculate the RID because the package always uses a specific RID, regardless of OS X version or Linux distro.
-if [ "$OSNAME" == "osx" ]; then
- RID=osx.10.10-x64
-elif [ "$OSNAME" == "ubuntu" ]; then
- RID=ubuntu.14.04-x64
-elif [ "$OSNAME" == "centos" ]; then
- RID=centos.7.1-x64
-else
- echo "Unknown OS: $OSNAME" 1>&2
- exit 1
-fi
-
-# Get Absolute Output Dir
-pushd $1
-OUTPUT_DIR="$(pwd)"
-popd
-
-## App Deps ##
-APPDEP_SDK=$NUGET_PACKAGES/toolchain.$RID.Microsoft.DotNet.AppDep/1.0.5-prerelease-00001/
-mkdir -p $OUTPUT_DIR/appdepsdk
-cp -a $APPDEP_SDK/. $OUTPUT_DIR/appdepsdk
diff --git a/scripts/build/build_info.sh b/scripts/build/build_info.sh
deleted file mode 100755
index 3002f798a..000000000
--- a/scripts/build/build_info.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env bash
-
-UNAME=$(uname)
-echo "Platform: $UNAME"
-
-if [ "$UNAME" = "Linux" ]; then
- DISTRO=$(cat /etc/os-release | grep "^ID=" | cut -d = -f 2 | sed s/\"//g)
- VERSION=$(cat /etc/os-release | grep "^VERSION_ID=" | cut -d = -f 2 | sed s/\"//g)
- echo "Distro: $DISTRO"
- echo "Version: $VERSION"
- echo "RID: $DISTRO.$VERSION-x64"
-else
- VERSION=$(sw_vers -productVersion)
- echo "OS: Mac OS X $VERSION"
- echo "RID: osx.$(echo $VERSION | cut -d . -f 1,2)-x64"
-fi
diff --git a/scripts/build/fix-mode-flags.sh b/scripts/build/fix-mode-flags.sh
deleted file mode 100755
index 955d184cd..000000000
--- a/scripts/build/fix-mode-flags.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-# Managed code doesn't need 'x'
-find . -type f -name "*.dll" | xargs chmod 644
-find . -type f -name "*.exe" | xargs chmod 644
-
-# Generally, dylibs and sos have 'x' (no idea if it's required ;))
-if [ "$(uname)" == "Darwin" ]; then
- find . -type f -name "*.dylib" | xargs chmod 755
-else
- find . -type f -name "*.so" | xargs chmod 755
-fi
-
-# Executables (those without dots) are executable :)
-find . -type f ! -name "*.*" | xargs chmod 755
diff --git a/scripts/build/generate-version.ps1 b/scripts/build/generate-version.ps1
deleted file mode 100644
index 28e49bec2..000000000
--- a/scripts/build/generate-version.ps1
+++ /dev/null
@@ -1,65 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-. "$PSScriptRoot\..\common\_common.ps1"
-
-# MSI versioning
-# Encode the CLI version to fit into the MSI versioning scheme - https://msdn.microsoft.com/en-us/library/windows/desktop/aa370859(v=vs.85).aspx
-# MSI versions are 3 part
-# major.minor.build
-# Size(bits) of each part 8 8 16
-# So we have 32 bits to encode the CLI version
-# Starting with most significant bit this how the CLI version is going to be encoded as MSI Version
-# CLI major -> 6 bits
-# CLI minor -> 6 bits
-# CLI patch -> 6 bits
-# CLI commitcount -> 14 bits
-function GetMSIVersionFromCLIVersion([uint32]$Major, [uint32]$Minor, [uint32]$Patch, [uint32]$CommitCount)
-{
- if($Major -ge 0x40)
- {
- throw [System.NotSupportedException] "Invalid Major version - $Major. Major version must be less than 64."
- }
-
- if($Minor -ge 0x40)
- {
- throw [System.NotSupportedException] "Invalid Minor version - $Minor. Minor version must be less than 64."
- }
-
- if($Patch -ge 0x40)
- {
- throw [System.NotSupportedException] "Invalid Patch version - $Patch. Patch version must be less than 64."
- }
-
- if($CommitCount -ge 0x4000)
- {
- throw [System.NotSupportedException] "Invalid CommitCount version - $CommitCount. CommitCount version must be less than 16384."
- }
-
- $Major = ($Major -shl 26)
- $Minor = ($Minor -shl 20)
- $Patch = ($Patch -shl 14)
- [System.UInt32]$MSIVersionNumber = ($Major -bor $Minor -bor $Patch -bor $CommitCount)
-
- $MSIMajor = ($MSIVersionNumber -shr 24) -band 0xFF
- $MSIMinor = ($MSIVersionNumber -shr 16) -band 0xFF
- $MSIBuild = $MSIVersionNumber -band 0xFFFF
- $MSIVersion = "$MSIMajor.$MSIMinor.$MSIBuild"
-
- return $MSIVersion
-}
-
-$env:MajorVersion = 1
-$env:MinorVersion = 0
-$env:PatchVersion = 0
-
-$CommitCount = [int32](git rev-list --count HEAD)
-$env:CommitCountVersion = ([string]$CommitCount).PadLeft(6, "0")
-
-# Zero Padded Suffix for use with Nuget
-$env:VersionSuffix = "$env:ReleaseSuffix-$env:CommitCountVersion"
-
-$env:DOTNET_CLI_VERSION = "$env:MajorVersion.$env:MinorVersion.$env:PatchVersion.$env:CommitCountVersion"
-$env:DOTNET_MSI_VERSION = GetMSIVersionFromCLIVersion $env:MajorVersion $env:MinorVersion $env:PatchVersion $CommitCount
diff --git a/scripts/build/generate-version.sh b/scripts/build/generate-version.sh
deleted file mode 100755
index 8d541bc4f..000000000
--- a/scripts/build/generate-version.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-export MAJOR_VERSION=1
-export MINOR_VERSION=0
-export PATCH_VERSION=0
-
-export COMMIT_COUNT_VERSION=$(printf "%06d" $(git rev-list --count HEAD))
-
-export DOTNET_CLI_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$PATCH_VERSION.$COMMIT_COUNT_VERSION
diff --git a/scripts/build/place-binary.cmd b/scripts/build/place-binary.cmd
deleted file mode 100644
index 143d4a9eb..000000000
--- a/scripts/build/place-binary.cmd
+++ /dev/null
@@ -1,24 +0,0 @@
-@echo off
-
-REM Copyright (c) .NET Foundation and contributors. All rights reserved.
-REM Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-set SRC=%1
-
-set SRC=%SRC:/=\%
-
-pushd %~dp0..\..
-set DST=%CD%\artifacts\win7-x64\stage2\bin
-popd
-
-if not exist "%SRC%" goto end
-if not exist "%DST%" goto skip
-
-xcopy /F /Y /I "%SRC%" "%DST%"
-
-goto end
-
-:skip
-echo The destination "%DST%" does not exist. This script is only designed to update a previous full build!
-
-:end
diff --git a/scripts/build/place-binary.sh b/scripts/build/place-binary.sh
deleted file mode 100755
index 533ff2b56..000000000
--- a/scripts/build/place-binary.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-
-echo "Copy From: $1"
-echo " To: $STAGE2_DIR/bin/"
-
-src=${1//\\//}
-dst=$STAGE2_DIR/bin/
-
-if [ ! -d "$dst" ]; then
- mkdir -p $dst
-fi
-
-# Copy the files, if they exist
-if ls $src 1> /dev/null 2>&1; then
- cp $src $dst
- rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
-fi
diff --git a/scripts/build/process-args.sh b/scripts/build/process-args.sh
deleted file mode 100755
index 53178bd0d..000000000
--- a/scripts/build/process-args.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-params=("$@")
-
-for i in "${!params[@]}"
-do
- lowerI="$(echo ${params[$i]} | awk '{print tolower($0)}')"
- case $lowerI in
- "release" | "--release")
- export CONFIGURATION=Release
- ;;
- "debug" | "--debug")
- export CONFIGURATION=Debug
- ;;
- "offline" | "--offline")
- export OFFLINE=true
- ;;
- "nopackage" | "--nopackage")
- export NOPACKAGE=true
- ;;
- "--buildindocker-ubuntu")
- export BUILD_IN_DOCKER=true
- export DOCKER_OS=ubuntu
- ;;
- "--buildindocker-centos")
- export BUILD_IN_DOCKER=true
- export DOCKER_OS=centos
- ;;
- *)
- esac
-done
diff --git a/scripts/build/restore-packages.ps1 b/scripts/build/restore-packages.ps1
deleted file mode 100644
index 9ba972481..000000000
--- a/scripts/build/restore-packages.ps1
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-. $PSScriptRoot\..\common\_common.ps1
-
-# Restore packages
-# NOTE(anurse): I had to remove --quiet, because NuGet3 is too quiet when that's provided :(
-header "Restoring packages"
-
-$StartPath = $env:PATH
-$env:PATH = "$env:DOTNET_INSTALL_DIR\cli\bin;$StartPath"
-
-& dotnet restore "$RepoRoot\src" --runtime "$Rid"
-& dotnet restore "$RepoRoot\tools" --runtime "$Rid"
-
-$env:PATH=$StartPath
diff --git a/scripts/build/restore-packages.sh b/scripts/build/restore-packages.sh
deleted file mode 100755
index 935bca61a..000000000
--- a/scripts/build/restore-packages.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-
-export StartPath=$PATH
-export PATH=$DOTNET_INSTALL_DIR/bin:$PATH
-
-header "Restoring packages"
-
-dotnet restore "$REPOROOT/src" --runtime "$RID" $DISABLE_PARALLEL
-dotnet restore "$REPOROOT/tools" --runtime "$RID" $DISABLE_PARALLEL
-
-export PATH=$StartPath
diff --git a/scripts/ci_build.cmd b/scripts/ci_build.cmd
index 54f5f51e3..e30184df7 100644
--- a/scripts/ci_build.cmd
+++ b/scripts/ci_build.cmd
@@ -4,7 +4,9 @@ REM Copyright (c) .NET Foundation and contributors. All rights reserved.
REM Licensed under the MIT license. See LICENSE file in the project root for full license information.
set CI_BUILD=1
+set CONFIGURATION=%1
+set VERBOSE=1
-CALL %~dp0..\build.cmd %*
+CALL %~dp0..\build.cmd %2
exit /b %errorlevel%
diff --git a/scripts/ci_build.sh b/scripts/ci_build.sh
index 488e3192a..29e9664e1 100755
--- a/scripts/ci_build.sh
+++ b/scripts/ci_build.sh
@@ -7,6 +7,7 @@
set -e
export CI_BUILD=1
+export NO_COLOR=1
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
@@ -16,7 +17,36 @@ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symli
done
SCRIPT_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-source "$SCRIPT_DIR/common/_common.sh"
+while [[ $# > 0 ]]; do
+ lowerI="$(echo $1 | awk '{print tolower($0)}')"
+ case $lowerI in
+ "release" | "--release")
+ export CONFIGURATION=Release
+ ;;
+ "debug" | "--debug")
+ export CONFIGURATION=Debug
+ ;;
+ "offline" | "--offline")
+ export OFFLINE=true
+ ;;
+ "nopackage" | "--nopackage")
+ export NOPACKAGE=true
+ ;;
+ "--buildindocker-ubuntu")
+ export BUILD_IN_DOCKER=1
+ export DOCKER_IMAGENAME=ubuntu
+ ;;
+ "--buildindocker-centos")
+ export BUILD_IN_DOCKER=1
+ export DOCKER_IMAGENAME=centos
+ ;;
+ *)
+ break
+ ;;
+ esac
+
+ shift
+done
# Tell install scripts to skip pre-req check since the CI has the pre-reqs but not ldconfig it seems
# Also, install to a directory under the repo root since we don't have permission to work elsewhere
@@ -35,17 +65,15 @@ container_name=""
#Jenkins
[ ! -z "$BUILD_TAG" ] && container_name="$BUILD_TAG"
+
#VSO
[ ! -z "$BUILD_BUILDID" ] && container_name="$BUILD_BUILDID"
export DOTNET_BUILD_CONTAINER_NAME="$container_name"
+## CentOS-based CI machines don't have docker, ditto OSX. So only build in docker if we're on Ubuntu
+#if [ "$(cat /etc/*-release | grep -cim1 ubuntu)" -eq 1 ]; then
+ #export BUILD_IN_DOCKER=1
+#fi
-if [[ "$OSNAME" == "ubuntu" ]]; then
- export PACKAGE_IN_DOCKER="true"
- unset BUILD_IN_DOCKER
-
- $SCRIPT_DIR/../build.sh $@
-else
- $SCRIPT_DIR/../build.sh $@
-fi
+VERBOSE=1 $SCRIPT_DIR/../build.sh "$@"
diff --git a/scripts/common/_clang.sh b/scripts/common/_clang.sh
deleted file mode 100644
index f4e442d23..000000000
--- a/scripts/common/_clang.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-# Set up the environment to be used for building with clang.
-if which "clang-3.5" > /dev/null 2>&1; then
- export CC="$(which clang-3.5)"
- export CXX="$(which clang++-3.5)"
-elif which "clang-3.6" > /dev/null 2>&1; then
- export CC="$(which clang-3.6)"
- export CXX="$(which clang++-3.6)"
-elif which clang > /dev/null 2>&1; then
- export CC="$(which clang)"
- export CXX="$(which clang++)"
-else
- error "Unable to find Clang Compiler"
- error "Install clang-3.5 or clang3.6"
- exit 1
-fi
diff --git a/scripts/common/_common.ps1 b/scripts/common/_common.ps1
index 85621ab53..dbc1101ce 100644
--- a/scripts/common/_common.ps1
+++ b/scripts/common/_common.ps1
@@ -5,33 +5,26 @@
. $PSScriptRoot\_utility.ps1
-$Skip_Crossgen = $false
-$Rid = "win7-x64"
-$Tfm = "dnxcore50"
-$RepoRoot = Resolve-Path "$PSScriptRoot\..\.."
-$OutputDir = "$RepoRoot\artifacts\$Rid"
-$Stage1Dir = "$OutputDir\stage1"
-$Stage1CompilationDir = "$OutputDir\stage1compilation"
-$Stage2Dir = "$OutputDir\stage2"
-$Stage2CompilationDir = "$OutputDir\stage2compilation"
-$HostDir = "$OutputDir\corehost"
-$PackageDir = "$RepoRoot\artifacts\packages\dnvm"
-$TestBinRoot = "$RepoRoot\artifacts\tests"
-$TestPackageDir = "$TestBinRoot\packages"
+# Copy things from environment variables that were sent by the build scripts
+$Rid = $env:Rid
+$Tfm = $env:Tfm
+$OutputDir = $env:OutputDir
+$Stage1Dir = $env:Stage1Dir
+$Stage1CompilationDir = $env:Stage1CompilationDir
+$Stage2Dir = $env:Stage2Dir
+$Stage2CompilationDir = $env:Stage2CompilationDir
+$HostDir = $env:HostDir
+$PackageDir = $env:PackageDir
+$TestBinRoot = $env:TestBinRoot
+$TestPackageDir = $env:TestPackageDir
-$env:TEST_ROOT = "$OutputDir\tests"
-$env:TEST_ARTIFACTS = "$env:TEST_ROOT\artifacts"
+$env:TEST_ROOT = "$OutputDir\tests"
+$env:TEST_ARTIFACTS = "$env:TEST_ROOT\artifacts"
-$env:ReleaseSuffix = "beta"
-$env:Channel = "$env:ReleaseSuffix"
+$env:Channel = "$env:RELEASE_SUFFIX"
# Set reasonable defaults for unset variables
setEnvIfDefault "DOTNET_INSTALL_DIR" "$RepoRoot\.dotnet_stage0\win7-x64"
setEnvIfDefault "DOTNET_CLI_VERSION" "0.1.0.0"
-setEnvIfDefault "SKIP_CROSSGEN" "$Skip_Crossgen"
setPathAndHomeIfDefault "$Stage2Dir"
setVarIfDefault "Configuration" "Debug"
-
-# Common Files which depend on above properties
-. $PSScriptRoot\_nuget.ps1
-. $PSScriptRoot\_configuration.ps1
\ No newline at end of file
diff --git a/scripts/common/_common.sh b/scripts/common/_common.sh
index 163bbf797..5f0477930 100644
--- a/scripts/common/_common.sh
+++ b/scripts/common/_common.sh
@@ -12,23 +12,11 @@ done
COMMONDIR="$( cd -P "$( dirname "$COMMONSOURCE" )" && pwd )"
source "$COMMONDIR/_prettyprint.sh"
-source "$COMMONDIR/_rid.sh"
-
-# TODO: Replace this with a dotnet generation
-export SKIP_CROSSGEN=false
-export TFM=dnxcore50
-export REPOROOT=$(cd $COMMONDIR/../.. && pwd)
-export OUTPUT_ROOT=$REPOROOT/artifacts/$RID
-export STAGE1_DIR=$OUTPUT_ROOT/stage1
-export STAGE2_DIR=$OUTPUT_ROOT/stage2
-export HOST_DIR=$OUTPUT_ROOT/corehost
-export TEST_BIN_ROOT="$REPOROOT/artifacts/tests"
-export TEST_PACKAGE_DIR="$TEST_BIN_ROOT/packages"
+# Other variables are set by the outer build script
export TEST_ROOT="$OUTPUT_ROOT/tests"
export TEST_ARTIFACTS="$TEST_ROOT/artifacts"
-export RELEASE_SUFFIX=beta
export CHANNEL=$RELEASE_SUFFIX
[ -z "$DOTNET_INSTALL_DIR" ] && export DOTNET_INSTALL_DIR=$REPOROOT/.dotnet_stage0/$RID
@@ -36,10 +24,6 @@ export CHANNEL=$RELEASE_SUFFIX
[ -z "$DOTNET_HOME" ] && export DOTNET_HOME=$STAGE2_DIR && export PATH=$STAGE2_DIR/bin:$PATH
[ -z "$CONFIGURATION" ] && export CONFIGURATION=Debug
-# Common Files which depend on above properties
-source "$COMMONDIR/_nuget.sh"
-source "$COMMONDIR/_configuration.sh"
-
#TODO this is a workaround for a nuget bug on ubuntu. Remove
export DISABLE_PARALLEL=""
[[ "$RID" =~ "ubuntu" ]] && export DISABLE_PARALLEL="--disable-parallel"
diff --git a/scripts/common/_configuration.ps1 b/scripts/common/_configuration.ps1
deleted file mode 100644
index e019a55c8..000000000
--- a/scripts/common/_configuration.ps1
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-function loadTestProjectList()
-{
- return Import-CSV "$RepoRoot\scripts\configuration\testProjects.csv" -Header "ProjectName"
-}
-
-function loadTestScriptList()
-{
- return Import-CSV "$RepoRoot\scripts\configuration\testScripts.csv" -Header "ProjectName"
-}
-
-function loadTestPackageList()
-{
- return Import-CSV "$RepoRoot\scripts\configuration\testPackageProjects.csv" -Header "ProjectName"
-}
-
-function loadBuildProjectList()
-{
- return Import-CSV "$RepoRoot\scripts\configuration\buildProjects.csv" -Header "ProjectName"
-}
\ No newline at end of file
diff --git a/scripts/common/_configuration.sh b/scripts/common/_configuration.sh
deleted file mode 100644
index 45d2502a7..000000000
--- a/scripts/common/_configuration.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-loadTestProjectList()
-{
- echo $(cat "$REPOROOT/scripts/configuration/testProjects.csv")
-}
-
-loadTestScriptList()
-{
- echo $(cat "$REPOROOT/scripts/configuration/testScripts.csv")
-}
-
-loadTestPackageList()
-{
- echo $(cat "$REPOROOT/scripts/configuration/testPackageProjects.csv")
-}
-
-loadBuildProjectList()
-{
- echo $(cat "$REPOROOT/scripts/configuration/buildProjects.csv")
-}
\ No newline at end of file
diff --git a/scripts/common/_nuget.ps1 b/scripts/common/_nuget.ps1
deleted file mode 100644
index df3428d69..000000000
--- a/scripts/common/_nuget.ps1
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-$env:NUGET_PACKAGES = (Join-Path $env:USERPROFILE ".nuget\packages")
-$env:DOTNET_PACKAGES = $env:NUGET_PACKAGES
-$env:DNX_PACKAGES = $env:NUGET_PACKAGES
-if(!(Test-Path $env:NUGET_PACKAGES)) {
- mkdir $env:NUGET_PACKAGES | Out-Null
-}
-
-# default the package cache expiration to 1 week, in hours
-setEnvIfDefault "NUGET_PACKAGES_CACHE_TIME_LIMIT" (7 * 24)
diff --git a/scripts/common/_nuget.sh b/scripts/common/_nuget.sh
deleted file mode 100644
index 81bb9fac5..000000000
--- a/scripts/common/_nuget.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-if [ ! -z "$CI_BUILD" ]; then
- # On CI, $HOME is redirected under the repo, which gets deleted after every build.
- # So make $NUGET_PACKAGES outside of the repo.
- NUGET_PACKAGES=$REPOROOT/../.nuget/packages
-else
- NUGET_PACKAGES=~/.nuget/packages
-fi
-
-export NUGET_PACKAGES
-export DOTNET_PACKAGES=$NUGET_PACKAGES
-export DNX_PACKAGES=$NUGET_PACKAGES
-
-if [ ! -d $NUGET_PACKAGES ]; then
- mkdir -p $NUGET_PACKAGES
-fi
-
-if [ -z "$NUGET_PACKAGES_CACHE_TIME_LIMIT" ]; then
- # default the package cache expiration to 1 week, in hours
- export NUGET_PACKAGES_CACHE_TIME_LIMIT=$(( 7 * 24 ))
-fi
diff --git a/scripts/common/_rid.sh b/scripts/common/_rid.sh
deleted file mode 100644
index 37f3c459e..000000000
--- a/scripts/common/_rid.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-export UNAME=$(uname)
-
-if [ -z "$RID" ]; then
- if [ "$UNAME" == "Darwin" ]; then
- export OSNAME=osx
- if [ -n "$(sw_vers -productVersion | grep 10.10)" ]; then
- export RID=osx.10.10-x64
- elif [ -n "$(sw_vers -productVersion | grep 10.11)" ]; then
- export RID=osx.10.11-x64
- else
- error "unknown OS X: $(sw_vers -productVersion)" 1>&2
- fi
- elif [ "$UNAME" == "Linux" ]; then
- # Detect Distro
- if [ "$(cat /etc/*-release | grep -cim1 ubuntu)" -eq 1 ]; then
- export OSNAME=ubuntu
- export RID=ubuntu.14.04-x64
- elif [ "$(cat /etc/*-release | grep -cim1 centos)" -eq 1 ]; then
- export OSNAME=centos
- export RID=centos.7-x64
- else
- error "unknown Linux Distro" 1>&2
- fi
- else
- error "unknown OS: $UNAME" 1>&2
- fi
-fi
-
-if [ -z "$RID" ]; then
- exit 1
-fi
diff --git a/scripts/common/_utility.ps1 b/scripts/common/_utility.ps1
index e331c776a..2e5d68a62 100644
--- a/scripts/common/_utility.ps1
+++ b/scripts/common/_utility.ps1
@@ -73,4 +73,4 @@ function _cmd([string]$command)
error "Command Failed: 'cmd /c $command'"
Exit 1
}
-}
\ No newline at end of file
+}
diff --git a/scripts/compile/compile-corehost.ps1 b/scripts/compile/compile-corehost.ps1
deleted file mode 100644
index ec2f88234..000000000
--- a/scripts/compile/compile-corehost.ps1
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-. $PSScriptRoot\..\common\_common.ps1
-
-header "Building corehost"
-pushd "$RepoRoot\src\corehost"
-try {
- if (!(Test-Path "cmake\$Rid")) {
- mkdir "cmake\$Rid" | Out-Null
- }
- cd "cmake\$Rid"
- cmake ..\.. -G "Visual Studio 14 2015 Win64"
- $pf = $env:ProgramFiles
- if (Test-Path "env:\ProgramFiles(x86)") {
- $pf = (cat "env:\ProgramFiles(x86)")
- }
- $BuildConfiguration = $Configuration
- if ($Configuration -eq "Release") {
- $BuildConfiguration = "RelWithDebInfo"
- }
- & "$pf\MSBuild\14.0\Bin\MSBuild.exe" ALL_BUILD.vcxproj /p:Configuration="$BuildConfiguration"
- if (!$?) {
- Write-Host "Command failed: $pf\MSBuild\14.0\Bin\MSBuild.exe" ALL_BUILD.vcxproj /p:Configuration="$BuildConfiguration"
- Exit 1
- }
-
- if (!(Test-Path $HostDir)) {
- mkdir $HostDir | Out-Null
- }
- cp "$RepoRoot\src\corehost\cmake\$Rid\cli\$BuildConfiguration\corehost.exe" $HostDir
- cp "$RepoRoot\src\corehost\cmake\$Rid\cli\dll\$BuildConfiguration\hostpolicy.dll" $HostDir
-
- if (Test-Path "$RepoRoot\src\corehost\cmake\$Rid\cli\$BuildConfiguration\corehost.pdb")
- {
- cp "$RepoRoot\src\corehost\cmake\$Rid\cli\$BuildConfiguration\corehost.pdb" $HostDir
- }
- if (Test-Path "$RepoRoot\src\corehost\cmake\$Rid\cli\dll\$BuildConfiguration\hostpolicy.pdb")
- {
- cp "$RepoRoot\src\corehost\cmake\$Rid\cli\dll\$BuildConfiguration\hostpolicy.pdb" $HostDir
- }
-} finally {
- popd
-}
diff --git a/scripts/compile/compile-corehost.sh b/scripts/compile/compile-corehost.sh
deleted file mode 100755
index 109e5a655..000000000
--- a/scripts/compile/compile-corehost.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-source "$DIR/../common/_clang.sh"
-
-header "Building corehost"
-
-pushd "$REPOROOT/src/corehost" 2>&1 >/dev/null
-[ -d "cmake/$RID" ] || mkdir -p "cmake/$RID"
-cd "cmake/$RID"
-cmake ../.. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE:STRING=$CONFIGURATION
-make
-
-# Publish to artifacts
-[ -d "$HOST_DIR" ] || mkdir -p $HOST_DIR
-if [[ "$OSNAME" == "osx" ]]; then
- COREHOST_LIBNAME=libhostpolicy.dylib
-else
- COREHOST_LIBNAME=libhostpolicy.so
-fi
-cp "$REPOROOT/src/corehost/cmake/$RID/cli/corehost" $HOST_DIR
-cp "$REPOROOT/src/corehost/cmake/$RID/cli/dll/${COREHOST_LIBNAME}" $HOST_DIR
-popd 2>&1 >/dev/null
diff --git a/scripts/compile/compile-stage-1.ps1 b/scripts/compile/compile-stage-1.ps1
deleted file mode 100644
index d682a75a9..000000000
--- a/scripts/compile/compile-stage-1.ps1
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-. $PSScriptRoot\..\common\_common.ps1
-
-header "Compiling stage1 dotnet using downloaded stage0 ..."
-$StartPath = $env:PATH
-$env:PATH = "$env:DOTNET_INSTALL_DIR\cli\bin;$StartPath"
-
-_ "$RepoRoot\scripts\compile\compile-stage.ps1" @("$Tfm","$Rid","$Configuration","$Stage1Dir","$RepoRoot","$HostDir", "$Stage1CompilationDir")
-
-$env:PATH=$StartPath
\ No newline at end of file
diff --git a/scripts/compile/compile-stage-1.sh b/scripts/compile/compile-stage-1.sh
deleted file mode 100755
index ce11e4690..000000000
--- a/scripts/compile/compile-stage-1.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-
-export StartPath=$PATH
-export PATH=$DOTNET_INSTALL_DIR/bin:$PATH
-
-# Build Stage 1
-header "Building stage1 dotnet using downloaded stage0 ..."
-OUTPUT_DIR=$STAGE1_DIR $REPOROOT/scripts/compile/compile-stage.sh
-
-export PATH=$StartPath
\ No newline at end of file
diff --git a/scripts/compile/compile-stage-2.ps1 b/scripts/compile/compile-stage-2.ps1
deleted file mode 100644
index 874438d4a..000000000
--- a/scripts/compile/compile-stage-2.ps1
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-. $PSScriptRoot\..\common\_common.ps1
-
-header "Compiling stage2 dotnet using stage1 ..."
-$StartPath = $env:PATH
-$env:PATH = "$Stage1Dir\bin;$env:PATH"
-
-# Compile
-_ "$RepoRoot\scripts\compile\compile-stage.ps1" @("$Tfm","$Rid","$Configuration","$Stage2Dir","$RepoRoot","$HostDir", "$Stage2CompilationDir")
-
-
-# Build the projects that we are going to ship as nuget packages
-. $REPOROOT\scripts\package\projectsToPack.ps1
-
-$ProjectsToPack | ForEach-Object {
- dotnet build --build-base-path "$Stage2CompilationDir\forPackaging" --configuration "$Configuration" "$RepoRoot\src\$_"
- if (!$?) {
- Write-Host Command failed: dotnet build --native-subdirectory --build-base-path "$Stage2CompilationDir\forPackaging" --configuration "$Configuration" "$RepoRoot\src\$_"
- exit 1
- }
-}
-
-$env:PATH=$StartPath
\ No newline at end of file
diff --git a/scripts/compile/compile-stage-2.sh b/scripts/compile/compile-stage-2.sh
deleted file mode 100755
index 521d1ae22..000000000
--- a/scripts/compile/compile-stage-2.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-
-# Use stage1 tools
-export StartPath=$PATH
-export DOTNET_TOOLS=$STAGE1_DIR
-export PATH=$STAGE1_DIR/bin:$PATH
-
-# Compile Stage 2
-header "Compiling stage2 dotnet using just-built stage1 ..."
-OUTPUT_DIR=$STAGE2_DIR $REPOROOT/scripts/compile/compile-stage.sh
-
-export DOTNET_HOME=$STAGE2_DIR
-export DOTNET_TOOLS=$STAGE2_DIR
\ No newline at end of file
diff --git a/scripts/compile/compile-stage.ps1 b/scripts/compile/compile-stage.ps1
deleted file mode 100644
index a2de5c30d..000000000
--- a/scripts/compile/compile-stage.ps1
+++ /dev/null
@@ -1,84 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-param(
- [Parameter(Mandatory=$true)][string]$Tfm,
- [Parameter(Mandatory=$true)][string]$Rid,
- [Parameter(Mandatory=$true)][string]$Configuration,
- [Parameter(Mandatory=$true)][string]$StageOutputDir,
- [Parameter(Mandatory=$true)][string]$RepoRoot,
- [Parameter(Mandatory=$true)][string]$HostDir,
- [Parameter(Mandatory=$true)][string]$CompilationOutputDir)
-
-$Projects = loadBuildProjectList
-
-$BinariesForCoreHost = @(
- "csi"
- "csc"
- "vbc"
-)
-
-$FilesToClean = @(
- "README.md"
- "Microsoft.DotNet.Runtime.exe"
- "Microsoft.DotNet.Runtime.dll"
- "Microsoft.DotNet.Runtime.deps"
- "Microsoft.DotNet.Runtime.pdb"
-)
-
-$RuntimeOutputDir = "$StageOutputDir\runtime\coreclr"
-
-# Publish each project
-$Projects | ForEach-Object {
- dotnet publish --native-subdirectory --framework "$Tfm" --runtime "$Rid" --output "$StageOutputDir\bin" --configuration "$Configuration" "$RepoRoot\src\$($_.ProjectName)"
- if (!$?) {
- Write-Host Command failed: dotnet publish --native-subdirectory --framework "$Tfm" --runtime "$Rid" --output "$StageOutputDir\bin" --configuration "$Configuration" "$RepoRoot\src\$($_.ProjectName)"
- exit 1
- }
-}
-
-# Publish the runtime
-dotnet publish --framework "$Tfm" --runtime "$Rid" --output "$RuntimeOutputDir" --configuration "$Configuration" "$RepoRoot\src\Microsoft.DotNet.Runtime"
-if (!$?) {
- Write-Host Command failed: dotnet publish --framework "$Tfm" --runtime "$Rid" --output "$RuntimeOutputDir" --configuration "$Configuration" "$RepoRoot\src\Microsoft.DotNet.Runtime"
- Exit 1
-}
-
-# Clean up bogus additional files
-$FilesToClean | ForEach-Object {
- $path = Join-Path $RuntimeOutputDir $_
- if (Test-Path $path) {
- del -for $path
- }
-}
-
-# Copy the runtime app-local for the tools
-cp -rec "$RuntimeOutputDir\*" "$StageOutputDir\bin" -ErrorVariable capturedErrors -ErrorAction SilentlyContinue
-$capturedErrors | foreach-object {
- if ($_ -notmatch "already exists") {
- write-error $_
- Exit 1
- }
-}
-
-# Deploy the CLR host to the output
-cp "$HostDir\corehost.exe" "$StageOutputDir\bin"
-cp "$HostDir\hostpolicy.dll" "$StageOutputDir\bin"
-
-# corehostify externally-provided binaries (csc, vbc, etc.)
-$BinariesForCoreHost | ForEach-Object {
- mv $StageOutputDir\bin\$_.exe $StageOutputDir\bin\$_.dll -Force
- cp $StageOutputDir\bin\corehost.exe $StageOutputDir\bin\$_.exe -Force
-}
-
-# Crossgen Roslyn
-if (-not (Test-Path "$StageOutputDir\bin\csc.ni.exe")) {
- _cmd "$RepoRoot\scripts\crossgen\crossgen_roslyn.cmd ""$StageOutputDir"""
-}
-
-# Copy in AppDeps
-header "Acquiring Native App Dependencies"
-_ "$RepoRoot\scripts\build\build_appdeps.ps1" @("$RepoRoot", "$StageOutputDir")
-
diff --git a/scripts/compile/compile-stage.sh b/scripts/compile/compile-stage.sh
deleted file mode 100755
index 2f4b8ef9d..000000000
--- a/scripts/compile/compile-stage.sh
+++ /dev/null
@@ -1,103 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-
-[ ! -z "$TFM" ] || die "Missing required environment variable TFM"
-[ ! -z "$RID" ] || die "Missing required environment variable RID"
-[ ! -z "$CONFIGURATION" ] || die "Missing required environment variable CONFIGURATION"
-[ ! -z "$OUTPUT_DIR" ] || die "Missing required environment variable OUTPUT_DIR"
-[ ! -z "$HOST_DIR" ] || die "Missing required environment variable HOST_DIR"
-
-PROJECTS=$(loadBuildProjectList)
-
-BINARIES_FOR_COREHOST=( \
- csi \
- csc \
- vbc \
-)
-
-FILES_TO_CLEAN=( \
- README.md \
- Microsoft.DotNet.Runtime \
- Microsoft.DotNet.Runtime.dll \
- Microsoft.DotNet.Runtime.deps \
- Microsoft.DotNet.Runtime.pdb \
-)
-
-RUNTIME_OUTPUT_DIR="$OUTPUT_DIR/runtime/coreclr"
-
-for project in $PROJECTS
-do
- echo dotnet publish --native-subdirectory --framework "$TFM" --output "$OUTPUT_DIR/bin" --configuration "$CONFIGURATION" "$REPOROOT/src/$project"
- dotnet publish --native-subdirectory --framework "$TFM" --output "$OUTPUT_DIR/bin" --configuration "$CONFIGURATION" "$REPOROOT/src/$project"
-done
-
-# Bring in the runtime
-dotnet publish --output "$RUNTIME_OUTPUT_DIR" --configuration "$CONFIGURATION" "$REPOROOT/src/Microsoft.DotNet.Runtime"
-
-# Clean up bogus additional files
-for file in ${FILES_TO_CLEAN[@]}
-do
- [ -e "$RUNTIME_OUTPUT_DIR/$file" ] && rm "$RUNTIME_OUTPUT_DIR/$file"
-done
-
-# Copy the runtime app-local for the tools
-cp -R $RUNTIME_OUTPUT_DIR/* $OUTPUT_DIR/bin
-
-# Deploy CLR host to the output
-if [[ "$OSNAME" == "osx" ]]; then
- COREHOST_LIBNAME=libhostpolicy.dylib
-else
- COREHOST_LIBNAME=libhostpolicy.so
-fi
-cp "$HOST_DIR/corehost" "$OUTPUT_DIR/bin"
-cp "$HOST_DIR/${COREHOST_LIBNAME}" "$OUTPUT_DIR/bin"
-
-# corehostify externally-provided binaries (csc, vbc, etc.)
-for binary in ${BINARIES_FOR_COREHOST[@]}
-do
- cp $OUTPUT_DIR/bin/corehost $OUTPUT_DIR/bin/$binary
- mv $OUTPUT_DIR/bin/${binary}.exe $OUTPUT_DIR/bin/${binary}.dll
-done
-
-cd $OUTPUT_DIR
-
-# Fix up permissions. Sometimes they get dropped with the wrong info
-find . -type f | xargs chmod 644
-$REPOROOT/scripts/build/fix-mode-flags.sh
-
-if [ ! -f "$OUTPUT_DIR/bin/csc.ni.exe" ]; then
- $REPOROOT/scripts/crossgen/crossgen_roslyn.sh "$OUTPUT_DIR/bin"
-fi
-
-# Make OUTPUT_DIR Folder Accessible
-chmod -R a+r $OUTPUT_DIR
-
-# No compile native support in centos yet
-# https://github.com/dotnet/cli/issues/453
-if [ "$OSNAME" != "centos" ]; then
- # Copy in AppDeps
- if [ ! -d "$OUTPUT_DIR/bin/appdepsdk" ]; then
- header "Acquiring Native App Dependencies"
- DOTNET_HOME=$OUTPUT_DIR DOTNET_TOOLS=$OUTPUT_DIR $REPOROOT/scripts/build/build_appdeps.sh "$OUTPUT_DIR/bin"
- fi
-fi
-
-# Stamp the output with the commit metadata
-COMMIT=$(git rev-parse HEAD)
-echo $COMMIT > $OUTPUT_DIR/.version
-echo $DOTNET_CLI_VERSION >> $OUTPUT_DIR/.version
diff --git a/scripts/compile/compile.ps1 b/scripts/compile/compile.ps1
deleted file mode 100644
index b562c4fab..000000000
--- a/scripts/compile/compile.ps1
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-param([string]$Configuration = "Debug")
-
-$ErrorActionPreference="Stop"
-
-. $PSScriptRoot\..\common\_common.ps1
-
-# Capture PATH for later
-$StartPath = $env:PATH
-$StartDotNetHome = $env:DOTNET_HOME
-
-try {
- _ "$RepoRoot\scripts\compile\compile-corehost.ps1"
-
- _ "$RepoRoot\scripts\compile\compile-stage-1.ps1"
-
- # Issue https://github.com/dotnet/cli/issues/1294
- _ "$RepoRoot\scripts\build\restore-packages.ps1"
-
- _ "$RepoRoot\scripts\compile\compile-stage-2.ps1"
-} finally {
- $env:PATH = $StartPath
- $env:DOTNET_HOME = $StartDotNetHome
-}
diff --git a/scripts/compile/compile.sh b/scripts/compile/compile.sh
deleted file mode 100755
index 3a1416a30..000000000
--- a/scripts/compile/compile.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-
-$REPOROOT/scripts/compile/compile-corehost.sh
-
-$REPOROOT/scripts/compile/compile-stage-1.sh
-
-# Issue https://github.com/dotnet/cli/issues/1294
-$REPOROOT/scripts/build/restore-packages.sh
-
-$REPOROOT/scripts/compile/compile-stage-2.sh
diff --git a/scripts/configuration/buildProjects.csv b/scripts/configuration/buildProjects.csv
deleted file mode 100644
index 3d25d1bdf..000000000
--- a/scripts/configuration/buildProjects.csv
+++ /dev/null
@@ -1 +0,0 @@
-dotnet
diff --git a/scripts/configuration/testPackageProjects.csv b/scripts/configuration/testPackageProjects.csv
deleted file mode 100644
index 90069c976..000000000
--- a/scripts/configuration/testPackageProjects.csv
+++ /dev/null
@@ -1,2 +0,0 @@
-dotnet-hello/v1/dotnet-hello
-dotnet-hello/v2/dotnet-hello
\ No newline at end of file
diff --git a/scripts/configuration/testProjects.csv b/scripts/configuration/testProjects.csv
deleted file mode 100644
index bc53a303d..000000000
--- a/scripts/configuration/testProjects.csv
+++ /dev/null
@@ -1,6 +0,0 @@
-EndToEnd
-dotnet-publish.Tests
-dotnet-compile.Tests
-dotnet-build.Tests
-Microsoft.DotNet.Cli.Utils.Tests
-Microsoft.DotNet.Compiler.Common.Tests
diff --git a/scripts/configuration/testScripts.csv b/scripts/configuration/testScripts.csv
deleted file mode 100644
index 6ce784583..000000000
--- a/scripts/configuration/testScripts.csv
+++ /dev/null
@@ -1,2 +0,0 @@
-argument-forwarding-tests
-package-command-test
\ No newline at end of file
diff --git a/scripts/crossgen/crossgen_roslyn.cmd b/scripts/crossgen/crossgen_roslyn.cmd
deleted file mode 100644
index f27515cbd..000000000
--- a/scripts/crossgen/crossgen_roslyn.cmd
+++ /dev/null
@@ -1,68 +0,0 @@
-REM Turn echo off off so we can echo with echo and the echoing
-REM (But seriously, this script has weird hangs and crashes sometimes so we want to know exactly which commands are failing)
-REM @echo off
-
-REM Copyright (c) .NET Foundation and contributors. All rights reserved.
-REM Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-if %SKIP_CROSSGEN% EQU 0 goto skip
-
-echo Crossgenning Roslyn compiler ...
-
-REM Get absolute path
-pushd %1
-set BIN_DIR=%CD%\bin
-popd
-
-REM Replace with a robust method for finding the right crossgen.exe
-set CROSSGEN_UTIL=%NUGET_PACKAGES%\runtime.win7-x64.Microsoft.NETCore.Runtime.CoreCLR\1.0.1-rc2-23811\tools\crossgen.exe
-
-REM Crossgen currently requires itself to be next to mscorlib
-copy %CROSSGEN_UTIL% /Y %BIN_DIR% > nul
-
-pushd %BIN_DIR%
-
-REM It must also be called mscorlib, not mscorlib.ni
-if exist mscorlib.ni.dll (
- copy /Y mscorlib.ni.dll mscorlib.dll > nul
-)
-
-set READYTORUN=
-
-crossgen /nologo %READYTORUN% /Platform_Assemblies_Paths %BIN_DIR% System.Collections.Immutable.dll >nul 2>nul
-if not %errorlevel% EQU 0 goto fail
-
-crossgen /nologo %READYTORUN% /Platform_Assemblies_Paths %BIN_DIR% System.Reflection.Metadata.dll >nul 2>nul
-if not %errorlevel% EQU 0 goto fail
-
-crossgen /nologo %READYTORUN% /Platform_Assemblies_Paths %BIN_DIR% Microsoft.CodeAnalysis.dll >nul 2>nul
-if not %errorlevel% EQU 0 goto fail
-
-crossgen /nologo %READYTORUN% /Platform_Assemblies_Paths %BIN_DIR% Microsoft.CodeAnalysis.CSharp.dll >nul 2>nul
-if not %errorlevel% EQU 0 goto fail
-
-crossgen /nologo %READYTORUN% /Platform_Assemblies_Paths %BIN_DIR% Microsoft.CodeAnalysis.VisualBasic.dll >nul 2>nul
-if not %errorlevel% EQU 0 goto fail
-
-crossgen /nologo %READYTORUN% /Platform_Assemblies_Paths %BIN_DIR% csc.dll >nul 2>nul
-if not %errorlevel% EQU 0 goto fail
-
-crossgen /nologo %READYTORUN% /Platform_Assemblies_Paths %BIN_DIR% vbc.dll >nul 2>nul
-if not %errorlevel% EQU 0 goto fail
-
-popd
-
-echo CrossGen Roslyn Finished
-
-goto end
-
-:fail
-popd
-echo Crossgen failed...
-exit /B 1
-
-:skip
-echo Skipping Crossgen
-goto end
-
-:end
diff --git a/scripts/crossgen/crossgen_roslyn.sh b/scripts/crossgen/crossgen_roslyn.sh
deleted file mode 100755
index d50bb8814..000000000
--- a/scripts/crossgen/crossgen_roslyn.sh
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-
-if $SKIP_CROSSGEN ; then
- echo "Skipping Crossgen"
- exit 0
-fi
-
-
-info "Crossgenning Roslyn compiler ..."
-
-set -e
-
-BIN_DIR="$( cd $1 && pwd )"
-
-UNAME=`uname`
-
-# Always recalculate the RID because the package always uses a specific RID, regardless of OS X version or Linux distro.
-if [ "$OSNAME" == "osx" ]; then
- RID=osx.10.10-x64
-elif [ "$OSNAME" == "ubuntu" ]; then
- RID=ubuntu.14.04-x64
-elif [ "$OSNAME" == "centos" ]; then
- RID=rhel.7-x64
-else
- echo "Unknown OS: $OSNAME" 1>&2
- exit 1
-fi
-
-READYTORUN=""
-
-# Replace with a robust method for finding the right crossgen.exe
-CROSSGEN_UTIL=$NUGET_PACKAGES/runtime.$RID.Microsoft.NETCore.Runtime.CoreCLR/1.0.1-rc2-23811/tools/crossgen
-
-cd $BIN_DIR
-
-# Crossgen currently requires itself to be next to mscorlib
-cp $CROSSGEN_UTIL $BIN_DIR
-chmod +x crossgen
-
-./crossgen -nologo $READYTORUN -platform_assemblies_paths $BIN_DIR mscorlib.dll
-
-./crossgen -nologo $READYTORUN -platform_assemblies_paths $BIN_DIR System.Collections.Immutable.dll
-
-./crossgen -nologo $READYTORUN -platform_assemblies_paths $BIN_DIR System.Reflection.Metadata.dll
-
-./crossgen -nologo $READYTORUN -platform_assemblies_paths $BIN_DIR Microsoft.CodeAnalysis.dll
-
-./crossgen -nologo $READYTORUN -platform_assemblies_paths $BIN_DIR Microsoft.CodeAnalysis.CSharp.dll
-
-./crossgen -nologo $READYTORUN -platform_assemblies_paths $BIN_DIR Microsoft.CodeAnalysis.VisualBasic.dll
-
-./crossgen -nologo $READYTORUN -platform_assemblies_paths $BIN_DIR csc.dll
-[ -e csc.ni.exe ] && [ ! -e csc.ni.dll ] && mv csc.ni.exe csc.ni.dll
-
-./crossgen -nologo $READYTORUN -platform_assemblies_paths $BIN_DIR vbc.dll
-[ -e vbc.ni.exe ] && [ ! -e vbc.ni.dll ] && mv vbc.ni.exe vbc.ni.dll
-
-info "CrossGen Roslyn Finished"
diff --git a/scripts/docker/dockerbuild.sh b/scripts/docker/dockerbuild.sh
deleted file mode 100755
index 6ec676a4b..000000000
--- a/scripts/docker/dockerbuild.sh
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-
-cd $REPOROOT
-
-[ -z "$DOTNET_BUILD_CONTAINER_TAG" ] && DOTNET_BUILD_CONTAINER_TAG="dotnetcli-build"
-[ -z "$DOTNET_BUILD_CONTAINER_NAME" ] && DOTNET_BUILD_CONTAINER_NAME="dotnetcli-build-container"
-[ -z "$DOCKER_HOST_SHARE_DIR" ] && DOCKER_HOST_SHARE_DIR=$(pwd)
-[ -z "$DOCKER_OS" ] && DOCKER_OS=$OSNAME
-[ -z "$BUILD_COMMAND" ] && BUILD_COMMAND="/opt/code/scripts/build/build.sh"
-
-# Build the docker container (will be fast if it is already built)
-header "Building Docker Container"
-docker build --build-arg USER_ID=$(id -u) -t $DOTNET_BUILD_CONTAINER_TAG scripts/docker/$DOCKER_OS
-
-# Run the build in the container
-header "Launching build in Docker Container"
-info "Using code from: $DOCKER_HOST_SHARE_DIR"
-docker run -t --rm --sig-proxy=true \
- --name $DOTNET_BUILD_CONTAINER_NAME \
- -v $DOCKER_HOST_SHARE_DIR:/opt/code \
- -e DOTNET_CLI_VERSION \
- -e SASTOKEN \
- -e STORAGE_ACCOUNT \
- -e STORAGE_CONTAINER \
- -e CHANNEL \
- -e CONNECTION_STRING \
- -e REPO_ID \
- -e REPO_USER \
- -e REPO_PASS \
- -e REPO_SERVER \
- $DOTNET_BUILD_CONTAINER_TAG \
- bash -c "${BUILD_COMMAND}"
diff --git a/scripts/docker/dockerrun.sh b/scripts/docker/dockerrun.sh
deleted file mode 100755
index d388d0b1b..000000000
--- a/scripts/docker/dockerrun.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../_common.sh"
-
-cd $REPOROOT
-
-[ -z "$DOTNET_BUILD_CONTAINER_TAG" ] && DOTNET_BUILD_CONTAINER_TAG="dotnetcli-build"
-[ -z "$DOTNET_BUILD_CONTAINER_NAME" ] && DOTNET_BUILD_CONTAINER_NAME="dotnetcli-build-container"
-[ -z "$DOCKER_HOST_SHARE_DIR" ] && DOCKER_HOST_SHARE_DIR=$(pwd)
-
-# Enter the container
-docker run -it --rm --sig-proxy=true \
- -v $DOCKER_HOST_SHARE_DIR:/opt/code \
- $DOTNET_BUILD_CONTAINER_TAG
diff --git a/scripts/docker/windows_dockerbuild.sh b/scripts/docker/windows_dockerbuild.sh
deleted file mode 100755
index 960740dbc..000000000
--- a/scripts/docker/windows_dockerbuild.sh
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-# Prerequisites:
-# Git Bash (http://www.git-scm.com/downloads)
-# Docker Toolbox (https://www.docker.com/docker-toolbox)
-# Ensure Hyper-V is disabled!
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-# This function is necessary to bypass POSIX Path Conversion in Git Bash
-# http://www.mingw.org/wiki/Posix_path_conversion
-_convert_path(){
- local path=$1
- path=$( echo "$path" | sed -r 's/[\/]+/\\/g')
- path=${path#\\}
- path=//$path
-
- echo $path
-}
-
-# Bypass Msys path conversion
-REPO_ROOT=$(readlink -f $DIR/../..)
-REPO_ROOT=$(_convert_path $REPO_ROOT)
-
-VM_NAME="dotnet"
-VM_CODE_DIR="/home/docker/code"
-
-RESULTS_DIR="$REPO_ROOT/artifacts"
-
-execute(){
- check_prereqs
-
- echo "Setting up VM..."
- create_or_start_vm
-
- echo "Copying code from Host to VM"
- eval $(docker-machine env --shell bash $VM_NAME)
- copy_code_to_vm
-
- echo "Running Build in Docker Container"
- run_build
-
- echo "Copying Results from VM to Hosts..."
- copy_results_from_vm
-}
-
-check_prereqs(){
- if ! which docker; then
- echo "Error: Install docker toolbox (https://www.docker.com/docker-toolbox)"
- exit 1
- fi
-
- if ! which docker-machine; then
- echo "Error: Install docker toolbox (https://www.docker.com/docker-toolbox)"
- exit 1
- fi
-
-}
-
-create_or_start_vm(){
-
- if [[ $(docker-machine ls | grep $VM_NAME) == "" ]]; then
- docker-machine create -d virtualbox $VM_NAME
- else
- # This fails sometimes
- if ! docker-machine start $VM_NAME; then
- docker-machine rm -f $VM_NAME
- docker-machine create -d virtualbox $VM_NAME
- fi
- fi
-
-}
-
-copy_code_to_vm(){
- docker-machine ssh $VM_NAME "sudo rm -rf $VM_CODE_DIR"
- docker-machine scp -r $REPO_ROOT $VM_NAME:$VM_CODE_DIR >> /dev/null 2>&1
-}
-
-
-run_build(){
- # These are env variables for dockerbuild.sh
- export DOCKER_HOST_SHARE_DIR="$(_convert_path $VM_CODE_DIR)"
- export BUILD_COMMAND="//opt\\code\\build.sh"
-
- $DIR/../dockerbuild.sh debian
-}
-
-# This will duplicate the entire repo + any side effects from
-# the operations in the docker container
-copy_results_from_vm(){
- T_RESULTS_DIR=$( echo "$RESULTS_DIR" | sed -r 's/[\\]+/\//g')
- T_RESULTS_DIR=${T_RESULTS_DIR#/}
-
- mkdir $T_RESULTS_DIR
- docker-machine ssh $VM_NAME "sudo chmod -R a+rx $VM_CODE_DIR"
- docker-machine scp -r $VM_NAME:$VM_CODE_DIR/artifacts $REPO_ROOT >> /dev/null 2>&1
-}
-
-execute
-
diff --git a/scripts/test/setup/restore-test-prerequisites.sh b/scripts/dockerbuild.sh
similarity index 51%
rename from scripts/test/setup/restore-test-prerequisites.sh
rename to scripts/dockerbuild.sh
index 1ade59817..34351f8b0 100755
--- a/scripts/test/setup/restore-test-prerequisites.sh
+++ b/scripts/dockerbuild.sh
@@ -1,8 +1,4 @@
#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
set -e
@@ -14,11 +10,4 @@ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symli
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-source "$DIR/../../common/_common.sh"
-
-header "Restoring TestAssets"
-dotnet restore "$REPOROOT/TestAssets" --runtime $RID --quiet $DISABLE_PARALLEL
-
-set +e
-dotnet restore "$REPOROOT/testapp" --runtime $RID $DISABLE_PARALLEL >/dev/null 2>&1
-set -e
\ No newline at end of file
+BUILD_COMMAND=/opt/code/scripts/run-build.sh $DIR/dockerrun.sh --non-interactive "$@"
diff --git a/scripts/dockerrun.sh b/scripts/dockerrun.sh
new file mode 100755
index 000000000..f56f04d24
--- /dev/null
+++ b/scripts/dockerrun.sh
@@ -0,0 +1,102 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) .NET Foundation and contributors. All rights reserved.
+# Licensed under the MIT license. See LICENSE file in the project root for full license information.
+#
+
+set -e
+
+SOURCE="${BASH_SOURCE[0]}"
+while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
+ DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+ SOURCE="$(readlink "$SOURCE")"
+ [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
+done
+DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+
+cd "$DIR/.."
+
+INTERACTIVE="-i"
+
+while [[ $# > 0 ]]; do
+ key=$1
+
+ case $key in
+ --non-interactive)
+ INTERACTIVE=
+ ;;
+ -i|--image)
+ DOCKER_IMAGENAME=$2
+ shift
+ ;;
+ -d|--dockerfile)
+ DOCKERFILE=$2
+ shift
+ ;;
+ -h|-?|--help)
+ echo "Usage: $0 [-d|--dockerfile ] [-i|--image ] "
+ echo ""
+ echo "Options:"
+ echo " The path to the Dockerfile to use to create the build container"
+ echo " The name of an existing Dockerfile folder under scripts/docker to use as the Dockerfile"
+ echo " The command to run once inside the container (/opt/code is mapped to the repo root; defaults to nothing, which runs the default shell)"
+ exit 0
+ ;;
+ *)
+ break # the first non-switch we get ends parsing
+ ;;
+ esac
+
+ shift
+done
+
+if [ -z "$DOCKERFILE" ]; then
+ if [ -z "$DOCKER_IMAGENAME" ]; then
+ if [ "$(uname)" == "Darwin" ]; then
+ echo "Defaulting to 'ubuntu' image for Darwin"
+ export DOCKERFILE=scripts/docker/ubuntu
+ elif [ "$(cat /etc/*-release | grep -cim1 ubuntu)" -eq 1 ]; then
+ echo "Detected current OS as Ubuntu, using 'ubuntu' image"
+ export DOCKERFILE=scripts/docker/ubuntu
+ elif [ "$(cat /etc/*-release | grep -cim1 centos)" -eq 1 ]; then
+ echo "Detected current OS as CentOS, using 'centos' image"
+ export DOCKERFILE=scripts/docker/centos
+ else
+ echo "Unknown Linux Distro. Using 'ubuntu' image"
+ export DOCKERFILE=scripts/docker/ubuntu
+ fi
+ else
+ echo "Using requested image: $DOCKER_IMAGENAME"
+ export DOCKERFILE="scripts/docker/$DOCKER_IMAGENAME"
+ fi
+fi
+
+[ -z "$DOTNET_BUILD_CONTAINER_TAG" ] && DOTNET_BUILD_CONTAINER_TAG="dotnetcli-build"
+[ -z "$DOTNET_BUILD_CONTAINER_NAME" ] && DOTNET_BUILD_CONTAINER_NAME="dotnetcli-build-container"
+[ -z "$DOCKER_HOST_SHARE_DIR" ] && DOCKER_HOST_SHARE_DIR=$(pwd)
+
+# Build the docker container (will be fast if it is already built)
+echo "Building Docker Container using Dockerfile: $DOCKERFILE"
+docker build --build-arg USER_ID=$(id -u) -t $DOTNET_BUILD_CONTAINER_TAG $DOCKERFILE
+
+# Run the build in the container
+echo "Launching build in Docker Container"
+echo "Running command: $BUILD_COMMAND"
+echo "Using code from: $DOCKER_HOST_SHARE_DIR"
+[ -z "$INTERACTIVE" ] || echo "Running Interactive"
+
+docker run $INTERACTIVE -t --rm --sig-proxy=true \
+ --name $DOTNET_BUILD_CONTAINER_NAME \
+ -v $DOCKER_HOST_SHARE_DIR:/opt/code \
+ -e SASTOKEN \
+ -e STORAGE_ACCOUNT \
+ -e STORAGE_CONTAINER \
+ -e CHANNEL \
+ -e CONNECTION_STRING \
+ -e REPO_ID \
+ -e REPO_USER \
+ -e REPO_PASS \
+ -e REPO_SERVER \
+ -e DOTNET_BUILD_SKIP_CROSSGEN \
+ $DOTNET_BUILD_CONTAINER_TAG \
+ $BUILD_COMMAND "$@"
diff --git a/scripts/dotnet-cli-build/CompileTargets.cs b/scripts/dotnet-cli-build/CompileTargets.cs
new file mode 100644
index 000000000..5185fa361
--- /dev/null
+++ b/scripts/dotnet-cli-build/CompileTargets.cs
@@ -0,0 +1,401 @@
+using Microsoft.DotNet.Cli.Build.Framework;
+using Microsoft.Extensions.PlatformAbstractions;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Runtime.InteropServices;
+
+using static Microsoft.DotNet.Cli.Build.FS;
+using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
+
+namespace Microsoft.DotNet.Cli.Build
+{
+ public class CompileTargets
+ {
+ public static readonly string CoreCLRVersion = "1.0.1-rc2-23811";
+ public static readonly string AppDepSdkVersion = "1.0.5-prerelease-00001";
+
+ public static readonly List AssembliesToCrossGen = GetAssembliesToCrossGen();
+
+ public static readonly string[] BinariesForCoreHost = new[]
+ {
+ "csi",
+ "csc",
+ "vbc"
+ };
+
+ public static readonly string[] ProjectsToPublish = new[]
+ {
+ "dotnet"
+ };
+
+ public static readonly string[] FilesToClean = new[]
+ {
+ "README.md",
+ "Microsoft.DotNet.Runtime.exe",
+ "Microsoft.DotNet.Runtime.dll",
+ "Microsoft.DotNet.Runtime.deps",
+ "Microsoft.DotNet.Runtime.pdb"
+ };
+
+ public static readonly string[] ProjectsToPack = new[]
+ {
+ "Microsoft.DotNet.Cli.Utils",
+ "Microsoft.DotNet.ProjectModel",
+ "Microsoft.DotNet.ProjectModel.Loader",
+ "Microsoft.DotNet.ProjectModel.Workspaces",
+ "Microsoft.Extensions.DependencyModel",
+ "Microsoft.Extensions.Testing.Abstractions"
+ };
+
+ [Target(nameof(PrepareTargets.Init), nameof(CompileCoreHost), nameof(CompileStage1), nameof(CompileStage2))]
+ public static BuildTargetResult Compile(BuildTargetContext c)
+ {
+ return c.Success();
+ }
+
+ [Target]
+ public static BuildTargetResult CompileCoreHost(BuildTargetContext c)
+ {
+ // Generate build files
+ var cmakeOut = Path.Combine(Dirs.Corehost, "cmake");
+
+ Rmdir(cmakeOut);
+ Mkdirp(cmakeOut);
+
+ var configuration = (string)c.BuildContext["Configuration"];
+
+ // Run the build
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ // Why does Windows directly call cmake but Linux/Mac calls "build.sh" in the corehost dir?
+ // See the comment in "src/corehost/build.sh" for details. It doesn't work for some reason.
+ ExecIn(cmakeOut, "cmake",
+ Path.Combine(c.BuildContext.BuildDirectory, "src", "corehost"),
+ "-G",
+ "Visual Studio 14 2015 Win64");
+
+ var pf32 = RuntimeInformation.OSArchitecture == Architecture.X64 ?
+ Environment.GetEnvironmentVariable("ProgramFiles(x86)") :
+ Environment.GetEnvironmentVariable("ProgramFiles");
+
+ if (configuration.Equals("Release"))
+ {
+ // Cmake calls it "RelWithDebInfo" in the generated MSBuild
+ configuration = "RelWithDebInfo";
+ }
+
+ Exec(Path.Combine(pf32, "MSBuild", "14.0", "Bin", "MSBuild.exe"),
+ Path.Combine(cmakeOut, "ALL_BUILD.vcxproj"),
+ $"/p:Configuration={configuration}");
+
+ // Copy the output out
+ File.Copy(Path.Combine(cmakeOut, "cli", "Debug", "corehost.exe"), Path.Combine(Dirs.Corehost, "corehost.exe"), overwrite: true);
+ File.Copy(Path.Combine(cmakeOut, "cli", "Debug", "corehost.pdb"), Path.Combine(Dirs.Corehost, "corehost.pdb"), overwrite: true);
+ File.Copy(Path.Combine(cmakeOut, "cli", "dll", "Debug", "hostpolicy.dll"), Path.Combine(Dirs.Corehost, "hostpolicy.dll"), overwrite: true);
+ File.Copy(Path.Combine(cmakeOut, "cli", "dll", "Debug", "hostpolicy.pdb"), Path.Combine(Dirs.Corehost, "hostpolicy.pdb"), overwrite: true);
+ }
+ else
+ {
+ ExecIn(cmakeOut, Path.Combine(c.BuildContext.BuildDirectory, "src", "corehost", "build.sh"));
+
+ // Copy the output out
+ File.Copy(Path.Combine(cmakeOut, "cli", "corehost"), Path.Combine(Dirs.Corehost, "corehost"), overwrite: true);
+ File.Copy(Path.Combine(cmakeOut, "cli", "dll", $"{Constants.DynamicLibPrefix}hostpolicy{Constants.DynamicLibSuffix}"), Path.Combine(Dirs.Corehost, $"{Constants.DynamicLibPrefix}hostpolicy{Constants.DynamicLibSuffix}"), overwrite: true);
+ }
+
+ return c.Success();
+ }
+
+ [Target]
+ public static BuildTargetResult CompileStage1(BuildTargetContext c)
+ {
+ CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "src"));
+ CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "test"));
+ return CompileStage(c,
+ dotnet: DotNetCli.Stage0,
+ outputDir: Dirs.Stage1);
+ }
+
+ [Target]
+ public static BuildTargetResult CompileStage2(BuildTargetContext c)
+ {
+ var configuration = (string)c.BuildContext["Configuration"];
+
+ CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "src"));
+ CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "test"));
+ var result = CompileStage(c,
+ dotnet: DotNetCli.Stage1,
+ outputDir: Dirs.Stage2);
+ if (!result.Success)
+ {
+ return result;
+ }
+
+ // Build projects that are packed in NuGet packages, but only on Windows
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ var packagingOutputDir = Path.Combine(Dirs.Stage2Compilation, "forPackaging");
+ Mkdirp(packagingOutputDir);
+ foreach(var project in ProjectsToPack)
+ {
+ // Just build them, we'll pack later
+ DotNetCli.Stage1.Build(
+ "--build-base-path",
+ packagingOutputDir,
+ "--configuration",
+ configuration,
+ Path.Combine(c.BuildContext.BuildDirectory, "src", project))
+ .Execute()
+ .EnsureSuccessful();
+ }
+ }
+
+ return c.Success();
+ }
+
+ private static BuildTargetResult CompileStage(BuildTargetContext c, DotNetCli dotnet, string outputDir)
+ {
+ Rmdir(outputDir);
+
+ dotnet.SetDotNetHome();
+
+ var configuration = (string)c.BuildContext["Configuration"];
+ var binDir = Path.Combine(outputDir, "bin");
+ var runtimeOutputDir = Path.Combine(outputDir, "runtime", "coreclr");
+
+ Mkdirp(binDir);
+ Mkdirp(runtimeOutputDir);
+
+ foreach (var project in ProjectsToPublish)
+ {
+ dotnet.Publish(
+ "--native-subdirectory",
+ "--output",
+ binDir,
+ "--configuration",
+ configuration,
+ Path.Combine(c.BuildContext.BuildDirectory, "src", project))
+ .Execute()
+ .EnsureSuccessful();
+ }
+
+ // Publish the runtime
+ dotnet.Publish(
+ "--output",
+ runtimeOutputDir,
+ "--configuration",
+ configuration,
+ Path.Combine(c.BuildContext.BuildDirectory, "src", "Microsoft.DotNet.Runtime"))
+ .Execute()
+ .EnsureSuccessful();
+
+ // Clean bogus files
+ foreach (var fileToClean in FilesToClean)
+ {
+ var pathToClean = Path.Combine(runtimeOutputDir, fileToClean);
+ if (File.Exists(pathToClean))
+ {
+ File.Delete(pathToClean);
+ }
+ }
+
+ FixModeFlags(outputDir);
+
+ // Copy the whole runtime local to the tools
+ CopyRecursive(runtimeOutputDir, binDir);
+
+ // Copy corehost
+ File.Copy(Path.Combine(Dirs.Corehost, $"corehost{Constants.ExeSuffix}"), Path.Combine(binDir, $"corehost{Constants.ExeSuffix}"), overwrite: true);
+ File.Copy(Path.Combine(Dirs.Corehost, $"{Constants.DynamicLibPrefix}hostpolicy{Constants.DynamicLibSuffix}"), Path.Combine(binDir, $"{Constants.DynamicLibPrefix}hostpolicy{Constants.DynamicLibSuffix}"), overwrite: true);
+
+ // Corehostify binaries
+ foreach(var binaryToCorehostify in BinariesForCoreHost)
+ {
+ try
+ {
+ // Yes, it is .exe even on Linux. This is the managed exe we're working with
+ File.Copy(Path.Combine(binDir, $"{binaryToCorehostify}.exe"), Path.Combine(binDir, $"{binaryToCorehostify}.dll"));
+ File.Delete(Path.Combine(binDir, $"{binaryToCorehostify}.exe"));
+ File.Copy(Path.Combine(binDir, $"corehost{Constants.ExeSuffix}"), Path.Combine(binDir, binaryToCorehostify + Constants.ExeSuffix));
+ }
+ catch(Exception ex)
+ {
+ return c.Failed($"Failed to corehostify '{binaryToCorehostify}': {ex.ToString()}");
+ }
+ }
+
+ // Crossgen Roslyn
+ var result = Crossgen(c, binDir);
+ if (!result.Success)
+ {
+ return result;
+ }
+
+ // Copy AppDeps
+ result = CopyAppDeps(c, binDir);
+ if(!result.Success)
+ {
+ return result;
+ }
+
+ // Generate .version file
+ var version = ((BuildVersion)c.BuildContext["BuildVersion"]).SimpleVersion;
+ var content = $@"{version}{Environment.NewLine}{c.BuildContext["CommitHash"]}{Environment.NewLine}";
+ File.WriteAllText(Path.Combine(outputDir, ".version"), content);
+
+ return c.Success();
+ }
+
+ private static BuildTargetResult CopyAppDeps(BuildTargetContext c, string outputDir)
+ {
+ var appDepOutputDir = Path.Combine(outputDir, "appdepsdk");
+ Rmdir(appDepOutputDir);
+ Mkdirp(appDepOutputDir);
+
+ // Find toolchain package
+ string packageId;
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ packageId = "toolchain.win7-x64.Microsoft.DotNet.AppDep";
+ }
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ {
+ var osname = PlatformServices.Default.Runtime.OperatingSystem;
+ if (string.Equals(osname, "ubuntu", StringComparison.OrdinalIgnoreCase))
+ {
+ packageId = "toolchain.ubuntu.14.04-x64.Microsoft.DotNet.AppDep";
+ }
+ else if (string.Equals(osname, "centos", StringComparison.OrdinalIgnoreCase))
+ {
+ c.Warn("Native compilation is not yet working on CentOS");
+ return c.Success();
+ }
+ else
+ {
+ return c.Failed($"Unknown Linux Distro: {osname}");
+ }
+ }
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ packageId = "toolchain.osx.10.10-x64.Microsoft.DotNet.AppDep";
+ }
+ else
+ {
+ return c.Failed("Unsupported OS Platform");
+ }
+
+ var appDepPath = Path.Combine(
+ Dirs.NuGetPackages,
+ packageId,
+ AppDepSdkVersion);
+ CopyRecursive(appDepPath, appDepOutputDir, overwrite: true);
+
+ return c.Success();
+ }
+
+ private static BuildTargetResult Crossgen(BuildTargetContext c, string outputDir)
+ {
+ // Check if we need to skip crossgen
+ if (string.Equals(Environment.GetEnvironmentVariable("DOTNET_BUILD_SKIP_CROSSGEN"), "1"))
+ {
+ c.Warn("Skipping crossgen because DOTNET_BUILD_SKIP_CROSSGEN is set");
+ return c.Success();
+ }
+
+ // Find crossgen
+ string packageId;
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ packageId = "runtime.win7-x64.Microsoft.NETCore.Runtime.CoreCLR";
+ }
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ {
+ var osname = PlatformServices.Default.Runtime.OperatingSystem;
+ if (string.Equals(osname, "ubuntu", StringComparison.OrdinalIgnoreCase))
+ {
+ packageId = "runtime.ubuntu.14.04-x64.Microsoft.NETCore.Runtime.CoreCLR";
+ }
+ else if (string.Equals(osname, "centos", StringComparison.OrdinalIgnoreCase))
+ {
+ // CentOS runtime is in the runtime.rhel.7-x64... package.
+ packageId = "runtime.rhel.7-x64.Microsoft.NETCore.Runtime.CoreCLR";
+ }
+ else
+ {
+ return c.Failed($"Unknown Linux Distro: {osname}");
+ }
+ }
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ packageId = "runtime.osx.10.10-x64.Microsoft.NETCore.Runtime.CoreCLR";
+ }
+ else
+ {
+ return c.Failed("Unsupported OS Platform");
+ }
+
+ var crossGenExePath = Path.Combine(
+ Dirs.NuGetPackages,
+ packageId,
+ CoreCLRVersion,
+ "tools",
+ $"crossgen{Constants.ExeSuffix}");
+
+ // We have to copy crossgen next to mscorlib
+ var crossgen = Path.Combine(outputDir, $"crossgen{Constants.ExeSuffix}");
+ File.Copy(crossGenExePath, crossgen, overwrite: true);
+ Chmod(crossgen, "a+x");
+
+ // And if we have mscorlib.ni.dll, we need to rename it to mscorlib.dll
+ if (File.Exists(Path.Combine(outputDir, "mscorlib.ni.dll")))
+ {
+ File.Copy(Path.Combine(outputDir, "mscorlib.ni.dll"), Path.Combine(outputDir, "mscorlib.dll"), overwrite: true);
+ }
+
+ foreach (var assemblyToCrossgen in AssembliesToCrossGen)
+ {
+ c.Info($"Crossgenning {assemblyToCrossgen}");
+ ExecIn(outputDir, crossgen, "-nologo", "-platform_assemblies_paths", outputDir, assemblyToCrossgen);
+ }
+
+ c.Info("Crossgen complete");
+
+ // Check if csc/vbc.ni.exe exists, and overwrite the dll with it just in case
+ if (File.Exists(Path.Combine(outputDir, "csc.ni.exe")) && !File.Exists(Path.Combine(outputDir, "csc.ni.dll")))
+ {
+ File.Move(Path.Combine(outputDir, "csc.ni.exe"), Path.Combine(outputDir, "csc.ni.dll"));
+ }
+
+ if (File.Exists(Path.Combine(outputDir, "vbc.ni.exe")) && !File.Exists(Path.Combine(outputDir, "vbc.ni.dll")))
+ {
+ File.Move(Path.Combine(outputDir, "vbc.ni.exe"), Path.Combine(outputDir, "vbc.ni.dll"));
+ }
+
+ return c.Success();
+ }
+
+ private static List GetAssembliesToCrossGen()
+ {
+ var list = new List
+ {
+ "System.Collections.Immutable.dll",
+ "System.Reflection.Metadata.dll",
+ "Microsoft.CodeAnalysis.dll",
+ "Microsoft.CodeAnalysis.CSharp.dll",
+ "Microsoft.CodeAnalysis.VisualBasic.dll",
+ "csc.dll",
+ "vbc.dll"
+ };
+
+ // mscorlib is already crossgenned on Windows
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ // mscorlib has to be crossgenned first
+ list.Insert(0, "mscorlib.dll");
+ }
+
+ return list;
+ }
+ }
+}
diff --git a/scripts/dotnet-cli-build/PrepareTargets.cs b/scripts/dotnet-cli-build/PrepareTargets.cs
new file mode 100644
index 000000000..abd94ba68
--- /dev/null
+++ b/scripts/dotnet-cli-build/PrepareTargets.cs
@@ -0,0 +1,219 @@
+using Microsoft.DotNet.Cli.Build.Framework;
+using Microsoft.Extensions.PlatformAbstractions;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Runtime.InteropServices;
+
+using static Microsoft.DotNet.Cli.Build.FS;
+using static Microsoft.DotNet.Cli.Build.Utils;
+using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
+
+namespace Microsoft.DotNet.Cli.Build
+{
+ public class PrepareTargets
+ {
+ [Target(nameof(Init), nameof(RestorePackages))]
+ public static BuildTargetResult Prepare(BuildTargetContext c) => c.Success();
+
+ // All major targets will depend on this in order to ensure variables are set up right if they are run independently
+ [Target(nameof(GenerateVersions), nameof(CheckPrereqs), nameof(LocateStage0))]
+ public static BuildTargetResult Init(BuildTargetContext c)
+ {
+ var runtimeInfo = PlatformServices.Default.Runtime;
+
+ var configEnv = Environment.GetEnvironmentVariable("CONFIGURATION");
+
+ if(string.IsNullOrEmpty(configEnv))
+ {
+ configEnv = "Debug";
+ }
+ c.BuildContext["Configuration"] = configEnv;
+
+ c.Info($"Building {c.BuildContext["Configuration"]} to: {Dirs.Output}");
+ c.Info("Build Environment:");
+ c.Info($" Operating System: {runtimeInfo.OperatingSystem} {runtimeInfo.OperatingSystemVersion}");
+ c.Info($" Platform: {runtimeInfo.OperatingSystemPlatform}");
+
+ return c.Success();
+ }
+
+ [Target]
+ public static BuildTargetResult GenerateVersions(BuildTargetContext c)
+ {
+ var gitResult = Cmd("git", "rev-list", "--count", "HEAD")
+ .CaptureStdOut()
+ .Execute();
+ gitResult.EnsureSuccessful();
+ var commitCount = int.Parse(gitResult.StdOut);
+
+ gitResult = Cmd("git", "rev-parse", "HEAD")
+ .CaptureStdOut()
+ .Execute();
+ gitResult.EnsureSuccessful();
+ var commitHash = gitResult.StdOut.Trim();
+
+ var branchInfo = ReadBranchInfo(c, Path.Combine(c.BuildContext.BuildDirectory, "branchinfo.txt"));
+ var buildVersion = new BuildVersion()
+ {
+ Major = int.Parse(branchInfo["MAJOR_VERSION"]),
+ Minor = int.Parse(branchInfo["MINOR_VERSION"]),
+ Patch = int.Parse(branchInfo["PATCH_VERSION"]),
+ ReleaseSuffix = branchInfo["RELEASE_SUFFIX"],
+ CommitCount = commitCount
+ };
+ c.BuildContext["BuildVersion"] = buildVersion;
+ c.BuildContext["CommitHash"] = commitHash;
+
+ c.Info($"Building Version: {buildVersion.SimpleVersion} (NuGet Packages: {buildVersion.NuGetVersion})");
+ c.Info($"From Commit: {commitHash}");
+
+ return c.Success();
+ }
+
+ [Target]
+ public static BuildTargetResult LocateStage0(BuildTargetContext c)
+ {
+ // We should have been run in the repo root, so locate the stage 0 relative to current directory
+ var stage0 = DotNetCli.Stage0.BinPath;
+
+ if (!Directory.Exists(stage0))
+ {
+ return c.Failed($"Stage 0 directory does not exist: {stage0}");
+ }
+
+ // Identify the version
+ var version = File.ReadAllLines(Path.Combine(stage0, "..", ".version"));
+ c.Info($"Using Stage 0 Version: {version[1]}");
+
+ return c.Success();
+ }
+
+ [Target]
+ public static BuildTargetResult CheckPrereqs(BuildTargetContext c)
+ {
+ try
+ {
+ Command.Create("cmake", "--version")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute();
+ }
+ catch (Exception ex)
+ {
+ string message = $@"Error running cmake: {ex.Message}
+cmake is required to build the native host 'corehost'";
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ message += Environment.NewLine + "Download it from https://www.cmake.org";
+ }
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ {
+ message += Environment.NewLine + "Ubuntu: 'sudo apt-get install cmake'";
+ }
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ message += Environment.NewLine + "OS X w/Homebrew: 'brew install cmake'";
+ }
+ return c.Failed(message);
+ }
+
+ return c.Success();
+ }
+
+ [Target]
+ public static BuildTargetResult CheckPackageCache(BuildTargetContext c)
+ {
+ var ciBuild = string.Equals(Environment.GetEnvironmentVariable("CI_BUILD"), "1", StringComparison.Ordinal);
+
+ if (ciBuild)
+ {
+ // On CI, HOME is redirected under the repo, which gets deleted after every build.
+ // So make NUGET_PACKAGES outside of the repo.
+ var nugetPackages = Path.GetFullPath(Path.Combine(c.BuildContext.BuildDirectory, "..", ".nuget", "packages"));
+ Environment.SetEnvironmentVariable("NUGET_PACKAGES", nugetPackages);
+ Dirs.NuGetPackages = nugetPackages;
+ }
+
+ // Set the package cache location in NUGET_PACKAGES just to be safe
+ if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("NUGET_PACKAGES")))
+ {
+ Environment.SetEnvironmentVariable("NUGET_PACKAGES", Dirs.NuGetPackages);
+ }
+
+ CleanNuGetTempCache();
+
+ // Determine cache expiration time
+ var cacheExpiration = 7 * 24; // cache expiration in hours
+ var cacheExpirationStr = Environment.GetEnvironmentVariable("NUGET_PACKAGES_CACHE_TIME_LIMIT");
+ if (!string.IsNullOrEmpty(cacheExpirationStr))
+ {
+ cacheExpiration = int.Parse(cacheExpirationStr);
+ }
+
+ if (ciBuild)
+ {
+ var cacheTimeFile = Path.Combine(Dirs.NuGetPackages, "packageCacheTime.txt");
+
+ DateTime? cacheTime = null;
+ try
+ {
+ // Read the cache file
+ if(File.Exists(cacheTimeFile))
+ {
+ var content = File.ReadAllText(cacheTimeFile);
+ if(!string.IsNullOrEmpty(content))
+ {
+ cacheTime = DateTime.ParseExact("O", content, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
+ }
+ }
+ }
+ catch(Exception ex)
+ {
+ c.Warn($"Error reading NuGet cache time file, leaving the cache alone");
+ c.Warn($"Error Detail: {ex.ToString()}");
+ }
+
+ if(cacheTime == null || (cacheTime.Value.AddHours(cacheExpiration) < DateTime.UtcNow))
+ {
+ // Cache has expired or the status is unknown, clear it and write the file
+ c.Info("Clearing NuGet cache");
+ Rmdir(Dirs.NuGetPackages);
+ Mkdirp(Dirs.NuGetPackages);
+ File.WriteAllText(cacheTimeFile, DateTime.UtcNow.ToString("O"));
+ }
+ }
+
+ return c.Success();
+ }
+
+ [Target(nameof(CheckPackageCache))]
+ public static BuildTargetResult RestorePackages(BuildTargetContext c)
+ {
+ var dotnet = DotNetCli.Stage0;
+
+ dotnet.Restore().WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "src")).Execute().EnsureSuccessful();
+ dotnet.Restore().WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "tools")).Execute().EnsureSuccessful();
+
+ return c.Success();
+ }
+
+ private static IDictionary ReadBranchInfo(BuildTargetContext c, string path)
+ {
+ var lines = File.ReadAllLines(path);
+ var dict = new Dictionary();
+ c.Verbose("Branch Info:");
+ foreach(var line in lines)
+ {
+ if(!line.Trim().StartsWith("#") && !string.IsNullOrWhiteSpace(line))
+ {
+ var splat = line.Split(new[] { '=' }, 2);
+ dict[splat[0]] = splat[1];
+ c.Verbose($" {splat[0]} = {splat[1]}");
+ }
+ }
+ return dict;
+ }
+ }
+}
diff --git a/scripts/dotnet-cli-build/Program.cs b/scripts/dotnet-cli-build/Program.cs
new file mode 100755
index 000000000..bc2661b2c
--- /dev/null
+++ b/scripts/dotnet-cli-build/Program.cs
@@ -0,0 +1,12 @@
+using Microsoft.DotNet.Cli.Build.Framework;
+
+namespace Microsoft.DotNet.Cli.Build
+{
+ public class Program
+ {
+ public static int Main(string[] args) => BuildSetup.Create(".NET Core CLI")
+ .UseStandardGoals()
+ .UseAllTargetsFromAssembly()
+ .Run(args);
+ }
+}
diff --git a/scripts/dotnet-cli-build/PublishTargets.cs b/scripts/dotnet-cli-build/PublishTargets.cs
new file mode 100644
index 000000000..e7dbe752b
--- /dev/null
+++ b/scripts/dotnet-cli-build/PublishTargets.cs
@@ -0,0 +1,71 @@
+using Microsoft.DotNet.Cli.Build.Framework;
+using Microsoft.Extensions.PlatformAbstractions;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Runtime.InteropServices;
+
+using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
+
+namespace Microsoft.DotNet.Cli.Build
+{
+ public static class PublishTargets
+ {
+ [Target(nameof(PrepareTargets.Init))]
+ public static BuildTargetResult Publish(BuildTargetContext c)
+ {
+ // NOTE(anurse): Currently, this just invokes the remaining build scripts as-is. We should port those to C# as well, but
+ // I want to get the merged in.
+
+ // Set up the environment variables previously defined by common.sh/ps1
+ // This is overkill, but I want to cover all the variables used in all OSes (including where some have the same names)
+ var buildVersion = (BuildVersion)c.BuildContext["BuildVersion"];
+ var env = new Dictionary()
+ {
+ { "RID", PlatformServices.Default.Runtime.GetRuntimeIdentifier() },
+ { "OSNAME", PlatformServices.Default.Runtime.OperatingSystem },
+ { "TFM", "dnxcore50" },
+ { "OutputDir", Dirs.Output },
+ { "Stage1Dir", Dirs.Stage1 },
+ { "Stage1CompilationDir", Dirs.Stage1Compilation },
+ { "Stage2Dir", Dirs.Stage2 },
+ { "STAGE2_DIR", Dirs.Stage2 },
+ { "Stage2CompilationDir", Dirs.Stage2Compilation },
+ { "HostDir", Dirs.Corehost },
+ { "PackageDir", Path.Combine(Dirs.Packages, "dnvm") }, // Legacy name
+ { "TestBinRoot", Dirs.TestOutput },
+ { "TestPackageDir", Dirs.TestPackages },
+ { "MajorVersion", buildVersion.Major.ToString() },
+ { "MinorVersion", buildVersion.Minor.ToString() },
+ { "PatchVersion", buildVersion.Patch.ToString() },
+ { "CommitCountVersion", buildVersion.CommitCountString },
+ { "COMMIT_COUNT_VERSION", buildVersion.CommitCountString },
+ { "DOTNET_CLI_VERSION", buildVersion.SimpleVersion },
+ { "DOTNET_MSI_VERSION", buildVersion.GenerateMsiVersion() },
+ { "VersionSuffix", buildVersion.VersionSuffix }
+ };
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ env["OSNAME"] = "osx";
+ }
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ Cmd("powershell", "-NoProfile", "-NoLogo", Path.Combine(c.BuildContext.BuildDirectory, "scripts", "package", "package.ps1"))
+ .Environment(env)
+ .Execute()
+ .EnsureSuccessful();
+ }
+ else
+ {
+ // Can directly execute scripts on Unix :). Thank you shebangs!
+ Cmd(Path.Combine(c.BuildContext.BuildDirectory, "scripts", "package", "package.sh"))
+ .Environment(env)
+ .Execute()
+ .EnsureSuccessful();
+ }
+ return c.Success();
+ }
+ }
+}
diff --git a/scripts/dotnet-cli-build/TestTargets.cs b/scripts/dotnet-cli-build/TestTargets.cs
new file mode 100644
index 000000000..6937781f8
--- /dev/null
+++ b/scripts/dotnet-cli-build/TestTargets.cs
@@ -0,0 +1,241 @@
+using Microsoft.DotNet.Cli.Build.Framework;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+
+using static Microsoft.DotNet.Cli.Build.FS;
+using static Microsoft.DotNet.Cli.Build.Utils;
+using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
+
+namespace Microsoft.DotNet.Cli.Build
+{
+ public class TestTargets
+ {
+ public static readonly string[] TestPackageProjects = new[]
+ {
+ "dotnet-hello/v1/dotnet-hello",
+ "dotnet-hello/v2/dotnet-hello"
+ };
+
+ public static readonly string[] TestProjects = new[]
+ {
+ "EndToEnd",
+ "dotnet-publish.Tests",
+ "dotnet-compile.Tests",
+ "dotnet-compile.UnitTests",
+ "dotnet-build.Tests",
+ "Microsoft.DotNet.Cli.Utils.Tests",
+ "Microsoft.DotNet.Compiler.Common.Tests",
+ "ArgumentForwardingTests"
+ };
+
+ [Target(nameof(PrepareTargets.Init), nameof(SetupTests), nameof(RestoreTests), nameof(BuildTests), nameof(RunTests), nameof(ValidateDependencies))]
+ public static BuildTargetResult Test(BuildTargetContext c) => c.Success();
+
+ [Target(nameof(RestoreTestPrerequisites), nameof(BuildTestPrerequisites))]
+ public static BuildTargetResult SetupTests(BuildTargetContext c) => c.Success();
+
+ [Target]
+ public static BuildTargetResult RestoreTestPrerequisites(BuildTargetContext c)
+ {
+ CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "src"));
+ CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "test"));
+
+ CleanNuGetTempCache();
+
+ var dotnet = DotNetCli.Stage2;
+ dotnet.Restore().WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "TestAssets")).Execute().EnsureSuccessful();
+
+ // The 'testapp' directory contains intentionally-unresolved dependencies, so don't check for success. Also, suppress the output
+ dotnet.Restore().WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "testapp")).CaptureStdErr().CaptureStdOut().Execute();
+
+ return c.Success();
+ }
+
+ [Target]
+ public static BuildTargetResult BuildTestPrerequisites(BuildTargetContext c)
+ {
+ var dotnet = DotNetCli.Stage2;
+
+ Rmdir(Dirs.TestPackages);
+ Mkdirp(Dirs.TestPackages);
+
+ foreach (var relativePath in TestPackageProjects)
+ {
+ var fullPath = Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "TestPackages", relativePath.Replace('/', Path.DirectorySeparatorChar));
+ c.Info("Packing: {fullPath}");
+ dotnet.Pack("--output", Dirs.TestPackages)
+ .WorkingDirectory(fullPath)
+ .Execute()
+ .EnsureSuccessful();
+ }
+
+ return c.Success();
+ }
+
+ [Target]
+ public static BuildTargetResult RestoreTests(BuildTargetContext c)
+ {
+ CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "src"));
+ CleanBinObj(c, Path.Combine(c.BuildContext.BuildDirectory, "test"));
+
+ CleanNuGetTempCache();
+ DotNetCli.Stage2.Restore("--fallbacksource", Dirs.TestPackages)
+ .WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "test"))
+ .Execute()
+ .EnsureSuccessful();
+ return c.Success();
+ }
+
+ [Target]
+ public static BuildTargetResult BuildTests(BuildTargetContext c)
+ {
+ var dotnet = DotNetCli.Stage2;
+ foreach (var testProject in TestProjects)
+ {
+ c.Info("Building tests: {project}");
+ dotnet.Build()
+ .WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "test", testProject))
+ .Execute()
+ .EnsureSuccessful();
+ }
+ return c.Success();
+ }
+
+ [Target(nameof(RunXUnitTests), nameof(RunPackageCommandTests))]
+ public static BuildTargetResult RunTests(BuildTargetContext c) => c.Success();
+
+ [Target]
+ public static BuildTargetResult RunXUnitTests(BuildTargetContext c)
+ {
+ // Need to load up the VS Vars
+ var dotnet = DotNetCli.Stage2;
+ var vsvars = LoadVsVars();
+
+ // Copy the test projects
+ var testProjectsDir = Path.Combine(Dirs.TestOutput, "TestProjects");
+ Rmdir(testProjectsDir);
+ Mkdirp(testProjectsDir);
+ CopyRecursive(Path.Combine(c.BuildContext.BuildDirectory, "TestAssets", "TestProjects"), testProjectsDir);
+
+ // Run the tests and set the VS vars in the environment when running them
+ var failingTests = new List();
+ foreach (var project in TestProjects)
+ {
+ c.Info("Running tests in: {project}");
+ var result = dotnet.Test("-xml", $"{project}-testResults.xml", "-notrait", "category=failing")
+ .WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "test", project))
+ .Environment(vsvars)
+ .EnvironmentVariable("PATH", $"{DotNetCli.Stage2.BinPath}{Path.PathSeparator}{Environment.GetEnvironmentVariable("PATH")}")
+ .Execute();
+ if (result.ExitCode != 0)
+ {
+ failingTests.Add(project);
+ }
+ }
+
+ if (failingTests.Any())
+ {
+ foreach (var project in failingTests)
+ {
+ c.Error($"{project} failed");
+ }
+ return c.Failed("Tests failed!");
+ }
+
+ return c.Success();
+ }
+
+ [Target]
+ public static BuildTargetResult RunPackageCommandTests(BuildTargetContext c)
+ {
+ var dotnet = DotNetCli.Stage2;
+ var consumers = Path.Combine(c.BuildContext.BuildDirectory, "test", "PackagedCommands", "Consumers");
+
+ // Compile the consumer apps
+ foreach(var dir in Directory.EnumerateDirectories(consumers))
+ {
+ dotnet.Build().WorkingDirectory(dir).Execute().EnsureSuccessful();
+ }
+
+ // Test the apps
+ foreach(var dir in Directory.EnumerateDirectories(consumers))
+ {
+ var result = dotnet.Exec("hello").WorkingDirectory(dir).CaptureStdOut().CaptureStdErr().Execute();
+ result.EnsureSuccessful();
+ if(!string.Equals("Hello", result.StdOut.Trim(), StringComparison.Ordinal))
+ {
+ var testName = Path.GetFileName(dir);
+ c.Error($"Packaged Commands Test '{testName}' failed");
+ c.Error($" Expected 'Hello', but got: '{result.StdOut.Trim()}'");
+ return c.Failed($"Packaged Commands Test failed '{testName}'");
+ }
+ }
+
+ return c.Success();
+ }
+
+ [Target]
+ public static BuildTargetResult ValidateDependencies(BuildTargetContext c)
+ {
+ var configuration = (string)c.BuildContext["Configuration"];
+ var dotnet = DotNetCli.Stage2;
+
+ c.Info("Publishing MultiProjectValidator");
+ dotnet.Publish("--output", Path.Combine(Dirs.Output, "tools"), "--configuration", configuration)
+ .WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "tools", "MultiProjectValidator"))
+ .Execute()
+ .EnsureSuccessful();
+
+ var validator = Path.Combine(Dirs.Output, "tools", $"pjvalidate{Constants.ExeSuffix}");
+
+ Cmd(validator, Path.Combine(c.BuildContext.BuildDirectory, "src"))
+ .Execute();
+
+ return c.Success();
+ }
+
+ private static Dictionary LoadVsVars()
+ {
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ return new Dictionary();
+ }
+
+ var vsvarsPath = Path.GetFullPath(Path.Combine(Environment.GetEnvironmentVariable("VS140COMNTOOLS"), "..", "..", "VC"));
+
+ // Write a temp batch file because that seems to be the easiest way to do this (argument parsing is hard)
+ var temp = Path.Combine(Path.GetTempPath(), $"{Path.GetRandomFileName()}.cmd");
+ File.WriteAllText(temp, $@"@echo off
+cd {vsvarsPath}
+call vcvarsall.bat x64
+set");
+
+ CommandResult result;
+ try
+ {
+ result = Cmd(Environment.GetEnvironmentVariable("COMSPEC"), "/c", temp)
+ .WorkingDirectory(vsvarsPath)
+ .CaptureStdOut()
+ .Execute();
+ }
+ finally
+ {
+ if (File.Exists(temp))
+ {
+ File.Delete(temp);
+ }
+ }
+ result.EnsureSuccessful();
+ var vars = new Dictionary();
+ foreach (var line in result.StdOut.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries))
+ {
+ var splat = line.Split(new[] { '=' }, 2);
+ vars[splat[0]] = splat[1];
+ }
+ return vars;
+ }
+ }
+}
diff --git a/scripts/dotnet-cli-build/Utils/BuildVersion.cs b/scripts/dotnet-cli-build/Utils/BuildVersion.cs
new file mode 100644
index 000000000..c03b48bd3
--- /dev/null
+++ b/scripts/dotnet-cli-build/Utils/BuildVersion.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Microsoft.DotNet.Cli.Build
+{
+ public class BuildVersion
+ {
+ public int Major { get; set; }
+ public int Minor { get; set; }
+ public int Patch { get; set; }
+ public int CommitCount { get; set; }
+ public string CommitCountString => CommitCount.ToString("000000");
+ public string ReleaseSuffix { get; set; }
+
+ public string SimpleVersion => $"{Major}.{Minor}.{Patch}.{CommitCount}";
+ public string VersionSuffix => $"{ReleaseSuffix}-{CommitCount}";
+ public string NuGetVersion => $"{Major}.{Minor}.{Patch}-{VersionSuffix}";
+
+ public string GenerateMsiVersion()
+ {
+ // MSI versioning
+ // Encode the CLI version to fit into the MSI versioning scheme - https://msdn.microsoft.com/en-us/library/windows/desktop/aa370859(v=vs.85).aspx
+ // MSI versions are 3 part
+ // major.minor.build
+ // Size(bits) of each part 8 8 16
+ // So we have 32 bits to encode the CLI version
+ // Starting with most significant bit this how the CLI version is going to be encoded as MSI Version
+ // CLI major -> 6 bits
+ // CLI minor -> 6 bits
+ // CLI patch -> 6 bits
+ // CLI commitcount -> 14 bits
+
+ var major = Major << 26;
+ var minor = Minor << 20;
+ var patch = Patch << 14;
+ var msiVersionNumber = major | minor | patch | CommitCount;
+
+ var msiMajor = (msiVersionNumber >> 24) & 0xFF;
+ var msiMinor = (msiVersionNumber >> 16) & 0xFF;
+ var msiBuild = msiVersionNumber & 0xFFFF;
+
+ return $"{msiMajor}.{msiMinor}.{msiBuild}";
+ }
+ }
+}
diff --git a/scripts/dotnet-cli-build/Utils/Dirs.cs b/scripts/dotnet-cli-build/Utils/Dirs.cs
new file mode 100644
index 000000000..c90b63406
--- /dev/null
+++ b/scripts/dotnet-cli-build/Utils/Dirs.cs
@@ -0,0 +1,38 @@
+using Microsoft.Extensions.PlatformAbstractions;
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace Microsoft.DotNet.Cli.Build
+{
+ public static class Dirs
+ {
+ public static readonly string Output = Path.Combine(
+ Directory.GetCurrentDirectory(),
+ "artifacts",
+ PlatformServices.Default.Runtime.GetRuntimeIdentifier());
+ public static readonly string Packages = Path.Combine(Output, "packages");
+ public static readonly string Stage1 = Path.Combine(Output, "stage1");
+ public static readonly string Stage1Compilation = Path.Combine(Output, "stage1compilation");
+ public static readonly string Stage2 = Path.Combine(Output, "stage2");
+ public static readonly string Stage2Compilation = Path.Combine(Output, "stage2compilation");
+ public static readonly string Corehost = Path.Combine(Output, "corehost");
+ public static readonly string TestOutput = Path.Combine(Output, "tests");
+ public static readonly string TestPackages = Path.Combine(TestOutput, "packages");
+
+ public static readonly string OSXReferenceAssembliesPath = "/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/xbuild-frameworks";
+ public static readonly string UsrLocalReferenceAssembliesPath = "/usr/local/lib/mono/xbuild-frameworks";
+ public static readonly string UsrReferenceAssembliesPath = "/usr/lib/mono/xbuild-frameworks";
+
+ public static string NuGetPackages = Environment.GetEnvironmentVariable("NUGET_PACKAGES") ?? GetNuGetPackagesDir();
+
+ private static string GetNuGetPackagesDir()
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ return Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), ".nuget", "packages");
+ }
+ return Path.Combine(Environment.GetEnvironmentVariable("HOME"), ".nuget", "packages");
+ }
+ }
+}
diff --git a/scripts/dotnet-cli-build/Utils/DotNetCli.cs b/scripts/dotnet-cli-build/Utils/DotNetCli.cs
new file mode 100644
index 000000000..51e194504
--- /dev/null
+++ b/scripts/dotnet-cli-build/Utils/DotNetCli.cs
@@ -0,0 +1,51 @@
+using System.IO;
+using System.Linq;
+using System;
+using System.Runtime.InteropServices;
+using Microsoft.DotNet.Cli.Build.Framework;
+using Microsoft.Extensions.PlatformAbstractions;
+
+namespace Microsoft.DotNet.Cli.Build
+{
+ internal class DotNetCli
+ {
+ public static readonly DotNetCli Stage0 = new DotNetCli(GetStage0Path());
+ public static readonly DotNetCli Stage1 = new DotNetCli(Path.Combine(Dirs.Stage1, "bin"));
+ public static readonly DotNetCli Stage2 = new DotNetCli(Path.Combine(Dirs.Stage2, "bin"));
+
+ public string BinPath { get; }
+
+ public DotNetCli(string binPath)
+ {
+ BinPath = binPath;
+ }
+
+ public void SetDotNetHome()
+ {
+ Environment.SetEnvironmentVariable("DOTNET_HOME", Path.GetDirectoryName(BinPath));
+ }
+
+ public Command Exec(string command, params string[] args)
+ {
+ return Command.Create(Path.Combine(BinPath, $"dotnet{Constants.ExeSuffix}"), Enumerable.Concat(new[] { command }, args));
+ }
+
+ public Command Restore(params string[] args) => Exec("restore", args);
+ public Command Build(params string[] args) => Exec("build", args);
+ public Command Pack(params string[] args) => Exec("pack", args);
+ public Command Test(params string[] args) => Exec("test", args);
+ public Command Publish(params string[] args) => Exec("publish", args);
+
+ private static string GetStage0Path()
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ return Path.Combine(Directory.GetCurrentDirectory(), ".dotnet_stage0", PlatformServices.Default.Runtime.OperatingSystemPlatform.ToString(), "cli", "bin");
+ }
+ else
+ {
+ return Path.Combine(Directory.GetCurrentDirectory(), ".dotnet_stage0", PlatformServices.Default.Runtime.OperatingSystemPlatform.ToString(), "share", "dotnet", "cli", "bin");
+ }
+ }
+ }
+}
diff --git a/scripts/dotnet-cli-build/Utils/FS.cs b/scripts/dotnet-cli-build/Utils/FS.cs
new file mode 100644
index 000000000..b336d46f2
--- /dev/null
+++ b/scripts/dotnet-cli-build/Utils/FS.cs
@@ -0,0 +1,114 @@
+using System.IO;
+using System.Runtime.InteropServices;
+using System;
+
+using Microsoft.DotNet.Cli.Build.Framework;
+
+using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
+
+namespace Microsoft.DotNet.Cli.Build
+{
+ public static class FS
+ {
+ public static void Mkdirp(string dir)
+ {
+ if (!Directory.Exists(dir))
+ {
+ Directory.CreateDirectory(dir);
+ }
+ }
+
+ public static void Rm(string file)
+ {
+ if(File.Exists(file))
+ {
+ File.Delete(file);
+ }
+ }
+
+ public static void Rmdir(string dir)
+ {
+ if(Directory.Exists(dir))
+ {
+ Directory.Delete(dir, recursive: true);
+ }
+ }
+
+ public static void Chmod(string file, string mode, bool recursive = false)
+ {
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ if (recursive)
+ {
+ Command.Create("chmod", "-R", mode, file).Execute().EnsureSuccessful();
+ }
+ else
+ {
+ Command.Create("chmod", mode, file).Execute().EnsureSuccessful();
+ }
+ }
+ }
+
+ public static void ChmodAll(string searchDir, string pattern, string mode)
+ {
+ Exec("find", searchDir, "-type", "f", "-name", pattern, "-exec", "chmod", mode, "{}", ";");
+ }
+
+ public static void FixModeFlags(string dir)
+ {
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ // Managed code doesn't need 'x'
+ ChmodAll(dir, "*.dll", "644");
+ ChmodAll(dir, "*.exe", "644");
+
+ // Generally, dylibs and sos have 'x' (no idea if it's required ;))
+ // (No need to condition this on OS since there shouldn't be any dylibs on Linux,
+ // but even if they are we may as well set their mode flags :))
+ ChmodAll(dir, "*.dylib", "755");
+ ChmodAll(dir, "*.so", "755");
+
+ // Executables (those without dots) are executable :)
+ Exec("find", dir, "-type", "f", "!", "-name", "*.*", "-exec", "chmod", "755", "{}", ";");
+ }
+ }
+
+ public static void CopyRecursive(string sourceDirectory, string destinationDirectory, bool overwrite = false)
+ {
+ Mkdirp(destinationDirectory);
+
+ foreach(var dir in Directory.EnumerateDirectories(sourceDirectory))
+ {
+ CopyRecursive(dir, Path.Combine(destinationDirectory, Path.GetFileName(dir)), overwrite);
+ }
+
+ foreach(var file in Directory.EnumerateFiles(sourceDirectory))
+ {
+ var dest = Path.Combine(destinationDirectory, Path.GetFileName(file));
+ if (!File.Exists(dest) || overwrite)
+ {
+ // We say overwrite true, because we only get here if the file didn't exist (thus it doesn't matter) or we
+ // wanted to overwrite :)
+ File.Copy(file, dest, overwrite: true);
+ }
+ }
+ }
+
+ public static void CleanBinObj(BuildTargetContext c, string dir)
+ {
+ dir = dir ?? c.BuildContext.BuildDirectory;
+ foreach(var candidate in Directory.EnumerateDirectories(dir))
+ {
+ if (string.Equals(Path.GetFileName(candidate), "bin") ||
+ string.Equals(Path.GetFileName(candidate), "obj"))
+ {
+ Directory.Delete(candidate, recursive: true);
+ }
+ else
+ {
+ CleanBinObj(c, candidate);
+ }
+ }
+ }
+ }
+}
diff --git a/scripts/dotnet-cli-build/Utils/Utils.cs b/scripts/dotnet-cli-build/Utils/Utils.cs
new file mode 100644
index 000000000..edbee23d1
--- /dev/null
+++ b/scripts/dotnet-cli-build/Utils/Utils.cs
@@ -0,0 +1,38 @@
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace Microsoft.DotNet.Cli.Build
+{
+ public static class Utils
+ {
+ public static void CleanNuGetTempCache()
+ {
+ // Clean NuGet Temp Cache on Linux (seeing some issues on Linux)
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && Directory.Exists("/tmp/NuGet"))
+ {
+ Directory.Delete("/tmp/NuGet", recursive: true);
+ }
+ }
+
+ public static string GetOSName()
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ return "win";
+ }
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ return "osx";
+ }
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ {
+ throw new NotImplementedException();
+ }
+ else
+ {
+ throw new PlatformNotSupportedException();
+ }
+ }
+ }
+}
diff --git a/scripts/dotnet-cli-build/dotnet-cli-build.xproj b/scripts/dotnet-cli-build/dotnet-cli-build.xproj
new file mode 100644
index 000000000..fadd44933
--- /dev/null
+++ b/scripts/dotnet-cli-build/dotnet-cli-build.xproj
@@ -0,0 +1,18 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ d7b9695d-23eb-4ea8-b8ab-707a0092e1d5
+ Microsoft.DotNet.Cli.Build
+ ..\..\artifacts\obj\$(MSBuildProjectName)
+ ..\..\artifacts\bin\$(MSBuildProjectName)\
+
+
+ 2.0
+
+
+
\ No newline at end of file
diff --git a/scripts/dotnet-cli-build/project.json b/scripts/dotnet-cli-build/project.json
new file mode 100755
index 000000000..326ce33b3
--- /dev/null
+++ b/scripts/dotnet-cli-build/project.json
@@ -0,0 +1,18 @@
+{
+ "version": "1.0.0-*",
+ "description": "Build scripts for dotnet-cli",
+ "compilationOptions": {
+ "emitEntryPoint": true
+ },
+
+ "dependencies": {
+ "NETStandard.Library": "1.0.0-rc2-23811",
+ "System.IO.Compression.ZipFile": "4.0.1-rc2-23811",
+ "Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc2-16537",
+ "Microsoft.DotNet.Cli.Build.Framework": "1.0.0-*"
+ },
+
+ "frameworks": {
+ "dnxcore50": { }
+ }
+}
diff --git a/scripts/global.json b/scripts/global.json
new file mode 100644
index 000000000..22936715c
--- /dev/null
+++ b/scripts/global.json
@@ -0,0 +1,3 @@
+{
+ "projects": [ "." ]
+}
diff --git a/scripts/obtain/install-tools.ps1 b/scripts/obtain/install-tools.ps1
deleted file mode 100644
index 89ae69dfe..000000000
--- a/scripts/obtain/install-tools.ps1
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-. $PSScriptRoot\..\common\_common.ps1
-
-# Use a repo-local install directory (but not the artifacts directory because that gets cleaned a lot
-if (!(Test-Path $env:DOTNET_INSTALL_DIR))
-{
- mkdir $env:DOTNET_INSTALL_DIR | Out-Null
-}
-
-# Install a stage 0
-header "Installing dotnet stage 0"
-_ "$RepoRoot\scripts\obtain\install.ps1" @("$env:Channel")
diff --git a/scripts/obtain/install-tools.sh b/scripts/obtain/install-tools.sh
deleted file mode 100755
index f4a99f26c..000000000
--- a/scripts/obtain/install-tools.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-
-# Use a repo-local install directory (but not the artifacts directory because that gets cleaned a lot
-[ -d $DOTNET_INSTALL_DIR ] || mkdir -p $DOTNET_INSTALL_DIR
-
-# Ensure the latest stage0 is installed
-header "Installing dotnet stage 0"
-$REPOROOT/scripts/obtain/install.sh
-
-# Now patch the runtime in stage 0
-# HACK(anurse): BIG HACK. This is just to dodge the current broken Linux stage0. We'll remove it as soon as we've got a new stage 0
-(
- export PATH="$DOTNET_INSTALL_DIR/bin:$PATH"
- cd $REPOROOT/src/Microsoft.DotNet.Runtime
- dotnet restore
- dotnet publish -o "$DOTNET_INSTALL_DIR/share/dotnet/cli/runtime/coreclr"
- cp $DOTNET_INSTALL_DIR/share/dotnet/cli/runtime/coreclr/* $DOTNET_INSTALL_DIR/share/dotnet/cli/bin
-)
diff --git a/scripts/package/package-dnvm.sh b/scripts/package/package-dnvm.sh
index 412161753..47d8fe396 100755
--- a/scripts/package/package-dnvm.sh
+++ b/scripts/package/package-dnvm.sh
@@ -33,6 +33,6 @@ header "Packaging $PACKAGE_SHORT_NAME"
# We need both "*" and ".version" to ensure we pick up that file
tar -czf $PACKAGE_NAME * .version
-info "Packaged stage2 to $PACKAGE_NAME"
+info "Packaged stage2 from '$STAGE2_DIR' to '$PACKAGE_NAME'"
$REPOROOT/scripts/publish/publish.sh $PACKAGE_NAME
diff --git a/scripts/package/package.ps1 b/scripts/package/package.ps1
index 577a17380..cfb3c13d8 100644
--- a/scripts/package/package.ps1
+++ b/scripts/package/package.ps1
@@ -4,7 +4,8 @@
#
. "$PSScriptRoot\..\common\_common.ps1"
-. "$RepoRoot\scripts\build\generate-version.ps1"
+
+$RepoRoot = Convert-Path "$PSScriptRoot\..\.."
header "Generating zip package"
_ "$RepoRoot\scripts\package\package-zip.ps1"
diff --git a/scripts/package/package.sh b/scripts/package/package.sh
index dea779842..a412a04f7 100755
--- a/scripts/package/package.sh
+++ b/scripts/package/package.sh
@@ -12,8 +12,9 @@ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symli
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+export REPOROOT="$(cd -P "$DIR/../.." && pwd)"
+
source "$DIR/../common/_common.sh"
-source "$REPOROOT/scripts/build/generate-version.sh"
if [ -z "$DOTNET_CLI_VERSION" ]; then
TIMESTAMP=$(date "+%Y%m%d%H%M%S")
@@ -33,5 +34,5 @@ header "Generating version badge"
sed "s/ver_number/$DOTNET_CLI_VERSION/g" $VERSION_BADGE > $BADGE_DESTINATION
header "Publishing version badge"
-$REPOROOT/scripts/publish/publish.sh $BADGE_DESTINATION
+$DIR/../publish/publish.sh $BADGE_DESTINATION
diff --git a/scripts/run-build.ps1 b/scripts/run-build.ps1
new file mode 100644
index 000000000..9b9453722
--- /dev/null
+++ b/scripts/run-build.ps1
@@ -0,0 +1,55 @@
+#
+# Copyright (c) .NET Foundation and contributors. All rights reserved.
+# Licensed under the MIT license. See LICENSE file in the project root for full license information.
+#
+
+param(
+ [string]$Configuration="Debug")
+
+$env:CONFIGURATION = $Configuration;
+
+# Load Branch Info
+cat "$PSScriptRoot\..\branchinfo.txt" | ForEach-Object {
+ if(!$_.StartsWith("#") -and ![String]::IsNullOrWhiteSpace($_)) {
+ $splat = $_.Split([char[]]@("="), 2)
+ Set-Content "env:\$($splat[0])" -Value $splat[1]
+ }
+}
+
+$env:CHANNEL=$env:RELEASE_SUFFIX
+
+# Use a repo-local install directory (but not the artifacts directory because that gets cleaned a lot
+if (!$env:DOTNET_INSTALL_DIR)
+{
+ $env:DOTNET_INSTALL_DIR="$PSScriptRoot\..\.dotnet_stage0\Windows"
+}
+
+if (!(Test-Path $env:DOTNET_INSTALL_DIR))
+{
+ mkdir $env:DOTNET_INSTALL_DIR | Out-Null
+}
+
+# Install a stage 0
+Write-Host "Installing .NET Core CLI Stage 0 from beta channel"
+& "$PSScriptRoot\obtain\install.ps1" -Channel $env:CHANNEL
+
+# Put the stage0 on the path
+$env:PATH = "$env:DOTNET_INSTALL_DIR\cli\bin;$env:PATH"
+
+# Restore the build scripts
+Write-Host "Restoring Build Script projects..."
+pushd $PSScriptRoot
+dotnet restore
+if($LASTEXITCODE -ne 0) { throw "Failed to restore" }
+popd
+
+# Publish the builder
+Write-Host "Compiling Build Scripts..."
+dotnet publish "$PSScriptRoot\dotnet-cli-build" -o "$PSScriptRoot/dotnet-cli-build/bin" --framework dnxcore50
+if($LASTEXITCODE -ne 0) { throw "Failed to compile build scripts" }
+
+# Run the builder
+Write-Host "Invoking Build Scripts..."
+$env:DOTNET_HOME="$env:DOTNET_INSTALL_DIR\cli"
+& "$PSScriptRoot\dotnet-cli-build\bin\dotnet-cli-build.exe" @args
+if($LASTEXITCODE -ne 0) { throw "Build failed" }
diff --git a/scripts/run-build.sh b/scripts/run-build.sh
new file mode 100755
index 000000000..c5a7f3542
--- /dev/null
+++ b/scripts/run-build.sh
@@ -0,0 +1,80 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) .NET Foundation and contributors. All rights reserved.
+# Licensed under the MIT license. See LICENSE file in the project root for full license information.
+#
+
+set -e
+
+SOURCE="${BASH_SOURCE[0]}"
+while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
+ DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+ SOURCE="$(readlink "$SOURCE")"
+ [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
+done
+DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+
+# Set up the environment to be used for building with clang.
+if which "clang-3.5" > /dev/null 2>&1; then
+ export CC="$(which clang-3.5)"
+ export CXX="$(which clang++-3.5)"
+elif which "clang-3.6" > /dev/null 2>&1; then
+ export CC="$(which clang-3.6)"
+ export CXX="$(which clang++-3.6)"
+elif which clang > /dev/null 2>&1; then
+ export CC="$(which clang)"
+ export CXX="$(which clang++)"
+else
+ error "Unable to find Clang Compiler"
+ error "Install clang-3.5 or clang3.6"
+ exit 1
+fi
+
+# Load Branch Info
+while read line; do
+ if [[ $line != \#* ]]; then
+ IFS='=' read -ra splat <<< "$line"
+ export ${splat[0]}="${splat[1]}"
+ fi
+done < "$DIR/../branchinfo.txt"
+
+# Use a repo-local install directory (but not the artifacts directory because that gets cleaned a lot
+[ -z "$DOTNET_INSTALL_DIR" ] && export DOTNET_INSTALL_DIR=$DIR/../.dotnet_stage0/$(uname)
+[ -d $DOTNET_INSTALL_DIR ] || mkdir -p $DOTNET_INSTALL_DIR
+
+# Ensure the latest stage0 is installed
+$DIR/obtain/install.sh --channel $RELEASE_SUFFIX
+
+# Put stage 0 on the PATH (for this shell only)
+PATH="$DOTNET_INSTALL_DIR/bin:$PATH"
+
+# Increases the file descriptors limit for this bash. It prevents an issue we were hitting during restore
+FILE_DESCRIPTOR_LIMIT=$( ulimit -n )
+if [ $FILE_DESCRIPTOR_LIMIT -lt 1024 ]
+then
+ echo "Increasing file description limit to 1024"
+ ulimit -n 1024
+fi
+
+# Restore the build scripts
+echo "Restoring Build Script projects..."
+(
+ cd $DIR
+ dotnet restore
+)
+
+# Build the builder
+echo "Compiling Build Scripts..."
+dotnet publish "$DIR/dotnet-cli-build" -o "$DIR/dotnet-cli-build/bin" --framework dnxcore50
+
+# Run the builder
+echo "Invoking Build Scripts..."
+
+if [ -f "$DIR/dotnet-cli-build/bin/dotnet-cli-build" ]; then
+ DOTNET_HOME="$DOTNET_INSTALL_DIR/share/dotnet/cli" $DIR/dotnet-cli-build/bin/dotnet-cli-build "$@"
+ exit $?
+else
+ # We're on an older CLI. This is temporary while Ubuntu and CentOS VSO builds are stalled.
+ DOTNET_HOME="$DOTNET_INSTALL_DIR/share/dotnet/cli" $DIR/dotnet-cli-build/bin/Debug/dnxcore50/dotnet-cli-build "$@"
+ exit $?
+fi
diff --git a/scripts/test/argument-forwarding-tests.ps1 b/scripts/test/argument-forwarding-tests.ps1
deleted file mode 100644
index 8461f2ac8..000000000
--- a/scripts/test/argument-forwarding-tests.ps1
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-. "$PSScriptRoot\..\common\_common.ps1"
-
-$ArgTestRoot = "$RepoRoot\test\ArgumentForwardingTests"
-$ArgTestOutputRoot = "$RepoRoot\artifacts\tests\arg-forwarding"
-
-dotnet publish --framework "dnxcore50" --runtime "$Rid" --output "$ArgTestOutputRoot" --configuration "$Configuration" "$ArgTestRoot\Reflector"
-if (!$?) {
- Write-Host Command failed: dotnet publish --framework "dnxcore50" --runtime "$Rid" --output "$ArgTestOutputRoot" --configuration "$Configuration" "$ArgTestRoot\Reflector"
- Exit 1
-}
-
-dotnet publish --framework "dnxcore50" --runtime "$Rid" --output "$ArgTestOutputRoot" --configuration "$Configuration" "$ArgTestRoot\ArgumentForwardingTests"
-if (!$?) {
- Write-Host Command failed: dotnet publish --framework "dnxcore50" --runtime "$Rid" --output "$ArgTestOutputRoot" --configuration "$Configuration" "$ArgTestRoot\ArgumentForwardingTests"
- Exit 1
-}
-
-cp "$ArgTestRoot\Reflector\reflector_cmd.cmd" "$ArgTestOutputRoot"
-
-pushd "$ArgTestOutputRoot"
-
-& ".\corerun" "xunit.console.netcore.exe" "ArgumentForwardingTests.dll" -xml "$_-testResults.xml" -notrait category=failing
-$exitCode = $LastExitCode
-
-popd
-
-# No need to output here, we'll get test results
-if ($exitCode -ne 0) {
- Exit 1
-}
\ No newline at end of file
diff --git a/scripts/test/argument-forwarding-tests.sh b/scripts/test/argument-forwarding-tests.sh
deleted file mode 100755
index 069683a35..000000000
--- a/scripts/test/argument-forwarding-tests.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-
-ArgTestRoot="$REPOROOT/test/ArgumentForwardingTests"
-ArgTestOutputRoot="$REPOROOT/artifacts/tests/arg-forwarding"
-
-dotnet publish --framework "dnxcore50" --output "$ArgTestOutputRoot" --configuration "$CONFIGURATION" "$ArgTestRoot/Reflector"
-dotnet publish --framework "dnxcore50" --output "$ArgTestOutputRoot" --configuration "$CONFIGURATION" "$ArgTestRoot/ArgumentForwardingTests"
-
-
-
-pushd "$ArgTestOutputRoot"
- ./corerun "xunit.console.netcore.exe" "ArgumentForwardingTests.dll" -xml "ArgumentForwardingTests-testResults.xml" -notrait category=failing
-popd
diff --git a/scripts/test/build-tests.ps1 b/scripts/test/build-tests.ps1
deleted file mode 100644
index 140e75ab6..000000000
--- a/scripts/test/build-tests.ps1
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-. "$PSScriptRoot\..\common\_common.ps1"
-
-# Publish each test project
-loadTestProjectList | foreach {
- #we should use publish to an output path, we will once issue #1183 has been fixed and we can point dotnet test do a dll.
- #we need to add back tfm, rid and configuration, but dotnet test need to be made aware of those as well. Tracked at issue #1237.
- dotnet build "$RepoRoot\test\$($_.ProjectName)"
- if (!$?) {
- Write-Host Command failed: dotnet build "$RepoRoot\test\$($_.ProjectName)"
- exit 1
- }
-}
diff --git a/scripts/test/build-tests.sh b/scripts/test/build-tests.sh
deleted file mode 100755
index d12d6d4c9..000000000
--- a/scripts/test/build-tests.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-
-PROJECTS=$(loadTestProjectList)
-
-for project in $PROJECTS
-do
- #we should use publish to an output path, we will once issue #1183 has been fixed and we can point dotnet test do a dll.
- dotnet build "$REPOROOT/test/$project"
-done
-
diff --git a/scripts/test/check-prereqs.ps1 b/scripts/test/check-prereqs.ps1
deleted file mode 100644
index 21a65b988..000000000
--- a/scripts/test/check-prereqs.ps1
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-if (!(Get-Command -ErrorAction SilentlyContinue cmake)) {
- throw @"
-cmake is required to build the native host 'corehost'
-Download it from https://www.cmake.org
-"@
-}
\ No newline at end of file
diff --git a/scripts/test/check-prereqs.sh b/scripts/test/check-prereqs.sh
deleted file mode 100755
index 8640ffb03..000000000
--- a/scripts/test/check-prereqs.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-
-if ! type -p cmake >/dev/null; then
- error "cmake is required to build the native host 'corehost'"
- error "OS X w/Homebrew: 'brew install cmake'"
- error "Ubuntu: 'sudo apt-get install cmake'"
- exit 1
-fi
diff --git a/scripts/test/package-command-test.ps1 b/scripts/test/package-command-test.ps1
deleted file mode 100644
index 476a171c9..000000000
--- a/scripts/test/package-command-test.ps1
+++ /dev/null
@@ -1,34 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-. "$PSScriptRoot\..\common\_common.ps1"
-
-#compile apps
-dir "$RepoRoot\test\PackagedCommands\Consumers" | where {$_.PsIsContainer} | where {$_.Name.Contains("Direct")} |
-foreach {
- pushd "$RepoRoot\test\PackagedCommands\Consumers\$_"
- dotnet build
- popd
-}
-
-#run test
-dir "$RepoRoot\test\PackagedCommands\Consumers" | where {$_.PsIsContainer} | where {$_.Name.Contains("AppWith")} |
-foreach {
- $testName = "test\PackagedCommands\Consumers\$_"
- pushd "$RepoRoot\$testName"
- $outputArray = dotnet hello | Out-String
- $output = [string]::Join('\n', $outputArray).Trim("`r", "`n")
-
- if ($output -ne "hello") {
- error "Test Failed: $testName\dotnet hello"
- error " printed $output"
- Exit 1
- }
-
- info "Test passed: $testName"
- popd
-}
-
-Exit 0
diff --git a/scripts/test/package-command-test.sh b/scripts/test/package-command-test.sh
deleted file mode 100755
index 6baf6eb59..000000000
--- a/scripts/test/package-command-test.sh
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-
-#compile tests with direct dependencies
-for test in $(ls -l "$REPOROOT/test/PackagedCommands/Consumers" | grep ^d | awk '{print $9}' | grep "Direct")
-do
- pushd "$REPOROOT/test/PackagedCommands/Consumers/$test"
- dotnet build
- popd
-done
-
-#run test
-for test in $(ls -l "$REPOROOT/test/PackagedCommands/Consumers" | grep ^d | awk '{print $9}' | grep "AppWith")
-do
- testName="test/PackagedCommands/Consumers/$test"
-
- pushd "$REPOROOT/$testName"
-
- output=$(dotnet hello)
-
-
- if [ "$output" == "Hello" ] ;
- then
- echo "Test Passed: $testName"
- else
- error "Test Failed: $testName/dotnet hello"
- error " printed $output"
- exit 1
- fi
-
- popd
-done
diff --git a/scripts/test/restore-tests.ps1 b/scripts/test/restore-tests.ps1
deleted file mode 100644
index 48d1dd5e7..000000000
--- a/scripts/test/restore-tests.ps1
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-. $PSScriptRoot\..\common\_common.ps1
-
-info "Restoring Test Projects"
-
-# Restore packages
-& dotnet restore "$RepoRoot\test" -f "$TestPackageDir"
diff --git a/scripts/test/run-tests.ps1 b/scripts/test/run-tests.ps1
deleted file mode 100644
index 31dcc70cb..000000000
--- a/scripts/test/run-tests.ps1
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-. "$PSScriptRoot\..\common\_common.ps1"
-
-$TestBinRoot = "$RepoRoot\artifacts\tests"
-
-$TestProjects = loadTestProjectList
-$TestScripts = loadTestScriptList
-
-$failCount = 0
-$failingTests = @()
-
-## Temporary Workaround for Native Compilation
-## Need x64 Native Tools Dev Prompt Env Vars
-## Tracked Here: https://github.com/dotnet/cli/issues/301
-pushd "$env:VS140COMNTOOLS\..\..\VC"
-cmd /c "vcvarsall.bat x64&set" |
-foreach {
- if ($_ -match "=") {
- $v = $_.split("=", 2); set-item -force -literalpath "ENV:\$($v[0])" -value "$($v[1])"
- }
-}
-popd
-
-# copy TestProjects to $TestBinRoot
-mkdir -Force "$TestBinRoot\TestProjects"
-cp -rec -Force "$RepoRoot\TestAssets\TestProjects\*" "$TestBinRoot\TestProjects"
-
-# Run each test project
-$TestProjects | foreach {
- # This is a workaroudn for issue #1184, where dotnet test needs to be executed from the folder containing the project.json.
- pushd "$RepoRoot\test\$($_.ProjectName)"
- dotnet test -xml "$TestBinRoot\$($_.ProjectName)-testResults.xml" -notrait category=failing
- popd
-
- $exitCode = $LastExitCode
- if ($exitCode -ne 0) {
- $failingTests += "$($_.ProjectName)"
- }
-
- $failCount += $exitCode
-}
-
-$TestScripts | foreach {
- $scriptName = "$($_.ProjectName).ps1"
-
- & "$RepoRoot\scripts\test\$scriptName"
- $exitCode = $LastExitCode
- if ($exitCode -ne 0) {
- $failingTests += "$scriptName"
- $failCount += 1
- }
-}
-
-if ($failCount -ne 0) {
- Write-Host -ForegroundColor Red "The following tests failed."
- $failingTests | foreach {
- Write-Host -ForegroundColor Red "$_.dll failed. Logs in '$TestBinRoot\$_-testResults.xml'"
- }
-} else {
- Write-Host -ForegroundColor Green "All the tests passed!"
-}
-
-Exit $failCount
diff --git a/scripts/test/run-tests.sh b/scripts/test/run-tests.sh
deleted file mode 100755
index fdf089426..000000000
--- a/scripts/test/run-tests.sh
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-
-TestProjects=$(loadTestProjectList)
-TestScripts=$(loadTestScriptList)
-
-failedTests=()
-failCount=0
-
-# Copy TestProjects to $TEST_BIN_ROOT
-mkdir -p "$TEST_BIN_ROOT/TestProjects"
-cp -a $REPOROOT/TestAssets/TestProjects/* $TEST_BIN_ROOT/TestProjects
-
-pushd "$TEST_BIN_ROOT"
-set +e
-
-for project in $TestProjects
-do
- # This is a workaroudn for issue #1184, where dotnet test needs to be executed from the folder containing the project.json.
- pushd "$REPOROOT/test/$project"
- dotnet test -xml "$TEST_BIN_ROOT/${project}-testResults.xml" -notrait category=failing
- popd
-
- exitCode=$?
- failCount+=$exitCode
- if [ $exitCode -ne 0 ]; then
- failedTests+=("${project}.dll")
- fi
-done
-
-popd
-
-for script in $TestScripts
-do
- scriptName=${script}.sh
-
- "$REPOROOT/scripts/test/${scriptName}"
- exitCode=$?
- if [ $exitCode -ne 0 ]; then
- failedTests+=("$scriptName")
- failCount+=1
- fi
-done
-
-for test in ${failedTests[@]}
-do
- error "$test failed. Logs in '$TEST_BIN_ROOT/${test}-testResults.xml'"
-done
-
-set -e
-
-exit $failCount
diff --git a/scripts/test/setup/build-test-prerequisites.sh b/scripts/test/setup/build-test-prerequisites.sh
deleted file mode 100755
index 7ce6c6c1f..000000000
--- a/scripts/test/setup/build-test-prerequisites.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../../common/_common.sh"
-
-buildTestPackages() {
- mkdir -p "$TEST_PACKAGE_DIR"
-
- PROJECTS=$(loadTestPackageList)
-
- for project in $PROJECTS
- do
- dotnet pack "$REPOROOT/TestAssets/TestPackages/$project" --output "$TEST_PACKAGE_DIR"
- done
-}
-
-buildTestProjects() {
- testProjectsRoot="$REPOROOT/TestAssets/TestProjects"
- exclusionList=( "$testProjectsRoot/CompileFail/project.json" )
- testProjectsList=( $(find $testProjectsRoot -name "project.json") )
-
- for project in "${testProjectsList[@]}"
- do
- if [[ "${exclusionList[@]}" != "${project}" ]]; then
- dotnet build "$project" --framework dnxcore50
- fi
- done
-}
-
-buildTestPackages
-buildTestProjects
diff --git a/scripts/test/setup/restore-test-prerequisites.ps1 b/scripts/test/setup/restore-test-prerequisites.ps1
deleted file mode 100644
index 6bfb8242f..000000000
--- a/scripts/test/setup/restore-test-prerequisites.ps1
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-". $PSScriptRoot\..\..\common\_common.ps1"
-
-header "Restoring TestAssets"
-& dotnet restore "$RepoRoot\TestAssets" --quiet --runtime "$Rid"
-
-$oldErrorAction=$ErrorActionPreference
-$ErrorActionPreference="SilentlyContinue"
-& dotnet restore "$RepoRoot\testapp" "$Rid" 2>&1 | Out-Null
-$ErrorActionPreference=$oldErrorAction
diff --git a/scripts/test/setup/setup-tests.ps1 b/scripts/test/setup/setup-tests.ps1
deleted file mode 100644
index 816c3950c..000000000
--- a/scripts/test/setup/setup-tests.ps1
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-. "$PSScriptRoot\..\..\common\_common.ps1"
-
-header "Test Setup: Restoring Prerequisites"
-_ "$RepoRoot\scripts\test\setup\restore-test-prerequisites.ps1"
-
-header "Test Setup: Building Prerequisites"
-_ "$RepoRoot\scripts\test\setup\build-test-prerequisites.ps1"
\ No newline at end of file
diff --git a/scripts/test/setup/setup-tests.sh b/scripts/test/setup/setup-tests.sh
deleted file mode 100755
index d8ad16d6d..000000000
--- a/scripts/test/setup/setup-tests.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../../common/_common.sh"
-
-header "Test Setup: Restoring Prerequisites"
-"$REPOROOT/scripts/test/setup/restore-test-prerequisites.sh"
-
-header "Test Setup: Building Prerequisites"
-"$REPOROOT/scripts/test/setup/build-test-prerequisites.sh"
\ No newline at end of file
diff --git a/scripts/test/test.ps1 b/scripts/test/test.ps1
deleted file mode 100644
index d586fb74e..000000000
--- a/scripts/test/test.ps1
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-. "$PSScriptRoot\..\common\_common.ps1"
-
-header "Setting up Tests"
-_ "$RepoRoot\scripts\test\setup\setup-tests.ps1"
-
-header "Restoring test projects"
-_ "$RepoRoot\scripts\test\restore-tests.ps1"
-
-header "Building test projects"
-_ "$RepoRoot\scripts\test\build-tests.ps1"
-
-header "Running Tests"
-_ "$RepoRoot\scripts\test\run-tests.ps1"
\ No newline at end of file
diff --git a/scripts/test/test.sh b/scripts/test/test.sh
deleted file mode 100755
index f05fe115a..000000000
--- a/scripts/test/test.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-source "$DIR/../common/_common.sh"
-
-header "Setting up Tests"
-"$REPOROOT/scripts/test/setup/setup-tests.sh"
-
-header "Restoring test projects"
-"$REPOROOT/scripts/test/restore-tests.sh"
-
-header "Building test projects"
-"$REPOROOT/scripts/test/build-tests.sh"
-
-header "Running Tests"
-"$REPOROOT/scripts/test/run-tests.sh"
\ No newline at end of file
diff --git a/scripts/test/validate-dependencies.ps1 b/scripts/test/validate-dependencies.ps1
deleted file mode 100644
index e47e55c1a..000000000
--- a/scripts/test/validate-dependencies.ps1
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-. "$PSScriptRoot\..\common\_common.ps1"
-
-# Run Validation for Project.json dependencies
-dotnet publish $RepoRoot\tools\MultiProjectValidator -o $Stage2Dir\..\tools -c "$Configuration"
-
-$pjvalidatePath = "$Stage2Dir\..\tools\$Configuration\$Tfm"
-if (! (Test-Path $pjvalidatePath)) {
- $pjvalidatePath = "$Stage2Dir\..\tools"
-}
-
-& "$pjvalidatePath\pjvalidate" "$RepoRoot\src"
-# TODO For release builds, this should be uncommented and fail.
-# if (!$?) {
-# Write-Host "Project Validation Failed"
-# Exit 1
-# }
\ No newline at end of file
diff --git a/scripts/test/validate-dependencies.sh b/scripts/test/validate-dependencies.sh
deleted file mode 100755
index a9e476097..000000000
--- a/scripts/test/validate-dependencies.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
-
-set -e
-
-SOURCE="${BASH_SOURCE[0]}"
-while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
- DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
- SOURCE="$(readlink "$SOURCE")"
- [[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
-done
-DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-
-. "$DIR/../common/_common.sh"
-
-# Run Validation for Project.json dependencies
-dotnet publish "$REPOROOT/tools/MultiProjectValidator" -o "$STAGE2_DIR/../tools" -c "$CONFIGURATION"
-#TODO for release builds this should fail
-set +e
-PJ_VALIDATE_PATH="$STAGE2_DIR/../tools/$CONFIGURATION/$TFM"
-if [ ! -d "$PJ_VALIDATE_PATH" ]
-then
- PJ_VALIDATE_PATH="$STAGE2_DIR/../tools"
-fi
-
-"$PJ_VALIDATE_PATH/pjvalidate" "$REPOROOT/src"
-set -e
diff --git a/src/Microsoft.DotNet.Cli.Utils/ArgumentEscaper.cs b/src/Microsoft.DotNet.Cli.Utils/ArgumentEscaper.cs
index 30835d159..4a5d0f4fe 100644
--- a/src/Microsoft.DotNet.Cli.Utils/ArgumentEscaper.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/ArgumentEscaper.cs
@@ -86,8 +86,10 @@ namespace Microsoft.DotNet.Cli.Utils
{
var sb = new StringBuilder();
- var quoted = ShouldSurroundWithQuotes(arg);
- if (quoted) sb.Append("\"");
+ var needsQuotes = ShouldSurroundWithQuotes(arg);
+ var isQuoted = needsQuotes || IsSurroundedWithQuotes(arg);
+
+ if (needsQuotes) sb.Append("\"");
for (int i = 0; i < arg.Length; ++i)
{
@@ -101,13 +103,21 @@ namespace Microsoft.DotNet.Cli.Utils
}
// Escape any backslashes at the end of the arg
+ // when the argument is also quoted.
// This ensures the outside quote is interpreted as
// an argument delimiter
- if (i == arg.Length)
+ if (i == arg.Length && isQuoted)
{
sb.Append('\\', 2 * backslashCount);
}
+ // At then end of the arg, which isn't quoted,
+ // just add the backslashes, no need to escape
+ else if (i == arg.Length)
+ {
+ sb.Append('\\', backslashCount);
+ }
+
// Escape any preceding backslashes and the quote
else if (arg[i] == '"')
{
@@ -123,7 +133,7 @@ namespace Microsoft.DotNet.Cli.Utils
}
}
- if (quoted) sb.Append("\"");
+ if (needsQuotes) sb.Append("\"");
return sb.ToString();
}
@@ -149,22 +159,14 @@ namespace Microsoft.DotNet.Cli.Utils
if (quoted) sb.Append("^\"");
+ // Prepend every character with ^
+ // This is harmless when passing through cmd
+ // and ensures cmd metacharacters are not interpreted
+ // as such
foreach (var character in argument)
{
-
- if (character == '"')
- {
-
- sb.Append('^');
- sb.Append('"');
- sb.Append('^');
- sb.Append(character);
- }
- else
- {
- sb.Append("^");
- sb.Append(character);
- }
+ sb.Append("^");
+ sb.Append(character);
}
if (quoted) sb.Append("^\"");
@@ -172,35 +174,27 @@ namespace Microsoft.DotNet.Cli.Utils
return sb.ToString();
}
- ///
- /// Prepare as single argument to
- /// roundtrip properly through cmd.
- ///
- /// This prefixes every character with the '^' character to force cmd to
- /// interpret the argument string literally. An alternative option would
- /// be to do this only for cmd metacharacters.
- ///
- /// See here for more info:
- /// http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
- ///
- ///
- ///
internal static bool ShouldSurroundWithQuotes(string argument)
{
// Don't quote already quoted strings
- if (argument.StartsWith("\"", StringComparison.Ordinal) &&
- argument.EndsWith("\"", StringComparison.Ordinal))
+ if (IsSurroundedWithQuotes(argument))
{
return false;
}
// Only quote if whitespace exists in the string
- if (argument.Contains(" ") || argument.Contains("\t") || argument.Contains("\n"))
- {
- return true;
- }
+ return ArgumentContainsWhitespace(argument);
+ }
- return true;
+ internal static bool IsSurroundedWithQuotes(string argument)
+ {
+ return argument.StartsWith("\"", StringComparison.Ordinal) &&
+ argument.EndsWith("\"", StringComparison.Ordinal);
+ }
+
+ internal static bool ArgumentContainsWhitespace(string argument)
+ {
+ return argument.Contains(" ") || argument.Contains("\t") || argument.Contains("\n");
}
}
}
diff --git a/src/Microsoft.DotNet.Cli.Utils/Command.cs b/src/Microsoft.DotNet.Cli.Utils/Command.cs
index 6118deaa1..1480c2c7f 100644
--- a/src/Microsoft.DotNet.Cli.Utils/Command.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/Command.cs
@@ -8,10 +8,11 @@ using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using NuGet.Frameworks;
+using Microsoft.DotNet.ProjectModel;
namespace Microsoft.DotNet.Cli.Utils
{
- public class Command
+ public class Command : ICommand
{
private readonly Process _process;
private readonly StreamForwarder _stdOut;
@@ -31,7 +32,7 @@ namespace Microsoft.DotNet.Cli.Utils
_stdOut = new StreamForwarder();
_stdErr = new StreamForwarder();
-
+
_process = new Process
{
StartInfo = psi
@@ -40,9 +41,9 @@ namespace Microsoft.DotNet.Cli.Utils
ResolutionStrategy = commandSpec.ResolutionStrategy;
}
- public static Command CreateDotNet(string commandName, IEnumerable args, NuGetFramework framework = null, bool useComSpec = false)
+ public static Command CreateDotNet(string commandName, IEnumerable args, NuGetFramework framework = null)
{
- return Create("dotnet", new[] { commandName }.Concat(args), framework, useComSpec);
+ return Create("dotnet", new[] { commandName }.Concat(args), framework);
}
///
@@ -55,9 +56,9 @@ namespace Microsoft.DotNet.Cli.Utils
///
///
///
- public static Command Create(string commandName, IEnumerable args, NuGetFramework framework = null, bool useComSpec = false)
+ public static Command Create(string commandName, IEnumerable args, NuGetFramework framework = null)
{
- var commandSpec = CommandResolver.TryResolveCommandSpec(commandName, args, framework, useComSpec);
+ var commandSpec = CommandResolver.TryResolveCommandSpec(commandName, args, framework);
if (commandSpec == null)
{
@@ -69,6 +70,20 @@ namespace Microsoft.DotNet.Cli.Utils
return command;
}
+ public static Command CreateForScript(string commandName, IEnumerable args, Project project, string[] inferredExtensionList)
+ {
+ var commandSpec = CommandResolver.TryResolveScriptCommandSpec(commandName, args, project, inferredExtensionList);
+
+ if (commandSpec == null)
+ {
+ throw new CommandUnknownException(commandName);
+ }
+
+ var command = new Command(commandSpec);
+
+ return command;
+ }
+
public CommandResult Execute()
{
@@ -115,33 +130,37 @@ namespace Microsoft.DotNet.Cli.Utils
_stdErr.CapturedOutput);
}
- public Command WorkingDirectory(string projectDirectory)
+ public ICommand WorkingDirectory(string projectDirectory)
{
_process.StartInfo.WorkingDirectory = projectDirectory;
return this;
}
- public Command EnvironmentVariable(string name, string value)
+ public ICommand EnvironmentVariable(string name, string value)
{
+#if NET451
+ _process.StartInfo.EnvironmentVariables[name] = value;
+#else
_process.StartInfo.Environment[name] = value;
+#endif
return this;
}
- public Command CaptureStdOut()
+ public ICommand CaptureStdOut()
{
ThrowIfRunning();
_stdOut.Capture();
return this;
}
- public Command CaptureStdErr()
+ public ICommand CaptureStdErr()
{
ThrowIfRunning();
_stdErr.Capture();
return this;
}
- public Command ForwardStdOut(TextWriter to = null, bool onlyIfVerbose = false)
+ public ICommand ForwardStdOut(TextWriter to = null, bool onlyIfVerbose = false)
{
ThrowIfRunning();
if (!onlyIfVerbose || CommandContext.IsVerbose())
@@ -158,7 +177,7 @@ namespace Microsoft.DotNet.Cli.Utils
return this;
}
- public Command ForwardStdErr(TextWriter to = null, bool onlyIfVerbose = false)
+ public ICommand ForwardStdErr(TextWriter to = null, bool onlyIfVerbose = false)
{
ThrowIfRunning();
if (!onlyIfVerbose || CommandContext.IsVerbose())
@@ -175,14 +194,14 @@ namespace Microsoft.DotNet.Cli.Utils
return this;
}
- public Command OnOutputLine(Action handler)
+ public ICommand OnOutputLine(Action handler)
{
ThrowIfRunning();
_stdOut.ForwardTo(writeLine: handler);
return this;
}
- public Command OnErrorLine(Action handler)
+ public ICommand OnErrorLine(Action handler)
{
ThrowIfRunning();
_stdErr.ForwardTo(writeLine: handler);
@@ -193,6 +212,8 @@ namespace Microsoft.DotNet.Cli.Utils
public string CommandName => _process.StartInfo.FileName;
+ public string CommandArgs => _process.StartInfo.Arguments;
+
private string FormatProcessInfo(ProcessStartInfo info)
{
if (string.IsNullOrWhiteSpace(info.Arguments))
diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolutionStrategy.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolutionStrategy.cs
index aecec2211..83589d989 100644
--- a/src/Microsoft.DotNet.Cli.Utils/CommandResolutionStrategy.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolutionStrategy.cs
@@ -8,6 +8,9 @@
//command loaded from the same directory as the executing assembly
BaseDirectory,
+ //command loaded from the same directory as a project.json file
+ ProjectLocal,
+
//command loaded from path
Path,
diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolver.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolver.cs
index d4b3ec243..f62486969 100644
--- a/src/Microsoft.DotNet.Cli.Utils/CommandResolver.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolver.cs
@@ -1,64 +1,72 @@
using System;
using System.Collections.Generic;
using System.IO;
-using NuGet.Frameworks;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.DotNet.ProjectModel;
using Microsoft.DotNet.ProjectModel.Graph;
using Microsoft.Extensions.PlatformAbstractions;
+using NuGet.Frameworks;
using NuGet.Packaging;
namespace Microsoft.DotNet.Cli.Utils
{
internal static class CommandResolver
{
- public static CommandSpec TryResolveCommandSpec(string commandName, IEnumerable args, NuGetFramework framework = null, bool useComSpec = false)
+ public static CommandSpec TryResolveCommandSpec(string commandName, IEnumerable args, NuGetFramework framework = null)
{
- return ResolveFromRootedCommand(commandName, args, useComSpec) ??
- ResolveFromProjectDependencies(commandName, args, framework, useComSpec) ??
- ResolveFromProjectTools(commandName, args, useComSpec) ??
- ResolveFromAppBase(commandName, args, useComSpec) ??
- ResolveFromPath(commandName, args, useComSpec);
+ return ResolveFromRootedCommand(commandName, args) ??
+ ResolveFromProjectDependencies(commandName, args, framework) ??
+ ResolveFromProjectTools(commandName, args) ??
+ ResolveFromAppBase(commandName, args) ??
+ ResolveFromPath(commandName, args);
+ }
+
+ public static CommandSpec TryResolveScriptCommandSpec(string commandName, IEnumerable args, Project project, string[] inferredExtensionList)
+ {
+ return ResolveFromRootedCommand(commandName, args) ??
+ ResolveFromProjectPath(commandName, args, project, inferredExtensionList) ??
+ ResolveFromAppBase(commandName, args) ??
+ ResolveFromPath(commandName, args);
}
- private static CommandSpec ResolveFromPath(string commandName, IEnumerable args, bool useComSpec = false)
+ private static CommandSpec ResolveFromPath(string commandName, IEnumerable args)
{
var commandPath = Env.GetCommandPath(commandName);
return commandPath == null
? null
- : CreateCommandSpecPreferringExe(commandName, args, commandPath, CommandResolutionStrategy.Path, useComSpec);
+ : CreateCommandSpecPreferringExe(commandName, args, commandPath, CommandResolutionStrategy.Path);
}
- private static CommandSpec ResolveFromAppBase(string commandName, IEnumerable args, bool useComSpec = false)
+ private static CommandSpec ResolveFromAppBase(string commandName, IEnumerable args)
{
- var commandPath = Env.GetCommandPathFromAppBase(AppContext.BaseDirectory, commandName);
+ var commandPath = Env.GetCommandPathFromRootPath(PlatformServices.Default.Application.ApplicationBasePath, commandName);
return commandPath == null
? null
- : CreateCommandSpecPreferringExe(commandName, args, commandPath, CommandResolutionStrategy.BaseDirectory, useComSpec);
+ : CreateCommandSpecPreferringExe(commandName, args, commandPath, CommandResolutionStrategy.BaseDirectory);
+ }
+
+ private static CommandSpec ResolveFromProjectPath(string commandName, IEnumerable args, Project project, string[] inferredExtensionList)
+ {
+ var commandPath = Env.GetCommandPathFromRootPath(project.ProjectDirectory, commandName, inferredExtensionList);
+ return commandPath == null
+ ? null
+ : CreateCommandSpecPreferringExe(commandName, args, commandPath, CommandResolutionStrategy.ProjectLocal);
}
- private static CommandSpec ResolveFromRootedCommand(string commandName, IEnumerable args, bool useComSpec = false)
+ private static CommandSpec ResolveFromRootedCommand(string commandName, IEnumerable args)
{
if (Path.IsPathRooted(commandName))
{
- if (useComSpec)
- {
- return CreateComSpecCommandSpec(commandName, args, CommandResolutionStrategy.Path);
- }
- else
- {
- var escapedArgs = ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(args);
- return new CommandSpec(commandName, escapedArgs, CommandResolutionStrategy.Path);
- }
-
+ var escapedArgs = ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(args);
+ return new CommandSpec(commandName, escapedArgs, CommandResolutionStrategy.Path);
}
return null;
}
public static CommandSpec ResolveFromProjectDependencies(string commandName, IEnumerable args,
- NuGetFramework framework, bool useComSpec = false)
+ NuGetFramework framework)
{
if (framework == null) return null;
@@ -72,7 +80,7 @@ namespace Microsoft.DotNet.Cli.Utils
var depsPath = projectContext.GetOutputPaths(Constants.DefaultConfiguration).RuntimeFiles.Deps;
- return ConfigureCommandFromPackage(commandName, args, commandPackage, projectContext, depsPath, useComSpec);
+ return ConfigureCommandFromPackage(commandName, args, commandPackage, projectContext, depsPath);
}
private static ProjectContext GetProjectContext(NuGetFramework framework)
@@ -101,7 +109,7 @@ namespace Microsoft.DotNet.Cli.Utils
e == FileNameSuffixes.DotNet.DynamicLib));
}
- public static CommandSpec ResolveFromProjectTools(string commandName, IEnumerable args, bool useComSpec = false)
+ public static CommandSpec ResolveFromProjectTools(string commandName, IEnumerable args)
{
var context = GetProjectContext(FrameworkConstants.CommonFrameworks.DnxCore50);
@@ -147,7 +155,7 @@ namespace Microsoft.DotNet.Cli.Utils
}
private static CommandSpec ConfigureCommandFromPackage(string commandName, IEnumerable args,
- PackageDescription commandPackage, ProjectContext projectContext, string depsPath = null, bool useComSpec = false)
+ PackageDescription commandPackage, ProjectContext projectContext, string depsPath = null)
{
var files = commandPackage.Library.Files;
@@ -157,11 +165,11 @@ namespace Microsoft.DotNet.Cli.Utils
var packageDir = Path.Combine(packageRoot, packagePath);
- return ConfigureCommandFromPackage(commandName, args, files, packageDir, depsPath, useComSpec);
+ return ConfigureCommandFromPackage(commandName, args, files, packageDir, depsPath);
}
private static CommandSpec ConfigureCommandFromPackage(string commandName, IEnumerable args,
- IEnumerable files, string packageDir, string depsPath = null, bool useComSpec = false)
+ IEnumerable files, string packageDir, string depsPath = null)
{
var fileName = string.Empty;
@@ -192,25 +200,19 @@ namespace Microsoft.DotNet.Cli.Utils
fileName = Path.Combine(packageDir, commandPath);
}
- if (useComSpec)
- {
- return CreateComSpecCommandSpec(fileName, args, CommandResolutionStrategy.NugetPackage);
- }
- else
- {
- var escapedArgs = ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(args);
- return new CommandSpec(fileName, escapedArgs, CommandResolutionStrategy.NugetPackage);
- }
+ var escapedArgs = ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(args);
+ return new CommandSpec(fileName, escapedArgs, CommandResolutionStrategy.NugetPackage);
}
private static CommandSpec CreateCommandSpecPreferringExe(
string commandName,
IEnumerable args,
string commandPath,
- CommandResolutionStrategy resolutionStrategy,
- bool useComSpec = false)
+ CommandResolutionStrategy resolutionStrategy)
{
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
+ var useComSpec = false;
+
+ if (PlatformServices.Default.Runtime.OperatingSystemPlatform == Platform.Windows &&
Path.GetExtension(commandPath).Equals(".cmd", StringComparison.OrdinalIgnoreCase))
{
var preferredCommandPath = Env.GetCommandPath(commandName, ".exe");
@@ -228,7 +230,7 @@ namespace Microsoft.DotNet.Cli.Utils
if (useComSpec)
{
- return CreateComSpecCommandSpec(commandPath, args, resolutionStrategy);
+ return CreateCmdCommandSpec(commandPath, args, resolutionStrategy);
}
else
{
@@ -237,14 +239,14 @@ namespace Microsoft.DotNet.Cli.Utils
}
}
- private static CommandSpec CreateComSpecCommandSpec(
+ private static CommandSpec CreateCmdCommandSpec(
string command,
IEnumerable args,
CommandResolutionStrategy resolutionStrategy)
{
- // To prevent Command Not Found, comspec gets passed in as
- // the command already in some cases
var comSpec = Environment.GetEnvironmentVariable("ComSpec");
+
+ // Handle the case where ComSpec is already the command
if (command.Equals(comSpec, StringComparison.OrdinalIgnoreCase))
{
command = args.FirstOrDefault();
diff --git a/src/Microsoft.DotNet.Cli.Utils/Constants.cs b/src/Microsoft.DotNet.Cli.Utils/Constants.cs
index 943fdb7c4..2a58ba8b6 100644
--- a/src/Microsoft.DotNet.Cli.Utils/Constants.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/Constants.cs
@@ -1,17 +1,19 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-using System.Runtime.InteropServices;
+using Microsoft.Extensions.PlatformAbstractions;
namespace Microsoft.DotNet.Cli.Utils
{
public static class Constants
{
+ private static Platform CurrentPlatform => PlatformServices.Default.Runtime.OperatingSystemPlatform;
+
public static readonly string ProjectFileName = "project.json";
- public static readonly string ExeSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : string.Empty;
+ public static readonly string ExeSuffix = CurrentPlatform == Platform.Windows ? ".exe" : string.Empty;
// Priority order of runnable suffixes to look for and run
- public static readonly string[] RunnableSuffixes = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
+ public static readonly string[] RunnableSuffixes = CurrentPlatform == Platform.Windows
? new string[] { ".exe", ".cmd", ".bat" }
: new string[] { string.Empty };
@@ -19,22 +21,23 @@ namespace Microsoft.DotNet.Cli.Utils
public static readonly string BinDirectoryName = "bin";
public static readonly string ObjDirectoryName = "obj";
- public static readonly string DynamicLibSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".dll" :
- RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? ".dylib" : ".so";
+ public static readonly string DynamicLibSuffix = CurrentPlatform == Platform.Windows ? ".dll" :
+ CurrentPlatform == Platform.Darwin ? ".dylib" : ".so";
- public static readonly string LibCoreClrName = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "coreclr" : "libcoreclr") + DynamicLibSuffix;
+ public static readonly string LibCoreClrName = (CurrentPlatform == Platform.Windows ? "coreclr" : "libcoreclr") + DynamicLibSuffix;
- public static readonly string RuntimeIdentifier = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "win7-x64" :
- RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "osx.10.10-x64" : "ubuntu.14.04-x64";
+ public static readonly string RuntimeIdentifier = CurrentPlatform == Platform.Windows ? "win7-x64" :
+ CurrentPlatform == Platform.Darwin ? "osx.10.10-x64" : "ubuntu.14.04-x64";
- public static readonly string StaticLibSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".lib" : ".a" ;
+ public static readonly string StaticLibSuffix = CurrentPlatform == Platform.Windows ? ".lib" : ".a";
public static readonly string ResponseFileSuffix = ".rsp";
public static readonly string HostExecutableName = "corehost" + ExeSuffix;
public static readonly string[] HostBinaryNames = new string[] {
HostExecutableName,
- (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "hostpolicy" : "libhostpolicy") + DynamicLibSuffix
+ (CurrentPlatform == Platform.Windows ? "hostpolicy" : "libhostpolicy") + DynamicLibSuffix
};
+
}
}
diff --git a/src/Microsoft.DotNet.Cli.Utils/CoreHost.cs b/src/Microsoft.DotNet.Cli.Utils/CoreHost.cs
index 0ab2d2c6f..7775800ec 100644
--- a/src/Microsoft.DotNet.Cli.Utils/CoreHost.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/CoreHost.cs
@@ -1,6 +1,5 @@
-using System;
using System.IO;
-using Microsoft.DotNet.ProjectModel;
+using Microsoft.Extensions.PlatformAbstractions;
namespace Microsoft.DotNet.Cli.Utils
{
@@ -12,7 +11,7 @@ namespace Microsoft.DotNet.Cli.Utils
///
/// Gets the path to the version of corehost that was shipped with this command
///
- public static string LocalHostExePath => Path.Combine(AppContext.BaseDirectory, Constants.HostExecutableName);
+ public static string LocalHostExePath => Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, Constants.HostExecutableName);
public static string HostExePath
{
@@ -33,7 +32,7 @@ namespace Microsoft.DotNet.Cli.Utils
if (_hostDir == null)
{
_hostDir = Path.GetDirectoryName(Env.GetCommandPath(
- Constants.HostExecutableName, new[] {string.Empty}));
+ Constants.HostExecutableName, new[] { string.Empty }));
}
return _hostDir;
diff --git a/src/Microsoft.DotNet.Cli.Utils/DotNetCommandFactory.cs b/src/Microsoft.DotNet.Cli.Utils/DotNetCommandFactory.cs
new file mode 100644
index 000000000..4f8f01935
--- /dev/null
+++ b/src/Microsoft.DotNet.Cli.Utils/DotNetCommandFactory.cs
@@ -0,0 +1,16 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Collections.Generic;
+using NuGet.Frameworks;
+
+namespace Microsoft.DotNet.Cli.Utils
+{
+ public class DotNetCommandFactory : ICommandFactory
+ {
+ public ICommand Create(string commandName, IEnumerable args, NuGetFramework framework = null)
+ {
+ return Command.CreateDotNet(commandName, args, framework);
+ }
+ }
+}
diff --git a/src/Microsoft.DotNet.Cli.Utils/Env.cs b/src/Microsoft.DotNet.Cli.Utils/Env.cs
index fcd47711c..6fdac60f1 100644
--- a/src/Microsoft.DotNet.Cli.Utils/Env.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/Env.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
+using Microsoft.Extensions.PlatformAbstractions;
namespace Microsoft.DotNet.Cli.Utils
{
@@ -18,7 +19,7 @@ namespace Microsoft.DotNet.Cli.Utils
if (_executableExtensions == null)
{
- _executableExtensions = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
+ _executableExtensions = PlatformServices.Default.Runtime.OperatingSystemPlatform == Platform.Windows
? Environment.GetEnvironmentVariable("PATHEXT")
.Split(';')
.Select(e => e.ToLower().Trim('"'))
@@ -35,7 +36,7 @@ namespace Microsoft.DotNet.Cli.Utils
{
if (_searchPaths == null)
{
- var searchPaths = new List {AppContext.BaseDirectory};
+ var searchPaths = new List { PlatformServices.Default.Application.ApplicationBasePath };
searchPaths.AddRange(Environment
.GetEnvironmentVariable("PATH")
@@ -65,14 +66,14 @@ namespace Microsoft.DotNet.Cli.Utils
return commandPath;
}
- public static string GetCommandPathFromAppBase(string appBase, string commandName, params string[] extensions)
+ public static string GetCommandPathFromRootPath(string rootPath, string commandName, params string[] extensions)
{
if (!extensions.Any())
{
extensions = Env.ExecutableExtensions.ToArray();
}
- var commandPath = extensions.Select(e => Path.Combine(appBase, commandName + e))
+ var commandPath = extensions.Select(e => Path.Combine(rootPath, commandName + e))
.FirstOrDefault(File.Exists);
return commandPath;
diff --git a/src/Microsoft.DotNet.Cli.Utils/ICommand.cs b/src/Microsoft.DotNet.Cli.Utils/ICommand.cs
new file mode 100644
index 000000000..1b7cde7b6
--- /dev/null
+++ b/src/Microsoft.DotNet.Cli.Utils/ICommand.cs
@@ -0,0 +1,35 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.IO;
+
+namespace Microsoft.DotNet.Cli.Utils
+{
+ public interface ICommand
+ {
+ CommandResult Execute();
+
+ ICommand WorkingDirectory(string projectDirectory);
+
+ ICommand EnvironmentVariable(string name, string value);
+
+ ICommand CaptureStdOut();
+
+ ICommand CaptureStdErr();
+
+ ICommand ForwardStdOut(TextWriter to = null, bool onlyIfVerbose = false);
+
+ ICommand ForwardStdErr(TextWriter to = null, bool onlyIfVerbose = false);
+
+ ICommand OnOutputLine(Action handler);
+
+ ICommand OnErrorLine(Action handler);
+
+ CommandResolutionStrategy ResolutionStrategy { get; }
+
+ string CommandName { get; }
+
+ string CommandArgs { get; }
+ }
+}
diff --git a/src/Microsoft.DotNet.Cli.Utils/ICommandFactory.cs b/src/Microsoft.DotNet.Cli.Utils/ICommandFactory.cs
new file mode 100644
index 000000000..8fcda8c53
--- /dev/null
+++ b/src/Microsoft.DotNet.Cli.Utils/ICommandFactory.cs
@@ -0,0 +1,14 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Collections.Generic;
+using NuGet.Frameworks;
+
+namespace Microsoft.DotNet.Cli.Utils
+{
+ public interface ICommandFactory
+ {
+ ICommand Create(
+ string commandName, IEnumerable args, NuGetFramework framework = null);
+ }
+}
diff --git a/src/Microsoft.DotNet.Cli.Utils/PathUtility.cs b/src/Microsoft.DotNet.Cli.Utils/PathUtility.cs
index d2fe50f2a..691c4f560 100644
--- a/src/Microsoft.DotNet.Cli.Utils/PathUtility.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/PathUtility.cs
@@ -3,7 +3,7 @@
using System;
using System.IO;
-using System.Runtime.InteropServices;
+using Microsoft.Extensions.PlatformAbstractions;
namespace Microsoft.DotNet.Tools.Common
{
@@ -98,7 +98,7 @@ namespace Microsoft.DotNet.Tools.Common
}
StringComparison compare;
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ if (PlatformServices.Default.Runtime.OperatingSystemPlatform == Platform.Windows)
{
compare = StringComparison.OrdinalIgnoreCase;
// check if paths are on the same volume
@@ -154,7 +154,7 @@ namespace Microsoft.DotNet.Tools.Common
path += ".." + separator;
}
}
-
+
for (var i = index; len2 - 1 > i; ++i)
{
path += path2Segments[i] + separator;
@@ -216,7 +216,7 @@ namespace Microsoft.DotNet.Tools.Common
{
var comparison = StringComparison.Ordinal;
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ if (PlatformServices.Default.Runtime.OperatingSystemPlatform == Platform.Windows)
{
comparison = StringComparison.OrdinalIgnoreCase;
}
diff --git a/src/Microsoft.DotNet.Cli.Utils/Reporter.cs b/src/Microsoft.DotNet.Cli.Utils/Reporter.cs
index e60ac3c50..c27314fc5 100644
--- a/src/Microsoft.DotNet.Cli.Utils/Reporter.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/Reporter.cs
@@ -2,7 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
-using System.Runtime.InteropServices;
+using Microsoft.Extensions.PlatformAbstractions;
namespace Microsoft.DotNet.Cli.Utils
{
@@ -25,7 +25,7 @@ namespace Microsoft.DotNet.Cli.Utils
public static Reporter Create(Func getter)
{
- return new Reporter(getter(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)));
+ return new Reporter(getter(PlatformServices.Default.Runtime.OperatingSystemPlatform == Platform.Windows));
}
public void WriteLine(string message)
diff --git a/src/Microsoft.DotNet.Cli.Utils/ScriptExecutor.cs b/src/Microsoft.DotNet.Cli.Utils/ScriptExecutor.cs
index 59ef038f9..8f8f91b73 100644
--- a/src/Microsoft.DotNet.Cli.Utils/ScriptExecutor.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/ScriptExecutor.cs
@@ -2,97 +2,62 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Runtime.InteropServices;
using Microsoft.DotNet.Cli.Utils.CommandParsing;
using Microsoft.DotNet.ProjectModel;
+using Microsoft.Extensions.PlatformAbstractions;
namespace Microsoft.DotNet.Cli.Utils
{
public static class ScriptExecutor
{
- public static Command CreateCommandForScript(Project project, string scriptCommandLine, IDictionary variables)
+ public static ICommand CreateCommandForScript(Project project, string scriptCommandLine, IDictionary variables)
{
return CreateCommandForScript(project, scriptCommandLine, WrapVariableDictionary(variables));
}
- public static Command CreateCommandForScript(Project project, string scriptCommandLine, Func getVariable)
+ public static ICommand CreateCommandForScript(Project project, string scriptCommandLine, Func getVariable)
+ {
+ var scriptArguments = ParseScriptArguments(project, scriptCommandLine, getVariable);
+ if (scriptArguments == null)
+ {
+ throw new Exception($"ScriptExecutor: failed to parse script \"{scriptCommandLine}\"");
+ }
+
+ var inferredExtensions = DetermineInferredScriptExtensions();
+
+ return Command
+ .CreateForScript(scriptArguments.First(), scriptArguments.Skip(1), project, inferredExtensions)
+ .WorkingDirectory(project.ProjectDirectory);
+ }
+
+ private static IEnumerable ParseScriptArguments(Project project, string scriptCommandLine, Func getVariable)
{
- // Preserve quotation marks around arguments since command is about to be passed to a shell. May need
- // the quotes to ensure the shell groups arguments correctly.
var scriptArguments = CommandGrammar.Process(
scriptCommandLine,
GetScriptVariable(project, getVariable),
- preserveSurroundingQuotes: true);
+ preserveSurroundingQuotes: false);
- // Ensure the array won't be empty and the elements won't be null or empty strings.
scriptArguments = scriptArguments.Where(argument => !string.IsNullOrEmpty(argument)).ToArray();
if (scriptArguments.Length == 0)
{
return null;
}
- var useComSpec = false;
+ return scriptArguments;
+ }
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ private static string[] DetermineInferredScriptExtensions()
+ {
+ if (PlatformServices.Default.Runtime.OperatingSystemPlatform == Platform.Windows)
{
- // Only forward slashes are used in script blocks. Replace with backslashes to correctly
- // locate the script. The directory separator is platform-specific.
- scriptArguments[0] = scriptArguments[0].Replace(
- Path.AltDirectorySeparatorChar,
- Path.DirectorySeparatorChar);
-
- // Command-lines on Windows are executed via "cmd /S /C" in order to support batch files, &&,
- // built-in commands like echo, et cetera. /S allows quoting the command as well as the arguments.
- // ComSpec is Windows-specific, and contains the full path to cmd.exe
- var comSpec = Environment.GetEnvironmentVariable("ComSpec");
- if (!string.IsNullOrEmpty(comSpec))
- {
- useComSpec=true;
-
- scriptArguments = new string[] { comSpec }
- .Concat(scriptArguments)
- .ToArray();
- }
+ return new string[] { "", ".cmd" };
}
else
{
- // Special-case a script name that, perhaps with added .sh, matches an existing file.
- var surroundWithQuotes = false;
- var scriptCandidate = scriptArguments[0];
- if (scriptCandidate.StartsWith("\"", StringComparison.Ordinal) &&
- scriptCandidate.EndsWith("\"", StringComparison.Ordinal))
- {
- // Strip surrounding quotes; they were required in project.json to keep the script name
- // together but confuse File.Exists() e.g. "My Script", lacking ./ prefix and .sh suffix.
- surroundWithQuotes = true;
- scriptCandidate = scriptCandidate.Substring(1, scriptCandidate.Length - 2);
- }
-
- if (!scriptCandidate.EndsWith(".sh", StringComparison.Ordinal))
- {
- scriptCandidate = scriptCandidate + ".sh";
- }
-
- if (File.Exists(Path.Combine(project.ProjectDirectory, scriptCandidate)))
- {
- // scriptCandidate may be a path relative to the project root. If so, likely will not be found
- // in the $PATH; add ./ to let bash know where to look.
- var prefix = Path.IsPathRooted(scriptCandidate) ? string.Empty : "./";
- var quote = surroundWithQuotes ? "\"" : string.Empty;
- scriptArguments[0] = $"{ quote }{ prefix }{ scriptCandidate }{ quote }";
- }
-
- // Always use /usr/bin/env bash -c in order to support redirection and so on; similar to Windows case.
- // Unlike Windows, must escape quotation marks within the newly-quoted string.
- scriptArguments = new[] { "/usr/bin/env", "bash", "-c", "\"" }
- .Concat(scriptArguments.Select(argument => argument.Replace("\"", "\\\"")))
- .Concat(new[] { "\"" })
- .ToArray();
+ return new string[] { "", ".sh" };
}
-
- return Command.Create(scriptArguments.FirstOrDefault(), scriptArguments.Skip(1), useComSpec: useComSpec)
- .WorkingDirectory(project.ProjectDirectory);
}
+
private static Func WrapVariableDictionary(IDictionary contextVariables)
{
return key =>
diff --git a/src/Microsoft.DotNet.Cli.Utils/StreamForwarder.cs b/src/Microsoft.DotNet.Cli.Utils/StreamForwarder.cs
index 0a4c70518..a2cbc32af 100644
--- a/src/Microsoft.DotNet.Cli.Utils/StreamForwarder.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/StreamForwarder.cs
@@ -13,7 +13,6 @@ namespace Microsoft.DotNet.Cli.Utils
private StringBuilder _builder;
private StringWriter _capture;
- private Action _write;
private Action _writeLine;
public string CapturedOutput
@@ -130,4 +129,4 @@ namespace Microsoft.DotNet.Cli.Utils
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.DotNet.Cli.Utils/project.json b/src/Microsoft.DotNet.Cli.Utils/project.json
index ec5a4c08c..279e70226 100644
--- a/src/Microsoft.DotNet.Cli.Utils/project.json
+++ b/src/Microsoft.DotNet.Cli.Utils/project.json
@@ -2,20 +2,24 @@
"version": "1.0.0-*",
"compilationOptions": {
- "keyFile": "../../tools/Key.snk"
+ "keyFile": "../../tools/Key.snk",
+ "warningsAsErrors": true
},
"dependencies": {
- "NETStandard.Library": "1.0.0-rc2-23811",
"Microsoft.DotNet.ProjectModel": "1.0.0-*",
"System.Reflection.Metadata": "1.2.0-rc2-23811",
"Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc2-16537"
},
"frameworks": {
+ "net451": { },
"dnxcore50": {
- "imports": "portable-net45+win8"
+ "imports": "portable-net45+win8",
+ "dependencies": {
+ "NETStandard.Library": "1.0.0-rc2-23811"
}
+ }
},
"scripts": {
diff --git a/src/Microsoft.DotNet.Compiler.Common/project.json b/src/Microsoft.DotNet.Compiler.Common/project.json
index 207ea5d19..25dd9fc6d 100644
--- a/src/Microsoft.DotNet.Compiler.Common/project.json
+++ b/src/Microsoft.DotNet.Compiler.Common/project.json
@@ -7,8 +7,9 @@
"dependencies": {
"NETStandard.Library": "1.0.0-rc2-23811",
+ "System.Reflection.Metadata": "1.2.0-rc3-23811",
"System.CommandLine": "0.1.0-e160119-1",
- "Microsoft.CodeAnalysis.CSharp": "1.2.0-beta1-20160108-01",
+ "Microsoft.CodeAnalysis.CSharp": "1.2.0-beta1-20160202-02",
"Microsoft.DotNet.ProjectModel": "1.0.0-*",
"Microsoft.DotNet.Cli.Utils": "1.0.0-*",
"Microsoft.DotNet.Files": {"version": "1.0.0-*", "target": "project"}
diff --git a/src/Microsoft.DotNet.ProjectModel.Workspaces/project.json b/src/Microsoft.DotNet.ProjectModel.Workspaces/project.json
index 5d60662e8..36e401df5 100644
--- a/src/Microsoft.DotNet.ProjectModel.Workspaces/project.json
+++ b/src/Microsoft.DotNet.ProjectModel.Workspaces/project.json
@@ -5,9 +5,10 @@
},
"dependencies": {
"NETStandard.Library": "1.0.0-rc2-23811",
+ "System.Reflection.Metadata": "1.2.0-rc3-23811",
"Microsoft.DotNet.ProjectModel": "1.0.0-*",
"Microsoft.DotNet.Compiler.Common": "1.0.0-*",
- "Microsoft.CodeAnalysis.CSharp.Workspaces": "1.2.0-beta1-20160108-01"
+ "Microsoft.CodeAnalysis.CSharp.Workspaces": "1.2.0-beta1-20160202-02"
},
"frameworks": {
"dnxcore50": {
diff --git a/src/Microsoft.DotNet.ProjectModel/CommonCompilerOptions.cs b/src/Microsoft.DotNet.ProjectModel/CommonCompilerOptions.cs
index c7d79b607..3e4e6216e 100644
--- a/src/Microsoft.DotNet.ProjectModel/CommonCompilerOptions.cs
+++ b/src/Microsoft.DotNet.ProjectModel/CommonCompilerOptions.cs
@@ -58,7 +58,7 @@ namespace Microsoft.DotNet.ProjectModel
}
private static bool EnumerableEquals(IEnumerable left, IEnumerable right)
- => Enumerable.SequenceEqual(left ?? Array.Empty(), right ?? Array.Empty());
+ => Enumerable.SequenceEqual(left ?? EmptyArray.Value, right ?? EmptyArray.Value);
public override int GetHashCode()
{
@@ -69,7 +69,7 @@ namespace Microsoft.DotNet.ProjectModel
{
if (@new != null)
{
- old = old ?? Array.Empty();
+ old = old ?? EmptyArray.Value;
return old.Concat(@new).Distinct().ToArray();
}
return old;
diff --git a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs
index 91469b7d9..333812b92 100644
--- a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs
+++ b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs
@@ -122,8 +122,8 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
}
///
- /// Create a LibraryExport from LibraryDescription.
- ///
+ /// Create a LibraryExport from LibraryDescription.
+ ///
/// When the library is not resolved the LibraryExport is created nevertheless.
///
private LibraryExport GetExport(LibraryDescription library)
@@ -162,7 +162,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
var analyzers = GetAnalyzerReferences(package);
return new LibraryExport(package, compileAssemblies,
- sourceReferences, runtimeAssemblies, Array.Empty(), nativeLibraries, analyzers);
+ sourceReferences, runtimeAssemblies, EmptyArray.Value, nativeLibraries, analyzers);
}
private LibraryExport ExportProject(ProjectDescription project)
@@ -175,8 +175,8 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
sourceReferences: Enumerable.Empty(),
nativeLibraries: Enumerable.Empty(),
runtimeAssets: Enumerable.Empty(),
- runtimeAssemblies: Array.Empty(),
- analyzers: Array.Empty());
+ runtimeAssemblies: EmptyArray.Value,
+ analyzers: EmptyArray.Value);
}
var compileAssemblies = new List();
@@ -226,7 +226,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
// just the same as compileAssemblies and nativeLibraries are empty
// Also no support for analyzer projects
return new LibraryExport(project, compileAssemblies, sourceReferences,
- compileAssemblies, runtimeAssets, Array.Empty(), Array.Empty());
+ compileAssemblies, runtimeAssets, EmptyArray.Value, EmptyArray.Value);
}
private static string ResolvePath(Project project, string configuration, string path)
@@ -250,13 +250,13 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
return new LibraryExport(
library,
string.IsNullOrEmpty(library.Path) ?
- Array.Empty() :
+ EmptyArray.Value :
new[] { new LibraryAsset(library.Identity.Name, library.Path, library.Path) },
- Array.Empty(),
- Array.Empty(),
- Array.Empty(),
- Array.Empty(),
- Array.Empty());
+ EmptyArray.Value,
+ EmptyArray.Value,
+ EmptyArray.Value,
+ EmptyArray.Value,
+ EmptyArray.Value);
}
private IEnumerable GetSharedSources(PackageDescription package)
diff --git a/src/Microsoft.DotNet.ProjectModel/FileNameSuffixes.cs b/src/Microsoft.DotNet.ProjectModel/FileNameSuffixes.cs
index c1015240f..c09f5bf07 100644
--- a/src/Microsoft.DotNet.ProjectModel/FileNameSuffixes.cs
+++ b/src/Microsoft.DotNet.ProjectModel/FileNameSuffixes.cs
@@ -1,5 +1,5 @@
using System;
-using System.Runtime.InteropServices;
+using Microsoft.Extensions.PlatformAbstractions;
namespace Microsoft.DotNet.ProjectModel
{
@@ -11,11 +11,17 @@ namespace Microsoft.DotNet.ProjectModel
{
get
{
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return Windows; }
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { return Linux; }
- if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { return OSX; }
-
- throw new InvalidOperationException("Unknown Platform");
+ switch (PlatformServices.Default.Runtime.OperatingSystemPlatform)
+ {
+ case Platform.Windows:
+ return Windows;
+ case Platform.Darwin:
+ return OSX;
+ case Platform.Linux:
+ return Linux;
+ default:
+ throw new InvalidOperationException("Unknown Platform");
+ }
}
}
diff --git a/src/Microsoft.DotNet.ProjectModel/Internal/EmptyArray.cs b/src/Microsoft.DotNet.ProjectModel/Internal/EmptyArray.cs
new file mode 100644
index 000000000..d55b1456b
--- /dev/null
+++ b/src/Microsoft.DotNet.ProjectModel/Internal/EmptyArray.cs
@@ -0,0 +1,14 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Microsoft.DotNet.ProjectModel
+{
+ internal static class EmptyArray
+ {
+#if NET451
+ public static readonly T[] Value = new T[0];
+#else
+ public static readonly T[] Value = System.Array.Empty();
+#endif
+ }
+}
diff --git a/src/Microsoft.DotNet.ProjectModel/ProjectReader.cs b/src/Microsoft.DotNet.ProjectModel/ProjectReader.cs
index 5ebbbeb4a..744023c1a 100644
--- a/src/Microsoft.DotNet.ProjectModel/ProjectReader.cs
+++ b/src/Microsoft.DotNet.ProjectModel/ProjectReader.cs
@@ -144,9 +144,9 @@ namespace Microsoft.DotNet.ProjectModel
project.CompilerName = rawProject.ValueAsString("compilerName");
project.TestRunner = rawProject.ValueAsString("testRunner");
- project.Authors = rawProject.ValueAsStringArray("authors") ?? Array.Empty();
- project.Owners = rawProject.ValueAsStringArray("owners") ?? Array.Empty();
- project.Tags = rawProject.ValueAsStringArray("tags") ?? Array.Empty();
+ project.Authors = rawProject.ValueAsStringArray("authors") ?? EmptyArray.Value;
+ project.Owners = rawProject.ValueAsStringArray("owners") ?? EmptyArray.Value;
+ project.Tags = rawProject.ValueAsStringArray("tags") ?? EmptyArray.Value;
project.Language = rawProject.ValueAsString("language");
project.ReleaseNotes = rawProject.ValueAsString("releaseNotes");
diff --git a/src/Microsoft.DotNet.ProjectModel/Resolution/FrameworkReferenceResolver.cs b/src/Microsoft.DotNet.ProjectModel/Resolution/FrameworkReferenceResolver.cs
index f63462629..17458d0eb 100644
--- a/src/Microsoft.DotNet.ProjectModel/Resolution/FrameworkReferenceResolver.cs
+++ b/src/Microsoft.DotNet.ProjectModel/Resolution/FrameworkReferenceResolver.cs
@@ -5,10 +5,10 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Xml.Linq;
using Microsoft.DotNet.ProjectModel.Utilities;
+using Microsoft.Extensions.PlatformAbstractions;
using NuGet.Frameworks;
namespace Microsoft.DotNet.ProjectModel.Resolution
@@ -60,7 +60,7 @@ namespace Microsoft.DotNet.ProjectModel.Resolution
return referenceAssembliesPath;
}
- if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ if (PlatformServices.Default.Runtime.OperatingSystemPlatform != Platform.Windows)
{
// There is no reference assemblies path outside of windows
// The environment variable can be used to specify one
diff --git a/src/Microsoft.DotNet.ProjectModel/Utilities/PathUtility.cs b/src/Microsoft.DotNet.ProjectModel/Utilities/PathUtility.cs
index 6185a7313..2381ea32b 100644
--- a/src/Microsoft.DotNet.ProjectModel/Utilities/PathUtility.cs
+++ b/src/Microsoft.DotNet.ProjectModel/Utilities/PathUtility.cs
@@ -3,7 +3,7 @@
using System;
using System.IO;
-using System.Runtime.InteropServices;
+using Microsoft.Extensions.PlatformAbstractions;
namespace Microsoft.DotNet.ProjectModel.Utilities
{
@@ -84,7 +84,7 @@ namespace Microsoft.DotNet.ProjectModel.Utilities
}
StringComparison compare;
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ if (PlatformServices.Default.Runtime.OperatingSystemPlatform == Platform.Windows)
{
compare = StringComparison.OrdinalIgnoreCase;
// check if paths are on the same volume
diff --git a/src/Microsoft.DotNet.ProjectModel/Utilities/VersionUtility.cs b/src/Microsoft.DotNet.ProjectModel/Utilities/VersionUtility.cs
index 4755457af..81c421bf3 100644
--- a/src/Microsoft.DotNet.ProjectModel/Utilities/VersionUtility.cs
+++ b/src/Microsoft.DotNet.ProjectModel/Utilities/VersionUtility.cs
@@ -1,7 +1,10 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+#if !NET451
using System.Runtime.Loader;
+#endif
+using System.Reflection;
using System.Text;
using NuGet.Versioning;
@@ -16,7 +19,11 @@ namespace Microsoft.DotNet.ProjectModel.Utilities
internal static NuGetVersion GetAssemblyVersion(string path)
{
+#if NET451
+ return new NuGetVersion(AssemblyName.GetAssemblyName(path).Version);
+#else
return new NuGetVersion(AssemblyLoadContext.GetAssemblyName(path).Version);
+#endif
}
public static string RenderVersion(VersionRange range)
diff --git a/src/Microsoft.DotNet.ProjectModel/project.json b/src/Microsoft.DotNet.ProjectModel/project.json
index 6b56073f6..f9c7dddf4 100644
--- a/src/Microsoft.DotNet.ProjectModel/project.json
+++ b/src/Microsoft.DotNet.ProjectModel/project.json
@@ -5,15 +5,9 @@
},
"description": "Types to model a .NET Project",
"dependencies": {
- "NETStandard.Library": "1.0.0-rc2-23811",
- "System.Reflection.Metadata": "1.2.0-rc2-23811",
- "System.Runtime.Loader": "4.0.0-rc2-23811",
- "System.Dynamic.Runtime": "4.0.11-rc2-23811",
- "System.Security.Cryptography.Algorithms": "4.0.0-rc2-23811",
- "Microsoft.CSharp": "4.0.1-rc2-23811",
- "System.Xml.XDocument": "4.0.11-rc2-23811",
- "NuGet.Packaging": "3.4.0-beta-583",
+ "System.Reflection.Metadata": "1.2.0-rc2-23811",
+ "NuGet.Packaging": "3.4.0-beta-583",
"Microsoft.Extensions.FileSystemGlobbing": "1.0.0-rc2-15996",
"Microsoft.Extensions.JsonParser.Sources": {
"type": "build",
@@ -28,11 +22,23 @@
"version": "1.0.0-*"
}
},
-
"frameworks": {
+ "net451": {
+ "frameworkAssemblies": {
+ "System.IO": ""
+ }
+ },
"dnxcore50": {
- "imports": "portable-net45+win8"
+ "imports": "portable-net45+win8",
+ "dependencies": {
+ "NETStandard.Library": "1.0.0-rc2-23811",
+ "System.Dynamic.Runtime": "4.0.11-rc2-23811",
+ "System.Runtime.Loader": "4.0.0-rc2-23811",
+ "System.Security.Cryptography.Algorithms": "4.0.0-rc2-23811",
+ "Microsoft.CSharp": "4.0.1-rc2-23811",
+ "System.Xml.XDocument": "4.0.11-rc2-23811"
}
+ }
},
"scripts": {
}
diff --git a/src/Microsoft.Extensions.DependencyModel/CompilationLibrary.cs b/src/Microsoft.Extensions.DependencyModel/CompilationLibrary.cs
index a00bcdb6d..6acd61e16 100644
--- a/src/Microsoft.Extensions.DependencyModel/CompilationLibrary.cs
+++ b/src/Microsoft.Extensions.DependencyModel/CompilationLibrary.cs
@@ -25,7 +25,7 @@ namespace Microsoft.Extensions.DependencyModel
string basePath;
- var appBase = Path.GetDirectoryName(entryAssembly.Location);
+ var appBase = PlatformServices.Default.Application.ApplicationBasePath;
var refsDir = Path.Combine(appBase, "refs");
var hasRefs = Directory.Exists(refsDir);
var isProject = string.Equals(LibraryType, "project", StringComparison.OrdinalIgnoreCase);
diff --git a/src/Microsoft.Extensions.Testing.Abstractions/project.json b/src/Microsoft.Extensions.Testing.Abstractions/project.json
index d22bed163..889044a2f 100644
--- a/src/Microsoft.Extensions.Testing.Abstractions/project.json
+++ b/src/Microsoft.Extensions.Testing.Abstractions/project.json
@@ -1,27 +1,29 @@
{
- "description": "Abstractions for test runners to communicate to a tool, such as Visual Studio.",
- "version": "1.0.0-*",
- "repository": {
- "type": "git",
- "url": "git://github.com/dotnet/cli"
- },
- "compilationOptions": {
- "warningsAsErrors": true,
- "keyFile": "../../tools/Key.snk"
- },
- "dependencies": {
- "Newtonsoft.Json": "7.0.1",
- "Microsoft.DotNet.ProjectModel": "1.0.0-*",
- "Microsoft.Extensions.Logging.Abstractions": "1.0.0-rc2-16040",
+ "description": "Abstractions for test runners to communicate to a tool, such as Visual Studio.",
+ "version": "1.0.0-*",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/dotnet/cli"
+ },
+ "compilationOptions": {
+ "warningsAsErrors": true,
+ "keyFile": "../../tools/Key.snk"
+ },
+ "dependencies": {
+ "Newtonsoft.Json": "7.0.1",
+ "Microsoft.DotNet.ProjectModel": "1.0.0-*",
+ "Microsoft.Extensions.Logging.Abstractions": "1.0.0-rc2-16040"
+ },
+ "frameworks": {
+ "net451": { },
+ "dnxcore50": {
+ "imports": "portable-net45+win8",
+ "dependencies": {
"NETStandard.Library": "1.0.0-rc2-23811",
"System.Resources.ResourceManager": "4.0.1-rc2-23811",
"System.Runtime.Serialization.Primitives": "4.1.0-rc2-23811"
- },
- "frameworks": {
- "dnxcore50": {
- "imports": "portable-net45+win8"
- }
- },
- "scripts": {
+ }
}
-}
+ },
+ "scripts": { }
+}
\ No newline at end of file
diff --git a/scripts/test/restore-tests.sh b/src/corehost/build.sh
similarity index 56%
rename from scripts/test/restore-tests.sh
rename to src/corehost/build.sh
index a39c795fd..339838348 100755
--- a/scripts/test/restore-tests.sh
+++ b/src/corehost/build.sh
@@ -1,8 +1,8 @@
#!/usr/bin/env bash
-#
-# Copyright (c) .NET Foundation and contributors. All rights reserved.
-# Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#
+
+# Why is this a separate script? Why not just invoke 'cmake' and 'make' in the C# build scripts themselves?
+# I really don't know, but it doesn't work when I do that. Something about SIGCHLD not getting from clang to cmake or something.
+# -anurse
set -e
@@ -14,8 +14,6 @@ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symli
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
-source "$DIR/../common/_common.sh"
-
-header "Restoring Test Packages"
-
-dotnet restore "$REPOROOT/test" --runtime $RID -f "$TEST_PACKAGE_DIR" $DISABLE_PARALLEL
+echo "Building Corehost from $DIR to $(pwd)"
+cmake "$DIR" -G "Unix Makefiles"
+make
diff --git a/src/corehost/cli/hostpolicy.cpp b/src/corehost/cli/hostpolicy.cpp
index efe4259b2..ead5f5da0 100644
--- a/src/corehost/cli/hostpolicy.cpp
+++ b/src/corehost/cli/hostpolicy.cpp
@@ -117,7 +117,7 @@ int run(const arguments_t& args, const pal::string_t& clr_path)
// Workaround for dotnet/cli Issue #488 and #652
pal::string_t server_gc;
- std::string server_gc_cstr = (pal::getenv(_X("COREHOST_SERVER_GC"), &server_gc) && !server_gc.empty()) ? pal::to_stdstring(server_gc) : "1";
+ std::string server_gc_cstr = (pal::getenv(_X("COREHOST_SERVER_GC"), &server_gc) && !server_gc.empty()) ? pal::to_stdstring(server_gc) : "0";
const char* property_values[] = {
// TRUSTED_PLATFORM_ASSEMBLIES
diff --git a/src/dotnet/commands/dotnet-build/BuilderCommandApp.cs b/src/dotnet/commands/dotnet-build/BuilderCommandApp.cs
index e9d3affa2..6f0348404 100644
--- a/src/dotnet/commands/dotnet-build/BuilderCommandApp.cs
+++ b/src/dotnet/commands/dotnet-build/BuilderCommandApp.cs
@@ -8,15 +8,18 @@ namespace Microsoft.DotNet.Tools.Build
internal class BuilderCommandApp : CompilerCommandApp
{
public const string BuildProfileFlag = "--build-profile";
- public const string ForceUnsafeFlag = "--no-incremental";
+ public const string NoIncrementalFlag = "--no-incremental";
+ public const string NoDependenciesFlag = "--no-dependencies";
- public bool BuildProfileValue => OptionHasValue(BuildProfileFlag);
- public bool ForceUnsafeValue => OptionHasValue(ForceUnsafeFlag);
+ public bool ShouldPrintIncrementalPreconditions => OptionHasValue(BuildProfileFlag);
+ public bool ShouldNotUseIncrementality => OptionHasValue(NoIncrementalFlag);
+ public bool ShouldSkipDependencies => OptionHasValue(NoDependenciesFlag);
public BuilderCommandApp(string name, string fullName, string description) : base(name, fullName, description)
{
AddNoValueOption(BuildProfileFlag, "Set this flag to print the incremental safety checks that prevent incremental compilation");
- AddNoValueOption(ForceUnsafeFlag, "Set this flag to turn off incremental build");
+ AddNoValueOption(NoIncrementalFlag, "Set this flag to turn off incremental build");
+ AddNoValueOption(NoDependenciesFlag, "Set this flag to ignore project to project references and only build the root project");
}
}
}
\ No newline at end of file
diff --git a/src/dotnet/commands/dotnet-build/CompileContext.cs b/src/dotnet/commands/dotnet-build/CompileContext.cs
index 0cae3a45b..6c2906386 100644
--- a/src/dotnet/commands/dotnet-build/CompileContext.cs
+++ b/src/dotnet/commands/dotnet-build/CompileContext.cs
@@ -23,9 +23,9 @@ namespace Microsoft.DotNet.Tools.Build
public static readonly string[] KnownCompilers = { "csc", "vbc", "fsc" };
private readonly ProjectContext _rootProject;
+ private readonly ProjectDependenciesFacade _rootProjectDependencies;
private readonly BuilderCommandApp _args;
private readonly IncrementalPreconditions _preconditions;
- private readonly ProjectDependenciesFacade _dependencies;
public bool IsSafeForIncrementalCompilation => !_preconditions.PreconditionsDetected();
@@ -36,12 +36,9 @@ namespace Microsoft.DotNet.Tools.Build
// Cleaner to clone the args and mutate the clone than have separate CompileContext fields for mutated args
// and then reasoning which ones to get from args and which ones from fields.
_args = (BuilderCommandApp)args.ShallowCopy();
-
- _args.OutputValue = _args.OutputValue;
- _args.BuildBasePathValue = _args.BuildBasePathValue;
// Set up dependencies
- _dependencies = new ProjectDependenciesFacade(_rootProject, _args.ConfigValue);
+ _rootProjectDependencies = new ProjectDependenciesFacade(_rootProject, _args.ConfigValue);
// gather preconditions
_preconditions = GatherIncrementalPreconditions();
@@ -51,17 +48,36 @@ namespace Microsoft.DotNet.Tools.Build
{
CreateOutputDirectories();
- // compile dependencies
- foreach (var dependency in Sort(_dependencies.ProjectDependenciesWithSources))
- {
- if (incremental)
- {
- var dependencyProjectContext = ProjectContext.Create(dependency.Path, dependency.Framework, new[] { _rootProject.RuntimeIdentifier });
+ return CompileDendencies(incremental) && CompileRootProject(incremental);
+ }
- if (!NeedsRebuilding(dependencyProjectContext, new ProjectDependenciesFacade(dependencyProjectContext, _args.ConfigValue)))
- {
- continue;
- }
+ private bool CompileRootProject(bool incremental)
+ {
+ if (incremental && !NeedsRebuilding(_rootProject, _rootProjectDependencies))
+ {
+ // todo: what if the previous build had errors / warnings and nothing changed? Need to propagate them in case of incremental
+ return true;
+ }
+
+ var success = InvokeCompileOnRootProject();
+
+ PrintSummary(success);
+
+ return success;
+ }
+
+ private bool CompileDendencies(bool incremental)
+ {
+ if (_args.ShouldSkipDependencies)
+ {
+ return true;
+ }
+
+ foreach (var dependency in Sort(_rootProjectDependencies.ProjectDependenciesWithSources))
+ {
+ if (incremental && !DependencyNeedsRebuilding(dependency))
+ {
+ continue;
}
if (!InvokeCompileOnDependency(dependency))
@@ -70,28 +86,18 @@ namespace Microsoft.DotNet.Tools.Build
}
}
- if (incremental && !NeedsRebuilding(_rootProject, _dependencies))
- {
- // todo: what if the previous build had errors / warnings and nothing changed? Need to propagate them in case of incremental
- return true;
- }
+ return true;
+ }
- // compile project
- var success = InvokeCompileOnRootProject();
-
- PrintSummary(success);
-
- return success;
+ private bool DependencyNeedsRebuilding(ProjectDescription dependency)
+ {
+ var dependencyProjectContext = ProjectContext.Create(dependency.Path, dependency.Framework, new[] { _rootProject.RuntimeIdentifier });
+ return NeedsRebuilding(dependencyProjectContext, new ProjectDependenciesFacade(dependencyProjectContext, _args.ConfigValue));
}
private bool NeedsRebuilding(ProjectContext project, ProjectDependenciesFacade dependencies)
{
- return NeedsRebuilding(project, dependencies, _args.BuildBasePathValue);
- }
-
- private bool NeedsRebuilding(ProjectContext project, ProjectDependenciesFacade dependencies, string baseBuildPath)
- {
- var compilerIO = GetCompileIO(project, _args.ConfigValue, baseBuildPath, _args.OutputValue, dependencies, project == _rootProject);
+ var compilerIO = GetCompileIO(project, _args.ConfigValue, _args.BuildBasePathValue, _args.OutputValue, dependencies, project == _rootProject);
// rebuild if empty inputs / outputs
if (!(compilerIO.Outputs.Any() && compilerIO.Inputs.Any()))
@@ -195,9 +201,9 @@ namespace Microsoft.DotNet.Tools.Build
private IncrementalPreconditions GatherIncrementalPreconditions()
{
- var preconditions = new IncrementalPreconditions(_args.BuildProfileValue);
+ var preconditions = new IncrementalPreconditions(_args.ShouldPrintIncrementalPreconditions);
- if (_args.ForceUnsafeValue)
+ if (_args.ShouldNotUseIncrementality)
{
preconditions.AddForceUnsafePrecondition();
}
@@ -217,11 +223,16 @@ namespace Microsoft.DotNet.Tools.Build
// check the entire project tree that needs to be compiled, duplicated for each framework
private List GetProjectsToCheck()
{
+ if (_args.ShouldSkipDependencies)
+ {
+ return new List(1) { _rootProject };
+ }
+
// include initial root project
- var contextsToCheck = new List(1 + _dependencies.ProjectDependenciesWithSources.Count) { _rootProject };
+ var contextsToCheck = new List(1 + _rootProjectDependencies.ProjectDependenciesWithSources.Count) { _rootProject };
// convert ProjectDescription to ProjectContext
- var dependencyContexts = _dependencies.ProjectDependenciesWithSources.Select
+ var dependencyContexts = _rootProjectDependencies.ProjectDependenciesWithSources.Select
(keyValuePair => ProjectContext.Create(keyValuePair.Value.Path, keyValuePair.Value.Framework));
contextsToCheck.AddRange(dependencyContexts);
diff --git a/src/dotnet/commands/dotnet-build/IncrementalPreconditions.cs b/src/dotnet/commands/dotnet-build/IncrementalPreconditions.cs
index bba3f4084..fbcd4435a 100644
--- a/src/dotnet/commands/dotnet-build/IncrementalPreconditions.cs
+++ b/src/dotnet/commands/dotnet-build/IncrementalPreconditions.cs
@@ -36,7 +36,7 @@ namespace Microsoft.DotNet.Tools.Build
public void AddForceUnsafePrecondition()
{
- _preconditions.Add($"[Forced Unsafe] The build was marked as unsafe. Remove the {BuilderCommandApp.ForceUnsafeFlag} flag to enable incremental compilation");
+ _preconditions.Add($"[Forced Unsafe] The build was marked as unsafe. Remove the {BuilderCommandApp.NoIncrementalFlag} flag to enable incremental compilation");
}
public bool PreconditionsDetected()
diff --git a/src/dotnet/commands/dotnet-build/README.md b/src/dotnet/commands/dotnet-build/README.md
index 4e7eac3f1..d958d923b 100644
--- a/src/dotnet/commands/dotnet-build/README.md
+++ b/src/dotnet/commands/dotnet-build/README.md
@@ -33,3 +33,6 @@ Prints out the incremental safety checks that users need to address in order for
--no-incremental
Marks the build as unsafe for incrementality. This turns off incremental compilation and forces a clean rebuild of the project dependency graph.
+
+--no-dependencies
+Ignore project to project references and only build the root project specified to build.
diff --git a/src/dotnet/commands/dotnet-compile-fsc/Program.cs b/src/dotnet/commands/dotnet-compile-fsc/Program.cs
index e22954eba..3dfff1547 100644
--- a/src/dotnet/commands/dotnet-compile-fsc/Program.cs
+++ b/src/dotnet/commands/dotnet-compile-fsc/Program.cs
@@ -12,6 +12,7 @@ using System.Text;
using Microsoft.DotNet.Cli.Compiler.Common;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.ProjectModel;
+using NuGet.Frameworks;
namespace Microsoft.DotNet.Tools.Compiler.Fsc
{
@@ -79,6 +80,9 @@ namespace Microsoft.DotNet.Tools.Compiler.Fsc
return returnCode;
}
+ outputName = outputName.Trim('"');
+ tempOutDir = tempOutDir.Trim('"');
+
var translated = TranslateCommonOptions(commonOptions, outputName);
var allArgs = new List(translated);
@@ -89,8 +93,10 @@ namespace Microsoft.DotNet.Tools.Compiler.Fsc
File.WriteAllText(assemblyInfo, AssemblyInfoFileGenerator.GenerateFSharp(assemblyInfoOptions));
allArgs.Add($"{assemblyInfo}");
+ bool targetNetCore = commonOptions.Defines.Contains("DNXCORE50");
+
//HACK fsc raise error FS0208 if target exe doesnt have extension .exe
- bool hackFS0208 = commonOptions.EmitEntryPoint == true;
+ bool hackFS0208 = targetNetCore && commonOptions.EmitEntryPoint == true;
string originalOutputName = outputName;
if (outputName != null)
@@ -100,26 +106,18 @@ namespace Microsoft.DotNet.Tools.Compiler.Fsc
outputName = Path.ChangeExtension(outputName, ".exe");
}
- allArgs.Add($"--out:");
- allArgs.Add($"{outputName}");
+ allArgs.Add($"--out:{outputName}");
}
- foreach (var reference in references)
+ //set target framework
+ if (targetNetCore)
{
- allArgs.Add("-r");
- allArgs.Add($"{reference}");
+ allArgs.Add("--targetprofile:netcore");
}
- foreach (var resource in resources)
- {
- allArgs.Add("--resource");
- allArgs.Add($"{resource}");
- }
-
- foreach (var source in sources)
- {
- allArgs.Add($"{source}");
- }
+ allArgs.AddRange(references.Select(r => $"-r:{r.Trim('"')}"));
+ allArgs.AddRange(resources.Select(resource => $"--resource:{resource.Trim('"')}"));
+ allArgs.AddRange(sources.Select(s => $"{s.Trim('"')}"));
var rsp = Path.Combine(tempOutDir, "dotnet-compile-fsc.rsp");
File.WriteAllLines(rsp, allArgs, Encoding.UTF8);
@@ -130,6 +128,8 @@ namespace Microsoft.DotNet.Tools.Compiler.Fsc
.ForwardStdOut()
.Execute();
+ bool successFsc = result.ExitCode == 0;
+
if (hackFS0208 && File.Exists(outputName))
{
if (File.Exists(originalOutputName))
@@ -137,6 +137,13 @@ namespace Microsoft.DotNet.Tools.Compiler.Fsc
File.Move(outputName, originalOutputName);
}
+ //HACK dotnet build require a pdb (crash without), fsc atm cant generate a portable pdb, so an empty pdb is created
+ string pdbPath = Path.ChangeExtension(outputName, ".pdb");
+ if (successFsc && !File.Exists(pdbPath))
+ {
+ File.WriteAllBytes(pdbPath, Array.Empty());
+ }
+
return result.ExitCode;
}
@@ -167,11 +174,29 @@ namespace Microsoft.DotNet.Tools.Compiler.Fsc
commonArgs.AddRange(options.Defines.Select(def => $"-d:{def}"));
}
+ if (options.SuppressWarnings != null)
+ {
+ }
+
+ // Additional arguments are added verbatim
+ if (options.AdditionalArguments != null)
+ {
+ commonArgs.AddRange(options.AdditionalArguments);
+ }
+
+ if (options.LanguageVersion != null)
+ {
+ }
+
if (options.Platform != null)
{
commonArgs.Add($"--platform:{options.Platform}");
}
+ if (options.AllowUnsafe == true)
+ {
+ }
+
if (options.WarningsAsErrors == true)
{
commonArgs.Add("--warnaserror");
@@ -182,7 +207,19 @@ namespace Microsoft.DotNet.Tools.Compiler.Fsc
commonArgs.Add("--optimize");
}
- if(options.GenerateXmlDocumentation == true)
+ if (options.KeyFile != null)
+ {
+ }
+
+ if (options.DelaySign == true)
+ {
+ }
+
+ if (options.PublicSign == true)
+ {
+ }
+
+ if (options.GenerateXmlDocumentation == true)
{
commonArgs.Add($"--doc:{Path.ChangeExtension(outputName, "xml")}");
}
@@ -199,7 +236,7 @@ namespace Microsoft.DotNet.Tools.Compiler.Fsc
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var win32manifestPath = Path.Combine(AppContext.BaseDirectory, "default.win32manifest");
- commonArgs.Add($"--win32manifest:\"{win32manifestPath}\"");
+ commonArgs.Add($"--win32manifest:{win32manifestPath}");
}
}
diff --git a/src/dotnet/commands/dotnet-compile/CompilationDriver.cs b/src/dotnet/commands/dotnet-compile/CompilationDriver.cs
new file mode 100644
index 000000000..897c293e3
--- /dev/null
+++ b/src/dotnet/commands/dotnet-compile/CompilationDriver.cs
@@ -0,0 +1,36 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Collections.Generic;
+using Microsoft.DotNet.ProjectModel;
+
+namespace Microsoft.DotNet.Tools.Compiler
+{
+ public class CompilationDriver
+ {
+ private readonly ICompiler _managedCompiler;
+ private readonly ICompiler _nativeCompiler;
+
+ public CompilationDriver(ICompiler managedCompiler, ICompiler nativeCompiler)
+ {
+ _managedCompiler = managedCompiler;
+ _nativeCompiler = nativeCompiler;
+ }
+
+ public bool Compile(IEnumerable contexts, CompilerCommandApp args)
+ {
+ var success = true;
+
+ foreach (var context in contexts)
+ {
+ success &= _managedCompiler.Compile(context, args);
+ if (args.IsNativeValue && success)
+ {
+ success &= _nativeCompiler.Compile(context, args);
+ }
+ }
+
+ return success;
+ }
+ }
+}
diff --git a/src/dotnet/commands/dotnet-compile/Compiler.cs b/src/dotnet/commands/dotnet-compile/Compiler.cs
new file mode 100644
index 000000000..6a0f6a75c
--- /dev/null
+++ b/src/dotnet/commands/dotnet-compile/Compiler.cs
@@ -0,0 +1,202 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using Microsoft.DotNet.Cli.Utils;
+using Microsoft.DotNet.ProjectModel;
+using Microsoft.DotNet.ProjectModel.Compilation;
+using Microsoft.DotNet.ProjectModel.Resources;
+
+namespace Microsoft.DotNet.Tools.Compiler
+{
+ public abstract class Compiler : ICompiler
+ {
+ public abstract bool Compile(ProjectContext context, CompilerCommandApp args);
+
+ protected static bool PrintSummary(List diagnostics, Stopwatch sw, bool success = true)
+ {
+ PrintDiagnostics(diagnostics);
+
+ Reporter.Output.WriteLine();
+
+ var errorCount = diagnostics.Count(d => d.Severity == DiagnosticMessageSeverity.Error);
+ var warningCount = diagnostics.Count(d => d.Severity == DiagnosticMessageSeverity.Warning);
+
+ if (errorCount > 0 || !success)
+ {
+ Reporter.Output.WriteLine("Compilation failed.".Red());
+ success = false;
+ }
+ else
+ {
+ Reporter.Output.WriteLine("Compilation succeeded.".Green());
+ }
+
+ Reporter.Output.WriteLine($" {warningCount} Warning(s)");
+ Reporter.Output.WriteLine($" {errorCount} Error(s)");
+
+ Reporter.Output.WriteLine();
+
+ Reporter.Output.WriteLine($"Time elapsed {sw.Elapsed}");
+
+ return success;
+ }
+
+ protected static bool AddNonCultureResources(Project project, List compilerArgs, string intermediateOutputPath)
+ {
+ var resgenFiles = CompilerUtil.GetNonCultureResources(project, intermediateOutputPath);
+
+ foreach (var resgenFile in resgenFiles)
+ {
+ if (ResourceUtility.IsResxFile(resgenFile.InputFile))
+ {
+ var arguments = new[]
+ {
+ resgenFile.InputFile,
+ $"-o:{resgenFile.OutputFile}",
+ $"-v:{project.Version.Version}"
+ };
+
+ var rsp = Path.Combine(intermediateOutputPath, $"dotnet-resgen-resx.rsp");
+ File.WriteAllLines(rsp, arguments);
+
+ var result = Resgen.ResgenCommand.Run(new[] { $"@{rsp}" });
+
+ if (result != 0)
+ {
+ return false;
+ }
+
+ compilerArgs.Add($"--resource:\"{resgenFile.OutputFile},{Path.GetFileName(resgenFile.MetadataName)}\"");
+ }
+ else
+ {
+ compilerArgs.Add($"--resource:\"{resgenFile.InputFile},{Path.GetFileName(resgenFile.MetadataName)}\"");
+ }
+ }
+
+ return true;
+ }
+
+ protected static bool GenerateCultureResourceAssemblies(
+ Project project,
+ List dependencies,
+ string intermediateOutputPath,
+ string outputPath)
+ {
+ var referencePaths = CompilerUtil.GetReferencePathsForCultureResgen(dependencies);
+ var resgenReferenceArgs = referencePaths.Select(path => $"-r:{path}").ToList();
+ var cultureResgenFiles = CompilerUtil.GetCultureResources(project, outputPath);
+
+ foreach (var resgenFile in cultureResgenFiles)
+ {
+ var resourceOutputPath = Path.GetDirectoryName(resgenFile.OutputFile);
+
+ if (!Directory.Exists(resourceOutputPath))
+ {
+ Directory.CreateDirectory(resourceOutputPath);
+ }
+
+ var arguments = new List();
+
+ arguments.AddRange(resgenReferenceArgs);
+ arguments.Add($"-o:{resgenFile.OutputFile}");
+ arguments.Add($"-c:{resgenFile.Culture}");
+ arguments.Add($"-v:{project.Version.Version}");
+ arguments.AddRange(resgenFile.InputFileToMetadata.Select(fileToMetadata => $"{fileToMetadata.Key},{fileToMetadata.Value}"));
+ var rsp = Path.Combine(intermediateOutputPath, $"dotnet-resgen.rsp");
+ File.WriteAllLines(rsp, arguments);
+
+ var result = Resgen.ResgenCommand.Run(new[] { $"@{rsp}" });
+ if (result != 0)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ protected static DiagnosticMessage ParseDiagnostic(string projectRootPath, string line)
+ {
+ var error = CanonicalError.Parse(line);
+
+ if (error != null)
+ {
+ var severity = error.category == CanonicalError.Parts.Category.Error ?
+ DiagnosticMessageSeverity.Error : DiagnosticMessageSeverity.Warning;
+
+ return new DiagnosticMessage(
+ error.code,
+ error.text,
+ Path.IsPathRooted(error.origin) ? line : projectRootPath + Path.DirectorySeparatorChar + line,
+ Path.Combine(projectRootPath, error.origin),
+ severity,
+ error.line,
+ error.column,
+ error.endColumn,
+ error.endLine,
+ source: null);
+ }
+
+ return null;
+ }
+
+ private static void PrintDiagnostics(List diagnostics)
+ {
+ foreach (var diag in diagnostics)
+ {
+ PrintDiagnostic(diag);
+ }
+ }
+
+ private static void PrintDiagnostic(DiagnosticMessage diag)
+ {
+ switch (diag.Severity)
+ {
+ case DiagnosticMessageSeverity.Info:
+ Reporter.Error.WriteLine(diag.FormattedMessage);
+ break;
+ case DiagnosticMessageSeverity.Warning:
+ Reporter.Error.WriteLine(diag.FormattedMessage.Yellow().Bold());
+ break;
+ case DiagnosticMessageSeverity.Error:
+ Reporter.Error.WriteLine(diag.FormattedMessage.Red().Bold());
+ break;
+ }
+ }
+
+ private static void CopyFiles(IEnumerable files, string outputPath)
+ {
+ foreach (var file in files)
+ {
+ File.Copy(file.ResolvedPath, Path.Combine(outputPath, Path.GetFileName(file.ResolvedPath)), overwrite: true);
+ }
+ }
+
+ private static string EnsureTrailingSlash(string path)
+ {
+ return EnsureTrailingCharacter(path, Path.DirectorySeparatorChar);
+ }
+
+ private static string EnsureTrailingCharacter(string path, char trailingCharacter)
+ {
+ if (path == null)
+ {
+ throw new ArgumentNullException(nameof(path));
+ }
+
+ // if the path is empty, we want to return the original string instead of a single trailing character.
+ if (path.Length == 0 || path[path.Length - 1] == trailingCharacter)
+ {
+ return path;
+ }
+
+ return path + trailingCharacter;
+ }
+ }
+}
diff --git a/src/dotnet/commands/dotnet-compile/ICompiler.cs b/src/dotnet/commands/dotnet-compile/ICompiler.cs
new file mode 100644
index 000000000..aecb49bee
--- /dev/null
+++ b/src/dotnet/commands/dotnet-compile/ICompiler.cs
@@ -0,0 +1,12 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using Microsoft.DotNet.ProjectModel;
+
+namespace Microsoft.DotNet.Tools.Compiler
+{
+ public interface ICompiler
+ {
+ bool Compile(ProjectContext context, CompilerCommandApp args);
+ }
+}
diff --git a/src/dotnet/commands/dotnet-compile/IScriptRunner.cs b/src/dotnet/commands/dotnet-compile/IScriptRunner.cs
new file mode 100644
index 000000000..05910cebc
--- /dev/null
+++ b/src/dotnet/commands/dotnet-compile/IScriptRunner.cs
@@ -0,0 +1,13 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Collections.Generic;
+using Microsoft.DotNet.ProjectModel;
+
+namespace Microsoft.DotNet.Tools.Compiler
+{
+ public interface IScriptRunner
+ {
+ void RunScripts(ProjectContext context, string name, Dictionary contextVariables);
+ }
+}
diff --git a/src/dotnet/commands/dotnet-compile/ManagedCompiler.cs b/src/dotnet/commands/dotnet-compile/ManagedCompiler.cs
new file mode 100644
index 000000000..d1d284f2e
--- /dev/null
+++ b/src/dotnet/commands/dotnet-compile/ManagedCompiler.cs
@@ -0,0 +1,200 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using Microsoft.DotNet.Cli.Compiler.Common;
+using Microsoft.DotNet.Cli.Utils;
+using Microsoft.DotNet.ProjectModel;
+using Microsoft.DotNet.ProjectModel.Utilities;
+using Microsoft.Extensions.DependencyModel;
+
+namespace Microsoft.DotNet.Tools.Compiler
+{
+ public class ManagedCompiler : Compiler
+ {
+ private readonly IScriptRunner _scriptRunner;
+ private readonly ICommandFactory _commandFactory;
+
+ public ManagedCompiler(IScriptRunner scriptRunner, ICommandFactory commandFactory)
+ {
+ _scriptRunner = scriptRunner;
+ _commandFactory = commandFactory;
+ }
+
+ public override bool Compile(ProjectContext context, CompilerCommandApp args)
+ {
+ // Set up Output Paths
+ var outputPaths = context.GetOutputPaths(args.ConfigValue, args.BuildBasePathValue);
+ var outputPath = outputPaths.CompilationOutputPath;
+ var intermediateOutputPath = outputPaths.IntermediateOutputDirectoryPath;
+
+ Directory.CreateDirectory(outputPath);
+ Directory.CreateDirectory(intermediateOutputPath);
+
+ // Create the library exporter
+ var exporter = context.CreateExporter(args.ConfigValue, args.BuildBasePathValue);
+
+ // Gather exports for the project
+ var dependencies = exporter.GetDependencies().ToList();
+
+ Reporter.Output.WriteLine($"Compiling {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}");
+ var sw = Stopwatch.StartNew();
+
+ var diagnostics = new List();
+ var missingFrameworkDiagnostics = new List();
+
+ // Collect dependency diagnostics
+ foreach (var diag in context.LibraryManager.GetAllDiagnostics())
+ {
+ if (diag.ErrorCode == ErrorCodes.DOTNET1011 ||
+ diag.ErrorCode == ErrorCodes.DOTNET1012)
+ {
+ missingFrameworkDiagnostics.Add(diag);
+ }
+
+ diagnostics.Add(diag);
+ }
+
+ if (missingFrameworkDiagnostics.Count > 0)
+ {
+ // The framework isn't installed so we should short circuit the rest of the compilation
+ // so we don't get flooded with errors
+ PrintSummary(missingFrameworkDiagnostics, sw);
+ return false;
+ }
+
+ // Get compilation options
+ var outputName = outputPaths.CompilationFiles.Assembly;
+
+ // Assemble args
+ var compilerArgs = new List()
+ {
+ $"--temp-output:\"{intermediateOutputPath}\"",
+ $"--out:\"{outputName}\""
+ };
+
+ var compilationOptions = CompilerUtil.ResolveCompilationOptions(context, args.ConfigValue);
+ var languageId = CompilerUtil.ResolveLanguageId(context);
+
+ var references = new List();
+
+ // Add compilation options to the args
+ compilerArgs.AddRange(compilationOptions.SerializeToArgs());
+
+ // Add metadata options
+ compilerArgs.AddRange(AssemblyInfoOptions.SerializeToArgs(AssemblyInfoOptions.CreateForProject(context)));
+
+ foreach (var dependency in dependencies)
+ {
+ references.AddRange(dependency.CompilationAssemblies.Select(r => r.ResolvedPath));
+ compilerArgs.AddRange(dependency.SourceReferences.Select(s => $"\"{s}\""));
+
+ // Add analyzer references
+ compilerArgs.AddRange(dependency.AnalyzerReferences
+ .Where(a => a.AnalyzerLanguage == languageId)
+ .Select(a => $"--analyzer:\"{a.AssemblyPath}\""));
+ }
+
+ compilerArgs.AddRange(references.Select(r => $"--reference:\"{r}\""));
+
+ if (compilationOptions.PreserveCompilationContext == true)
+ {
+ var dependencyContext = DependencyContextBuilder.Build(compilationOptions,
+ exporter,
+ args.ConfigValue,
+ context.TargetFramework,
+ context.RuntimeIdentifier);
+
+ var writer = new DependencyContextWriter();
+ var depsJsonFile = Path.Combine(intermediateOutputPath, context.ProjectFile.Name + "dotnet-compile.deps.json");
+ using (var fileStream = File.Create(depsJsonFile))
+ {
+ writer.Write(dependencyContext, fileStream);
+ }
+
+ compilerArgs.Add($"--resource:\"{depsJsonFile},{context.ProjectFile.Name}.deps.json\"");
+ }
+
+ if (!AddNonCultureResources(context.ProjectFile, compilerArgs, intermediateOutputPath))
+ {
+ return false;
+ }
+ // Add project source files
+ var sourceFiles = CompilerUtil.GetCompilationSources(context);
+ compilerArgs.AddRange(sourceFiles);
+
+ var compilerName = CompilerUtil.ResolveCompilerName(context);
+
+ // Write RSP file
+ var rsp = Path.Combine(intermediateOutputPath, $"dotnet-compile.rsp");
+ File.WriteAllLines(rsp, compilerArgs);
+
+ // Run pre-compile event
+ var contextVariables = new Dictionary()
+ {
+ { "compile:TargetFramework", context.TargetFramework.GetShortFolderName() },
+ { "compile:FullTargetFramework", context.TargetFramework.DotNetFrameworkName },
+ { "compile:Configuration", args.ConfigValue },
+ { "compile:OutputFile", outputName },
+ { "compile:OutputDir", outputPath.TrimEnd('\\', '/') },
+ { "compile:ResponseFile", rsp }
+ };
+
+ if (!string.IsNullOrEmpty(context.RuntimeIdentifier))
+ {
+ contextVariables.Add(
+ "compile:RuntimeOutputDir",
+ outputPaths.RuntimeOutputPath.TrimEnd('\\', '/'));
+ }
+
+ _scriptRunner.RunScripts(context, ScriptNames.PreCompile, contextVariables);
+
+ var result = _commandFactory.Create($"compile-{compilerName}", new[] { "@" + $"{rsp}" })
+ .OnErrorLine(line =>
+ {
+ var diagnostic = ParseDiagnostic(context.ProjectDirectory, line);
+ if (diagnostic != null)
+ {
+ diagnostics.Add(diagnostic);
+ }
+ else
+ {
+ Reporter.Error.WriteLine(line);
+ }
+ })
+ .OnOutputLine(line =>
+ {
+ var diagnostic = ParseDiagnostic(context.ProjectDirectory, line);
+ if (diagnostic != null)
+ {
+ diagnostics.Add(diagnostic);
+ }
+ else
+ {
+ Reporter.Output.WriteLine(line);
+ }
+ }).Execute();
+
+ // Run post-compile event
+ contextVariables["compile:CompilerExitCode"] = result.ExitCode.ToString();
+ _scriptRunner.RunScripts(context, ScriptNames.PostCompile, contextVariables);
+
+ var success = result.ExitCode == 0;
+
+ if (!success)
+ {
+ Reporter.Error.WriteLine($"{result.StartInfo.FileName} {result.StartInfo.Arguments} returned Exit Code {result.ExitCode}");
+ }
+
+ if (success)
+ {
+ success &= GenerateCultureResourceAssemblies(context.ProjectFile, dependencies, intermediateOutputPath, outputPath);
+ }
+
+ return PrintSummary(diagnostics, sw, success);
+ }
+ }
+}
diff --git a/src/dotnet/commands/dotnet-compile/NativeCompiler.cs b/src/dotnet/commands/dotnet-compile/NativeCompiler.cs
new file mode 100644
index 000000000..e3a5efbda
--- /dev/null
+++ b/src/dotnet/commands/dotnet-compile/NativeCompiler.cs
@@ -0,0 +1,106 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Collections.Generic;
+using System.IO;
+using Microsoft.DotNet.ProjectModel;
+
+namespace Microsoft.DotNet.Tools.Compiler
+{
+ public class NativeCompiler : Compiler
+ {
+ public override bool Compile(ProjectContext context, CompilerCommandApp args)
+ {
+ var outputPaths = context.GetOutputPaths(args.ConfigValue, args.BuildBasePathValue, args.OutputValue);
+ var outputPath = outputPaths.RuntimeOutputPath;
+ var nativeOutputPath = Path.Combine(outputPath, "native");
+ var intermediateOutputPath =
+ outputPaths.IntermediateOutputDirectoryPath;
+ var nativeTempOutput = Path.Combine(intermediateOutputPath, "native");
+ Directory.CreateDirectory(nativeOutputPath);
+ Directory.CreateDirectory(nativeTempOutput);
+
+ var managedOutput = outputPaths.CompilationFiles.Assembly;
+
+ var nativeArgs = new List();
+
+ // Input Assembly
+ nativeArgs.Add($"{managedOutput}");
+
+ // ILC Args
+ if (!string.IsNullOrWhiteSpace(args.IlcArgsValue))
+ {
+ nativeArgs.Add("--ilcargs");
+ nativeArgs.Add($"{args.IlcArgsValue}");
+ }
+
+ // ILC Path
+ if (!string.IsNullOrWhiteSpace(args.IlcPathValue))
+ {
+ nativeArgs.Add("--ilcpath");
+ nativeArgs.Add(args.IlcPathValue);
+ }
+
+ // ILC SDK Path
+ if (!string.IsNullOrWhiteSpace(args.IlcSdkPathValue))
+ {
+ nativeArgs.Add("--ilcsdkpath");
+ nativeArgs.Add(args.IlcSdkPathValue);
+ }
+
+ // AppDep SDK Path
+ if (!string.IsNullOrWhiteSpace(args.AppDepSdkPathValue))
+ {
+ nativeArgs.Add("--appdepsdk");
+ nativeArgs.Add(args.AppDepSdkPathValue);
+ }
+
+ // CodeGen Mode
+ if (args.IsCppModeValue)
+ {
+ nativeArgs.Add("--mode");
+ nativeArgs.Add("cpp");
+ }
+
+ if (!string.IsNullOrWhiteSpace(args.CppCompilerFlagsValue))
+ {
+ nativeArgs.Add("--cppcompilerflags");
+ nativeArgs.Add(args.CppCompilerFlagsValue);
+ }
+
+ // Configuration
+ if (args.ConfigValue != null)
+ {
+ nativeArgs.Add("--configuration");
+ nativeArgs.Add(args.ConfigValue);
+ }
+
+ // Architecture
+ if (args.ArchValue != null)
+ {
+ nativeArgs.Add("--arch");
+ nativeArgs.Add(args.ArchValue);
+ }
+
+ // Intermediate Path
+ nativeArgs.Add("--temp-output");
+ nativeArgs.Add($"{nativeTempOutput}");
+
+ // Output Path
+ nativeArgs.Add("--output");
+ nativeArgs.Add($"{nativeOutputPath}");
+
+ // Write Response File
+ var rsp = Path.Combine(nativeTempOutput, $"dotnet-compile-native.{context.ProjectFile.Name}.rsp");
+ File.WriteAllLines(rsp, nativeArgs);
+
+ // TODO Add -r assembly.dll for all Nuget References
+ // Need CoreRT Framework published to nuget
+
+ // Do Native Compilation
+ var result = Native.CompileNativeCommand.Run(new string[] { "--rsp", $"{rsp}" });
+
+ return result == 0;
+ }
+ }
+}
diff --git a/src/dotnet/commands/dotnet-compile/Program.cs b/src/dotnet/commands/dotnet-compile/Program.cs
index 8d75e6dc9..40e8d0485 100644
--- a/src/dotnet/commands/dotnet-compile/Program.cs
+++ b/src/dotnet/commands/dotnet-compile/Program.cs
@@ -2,19 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using Microsoft.Dotnet.Cli.Compiler.Common;
-using Microsoft.DotNet.Cli.Compiler.Common;
using Microsoft.DotNet.Cli.Utils;
-using Microsoft.DotNet.ProjectModel;
-using Microsoft.DotNet.ProjectModel.Compilation;
-using Microsoft.DotNet.ProjectModel.Resources;
-using Microsoft.DotNet.ProjectModel.Utilities;
-using Microsoft.Extensions.DependencyModel;
-using Microsoft.Extensions.PlatformAbstractions;
namespace Microsoft.DotNet.Tools.Compiler
{
@@ -27,8 +15,15 @@ namespace Microsoft.DotNet.Tools.Compiler
try
{
+ var commandFactory = new DotNetCommandFactory();
+ var scriptRunner = new ScriptRunner();
+ var managedCompiler = new ManagedCompiler(scriptRunner, commandFactory);
+ var nativeCompiler = new NativeCompiler();
+ var compilationDriver = new CompilationDriver(managedCompiler, nativeCompiler);
+
var compilerCommandArgs = new CompilerCommandApp("dotnet compile", ".NET Compiler", "Compiler for the .NET Platform");
- return compilerCommandArgs.Execute(OnExecute, args);
+
+ return compilerCommandArgs.Execute(compilationDriver.Compile, args);
}
catch (Exception ex)
{
@@ -40,474 +35,5 @@ namespace Microsoft.DotNet.Tools.Compiler
return 1;
}
}
-
- private static bool OnExecute(List contexts, CompilerCommandApp args)
- {
- var success = true;
-
- foreach (var context in contexts)
- {
- success &= CompileProject(context, args);
- if (args.IsNativeValue && success)
- {
- success &= CompileNative(context, args);
- }
- }
- return success;
- }
-
- private static bool CompileNative(
- ProjectContext context,
- CompilerCommandApp args)
- {
- var outputPaths = context.GetOutputPaths(args.ConfigValue, args.BuildBasePathValue, args.OutputValue);
- var outputPath = outputPaths.RuntimeOutputPath;
- var nativeOutputPath = Path.Combine(outputPath, "native");
- var intermediateOutputPath =
- outputPaths.IntermediateOutputDirectoryPath;
- var nativeTempOutput = Path.Combine(intermediateOutputPath, "native");
- Directory.CreateDirectory(nativeOutputPath);
- Directory.CreateDirectory(nativeTempOutput);
-
- var managedOutput = outputPaths.CompilationFiles.Assembly;
-
- var nativeArgs = new List();
-
- // Input Assembly
- nativeArgs.Add($"{managedOutput}");
-
- // ILC Args
- if (!string.IsNullOrWhiteSpace(args.IlcArgsValue))
- {
- nativeArgs.Add("--ilcargs");
- nativeArgs.Add($"{args.IlcArgsValue}");
- }
-
- // ILC Path
- if (!string.IsNullOrWhiteSpace(args.IlcPathValue))
- {
- nativeArgs.Add("--ilcpath");
- nativeArgs.Add(args.IlcPathValue);
- }
-
- // ILC SDK Path
- if (!string.IsNullOrWhiteSpace(args.IlcSdkPathValue))
- {
- nativeArgs.Add("--ilcsdkpath");
- nativeArgs.Add(args.IlcSdkPathValue);
- }
-
- // AppDep SDK Path
- if (!string.IsNullOrWhiteSpace(args.AppDepSdkPathValue))
- {
- nativeArgs.Add("--appdepsdk");
- nativeArgs.Add(args.AppDepSdkPathValue);
- }
-
- // CodeGen Mode
- if (args.IsCppModeValue)
- {
- nativeArgs.Add("--mode");
- nativeArgs.Add("cpp");
- }
-
- if (!string.IsNullOrWhiteSpace(args.CppCompilerFlagsValue))
- {
- nativeArgs.Add("--cppcompilerflags");
- nativeArgs.Add(args.CppCompilerFlagsValue);
- }
-
- // Configuration
- if (args.ConfigValue != null)
- {
- nativeArgs.Add("--configuration");
- nativeArgs.Add(args.ConfigValue);
- }
-
- // Architecture
- if (args.ArchValue != null)
- {
- nativeArgs.Add("--arch");
- nativeArgs.Add(args.ArchValue);
- }
-
- // Intermediate Path
- nativeArgs.Add("--temp-output");
- nativeArgs.Add($"{nativeTempOutput}");
-
- // Output Path
- nativeArgs.Add("--output");
- nativeArgs.Add($"{nativeOutputPath}");
-
- // Write Response File
- var rsp = Path.Combine(nativeTempOutput, $"dotnet-compile-native.{context.ProjectFile.Name}.rsp");
- File.WriteAllLines(rsp, nativeArgs);
-
- // TODO Add -r assembly.dll for all Nuget References
- // Need CoreRT Framework published to nuget
-
- // Do Native Compilation
- var result = Native.CompileNativeCommand.Run(new string[] { "--rsp", $"{rsp}" });
-
- return result == 0;
- }
-
- private static bool CompileProject(ProjectContext context, CompilerCommandApp args)
- {
- // Set up Output Paths
- var outputPaths = context.GetOutputPaths(args.ConfigValue, args.BuildBasePathValue);
- var outputPath = outputPaths.CompilationOutputPath;
- var intermediateOutputPath =
- outputPaths.IntermediateOutputDirectoryPath;
-
- Directory.CreateDirectory(outputPath);
- Directory.CreateDirectory(intermediateOutputPath);
-
- // Create the library exporter
- var exporter = context.CreateExporter(args.ConfigValue, args.BuildBasePathValue);
-
- // Gather exports for the project
- var dependencies = exporter.GetDependencies().ToList();
-
- Reporter.Output.WriteLine($"Compiling {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}");
- var sw = Stopwatch.StartNew();
-
- var diagnostics = new List();
- var missingFrameworkDiagnostics = new List();
-
- // Collect dependency diagnostics
- foreach (var diag in context.LibraryManager.GetAllDiagnostics())
- {
- if (diag.ErrorCode == ErrorCodes.DOTNET1011 ||
- diag.ErrorCode == ErrorCodes.DOTNET1012)
- {
- missingFrameworkDiagnostics.Add(diag);
- }
-
- diagnostics.Add(diag);
- }
-
- if (missingFrameworkDiagnostics.Count > 0)
- {
- // The framework isn't installed so we should short circuit the rest of the compilation
- // so we don't get flooded with errors
- PrintSummary(missingFrameworkDiagnostics, sw);
- return false;
- }
-
- // Get compilation options
- var outputName = outputPaths.CompilationFiles.Assembly;
-
- // Assemble args
- var compilerArgs = new List()
- {
- $"--temp-output:\"{intermediateOutputPath}\"",
- $"--out:\"{outputName}\""
- };
-
- var compilationOptions = CompilerUtil.ResolveCompilationOptions(context, args.ConfigValue);
- var languageId = CompilerUtil.ResolveLanguageId(context);
-
- var references = new List();
-
- // Add compilation options to the args
- compilerArgs.AddRange(compilationOptions.SerializeToArgs());
-
- // Add metadata options
- compilerArgs.AddRange(AssemblyInfoOptions.SerializeToArgs(AssemblyInfoOptions.CreateForProject(context)));
-
- foreach (var dependency in dependencies)
- {
- references.AddRange(dependency.CompilationAssemblies.Select(r => r.ResolvedPath));
- compilerArgs.AddRange(dependency.SourceReferences.Select(s => $"\"{s}\""));
-
- // Add analyzer references
- compilerArgs.AddRange(dependency.AnalyzerReferences
- .Where(a => a.AnalyzerLanguage == languageId)
- .Select(a => $"--analyzer:\"{a.AssemblyPath}\""));
- }
-
- compilerArgs.AddRange(references.Select(r => $"--reference:\"{r}\""));
-
- if (compilationOptions.PreserveCompilationContext == true)
- {
- var dependencyContext = DependencyContextBuilder.Build(compilationOptions,
- exporter,
- args.ConfigValue,
- context.TargetFramework,
- context.RuntimeIdentifier);
-
- var writer = new DependencyContextWriter();
- var depsJsonFile = Path.Combine(intermediateOutputPath, context.ProjectFile.Name + "dotnet-compile.deps.json");
- using (var fileStream = File.Create(depsJsonFile))
- {
- writer.Write(dependencyContext, fileStream);
- }
-
- compilerArgs.Add($"--resource:\"{depsJsonFile},{context.ProjectFile.Name}.deps.json\"");
- }
-
- if (!AddNonCultureResources(context.ProjectFile, compilerArgs, intermediateOutputPath))
- {
- return false;
- }
- // Add project source files
- var sourceFiles = CompilerUtil.GetCompilationSources(context);
- compilerArgs.AddRange(sourceFiles);
-
- var compilerName = CompilerUtil.ResolveCompilerName(context);
-
- // Write RSP file
- var rsp = Path.Combine(intermediateOutputPath, $"dotnet-compile.rsp");
- File.WriteAllLines(rsp, compilerArgs);
-
- // Run pre-compile event
- var contextVariables = new Dictionary()
- {
- { "compile:TargetFramework", context.TargetFramework.DotNetFrameworkName },
- { "compile:Configuration", args.ConfigValue },
- { "compile:OutputFile", outputName },
- { "compile:OutputDir", outputPath },
- { "compile:ResponseFile", rsp }
- };
- RunScripts(context, ScriptNames.PreCompile, contextVariables);
-
- var result = Command.CreateDotNet($"compile-{compilerName}", new[] { "@" + $"{rsp}" })
- .OnErrorLine(line =>
- {
- var diagnostic = ParseDiagnostic(context.ProjectDirectory, line);
- if (diagnostic != null)
- {
- diagnostics.Add(diagnostic);
- }
- else
- {
- Reporter.Error.WriteLine(line);
- }
- })
- .OnOutputLine(line =>
- {
- var diagnostic = ParseDiagnostic(context.ProjectDirectory, line);
- if (diagnostic != null)
- {
- diagnostics.Add(diagnostic);
- }
- else
- {
- Reporter.Output.WriteLine(line);
- }
- }).Execute();
-
- // Run post-compile event
- contextVariables["compile:CompilerExitCode"] = result.ExitCode.ToString();
- RunScripts(context, ScriptNames.PostCompile, contextVariables);
-
- var success = result.ExitCode == 0;
-
- if (!success)
- {
- Reporter.Error.WriteLine($"{result.StartInfo.FileName} {result.StartInfo.Arguments} returned Exit Code {result.ExitCode}");
- }
-
- if (success)
- {
- success &= GenerateCultureResourceAssemblies(context.ProjectFile, dependencies, intermediateOutputPath, outputPath);
- }
-
- return PrintSummary(diagnostics, sw, success);
- }
-
- private static void RunScripts(ProjectContext context, string name, Dictionary contextVariables)
- {
- foreach (var script in context.ProjectFile.Scripts.GetOrEmpty(name))
- {
- ScriptExecutor.CreateCommandForScript(context.ProjectFile, script, contextVariables)
- .ForwardStdErr()
- .ForwardStdOut()
- .Execute();
- }
- }
-
- private static bool PrintSummary(List diagnostics, Stopwatch sw, bool success = true)
- {
- PrintDiagnostics(diagnostics);
-
- Reporter.Output.WriteLine();
-
- var errorCount = diagnostics.Count(d => d.Severity == DiagnosticMessageSeverity.Error);
- var warningCount = diagnostics.Count(d => d.Severity == DiagnosticMessageSeverity.Warning);
-
- if (errorCount > 0 || !success)
- {
- Reporter.Output.WriteLine("Compilation failed.".Red());
- success = false;
- }
- else
- {
- Reporter.Output.WriteLine("Compilation succeeded.".Green());
- }
-
- Reporter.Output.WriteLine($" {warningCount} Warning(s)");
- Reporter.Output.WriteLine($" {errorCount} Error(s)");
-
- Reporter.Output.WriteLine();
-
- Reporter.Output.WriteLine($"Time elapsed {sw.Elapsed}");
-
- return success;
- }
-
- private static bool AddNonCultureResources(Project project, List compilerArgs, string intermediateOutputPath)
- {
- var resgenFiles = CompilerUtil.GetNonCultureResources(project, intermediateOutputPath);
-
- foreach (var resgenFile in resgenFiles)
- {
- if (ResourceUtility.IsResxFile(resgenFile.InputFile))
- {
- var arguments = new[]
- {
- resgenFile.InputFile,
- $"-o:{resgenFile.OutputFile}",
- $"-v:{project.Version.Version}"
- };
-
- var rsp = Path.Combine(intermediateOutputPath, $"dotnet-resgen-resx.rsp");
- File.WriteAllLines(rsp, arguments);
-
- var result = Resgen.ResgenCommand.Run(new[] { $"@{rsp}" });
-
- if (result != 0)
- {
- return false;
- }
-
- compilerArgs.Add($"--resource:\"{resgenFile.OutputFile},{Path.GetFileName(resgenFile.MetadataName)}\"");
- }
- else
- {
- compilerArgs.Add($"--resource:\"{resgenFile.InputFile},{Path.GetFileName(resgenFile.MetadataName)}\"");
- }
- }
-
- return true;
- }
-
- private static bool GenerateCultureResourceAssemblies(
- Project project,
- List dependencies,
- string intermediateOutputPath,
- string outputPath)
- {
- var referencePaths = CompilerUtil.GetReferencePathsForCultureResgen(dependencies);
- var resgenReferenceArgs = referencePaths.Select(path => $"-r:{path}").ToList();
- var cultureResgenFiles = CompilerUtil.GetCultureResources(project, outputPath);
-
- foreach (var resgenFile in cultureResgenFiles)
- {
- var resourceOutputPath = Path.GetDirectoryName(resgenFile.OutputFile);
-
- if (!Directory.Exists(resourceOutputPath))
- {
- Directory.CreateDirectory(resourceOutputPath);
- }
-
- var arguments = new List();
-
- arguments.AddRange(resgenReferenceArgs);
- arguments.Add($"-o:{resgenFile.OutputFile}");
- arguments.Add($"-c:{resgenFile.Culture}");
- arguments.Add($"-v:{project.Version.Version}");
- arguments.AddRange(resgenFile.InputFileToMetadata.Select(fileToMetadata => $"{fileToMetadata.Key},{fileToMetadata.Value}"));
- var rsp = Path.Combine(intermediateOutputPath, $"dotnet-resgen.rsp");
- File.WriteAllLines(rsp, arguments);
-
- var result = Resgen.ResgenCommand.Run(new[] { $"@{rsp}" });
- if (result != 0)
- {
- return false;
- }
- }
-
- return true;
- }
-
- private static DiagnosticMessage ParseDiagnostic(string projectRootPath, string line)
- {
- var error = CanonicalError.Parse(line);
-
- if (error != null)
- {
- var severity = error.category == CanonicalError.Parts.Category.Error ?
- DiagnosticMessageSeverity.Error : DiagnosticMessageSeverity.Warning;
-
- return new DiagnosticMessage(
- error.code,
- error.text,
- Path.IsPathRooted(error.origin) ? line : projectRootPath + Path.DirectorySeparatorChar + line,
- Path.Combine(projectRootPath, error.origin),
- severity,
- error.line,
- error.column,
- error.endColumn,
- error.endLine,
- source: null);
- }
-
- return null;
- }
-
- private static void PrintDiagnostics(List diagnostics)
- {
- foreach (var diag in diagnostics)
- {
- PrintDiagnostic(diag);
- }
- }
-
- private static void PrintDiagnostic(DiagnosticMessage diag)
- {
- switch (diag.Severity)
- {
- case DiagnosticMessageSeverity.Info:
- Reporter.Error.WriteLine(diag.FormattedMessage);
- break;
- case DiagnosticMessageSeverity.Warning:
- Reporter.Error.WriteLine(diag.FormattedMessage.Yellow().Bold());
- break;
- case DiagnosticMessageSeverity.Error:
- Reporter.Error.WriteLine(diag.FormattedMessage.Red().Bold());
- break;
- }
- }
-
- private static void CopyFiles(IEnumerable files, string outputPath)
- {
- foreach (var file in files)
- {
- File.Copy(file.ResolvedPath, Path.Combine(outputPath, Path.GetFileName(file.ResolvedPath)), overwrite: true);
- }
- }
-
- private static string EnsureTrailingSlash(string path)
- {
- return EnsureTrailingCharacter(path, Path.DirectorySeparatorChar);
- }
-
- private static string EnsureTrailingCharacter(string path, char trailingCharacter)
- {
- if (path == null)
- {
- throw new ArgumentNullException(nameof(path));
- }
-
- // if the path is empty, we want to return the original string instead of a single trailing character.
- if (path.Length == 0 || path[path.Length - 1] == trailingCharacter)
- {
- return path;
- }
-
- return path + trailingCharacter;
- }
}
}
diff --git a/src/dotnet/commands/dotnet-compile/ScriptRunner.cs b/src/dotnet/commands/dotnet-compile/ScriptRunner.cs
new file mode 100644
index 000000000..72cb47cd6
--- /dev/null
+++ b/src/dotnet/commands/dotnet-compile/ScriptRunner.cs
@@ -0,0 +1,24 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Collections.Generic;
+using Microsoft.DotNet.Cli.Utils;
+using Microsoft.DotNet.ProjectModel;
+using Microsoft.DotNet.ProjectModel.Utilities;
+
+namespace Microsoft.DotNet.Tools.Compiler
+{
+ public class ScriptRunner : IScriptRunner
+ {
+ public void RunScripts(ProjectContext context, string name, Dictionary contextVariables)
+ {
+ foreach (var script in context.ProjectFile.Scripts.GetOrEmpty(name))
+ {
+ ScriptExecutor.CreateCommandForScript(context.ProjectFile, script, contextVariables)
+ .ForwardStdErr()
+ .ForwardStdOut()
+ .Execute();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/dotnet/commands/dotnet-publish/PublishCommand.cs b/src/dotnet/commands/dotnet-publish/PublishCommand.cs
index 112712794..ce3acfc60 100644
--- a/src/dotnet/commands/dotnet-publish/PublishCommand.cs
+++ b/src/dotnet/commands/dotnet-publish/PublishCommand.cs
@@ -96,7 +96,8 @@ namespace Microsoft.DotNet.Tools.Publish
{ "publish:ProjectPath", context.ProjectDirectory },
{ "publish:Configuration", configuration },
{ "publish:OutputPath", outputPath },
- { "publish:Framework", context.TargetFramework.Framework },
+ { "publish:TargetFramework", context.TargetFramework.GetShortFolderName() },
+ { "publish:FullTargetFramework", context.TargetFramework.DotNetFrameworkName },
{ "publish:Runtime", context.RuntimeIdentifier },
};
diff --git a/src/dotnet/commands/dotnet-restore/NuGet3.cs b/src/dotnet/commands/dotnet-restore/NuGet3.cs
index 1458040e3..58f74a6b8 100644
--- a/src/dotnet/commands/dotnet-restore/NuGet3.cs
+++ b/src/dotnet/commands/dotnet-restore/NuGet3.cs
@@ -21,8 +21,8 @@ namespace Microsoft.DotNet.Tools.Restore
var result = Run(Enumerable.Concat(
prefixArgs,
args))
- .ForwardStdErr()
.ForwardStdOut()
+ .ForwardStdErr()
.Execute();
return result.ExitCode;
diff --git a/src/dotnet/project.json b/src/dotnet/project.json
index bf5ea8b6e..6ffe6144f 100644
--- a/src/dotnet/project.json
+++ b/src/dotnet/project.json
@@ -18,10 +18,12 @@
"dependencies": {
"Newtonsoft.Json": "7.0.1",
- "Microsoft.Net.Compilers.netcore": "1.2.0-beta1-20160108-01",
+ "Microsoft.Net.Compilers.netcore": "1.2.0-beta1-20160202-02",
"Microsoft.FSharp.Compiler.netcore": "1.0.0-alpha-151218",
- "Microsoft.Net.CSharp.Interactive.netcore": "1.2.0-beta1-20160108-01",
- "Microsoft.CodeAnalysis.CSharp": "1.2.0-beta1-20160108-01",
+ "Microsoft.Net.CSharp.Interactive.netcore": "1.2.0-beta1-20160202-02",
+ "Microsoft.CodeAnalysis.CSharp": "1.2.0-beta1-20160202-02",
+ "Microsoft.DiaSymReader.Native": "1.3.3",
+
"NuGet.CommandLine.XPlat": "3.4.0-beta-583",
"System.CommandLine": "0.1.0-e160119-1",
@@ -52,6 +54,7 @@
"Microsoft.NETCore.ConsoleHost": "1.0.0-rc2-23811",
"Microsoft.NETCore.TestHost": "1.0.0-rc2-23811",
"NETStandard.Library": "1.0.0-rc2-23811",
+ "System.Reflection.Metadata": "1.2.0-rc3-23811",
"System.Diagnostics.TextWriterTraceListener": "4.0.0-rc2-23811",
"System.Diagnostics.TraceSource": "4.0.0-rc2-23811",
"System.Linq.Expressions": "4.0.11-rc2-23811",
diff --git a/test/ArgumentForwardingTests/ArgumentForwardingTests/ArgumentForwardingTests.cs b/test/ArgumentForwardingTests/ArgumentForwardingTests.cs
similarity index 90%
rename from test/ArgumentForwardingTests/ArgumentForwardingTests/ArgumentForwardingTests.cs
rename to test/ArgumentForwardingTests/ArgumentForwardingTests.cs
index adde47bf9..8834625af 100644
--- a/test/ArgumentForwardingTests/ArgumentForwardingTests/ArgumentForwardingTests.cs
+++ b/test/ArgumentForwardingTests/ArgumentForwardingTests.cs
@@ -18,7 +18,7 @@ namespace Microsoft.DotNet.Tests.ArgumentForwarding
{
public class ArgumentForwardingTests : TestBase
{
- private static readonly string s_reflectorExeName = "Reflector" + Constants.ExeSuffix;
+ private static readonly string s_reflectorExeName = "ArgumentsReflector" + Constants.ExeSuffix;
private static readonly string s_reflectorCmdName = "reflector_cmd";
private string ReflectorPath { get; set; }
@@ -28,7 +28,7 @@ namespace Microsoft.DotNet.Tests.ArgumentForwarding
{
Console.WriteLine("Dummy Entrypoint.");
}
-
+
public ArgumentForwardingTests()
{
// This test has a dependency on an argument reflector
@@ -94,16 +94,12 @@ namespace Microsoft.DotNet.Tests.ArgumentForwarding
[InlineData("\"abc\"\t\td\te")]
[InlineData(@"a\\b d""e f""g h")]
[InlineData(@"\ \\ \\\")]
- [InlineData(@"a\""b c d")]
[InlineData(@"a\\""b c d")]
- [InlineData(@"a\\\""b c d")]
[InlineData(@"a\\\\""b c d")]
[InlineData(@"a\\\\""b c d")]
[InlineData(@"a\\\\""b c"" d e")]
[InlineData(@"a""b c""d e""f g""h i""j k""l")]
[InlineData(@"a b c""def")]
- [InlineData(@"""\a\"" \\""\\\ b c")]
- [InlineData(@"a\""b \\ cd ""\e f\"" \\""\\\")]
public void TestArgumentForwardingCmd(string testUserArgument)
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
@@ -139,7 +135,7 @@ namespace Microsoft.DotNet.Tests.ArgumentForwarding
{
var rawArg = rawEvaluatedArgument[i];
var escapedArg = escapedEvaluatedRawArgument[i];
-
+
try
{
rawArg.Should().Be(escapedArg);
@@ -153,10 +149,33 @@ namespace Microsoft.DotNet.Tests.ArgumentForwarding
}
}
+ [Theory]
+ [InlineData(@"a\""b c d")]
+ [InlineData(@"a\\\""b c d")]
+ [InlineData(@"""\a\"" \\""\\\ b c")]
+ [InlineData(@"a\""b \\ cd ""\e f\"" \\""\\\")]
+ public void TestArgumentForwardingCmdFailsWithUnbalancedQuote(string testArgString)
+ {
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ return;
+ }
+
+ // Get Baseline Argument Evaluation via Reflector
+ // This does not need to be different for cmd because
+ // it only establishes what the string[] args should be
+ var rawEvaluatedArgument = RawEvaluateArgumentString(testArgString);
+
+ // Escape and Re-Evaluate the rawEvaluatedArgument
+ var escapedEvaluatedRawArgument = EscapeAndEvaluateArgumentStringCmd(rawEvaluatedArgument);
+
+ rawEvaluatedArgument.Length.Should().NotBe(escapedEvaluatedRawArgument.Length);
+ }
+
///
/// EscapeAndEvaluateArgumentString returns a representation of string[] args
/// when rawEvaluatedArgument is passed as an argument to a process using
- /// Command.Create(). Ideally this should escape the argument such that
+ /// Command.Create(). Ideally this should escape the argument such that
/// the output is == rawEvaluatedArgument.
///
/// A string[] representing string[] args as already evaluated by a process
@@ -176,7 +195,7 @@ namespace Microsoft.DotNet.Tests.ArgumentForwarding
///
/// EscapeAndEvaluateArgumentString returns a representation of string[] args
/// when rawEvaluatedArgument is passed as an argument to a process using
- /// Command.Create(). Ideally this should escape the argument such that
+ /// Command.Create(). Ideally this should escape the argument such that
/// the output is == rawEvaluatedArgument.
///
/// A string[] representing string[] args as already evaluated by a process
@@ -199,7 +218,7 @@ namespace Microsoft.DotNet.Tests.ArgumentForwarding
///
/// Parse the output of the reflector into a string array.
- /// Reflector output is simply string[] args written to
+ /// Reflector output is simply string[] args written to
/// one string separated by commas.
///
///
@@ -211,7 +230,7 @@ namespace Microsoft.DotNet.Tests.ArgumentForwarding
///
/// Parse the output of the reflector into a string array.
- /// Reflector output is simply string[] args written to
+ /// Reflector output is simply string[] args written to
/// one string separated by commas.
///
///
@@ -243,7 +262,7 @@ namespace Microsoft.DotNet.Tests.ArgumentForwarding
{
StartInfo = new ProcessStartInfo
{
- FileName = s_reflectorExeName,
+ FileName = ReflectorPath,
Arguments = testUserArgument,
UseShellExecute = false,
RedirectStandardOutput = true,
diff --git a/test/ArgumentForwardingTests/ArgumentForwardingTests/ArgumentForwardingTests.xproj b/test/ArgumentForwardingTests/ArgumentForwardingTests.xproj
similarity index 100%
rename from test/ArgumentForwardingTests/ArgumentForwardingTests/ArgumentForwardingTests.xproj
rename to test/ArgumentForwardingTests/ArgumentForwardingTests.xproj
diff --git a/test/ArgumentForwardingTests/ArgumentForwardingTests/project.json b/test/ArgumentForwardingTests/ArgumentForwardingTests/project.json
deleted file mode 100644
index e895933c4..000000000
--- a/test/ArgumentForwardingTests/ArgumentForwardingTests/project.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "version": "1.0.0-*",
- "compilationOptions": {
- "emitEntryPoint": true
- },
-
- "dependencies": {
- "NETStandard.Library" : "1.0.0-rc2-23811",
- "Microsoft.NETCore.TestHost": "1.0.0-rc2-23811",
-
- "xunit": "2.1.0",
- "xunit.console.netcore": "1.0.2-prerelease-00101",
- "xunit.netcore.extensions": "1.0.0-prerelease-00153",
- "xunit.runner.utility": "2.1.0",
-
- "Microsoft.DotNet.ProjectModel": { "target": "project" },
- "Microsoft.DotNet.Cli.Utils": { "target": "project" },
- "Microsoft.DotNet.Tools.Tests.Utilities": { "target": "project" }
- },
-
- "frameworks": {
- "dnxcore50": {
- "imports": "portable-net45+win8"
- }
- }
-}
diff --git a/test/ArgumentForwardingTests/Reflector/project.json b/test/ArgumentForwardingTests/project.json
similarity index 67%
rename from test/ArgumentForwardingTests/Reflector/project.json
rename to test/ArgumentForwardingTests/project.json
index e895933c4..19d7b3954 100644
--- a/test/ArgumentForwardingTests/Reflector/project.json
+++ b/test/ArgumentForwardingTests/project.json
@@ -6,21 +6,22 @@
"dependencies": {
"NETStandard.Library" : "1.0.0-rc2-23811",
- "Microsoft.NETCore.TestHost": "1.0.0-rc2-23811",
-
- "xunit": "2.1.0",
- "xunit.console.netcore": "1.0.2-prerelease-00101",
- "xunit.netcore.extensions": "1.0.0-prerelease-00153",
- "xunit.runner.utility": "2.1.0",
"Microsoft.DotNet.ProjectModel": { "target": "project" },
"Microsoft.DotNet.Cli.Utils": { "target": "project" },
- "Microsoft.DotNet.Tools.Tests.Utilities": { "target": "project" }
+ "Microsoft.DotNet.Tools.Tests.Utilities": { "target": "project" },
+
+ "xunit": "2.1.0",
+ "dotnet-test-xunit": "1.0.0-dev-48273-16"
},
"frameworks": {
"dnxcore50": {
"imports": "portable-net45+win8"
}
- }
+ },
+
+ "testRunner": "xunit",
+
+ "scripts": { "precompile": "dotnet build ../ArgumentsReflector/project.json --framework dnxcore50 --output %compile:RuntimeOutputDir%" }
}
diff --git a/test/ArgumentForwardingTests/Reflector/Reflector.cs b/test/ArgumentsReflector/Reflector.cs
similarity index 66%
rename from test/ArgumentForwardingTests/Reflector/Reflector.cs
rename to test/ArgumentsReflector/Reflector.cs
index 1af26f716..4176ebb0d 100644
--- a/test/ArgumentForwardingTests/Reflector/Reflector.cs
+++ b/test/ArgumentsReflector/Reflector.cs
@@ -2,17 +2,6 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Text;
-using Xunit;
-using Microsoft.DotNet.Cli.Utils;
-using Microsoft.DotNet.ProjectModel;
-using Microsoft.DotNet.Tools.Test.Utilities;
-using Microsoft.Extensions.PlatformAbstractions;
-using System.Diagnostics;
-using FluentAssertions;
namespace Microsoft.DotNet.Tests.ArgumentForwarding
{
diff --git a/test/ArgumentForwardingTests/Reflector/Reflector.xproj b/test/ArgumentsReflector/Reflector.xproj
similarity index 100%
rename from test/ArgumentForwardingTests/Reflector/Reflector.xproj
rename to test/ArgumentsReflector/Reflector.xproj
diff --git a/test/ArgumentsReflector/project.json b/test/ArgumentsReflector/project.json
new file mode 100644
index 000000000..e2dc63e05
--- /dev/null
+++ b/test/ArgumentsReflector/project.json
@@ -0,0 +1,18 @@
+{
+ "version": "1.0.0-*",
+ "compilationOptions": {
+ "emitEntryPoint": true
+ },
+
+ "dependencies": {
+ "NETStandard.Library" : "1.0.0-rc2-23811"
+ },
+
+ "frameworks": {
+ "dnxcore50": {
+ "imports": "portable-net45+win8"
+ }
+ },
+
+ "content": ["reflector_cmd.cmd"]
+}
diff --git a/test/ArgumentForwardingTests/Reflector/reflector_cmd.cmd b/test/ArgumentsReflector/reflector_cmd.cmd
similarity index 100%
rename from test/ArgumentForwardingTests/Reflector/reflector_cmd.cmd
rename to test/ArgumentsReflector/reflector_cmd.cmd
diff --git a/test/EndToEnd/EndToEndTest.cs b/test/EndToEnd/EndToEndTest.cs
index 25450216a..bd93d730c 100644
--- a/test/EndToEnd/EndToEndTest.cs
+++ b/test/EndToEnd/EndToEndTest.cs
@@ -16,7 +16,7 @@ namespace Microsoft.DotNet.Tests.EndToEnd
private static readonly string s_expectedOutput = "Hello World!" + Environment.NewLine;
private static readonly string s_testdirName = "e2etestroot";
private static readonly string s_outputdirName = "test space/bin";
-
+
private static string RestoredTestProjectDirectory { get; set; }
private string Rid { get; set; }
@@ -33,7 +33,7 @@ namespace Microsoft.DotNet.Tests.EndToEnd
{
Console.WriteLine("Dummy Entrypoint.");
}
-
+
public EndToEndTest()
{
TestInstanceSetup();
@@ -192,7 +192,7 @@ namespace Microsoft.DotNet.Tests.EndToEnd
{
Directory.Delete(RestoredTestProjectDirectory, true);
}
- catch(Exception e) {}
+ catch(Exception) {}
Directory.CreateDirectory(RestoredTestProjectDirectory);
@@ -231,4 +231,4 @@ namespace Microsoft.DotNet.Tests.EndToEnd
File.SetLastWriteTimeUtc(csFile, DateTime.UtcNow);
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/BuildCommand.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/BuildCommand.cs
index 4c1b4f2d6..6b6534feb 100644
--- a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/BuildCommand.cs
+++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/BuildCommand.cs
@@ -26,6 +26,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
private string _cppCompilerFlags;
private bool _buildProfile;
private bool _noIncremental;
+ private bool _noDependencies;
private string OutputOption
{
@@ -166,6 +167,16 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
}
}
+ private string NoDependencies
+ {
+ get
+ {
+ return _noDependencies ?
+ "--no-dependencies" :
+ "";
+ }
+ }
+
public BuildCommand(
string projectPath,
string output="",
@@ -181,11 +192,11 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
bool nativeCppMode=false,
string cppCompilerFlags="",
bool buildProfile=true,
- bool noIncremental=false
+ bool noIncremental=false,
+ bool noDependencies=false
)
: base("dotnet")
{
-
_projectPath = projectPath;
_project = ProjectReader.GetProject(projectPath);
@@ -203,6 +214,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
_cppCompilerFlags = cppCompilerFlags;
_buildProfile = buildProfile;
_noIncremental = noIncremental;
+ _noDependencies = noDependencies;
}
public override CommandResult Execute(string args = "")
@@ -226,7 +238,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
private string BuildArgs()
{
- return $"{BuildProfile} {NoIncremental} \"{_projectPath}\" {OutputOption} {BuildBasePathOption} {ConfigurationOption} {FrameworkOption} {NoHostOption} {NativeOption} {ArchitectureOption} {IlcArgsOption} {IlcPathOption} {AppDepSDKPathOption} {NativeCppModeOption} {CppCompilerFlagsOption}";
+ return $"{BuildProfile} {NoDependencies} {NoIncremental} \"{_projectPath}\" {OutputOption} {BuildBasePathOption} {ConfigurationOption} {FrameworkOption} {NoHostOption} {NativeOption} {ArchitectureOption} {IlcArgsOption} {IlcPathOption} {AppDepSDKPathOption} {NativeCppModeOption} {CppCompilerFlagsOption}";
}
}
}
diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/TestCommand.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/TestCommand.cs
index f1672a62a..ef78f1018 100644
--- a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/TestCommand.cs
+++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/TestCommand.cs
@@ -24,7 +24,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
if (!Path.IsPathRooted(_command))
{
_command = Env.GetCommandPath(_command) ??
- Env.GetCommandPathFromAppBase(AppContext.BaseDirectory, _command);
+ Env.GetCommandPathFromRootPath(AppContext.BaseDirectory, _command);
}
Console.WriteLine($"Executing - {_command} {args}");
@@ -43,7 +43,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
Console.WriteLine($"Executing (Captured Output) - {_command} {args}");
var commandPath = Env.GetCommandPath(_command, ".exe", ".cmd", "") ??
- Env.GetCommandPathFromAppBase(AppContext.BaseDirectory, _command, ".exe", ".cmd", "");
+ Env.GetCommandPathFromRootPath(AppContext.BaseDirectory, _command, ".exe", ".cmd", "");
var stdOut = new StreamForwarder();
var stdErr = new StreamForwarder();
diff --git a/test/ScriptExecutorTests/ScriptExecutorTests.cs b/test/ScriptExecutorTests/ScriptExecutorTests.cs
new file mode 100644
index 000000000..b1e156cac
--- /dev/null
+++ b/test/ScriptExecutorTests/ScriptExecutorTests.cs
@@ -0,0 +1,155 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using Microsoft.DotNet.Cli.Utils;
+using Microsoft.DotNet.ProjectModel;
+using Microsoft.DotNet.Tools.Test.Utilities;
+using System.Runtime.InteropServices;
+using Xunit;
+using FluentAssertions;
+using NuGet.Frameworks;
+
+namespace Microsoft.DotNet.Cli.Utils.ScriptExecutorTests
+{
+ public class ScriptExecutorTests : TestBase
+ {
+ private static readonly string s_testProjectRoot = Path.Combine(AppContext.BaseDirectory, "TestAssets/TestProjects");
+
+ private TempDirectory _root;
+ private string binTestProjectPath;
+ private Project project;
+
+ public ScriptExecutorTests()
+ {
+ _root = Temp.CreateDirectory();
+
+ var sourceTestProjectPath = Path.Combine(s_testProjectRoot, "TestApp");
+ binTestProjectPath = _root.CopyDirectory(sourceTestProjectPath).Path;
+ project = ProjectContext.Create(binTestProjectPath, NuGetFramework.Parse("dnxcore50")).ProjectFile;
+ }
+
+ [Fact]
+ public void Test_Project_Local_Script_is_Resolved()
+ {
+ CreateTestFile("some.script", binTestProjectPath);
+ var scriptCommandLine = "some.script";
+
+ var command = ScriptExecutor.CreateCommandForScript(project, scriptCommandLine, new Dictionary());
+
+ command.Should().NotBeNull();
+ command.ResolutionStrategy.Should().Be(CommandResolutionStrategy.ProjectLocal);
+ }
+
+ [Fact]
+ public void Test_Nonexistent_Project_Local_Script_throws_CommandUnknownException()
+ {
+ var scriptCommandLine = "nonexistent.script";
+
+ Action action = () => ScriptExecutor.CreateCommandForScript(project, scriptCommandLine, new Dictionary());
+ action.ShouldThrow();
+ }
+
+ [Fact]
+ public void Test_Extension_sh_is_Inferred_over_cmd_in_Project_Local_Scripts_on_Unix()
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ return;
+ }
+
+ var extensionList = new string[] { ".cmd", ".sh" };
+
+ var expectedExtension = ".sh";
+
+ foreach (var extension in extensionList)
+ {
+ CreateTestFile("uniquescriptname" + extension, binTestProjectPath);
+ }
+
+ // Don't include extension
+ var scriptCommandLine = "uniquescriptname";
+
+ var command = ScriptExecutor.CreateCommandForScript(project, scriptCommandLine, new Dictionary());
+
+ command.Should().NotBeNull();
+ command.ResolutionStrategy.Should().Be(CommandResolutionStrategy.ProjectLocal);
+ command.CommandArgs.Should().Contain(scriptCommandLine + expectedExtension);
+ }
+
+ [Fact]
+ public void Test_Extension_cmd_is_Inferred_over_sh_in_Project_Local_Scripts_on_Windows()
+ {
+ if (! RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ return;
+ }
+
+ var extensionList = new string[] { ".cmd", ".sh" };
+
+ var expectedExtension = ".cmd";
+
+ foreach (var extension in extensionList)
+ {
+ CreateTestFile("uniquescriptname" + extension, binTestProjectPath);
+ }
+
+ // Don't include extension
+ var scriptCommandLine = "uniquescriptname";
+
+ var command = ScriptExecutor.CreateCommandForScript(project, scriptCommandLine, new Dictionary());
+
+ command.Should().NotBeNull();
+ command.ResolutionStrategy.Should().Be(CommandResolutionStrategy.ProjectLocal);
+ command.CommandArgs.Should().Contain(scriptCommandLine + expectedExtension);
+ }
+
+ [Fact]
+ public void Test_Script_Exe_Files_Dont_Use_Cmd_or_Sh()
+ {
+ CreateTestFile("some.exe", binTestProjectPath);
+ var scriptCommandLine = "some.exe";
+
+ var command = ScriptExecutor.CreateCommandForScript(project, scriptCommandLine, new Dictionary());
+
+ command.Should().NotBeNull();
+ command.ResolutionStrategy.Should().Be(CommandResolutionStrategy.ProjectLocal);
+
+ Path.GetFileName(command.CommandName).Should().NotBe("cmd.exe");
+ Path.GetFileName(command.CommandName).Should().NotBe("sh");
+ }
+
+ [Fact]
+ public void Test_Script_Cmd_Files_Use_CmdExe()
+ {
+ if (! RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ return;
+ }
+
+ CreateTestFile("some.cmd", binTestProjectPath);
+ var scriptCommandLine = "some.cmd";
+
+ var command = ScriptExecutor.CreateCommandForScript(project, scriptCommandLine, new Dictionary());
+
+ command.Should().NotBeNull();
+ command.ResolutionStrategy.Should().Be(CommandResolutionStrategy.ProjectLocal);
+
+ Path.GetFileName(command.CommandName).Should().Be("cmd.exe");
+ }
+
+ [Fact]
+ public void Test_Script_Builtins_throws_CommandUnknownException()
+ {
+ var scriptCommandLine = "echo";
+
+ Action action = () => ScriptExecutor.CreateCommandForScript(project, scriptCommandLine, new Dictionary());
+ action.ShouldThrow();
+ }
+
+ private void CreateTestFile(string filename, string directory)
+ {
+ string path = Path.Combine(directory, filename);
+ File.WriteAllText(path, "echo hello");
+ }
+ }
+}
diff --git a/test/ScriptExecutorTests/ScriptExecutorTests.xproj b/test/ScriptExecutorTests/ScriptExecutorTests.xproj
new file mode 100644
index 000000000..8b66a40d6
--- /dev/null
+++ b/test/ScriptExecutorTests/ScriptExecutorTests.xproj
@@ -0,0 +1,19 @@
+
+
+
+ 14.0.23107
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ 833ffee1-7eed-4f51-8dfd-946d48833333
+ Microsoft.DotNet.Cli.Utils.ScriptExecutorTests
+ ..\..\artifacts\obj\$(MSBuildProjectName)
+ ..\..\artifacts\bin\$(MSBuildProjectName)\
+
+
+
+ 2.0
+
+
+
\ No newline at end of file
diff --git a/test/ScriptExecutorTests/project.json b/test/ScriptExecutorTests/project.json
new file mode 100644
index 000000000..22bda6b8e
--- /dev/null
+++ b/test/ScriptExecutorTests/project.json
@@ -0,0 +1,26 @@
+{
+ "version": "1.0.0-*",
+
+ "dependencies": {
+ "NETStandard.Library": "1.0.0-rc2-23805",
+
+ "Microsoft.DotNet.ProjectModel": { "target": "project" },
+ "Microsoft.DotNet.Cli.Utils": { "target": "project" },
+ "Microsoft.DotNet.Tools.Tests.Utilities": { "target": "project" },
+
+ "xunit": "2.1.0",
+ "dotnet-test-xunit": "1.0.0-dev-48273-16"
+ },
+
+ "frameworks": {
+ "dnxcore50": {
+ "imports": "portable-net45+win8"
+ }
+ },
+
+ "content": [
+ "../../TestAssets/TestProjects/TestApp/**/*"
+ ],
+
+ "testRunner": "xunit"
+}
diff --git a/test/dotnet-build.Tests/BuildProjectToProjectTests.cs b/test/dotnet-build.Tests/BuildProjectToProjectTests.cs
index 662b1e773..dacc29a28 100644
--- a/test/dotnet-build.Tests/BuildProjectToProjectTests.cs
+++ b/test/dotnet-build.Tests/BuildProjectToProjectTests.cs
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using FluentAssertions;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Test.Utilities;
using Xunit;
@@ -14,7 +15,7 @@ namespace Microsoft.DotNet.Tools.Builder.Tests
{
public class ProjectToProjectDependenciesIncrementalTest : IncrementalTestBase
{
- private string[] _projects = new[] { "L0", "L11", "L12", "L21", "L22" };
+ private readonly string[] _projects = new[] { "L0", "L11", "L12", "L21", "L22" };
private string MainProjectExe
{
@@ -58,6 +59,38 @@ namespace Microsoft.DotNet.Tools.Builder.Tests
AssertRebuilt(result3, expectedRebuiltProjects);
}
+ [Fact]
+ public void TestNoDependencyFlag()
+ {
+ var dependencies = new[] { "L11", "L12", "L21", "L22" };
+
+ // first clean build; all projects required compilation
+ var result1 = BuildProject();
+ AssertRebuilt(result1, _projects);
+
+ // modify the source code of a leaf dependency
+ TouchSourcesOfProject("L22");
+
+ // second build with no dependencies and no incremental; only the root rebuilds
+ var result2 = BuildProject(noDependencies: true, noIncremental: true);
+ result2.Should().StdOutMatchPattern("Compiling.*L0.*");
+
+ AssertResultDoesNotContainStrings(result2, dependencies);
+
+ // third build with no dependencies but incremental; nothing rebuilds
+ var result3 = BuildProject(noDependencies: true);
+ result3.Should().HaveSkippedProjectCompilation("L0");
+ AssertResultDoesNotContainStrings(result3, dependencies);
+ }
+
+ private static void AssertResultDoesNotContainStrings(CommandResult commandResult, string[] strings)
+ {
+ foreach (var s in strings)
+ {
+ commandResult.StdOut.Should().NotContain(s);
+ }
+ }
+
// compute A - B
private T[] SetDifference(T[] A, T[] B)
{
diff --git a/test/dotnet-build.Tests/IncrementalTestBase.cs b/test/dotnet-build.Tests/IncrementalTestBase.cs
index b4fce519a..ca202766e 100644
--- a/test/dotnet-build.Tests/IncrementalTestBase.cs
+++ b/test/dotnet-build.Tests/IncrementalTestBase.cs
@@ -58,15 +58,15 @@ namespace Microsoft.DotNet.Tools.Builder.Tests
File.SetLastWriteTimeUtc(file, DateTime.UtcNow);
}
- protected CommandResult BuildProject(bool noIncremental = false, bool expectBuildFailure = false)
+ protected CommandResult BuildProject(bool noDependencies = false, bool noIncremental = false, bool expectBuildFailure = false)
{
var mainProjectFile = GetProjectFile(MainProject);
return BuildProject(mainProjectFile, noIncremental, expectBuildFailure);
}
- protected CommandResult BuildProject(string projectFile, bool noIncremental = false, bool expectBuildFailure = false)
+ protected CommandResult BuildProject(string projectFile, bool noDependencies = false, bool noIncremental = false, bool expectBuildFailure = false)
{
- var buildCommand = new BuildCommand(projectFile, output: GetOutputDir(), framework: "dnxcore50", noIncremental: noIncremental);
+ var buildCommand = new BuildCommand(projectFile, output: GetOutputDir(), framework: "dnxcore50", noIncremental: noIncremental, noDependencies : noDependencies);
var result = buildCommand.ExecuteWithCapturedOutput();
if (!expectBuildFailure)
diff --git a/test/dotnet-compile.UnitTests/GivenACompilationDriver.cs b/test/dotnet-compile.UnitTests/GivenACompilationDriver.cs
new file mode 100644
index 000000000..b0724bd99
--- /dev/null
+++ b/test/dotnet-compile.UnitTests/GivenACompilationDriver.cs
@@ -0,0 +1,83 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using FluentAssertions;
+using Microsoft.DotNet.ProjectModel;
+using Microsoft.DotNet.Tools.Compiler;
+using Moq;
+using NuGet.Frameworks;
+using Xunit;
+
+namespace Microsoft.DotNet.Tools.Compiler.Tests
+{
+ public class GivenACompilationDriverController
+ {
+ private string _projectJson;
+ private Mock _managedCompilerMock;
+ private Mock _nativeCompilerMock;
+ private List _contexts;
+ private CompilerCommandApp _args;
+
+ public GivenACompilationDriverController()
+ {
+ _projectJson =
+ Path.Combine(AppContext.BaseDirectory, "TestAssets", "TestProjects", "TestApp", "project.json");
+ _managedCompilerMock = new Mock();
+ _managedCompilerMock.Setup(c => c
+ .Compile(It.IsAny(), It.IsAny()))
+ .Returns(true);
+ _nativeCompilerMock = new Mock();
+ _nativeCompilerMock.Setup(c => c
+ .Compile(It.IsAny(), It.IsAny()))
+ .Returns(true);
+
+ _contexts = new List
+ {
+ ProjectContext.Create(_projectJson, new NuGetFramework(string.Empty))
+ };
+
+ _args = new CompilerCommandApp("dotnet compile", ".NET Compiler", "Compiler for the .NET Platform");
+ }
+
+ [Fact]
+ public void It_compiles_all_project_contexts()
+ {
+ var compiledProjectContexts = new List();
+ _managedCompilerMock.Setup(c => c
+ .Compile(It.IsAny(), It.IsAny()))
+ .Callback((p, c) => compiledProjectContexts.Add(p))
+ .Returns(true);
+
+ var compilerController = new CompilationDriver(_managedCompilerMock.Object, _nativeCompilerMock.Object);
+
+ compilerController.Compile(_contexts, _args);
+
+ compiledProjectContexts.Should().BeEquivalentTo(_contexts);
+ }
+
+ [Fact]
+ public void It_does_not_compile_native_when_the_native_parameter_is_not_passed()
+ {
+ var compilerController = new CompilationDriver(_managedCompilerMock.Object, _nativeCompilerMock.Object);
+
+ compilerController.Compile(_contexts, _args);
+
+ _nativeCompilerMock.Verify(c => c.Compile(It.IsAny(), It.IsAny()), Times.Never);
+ }
+
+ [Fact]
+ public void It_does_compile_native_when_the_native_parameter_is_passed()
+ {
+ var compilerController = new CompilationDriver(_managedCompilerMock.Object, _nativeCompilerMock.Object);
+
+ _args.IsNativeValue = true;
+
+ compilerController.Compile(_contexts, _args);
+
+ _nativeCompilerMock.Verify(c => c.Compile(It.IsAny(), It.IsAny()), Times.Once);
+ }
+ }
+}
diff --git a/test/dotnet-compile.UnitTests/GivenThatICareAboutScriptVariablesFromAManagedCompiler.cs b/test/dotnet-compile.UnitTests/GivenThatICareAboutScriptVariablesFromAManagedCompiler.cs
new file mode 100644
index 000000000..bfb98b0b7
--- /dev/null
+++ b/test/dotnet-compile.UnitTests/GivenThatICareAboutScriptVariablesFromAManagedCompiler.cs
@@ -0,0 +1,242 @@
+// Copyright (c) .NET Foundation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Microsoft.DotNet.ProjectModel;
+using Moq;
+using NuGet.Frameworks;
+using Xunit;
+using Microsoft.DotNet.Cli.Utils;
+using FluentAssertions;
+using System.Linq;
+using Microsoft.Extensions.PlatformAbstractions;
+
+namespace Microsoft.DotNet.Tools.Compiler.Tests
+{
+ public class GivenThatICareAboutScriptVariablesFromAManagedCompiler : IClassFixture
+ {
+ private readonly ScriptVariablesFixture _fixture;
+
+ public GivenThatICareAboutScriptVariablesFromAManagedCompiler(ScriptVariablesFixture fixture)
+ {
+ _fixture = fixture;
+ }
+
+ [Fact]
+ public void It_passes_a_FullTargetFramework_variable_to_the_pre_compile_scripts()
+ {
+ _fixture.PreCompileScriptVariables.Should().ContainKey("compile:FullTargetFramework");
+ _fixture.PreCompileScriptVariables["compile:FullTargetFramework"].Should().Be("dnxcore,Version=v5.0");
+ }
+
+ [Fact]
+ public void It_passes_a_TargetFramework_variable_to_the_pre_compile_scripts()
+ {
+ _fixture.PreCompileScriptVariables.Should().ContainKey("compile:TargetFramework");
+ _fixture.PreCompileScriptVariables["compile:TargetFramework"].Should().Be("dnxcore50");
+ }
+
+ [Fact]
+ public void It_passes_a_Configuration_variable_to_the_pre_compile_scripts()
+ {
+ _fixture.PreCompileScriptVariables.Should().ContainKey("compile:Configuration");
+ _fixture.PreCompileScriptVariables["compile:Configuration"].Should().Be(
+ ScriptVariablesFixture.ConfigValue);
+ }
+
+ [Fact]
+ public void It_passes_a_OutputFile_variable_to_the_pre_compile_scripts()
+ {
+ _fixture.PreCompileScriptVariables.Should().ContainKey("compile:OutputFile");
+ _fixture.PreCompileScriptVariables["compile:OutputFile"].Should().Be(ScriptVariablesFixture.OutputFile);
+ }
+
+ [Fact]
+ public void It_passes_a_OutputDir_variable_to_the_pre_compile_scripts()
+ {
+ _fixture.PreCompileScriptVariables.Should().ContainKey("compile:OutputDir");
+ _fixture.PreCompileScriptVariables["compile:OutputDir"].Should().Be(ScriptVariablesFixture.OutputPath);
+ }
+
+ [Fact]
+ public void It_passes_a_ResponseFile_variable_to_the_pre_compile_scripts()
+ {
+ _fixture.PreCompileScriptVariables.Should().ContainKey("compile:ResponseFile");
+ _fixture.PreCompileScriptVariables["compile:ResponseFile"].Should().Be(ScriptVariablesFixture.ResponseFile);
+ }
+
+ [Fact]
+ public void It_does_not_pass_a_RuntimeOutputDir_variable_to_the_pre_compile_scripts_if_rid_is_not_set_in()
+ {
+ _fixture.PreCompileScriptVariables.Should().NotContainKey("compile:RuntimeOutputDir");
+ }
+
+ [Fact]
+ public void It_passes_a_RuntimeOutputDir_variable_to_the_pre_compile_scripts_if_rid_is_set_in_the_ProjectContext()
+ {
+ var rid = PlatformServices.Default.Runtime.GetLegacyRestoreRuntimeIdentifier();
+ var fixture = ScriptVariablesFixture.GetFixtureWithRids(rid);
+ fixture.PreCompileScriptVariables.Should().ContainKey("compile:RuntimeOutputDir");
+ fixture.PreCompileScriptVariables["compile:RuntimeOutputDir"].Should().Be(fixture.RuntimeOutputDir);
+ }
+
+ [Fact]
+ public void It_passes_a_FullTargetFramework_variable_to_the_post_compile_scripts()
+ {
+ _fixture.PostCompileScriptVariables.Should().ContainKey("compile:FullTargetFramework");
+ _fixture.PostCompileScriptVariables["compile:FullTargetFramework"].Should().Be("dnxcore,Version=v5.0");
+ }
+
+ [Fact]
+ public void It_passes_a_TargetFramework_variable_to_the_post_compile_scripts()
+ {
+ _fixture.PostCompileScriptVariables.Should().ContainKey("compile:TargetFramework");
+ _fixture.PostCompileScriptVariables["compile:TargetFramework"].Should().Be("dnxcore50");
+ }
+
+ [Fact]
+ public void It_passes_a_Configuration_variable_to_the_post_compile_scripts()
+ {
+ _fixture.PostCompileScriptVariables.Should().ContainKey("compile:Configuration");
+ _fixture.PostCompileScriptVariables["compile:Configuration"].Should().Be(
+ ScriptVariablesFixture.ConfigValue);
+ }
+
+ [Fact]
+ public void It_passes_a_OutputFile_variable_to_the_post_compile_scripts()
+ {
+ _fixture.PostCompileScriptVariables.Should().ContainKey("compile:OutputFile");
+ _fixture.PostCompileScriptVariables["compile:OutputFile"].Should().Be(ScriptVariablesFixture.OutputFile);
+ }
+
+ [Fact]
+ public void It_passes_a_OutputDir_variable_to_the_post_compile_scripts()
+ {
+ _fixture.PostCompileScriptVariables.Should().ContainKey("compile:OutputDir");
+ _fixture.PostCompileScriptVariables["compile:OutputDir"].Should().Be(ScriptVariablesFixture.OutputPath);
+ }
+
+ [Fact]
+ public void It_passes_a_ResponseFile_variable_to_the_post_compile_scripts()
+ {
+ _fixture.PostCompileScriptVariables.Should().ContainKey("compile:ResponseFile");
+ _fixture.PostCompileScriptVariables["compile:ResponseFile"].Should().Be(ScriptVariablesFixture.ResponseFile);
+ }
+
+ [Fact]
+ public void It_passes_a_CompilerExitCode_variable_to_the_post_compile_scripts()
+ {
+ _fixture.PostCompileScriptVariables.Should().ContainKey("compile:CompilerExitCode");
+ _fixture.PostCompileScriptVariables["compile:CompilerExitCode"].Should().Be("0");
+ }
+
+ [Fact]
+ public void It_does_not_pass_a_RuntimeOutputDir_variable_to_the_post_compile_scripts_if_rid_is_not_set_in_the_ProjectContext()
+ {
+ _fixture.PostCompileScriptVariables.Should().NotContainKey("compile:RuntimeOutputDir");
+ }
+
+ [Fact]
+ public void It_passes_a_RuntimeOutputDir_variable_to_the_post_compile_scripts_if_rid_is_set_in_the_ProjectContext()
+ {
+ var rid = PlatformServices.Default.Runtime.GetLegacyRestoreRuntimeIdentifier();
+ var fixture = ScriptVariablesFixture.GetFixtureWithRids(rid);
+ fixture.PostCompileScriptVariables.Should().ContainKey("compile:RuntimeOutputDir");
+ fixture.PostCompileScriptVariables["compile:RuntimeOutputDir"].Should().Be(fixture.RuntimeOutputDir);
+ }
+ }
+
+ public class ScriptVariablesFixture
+ {
+ public const string ConfigValue = "Debug";
+
+ public static string TestAssetPath = Path.Combine(
+ AppContext.BaseDirectory,
+ "TestAssets",
+ "TestProjects",
+ "TestApp");
+
+ public static string OutputPath = Path.Combine(
+ TestAssetPath,
+ "bin",
+ ConfigValue,
+ "dnxcore50");
+
+ public string RuntimeOutputDir { get; private set; }
+
+ public static string OutputFile = Path.Combine(OutputPath, "TestApp.dll");
+
+ public static string ResponseFile = Path.Combine(
+ TestAssetPath,
+ "obj",
+ ConfigValue,
+ "dnxcore50",
+ "dotnet-compile.rsp");
+
+ public Dictionary PreCompileScriptVariables { get; private set; }
+ public Dictionary PostCompileScriptVariables { get; private set; }
+
+ public ScriptVariablesFixture() : this(string.Empty)
+ {
+ }
+
+ private ScriptVariablesFixture(string rid)
+ {
+ var projectJson = Path.Combine(TestAssetPath, "project.json");
+ var command = new Mock();
+ command.Setup(c => c.Execute()).Returns(new CommandResult());
+ command.Setup(c => c.OnErrorLine(It.IsAny>())).Returns(() => command.Object);
+ command.Setup(c => c.OnOutputLine(It.IsAny>())).Returns(() => command.Object);
+ var commandFactory = new Mock();
+ commandFactory.Setup(c => c
+ .Create(
+ It.IsAny(),
+ It.IsAny>(),
+ It.IsAny()))
+ .Returns(command.Object);
+
+ var _args = new CompilerCommandApp("dotnet compile", ".NET Compiler", "Compiler for the .NET Platform");
+ _args.ConfigValue = ConfigValue;
+
+ PreCompileScriptVariables = new Dictionary();
+ PostCompileScriptVariables = new Dictionary();
+
+ var _scriptRunner = new Mock();
+ _scriptRunner.Setup(
+ s =>
+ s.RunScripts(It.IsAny(), It.IsAny(), It.IsAny>()))
+ .Callback>((p, n, v) =>
+ {
+ if (n.Equals(ScriptNames.PreCompile))
+ {
+ PreCompileScriptVariables = v;
+ }
+
+ if (n.Equals(ScriptNames.PostCompile))
+ {
+ PostCompileScriptVariables = v;
+ }
+ });
+
+ var managedCompiler = new ManagedCompiler(_scriptRunner.Object, commandFactory.Object);
+
+ var rids = new List();
+ if (!string.IsNullOrEmpty(rid))
+ {
+ rids.Add(rid);
+ }
+
+ var context = ProjectContext.Create(projectJson, new NuGetFramework("dnxcore", new Version(5, 0)), rids);
+ managedCompiler.Compile(context, _args);
+
+ RuntimeOutputDir = Path.Combine(OutputPath, rid);
+ }
+
+ public static ScriptVariablesFixture GetFixtureWithRids(string rid)
+ {
+ return new ScriptVariablesFixture(rid);
+ }
+ }
+}
diff --git a/test/dotnet-compile.UnitTests/dotnet-compile.UnitTests.xproj b/test/dotnet-compile.UnitTests/dotnet-compile.UnitTests.xproj
new file mode 100644
index 000000000..f2b743757
--- /dev/null
+++ b/test/dotnet-compile.UnitTests/dotnet-compile.UnitTests.xproj
@@ -0,0 +1,19 @@
+
+
+
+ 14.0.24720
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ 920b71d8-62da-4f5e-8a26-926c113f1d97
+ dotnet-compile.UnitTests
+ ..\..\artifacts\obj\$(MSBuildProjectName)
+ ..\..\artifacts\bin\$(MSBuildProjectName)\
+
+
+
+ 2.0
+
+
+
\ No newline at end of file
diff --git a/test/dotnet-compile.UnitTests/project.json b/test/dotnet-compile.UnitTests/project.json
new file mode 100644
index 000000000..3ecadbe2d
--- /dev/null
+++ b/test/dotnet-compile.UnitTests/project.json
@@ -0,0 +1,34 @@
+{
+ "version": "1.0.0-*",
+
+ "dependencies": {
+ "NETStandard.Library": "1.0.0-rc2-23811",
+
+ "Microsoft.DotNet.Cli.Utils": {
+ "target": "project",
+ "type": "build"
+ },
+
+ "dotnet": { "target": "project" },
+ "Microsoft.DotNet.ProjectModel": { "target": "project" },
+
+ "xunit": "2.1.0",
+ "dotnet-test-xunit": "1.0.0-dev-48273-16",
+ "moq.netcore": "4.4.0-beta8",
+ "FluentAssertions": "4.2.2"
+ },
+
+ "frameworks": {
+ "dnxcore50": {
+ "imports": "portable-net451+win8"
+ }
+ },
+
+ "content": [
+ "../../TestAssets/TestProjects/TestLibrary/*",
+ "../../TestAssets/TestProjects/TestApp/*",
+ "../../TestAssets/TestProjects/global.json"
+ ],
+
+ "testRunner": "xunit"
+}
diff --git a/test/dotnet-publish.Tests/Microsoft.DotNet.Tools.Publish.Tests.cs b/test/dotnet-publish.Tests/Microsoft.DotNet.Tools.Publish.Tests.cs
index 7972f7a91..9ab89cc6c 100644
--- a/test/dotnet-publish.Tests/Microsoft.DotNet.Tools.Publish.Tests.cs
+++ b/test/dotnet-publish.Tests/Microsoft.DotNet.Tools.Publish.Tests.cs
@@ -177,14 +177,13 @@ namespace Microsoft.DotNet.Tools.Publish.Tests
}
[Fact]
- [ActiveIssue(982)]
public void PublishScriptsRun()
{
- TestInstance instance = TestAssetsManager.CreateTestInstance("TestAppWithLibrary")
+ TestInstance instance = TestAssetsManager.CreateTestInstance("TestAppWithScripts")
.WithLockFiles()
.WithBuildArtifacts();
- var testProject = _getProjectJson(instance.TestRoot, "TestApp");
+ var testProject = _getProjectJson(instance.TestRoot, "TestAppWithScripts");
var publishCommand = new PublishCommand(testProject);
var result = publishCommand.ExecuteWithCapturedOutput();