Merge pull request #3911 from eerhardt/msbuild-E2E

MSBuild end to end
This commit is contained in:
Eric Erhardt 2016-07-22 18:49:22 -05:00 committed by GitHub
commit fd8bbdcb63
29 changed files with 789 additions and 65 deletions

View file

@ -147,6 +147,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{FF498306-2
build\test\TestPackageProjects.props = build\test\TestPackageProjects.props
EndProjectSection
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Core.Build.Tasks", "src\Microsoft.DotNet.Core.Build.Tasks\Microsoft.DotNet.Core.Build.Tasks.xproj", "{E8E7D24B-4830-4662-80A8-255D6FE3B0BE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -895,6 +897,22 @@ Global
{49D7318E-D198-4E2B-BBEA-3A24D805F88D}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{49D7318E-D198-4E2B-BBEA-3A24D805F88D}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{49D7318E-D198-4E2B-BBEA-3A24D805F88D}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
{E8E7D24B-4830-4662-80A8-255D6FE3B0BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E8E7D24B-4830-4662-80A8-255D6FE3B0BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E8E7D24B-4830-4662-80A8-255D6FE3B0BE}.Debug|x64.ActiveCfg = Debug|Any CPU
{E8E7D24B-4830-4662-80A8-255D6FE3B0BE}.Debug|x64.Build.0 = Debug|Any CPU
{E8E7D24B-4830-4662-80A8-255D6FE3B0BE}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
{E8E7D24B-4830-4662-80A8-255D6FE3B0BE}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
{E8E7D24B-4830-4662-80A8-255D6FE3B0BE}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
{E8E7D24B-4830-4662-80A8-255D6FE3B0BE}.MinSizeRel|x64.Build.0 = Debug|Any CPU
{E8E7D24B-4830-4662-80A8-255D6FE3B0BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E8E7D24B-4830-4662-80A8-255D6FE3B0BE}.Release|Any CPU.Build.0 = Release|Any CPU
{E8E7D24B-4830-4662-80A8-255D6FE3B0BE}.Release|x64.ActiveCfg = Release|Any CPU
{E8E7D24B-4830-4662-80A8-255D6FE3B0BE}.Release|x64.Build.0 = Release|Any CPU
{E8E7D24B-4830-4662-80A8-255D6FE3B0BE}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
{E8E7D24B-4830-4662-80A8-255D6FE3B0BE}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
{E8E7D24B-4830-4662-80A8-255D6FE3B0BE}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
{E8E7D24B-4830-4662-80A8-255D6FE3B0BE}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -954,5 +972,6 @@ Global
{FD7D515A-D10F-4F49-B8AE-21CF7ED071AE} = {89905EC4-BC0F-443B-8ADF-691321F10108}
{8E3354BD-827F-41B7-9EE6-6BE1F1EDD8E9} = {89905EC4-BC0F-443B-8ADF-691321F10108}
{FF498306-2DE2-47F6-8C35-3CF0589CF2B8} = {89905EC4-BC0F-443B-8ADF-691321F10108}
{E8E7D24B-4830-4662-80A8-255D6FE3B0BE} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F}
EndGlobalSection
EndGlobal

View file

@ -1,44 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft.NuGet.props" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x64</Platform>
<PlatformTarget Condition=" '$(PlatformTarget)' == '' ">x64</PlatformTarget>
<OutputType>Exe</OutputType>
<RootNamespace>MSBuildTestApp</RootNamespace>
<AssemblyName>$(MSBuildThisFileName)</AssemblyName>
<TargetFrameworkIdentifier>NETCoreApp</TargetFrameworkIdentifier>
<TargetFrameworkIdentifier>.NETCoreApp</TargetFrameworkIdentifier>
<TargetFrameworkVersion>v1.0</TargetFrameworkVersion>
<OutputPath>bin\$(Configuration)\netcoreapp1.0</OutputPath>
<AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<NoStdLib>true</NoStdLib>
<NoLogo>true</NoLogo> <!-- Temp Hack: https://github.com/dotnet/roslyn/issues/12167 -->
<NuGetTargetMoniker>.NETCoreApp,Version=v1.0</NuGetTargetMoniker>
<!-- Temp Hack: Being passed through from cli, where should this come from? -->
<BaseNuGetRuntimeIdentifier Condition=" '$(BaseNuGetRuntimeIdentifier)' == '' ">win7</BaseNuGetRuntimeIdentifier>
<DebugSymbols>false</DebugSymbols>
<DebugType>none</DebugType>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" />
<None Include="project.json" />
</ItemGroup>
<PropertyGroup>
<!-- Temp Hack: https://github.com/Microsoft/msbuild/issues/720 -->
<OverrideToolHost Condition=" '$(DotnetHostPath)' != '' and '$(OverrideToolHost)' == ''">$(DotnetHostPath)</OverrideToolHost>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft.NuGet.targets" />
<!-- Temporary Hack, this should happen in build -->
<Target Name="AfterBuild">
<Move SourceFiles="$(TargetPath)" DestinationFiles="$(TargetDir)\$(AssemblyName).dll" />
<Copy SourceFiles="$(DotnetHostPath)" DestinationFiles="$(TargetPath)" />
</Target>
</Project>

View file

@ -3,7 +3,8 @@
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.0"
"version": "1.0.0",
"type": "platform"
}
}
}

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="Local" value="Packages" />

View file

@ -31,10 +31,14 @@
<SdkDebianIntermediateDirectory>$(IntermediateDirectory)/debian/sdk</SdkDebianIntermediateDirectory>
<DebianTestResultsXmlFile>$(SdkDebianIntermediateDirectory)/debian-testResults.xml</DebianTestResultsXmlFile>
<DebianInstalledDotnet>/usr/share/dotnet/dotnet</DebianInstalledDotnet>
<DebianInstalledDirectory>/usr/share/dotnet</DebianInstalledDirectory>
<EndToEndTestDirectory>$(RepoRoot)/test/EndToEnd</EndToEndTestDirectory>
</PropertyGroup>
<ItemGroup>
<TestSdkDebTaskEnvironmentVariables Include="PATH=$(DebianInstalledDirectory)$(PathListSeparator)$(PATH)" />
</ItemGroup>
<!-- Consumed By Publish -->
<ItemGroup>
<GeneratedInstallers Include="$(SdkInstallerFile)" />
@ -89,8 +93,10 @@
<Exec Command="sudo dpkg -i $(SdkInstallerFile)" />
<!-- Run E2E -->
<Exec Command="$(DebianInstalledDotnet) test -xml $(DebianTestResultsXmlFile)"
WorkingDirectory="$(EndToEndTestDirectory)" />
<DotNetTest WorkingDirectory="$(EndToEndTestDirectory)"
EnvironmentVariables="@(TestSdkDebTaskEnvironmentVariables)"
ToolPath="$(DebianInstalledDirectory)"
Xml="$(DebianTestResultsXmlFile)" />
<!-- Remove Packages -->
<Exec Command="sudo dpkg -r $(SdkDebianPackageName)" />

View file

@ -97,9 +97,9 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
{
WriteDepsFileAndCopyProjectDependencies(_exporter);
var emitEntryPoint = _compilerOptions.EmitEntryPoint ?? false;
var isRunnable = _compilerOptions.EmitEntryPoint ?? _context.ProjectFile.OverrideIsRunnable;
if (emitEntryPoint && !_context.IsPortable)
if (isRunnable && !_context.IsPortable)
{
// TODO: Pick a host based on the RID
VerifyCoreClrPresenceInPackageGraph();

View file

@ -0,0 +1,89 @@
// 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.Linq;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Microsoft.DotNet.Cli.Compiler.Common;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.InternalAbstractions;
using Microsoft.DotNet.ProjectModel;
using Microsoft.DotNet.ProjectModel.Compilation;
using NuGet.Frameworks;
namespace Microsoft.DotNet.Cli.Tasks
{
public class MakeNetCoreRunnable : Task
{
[Required]
public string ProjectPath { get; set; }
[Required]
public string Configuration { get; set; }
[Required]
public string OutputPath { get; set; }
[Required]
public string OutputType { get; set; }
public string Runtime { get; set; }
private bool HasRuntimeOutput
{
get { return string.Equals("Exe", OutputType, StringComparison.OrdinalIgnoreCase); }
}
public override bool Execute()
{
BuildWorkspace workspace = BuildWorkspace.Create();
string framework = null; //TODO: should we take a NuGet framework ?
IEnumerable<ProjectContext> projectContexts = GetProjectContexts(workspace,
framework == null ? null : NuGetFramework.Parse(framework),
Runtime);
if (!projectContexts.Any())
{
Log.LogError($"'{ProjectPath}' cannot be made runnable for '{framework ?? "<no framework provided>"}' '{Runtime ?? "<no runtime provided>"}'");
return false;
}
foreach (ProjectContext projectContext in projectContexts)
{
string buildBasePath = null; // TODO: Is there an "Intermediate Directory" property we can take?
projectContext.ProjectFile.OverrideIsRunnable = HasRuntimeOutput;
OutputPaths outputPaths = projectContext.GetOutputPaths(Configuration, buildBasePath, OutputPath);
LibraryExporter libraryExporter = projectContext.CreateExporter(Configuration, buildBasePath);
Executable executable = new Executable(projectContext, outputPaths, libraryExporter, Configuration);
executable.MakeCompilationOutputRunnable();
}
return true;
}
private IEnumerable<ProjectContext> GetProjectContexts(BuildWorkspace workspace, NuGetFramework framework, string runtime)
{
var contexts = workspace.GetProjectContextCollection(ProjectPath)
.EnsureValid(ProjectPath)
.FrameworkOnlyContexts;
contexts = framework == null ?
contexts :
contexts.Where(c => Equals(c.TargetFramework, framework));
var rids = string.IsNullOrEmpty(runtime) ?
RuntimeEnvironmentRidExtensions.GetAllCandidateRuntimeIdentifiers() :
new[] { runtime };
return contexts.Select(c => workspace.GetRuntimeContext(c, rids));
}
}
}

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0.25420" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25420</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>e8e7d24b-4830-4662-80a8-255d6fe3b0be</ProjectGuid>
<RootNamespace>Microsoft.DotNet.Core.Build.Tasks</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View file

@ -0,0 +1,34 @@
{
"version": "1.0.0-preview3-*",
"buildOptions": {
"keyFile": "../../tools/Key.snk",
"warningsAsErrors": true
},
"dependencies": {
"Microsoft.DotNet.Compiler.Common": {
"target": "project"
}
},
"frameworks": {
"net451": {
"frameworkAssemblies": {
"Microsoft.Build.Utilities.v4.0": {
"type": "build"
},
"Microsoft.Build.Framework": {
"type": "build"
}
}
},
"netstandard1.6": {
"imports": [
"portable-net45+wp80+win8+wpa81+dnxcore50"
],
"dependencies": {
"Microsoft.Build.Framework": "0.1.0-preview-00024-160610",
"Microsoft.Build.Tasks.Core": "0.1.0-preview-00024-160610",
"Microsoft.Build.Utilities.Core": "0.1.0-preview-00024-160610"
}
}
}
}

View file

@ -84,6 +84,8 @@ namespace Microsoft.DotNet.ProjectModel
public bool IsTestProject => !string.IsNullOrEmpty(TestRunner);
public bool OverrideIsRunnable { get; set; }
public IEnumerable<TargetFrameworkInformation> GetTargetFrameworks()
{
return _targetFrameworks.Values;
@ -128,7 +130,7 @@ namespace Microsoft.DotNet.ProjectModel
var compilerOptions = GetCompilerOptions(targetFramework: null, configurationName: configuration);
// TODO: Make this opt in via another mechanism
return compilerOptions.EmitEntryPoint.GetValueOrDefault() || IsTestProject;
return compilerOptions.EmitEntryPoint.GetValueOrDefault() || IsTestProject || OverrideIsRunnable;
}
private CommonCompilerOptions GetCompilerOptions()

View file

@ -0,0 +1,17 @@
<!--
***********************************************************************************************
Microsoft.NETCore.ImportBefore.props
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
created a backup copy. Incorrect changes to this file will make it
impossible to load or build your projects from the command-line or the IDE.
Copyright (c) .NET Foundation. All rights reserved.
***********************************************************************************************
-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<NETCoreProps Condition="'$(NETCoreProps)'==''">$(MSBuildExtensionsPath)\Microsoft.DotNet.Core.Sdk.props</NETCoreProps>
</PropertyGroup>
<Import Condition="Exists('$(NETCoreProps)')" Project="$(NETCoreProps)" />
</Project>

View file

@ -0,0 +1,17 @@
<!--
***********************************************************************************************
Microsoft.NETCore.ImportAfter.targets
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
created a backup copy. Incorrect changes to this file will make it
impossible to load or build your projects from the command-line or the IDE.
Copyright (c) .NET Foundation. All rights reserved.
***********************************************************************************************
-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<NETCoreTargets Condition="'$(NETCoreTargets)'==''">$(MSBuildExtensionsPath)\Microsoft.DotNet.Core.Sdk.targets</NETCoreTargets>
</PropertyGroup>
<Import Condition="Exists('$(NETCoreTargets)')" Project="$(NETCoreTargets)" />
</Project>

View file

@ -0,0 +1,69 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
</PropertyGroup>
<!-- User-facing configuration-agnostic defaults -->
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform>AnyCPU</Platform>
<FileAlignment>512</FileAlignment>
<GlobalExclude>bin\**;obj\**;</GlobalExclude>
</PropertyGroup>
<!-- User-facing configuration-specific defaults -->
<PropertyGroup>
<!-- TODO: This property can't be set in the CLI since ResolveNuGetPackageAssets needs an exact RID from the project.json, and the RID is made up of the PlatformTarget -->
<!--<PlatformTarget>AnyCPU</PlatformTarget>-->
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoWarn>$(NoWarn);1701</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
<!-- Default settings for .NET Core build logic -->
<PropertyGroup>
<GenerateDependencyFile Condition=" '$(GenerateDependencyFile)' == '' ">true</GenerateDependencyFile>
<GenerateRuntimeConfigurationFiles Condition=" '$(GenerateRuntimeConfigurationFiles)' == '' ">true</GenerateRuntimeConfigurationFiles>
<!-- This will turn off the base 'ResolveNuGetPackages' target since it is UWP specific, and .NET Core needs it to be split up -->
<!--<ResolveNuGetPackages>false</ResolveNuGetPackages>-->
</PropertyGroup>
<PropertyGroup>
<NoStdLib>true</NoStdLib>
<!-- TODO: Need to figure out runtimes -->
<!-- TODO: Below are hacks eerhardt made on top of davkean's .props file -->
<!-- Temp Hack: davkean had this, but that casues all references not to be copied to output dir:
<CopyNuGetImplementations>false</CopyNuGetImplementations>
This will be set to false during "build", but set to true during "publish"
-->
<!-- Temp Hack: https://github.com/dotnet/roslyn/issues/12167 -->
<NoLogo>true</NoLogo>
<!-- Need to revisit this and see if this is the correct default for both Debug and Release -->
<DebugType>portable</DebugType>
<!-- Temp Hack: https://github.com/Microsoft/msbuild/issues/720 -->
<OverrideToolHost Condition=" '$(DotnetHostPath)' != '' and '$(OverrideToolHost)' == ''">$(DotnetHostPath)</OverrideToolHost>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,100 @@
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MicrosoftDotNetCoreBuildTasksDirectoryRoot>$(MSBuildThisFileDirectory)../../lib/</MicrosoftDotNetCoreBuildTasksDirectoryRoot>
<MicrosoftDotNetCoreBuildTasksTFM Condition=" '$(MSBuildRuntimeType)' == 'Core'">netstandard1.6</MicrosoftDotNetCoreBuildTasksTFM>
<MicrosoftDotNetCoreBuildTasksTFM Condition=" '$(MicrosoftDotNetCoreBuildTasksTFM)' == ''">net451</MicrosoftDotNetCoreBuildTasksTFM>
<MicrosoftDotNetCoreBuildTasksDirectory>$(MicrosoftDotNetCoreBuildTasksDirectoryRoot)$(MicrosoftDotNetCoreBuildTasksTFM)/</MicrosoftDotNetCoreBuildTasksDirectory>
<!-- If the build task directory doesn't exist (since we aren't in a NuGet package), load the task assembly in the tools path -->
<MicrosoftDotNetCoreBuildTasksDirectory Condition=" !Exists('$(MicrosoftDotNetCoreBuildTasksDirectory)') ">$(MSBuildToolsPath)/</MicrosoftDotNetCoreBuildTasksDirectory>
</PropertyGroup>
<PropertyGroup>
<!-- We don't use any of MSBuild's resolution logic for resolving the framework, so just set these two
properties to any folder that exists to skip the GetReferenceAssemblyPaths task (not target) and
to prevent it from outputting a warning (MSB3644).
-->
<_TargetFrameworkDirectories>$(MSBuildThisFileDirectory)</_TargetFrameworkDirectories>
<_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory)</_FullFrameworkReferenceAssemblyPaths>
</PropertyGroup>
<UsingTask TaskName="MakeNetCoreRunnable" AssemblyFile="$(MicrosoftDotNetCoreBuildTasksDirectory)Microsoft.DotNet.Core.Build.Tasks.dll" />
<PropertyGroup>
<CoreBuildDependsOn>
$(CoreBuildDependsOn);
GenerateDependencyFile;
GenerateRuntimeConfigurationFiles
</CoreBuildDependsOn>
</PropertyGroup>
<Target Name="GenerateDependencyFile"
Condition=" '$(GenerateDependencyFile)' == 'true'">
<!--
TODO: Is this the best way? Should we just tell CSC to output $(AssemblyName).dll directly?
-->
<Move SourceFiles="$(TargetPath)" DestinationFiles="$(TargetDir)/$(AssemblyName).dll" />
<!--
TODO: need to remove ProjectPath (to load up the project.json) and instead pass @(PackageDependency)
-->
<MakeNetCoreRunnable ProjectPath="$(MSBuildProjectDirectory)"
Configuration="$(Configuration)"
OutputPath="$(OutDir)"
OutputType="$(OutputType)" />
</Target>
<Target Name="GenerateRuntimeConfigurationFiles"
Condition=" '$(GenerateRuntimeConfigurationFiles)' == 'true'">
<!-- TODO: Split up MakeNetCoreRunnable and implement this target-->
<!-- Putting this here to show the structure that we should use in production -->
</Target>
<!--
============================================================
GetRunInformation
Returns the ProcessStart information that can be used to run this project.
============================================================
-->
<Target Name="GetRunInformation"
DependsOnTargets="GenerateRunInformation"
Outputs="@(RunInformation)" />
<Target Name="GenerateRunInformation">
<ItemGroup>
<RunInformation Include="$(MSBuildProjectFullPath)">
<!-- TODO: Need to get the Muxer path from MSBuild -->
<CommandName>dotnet</CommandName>
<Args>exec;$(TargetDir)/$(AssemblyName).dll</Args>
</RunInformation>
</ItemGroup>
</Target>
<!--
============================================================
Publish
Override the "in-box" publish, which is very ClickOnce centric.
============================================================
-->
<PropertyGroup>
<PublishDependsOn>
Build;
CopyPublishArtifacts
</PublishDependsOn>
<PublishDir Condition=" '$(PublishDir)' == '' ">$(OutDir)publish\</PublishDir>
</PropertyGroup>
<Target
Name="Publish"
DependsOnTargets="$(PublishDependsOn)" />
<Target Name="CopyPublishArtifacts">
<Message Text="TODO: Implement CopyPublishArtifacts" />
</Target>
</Project>

View file

@ -36,7 +36,8 @@ namespace Microsoft.DotNet.Cli
["restore"] = RestoreCommand.Run,
["run"] = RunCommand.Run,
["test"] = TestCommand.Run,
["build3"] = Build3Command.Run
["build3"] = Build3Command.Run,
["run3"] = Run3Command.Run
};
public static int Main(string[] args)

View file

@ -0,0 +1,17 @@
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworkIdentifier>.NETCoreApp</TargetFrameworkIdentifier>
<TargetFrameworkVersion>v1.0</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" Exclude="$(GlobalExclude)" />
<EmbeddedResource Include="**\*.resx" Exclude="$(GlobalExclude)" />
<None Include="project.json" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -0,0 +1,12 @@
using System;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}

View file

@ -0,0 +1,16 @@
{
"dependencies": {},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
}
}
}
},
"runtimes": {
"$currentruntime$": {}
}
}

View file

@ -1,14 +1,15 @@
// 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.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.IO.Compression;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.InternalAbstractions;
namespace Microsoft.DotNet.Tools.New
{
@ -64,11 +65,12 @@ namespace Microsoft.DotNet.Tools.New
}
}
archive.ExtractToDirectory(Directory.GetCurrentDirectory());
string projectDirectory = Directory.GetCurrentDirectory();
File.Move(
Path.Combine(Directory.GetCurrentDirectory(), "project.json.template"),
Path.Combine(Directory.GetCurrentDirectory(), "project.json"));
archive.ExtractToDirectory(projectDirectory);
ReplaceProjectJsonTemplateValues(projectDirectory);
ReplaceFileTemplateNames(projectDirectory);
}
catch (IOException ex)
{
@ -89,6 +91,40 @@ namespace Microsoft.DotNet.Tools.New
return 0;
}
private static void ReplaceProjectJsonTemplateValues(string projectDirectory)
{
string projectJsonFile = Path.Combine(projectDirectory, "project.json");
File.Move(
Path.Combine(projectDirectory, "project.json.template"),
projectJsonFile);
string originalProjectJsonText = File.ReadAllText(projectJsonFile);
string replacedProjectJsonText = originalProjectJsonText
.Replace("$currentruntime$", RuntimeEnvironment.GetRuntimeIdentifier());
if (replacedProjectJsonText != originalProjectJsonText)
{
File.WriteAllText(projectJsonFile, replacedProjectJsonText);
}
}
private static void ReplaceFileTemplateNames(string projectDirectory)
{
string projectName = new DirectoryInfo(projectDirectory).Name;
foreach (string file in Directory.GetFiles(projectDirectory, "*", SearchOption.AllDirectories))
{
if (Path.GetFileNameWithoutExtension(file) == "$projectName$")
{
string extension = Path.GetExtension(file);
File.Move(
file,
Path.Combine(Path.GetDirectoryName(file), $"{projectName}{extension}"));
}
}
}
public static int Run(string[] args)
{
DebugHelper.HandleDebugSwitch(ref args);
@ -99,7 +135,7 @@ namespace Microsoft.DotNet.Tools.New
app.Description = "Initializes empty project for .NET Platform";
app.HelpOption("-h|--help");
var csharp = new { Name = "C#", Alias = new[] { "c#", "cs", "csharp" }, TemplatePrefix = "CSharp", Templates = new[] { "Console", "Web", "Lib", "xunittest" } };
var csharp = new { Name = "C#", Alias = new[] { "c#", "cs", "csharp" }, TemplatePrefix = "CSharp", Templates = new[] { "Console", "Web", "Lib", "xunittest", "MSBuild" } };
var fsharp = new { Name = "F#", Alias = new[] { "f#", "fs", "fsharp" }, TemplatePrefix = "FSharp", Templates = new[] { "Console", "Lib" } };
var languages = new[] { csharp, fsharp };

View file

@ -12,7 +12,6 @@ using Microsoft.DotNet.InternalAbstractions;
using Microsoft.DotNet.ProjectModel;
using Microsoft.DotNet.ProjectModel.Compilation;
using Microsoft.DotNet.ProjectModel.Files;
using Microsoft.DotNet.ProjectModel.Graph;
using Microsoft.DotNet.ProjectModel.Utilities;
using Microsoft.DotNet.Tools.Common;
using NuGet.Frameworks;
@ -341,16 +340,6 @@ namespace Microsoft.DotNet.Tools.Publish
Reporter.Verbose.WriteLine($"failed to resolve published host in: {outputPath}");
return null;
}
private static void PublishFiles(IEnumerable<string> files, string outputPath)
{
foreach (var file in files)
{
var targetPath = Path.Combine(outputPath, Path.GetFileName(file));
File.Copy(file, targetPath, overwrite: true);
}
}
private void PublishAssetGroups(IEnumerable<LibraryAssetGroup> groups, string outputPath, bool nativeSubdirectories, bool includeRuntimeGroups)
{
foreach (var group in groups.Where(g => includeRuntimeGroups || string.IsNullOrEmpty(g.Runtime)))

View file

@ -0,0 +1,60 @@
// 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 Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Tools.Run
{
public partial class Run3Command
{
public static int Run(string[] args)
{
DebugHelper.HandleDebugSwitch(ref args);
CommandLineApplication app = new CommandLineApplication(throwOnUnexpectedArg: false);
app.Name = "dotnet run3";
app.FullName = ".NET Run3 Command";
app.Description = "Command used to run .NET apps";
app.HandleResponseFiles = true;
app.AllowArgumentSeparator = true;
app.HelpOption("-h|--help");
CommandOption configuration = app.Option("-c|--configuration", "Configuration under which to build", CommandOptionType.SingleValue);
CommandOption project = app.Option("-p|--project", "The path to the project file to run (defaults to the current directory if there is only one project).", CommandOptionType.SingleValue);
app.OnExecute(() =>
{
Run3Command runCmd = new Run3Command();
runCmd.Configuration = configuration.Value();
runCmd.Project = project.Value();
runCmd.Args = app.RemainingArguments;
return runCmd.Start();
});
try
{
return app.Execute(args);
}
catch (Exception ex)
{
#if DEBUG
Reporter.Error.WriteLine(ex.ToString());
#else
if (Reporter.IsVerbose)
{
Reporter.Error.WriteLine(ex.ToString());
}
else
{
Reporter.Error.WriteLine(ex.Message);
}
#endif
return 1;
}
}
}
}

View file

@ -0,0 +1,132 @@
// 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 System.Linq;
using Microsoft.Build.Execution;
using Microsoft.Build.Framework;
using Microsoft.DotNet.Cli.Utils;
using NuGet.Frameworks;
namespace Microsoft.DotNet.Tools.Run
{
public partial class Run3Command
{
private const string GetRunInformationTaskName = "GetRunInformation";
public string Configuration { get; set; }
public string Project { get; set; }
public IReadOnlyList<string> Args { get; set; }
private readonly ICommandFactory _commandFactory;
private List<string> _args;
public Run3Command()
: this(new RunCommandFactory())
{
}
public Run3Command(ICommandFactory commandFactory)
{
_commandFactory = commandFactory;
}
public int Start()
{
Initialize();
ITaskItem runInfoItem = GetRunInformation();
string commandName = runInfoItem.GetMetadata("CommandName");
string[] args = runInfoItem.GetMetadata("Args").Split(';');
ICommand command = _commandFactory.Create(commandName, Enumerable.Concat(args, _args));
return command
.Execute()
.ExitCode;
}
private ITaskItem GetRunInformation()
{
Dictionary<string, string> globalProperties = new Dictionary<string, string>()
{
{ "MSBuildExtensionsPath", AppContext.BaseDirectory }
};
if (!string.IsNullOrWhiteSpace(Configuration))
{
globalProperties.Add("Configuration", Configuration);
}
ProjectInstance projectInstance = new ProjectInstance(Project, globalProperties, null);
BuildRequestData buildRequestData = new BuildRequestData(projectInstance, new string[] { GetRunInformationTaskName });
BuildParameters buildParameters = new BuildParameters();
BuildResult result = BuildManager.DefaultBuildManager.Build(buildParameters, buildRequestData);
TargetResult runInfoResult;
if (!result.ResultsByTarget.TryGetValue(GetRunInformationTaskName, out runInfoResult))
{
throw new InvalidOperationException($"Could not find a target named '{GetRunInformationTaskName}' in your project. Please ensure 'dotnet run' supports this project.");
}
if (runInfoResult.ResultCode != TargetResultCode.Success)
{
throw new InvalidOperationException($"Could not get the run information for project {Project}. An internal MSBuild error has occured" + Environment.NewLine +
runInfoResult.Exception?.ToString());
}
ITaskItem runInfoItem = runInfoResult.Items.FirstOrDefault(i => i.ItemSpec == projectInstance.FullPath);
if (runInfoItem == null)
{
throw new InvalidOperationException($"'{GetRunInformationTaskName}' did not return an ITaskItem with the project's FullPath as the ItemSpec.");
}
return runInfoItem;
}
private void Initialize()
{
if (string.IsNullOrWhiteSpace(Project))
{
string directory = Directory.GetCurrentDirectory();
string[] projectFiles = Directory.GetFiles(directory, "*.*proj");
if (projectFiles.Length == 0)
{
throw new InvalidOperationException(
$"Couldn't find a project to run. Ensure a project exists in {directory}." + Environment.NewLine +
"Or pass the path to the project using --project");
}
else if (projectFiles.Length > 1)
{
throw new InvalidOperationException(
$"Specify which project file to use because this '{directory}' contains more than one project file.");
}
Project = projectFiles[0];
}
if (Args == null)
{
_args = new List<string>();
}
else
{
_args = new List<string>(Args);
}
}
private class RunCommandFactory : ICommandFactory
{
public ICommand Create(string commandName, IEnumerable<string> args, NuGetFramework framework = null, string configuration = Constants.DefaultConfiguration)
{
return Command.Create(commandName, args, framework, configuration);
}
}
}
}

View file

@ -6,6 +6,7 @@
"include": [
"commands/dotnet-new/CSharp_Console.zip",
"commands/dotnet-new/CSharp_Lib.zip",
"commands/dotnet-new/CSharp_MSBuild.zip",
"commands/dotnet-new/CSharp_xunittest.zip",
"commands/dotnet-new/CSharp_Web.zip",
"commands/dotnet-new/FSharp_Console.zip",
@ -18,13 +19,18 @@
"commands/dotnet-new/FSharp_Console/**",
"commands/dotnet-new/CSharp_Web/**",
"commands/dotnet-new/CSharp_Lib/**",
"commands/dotnet-new/CSharp_MSBuild/**",
"commands/dotnet-new/FSharp_Lib/**",
"commands/dotnet-new/CSharp_xunittest/**"
]
}
},
"publishOptions": {
"include": "14.1/**"
"include": [
"14.1/**",
"*.props",
"*.targets"
]
},
"dependencies": {
"NuGet.Commands": {
@ -75,7 +81,11 @@
"Microsoft.Net.Compilers.Targets.NetCore": "0.1.5-dev",
"Microsoft.Cci": "4.0.0-rc3-24128-00",
"Microsoft.Composition": "1.0.30",
"Microsoft.NuGet.Build.Tasks": "1.0.0-alpha-000001"
"Microsoft.NuGet.Build.Tasks": "1.0.0-alpha-000001",
"Microsoft.DotNet.Core.Build.Tasks": {
"target": "project"
}
},
"frameworks": {
"netcoreapp1.0": {

View file

@ -0,0 +1,46 @@
// 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.Tools.Test.Utilities;
using Xunit;
namespace Microsoft.DotNet.Tests.EndToEnd
{
public class GivenDotNetUsesMSBuild : TestBase
{
[Fact]
public void ItCanNewRestoreBuildRunMSBuildProject()
{
using (DisposableDirectory directory = Temp.CreateDirectory())
{
string projectDirectory = directory.Path;
new NewCommand()
.WithWorkingDirectory(projectDirectory)
.Execute("-t msbuild")
.Should()
.Pass();
new RestoreCommand()
.WithWorkingDirectory(projectDirectory)
.Execute()
.Should()
.Pass();
new Build3Command()
.WithWorkingDirectory(projectDirectory)
.Execute()
.Should()
.Pass();
new Run3Command()
.WithWorkingDirectory(projectDirectory)
.ExecuteWithCapturedOutput()
.Should()
.Pass()
.And
.HaveStdOutContaining("Hello World!");
}
}
}
}

View file

@ -0,0 +1,30 @@
// 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 Microsoft.DotNet.Cli.Utils;
using System.Runtime.InteropServices;
using Microsoft.DotNet.ProjectModel;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public sealed class Build3Command : TestCommand
{
public Build3Command()
: base("dotnet")
{
}
public override CommandResult Execute(string args = "")
{
args = $"build3 {args}";
return base.Execute(args);
}
public override CommandResult ExecuteWithCapturedOutput(string args = "")
{
args = $"build3 {args}";
return base.ExecuteWithCapturedOutput(args);
}
}
}

View file

@ -0,0 +1,30 @@
// 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 Microsoft.DotNet.Cli.Utils;
using System.Runtime.InteropServices;
using Microsoft.DotNet.ProjectModel;
namespace Microsoft.DotNet.Tools.Test.Utilities
{
public sealed class Run3Command : TestCommand
{
public Run3Command()
: base("dotnet")
{
}
public override CommandResult Execute(string args = "")
{
args = $"run3 {args}";
return base.Execute(args);
}
public override CommandResult ExecuteWithCapturedOutput(string args = "")
{
args = $"run3 {args}";
return base.ExecuteWithCapturedOutput(args);
}
}
}

View file

@ -55,7 +55,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
}
}
public TempDirectory CreateDirectory()
public DisposableDirectory CreateDirectory()
{
var dir = new DisposableDirectory(this);
_temps.Add(dir);

View file

@ -21,10 +21,9 @@ namespace Microsoft.DotNet.Cli.Build3.Tests
var testProjectDirectory = testInstance.TestRoot;
var build3Command = new TestCommand("dotnet");
build3Command.WorkingDirectory = testProjectDirectory;
build3Command.ExecuteWithCapturedOutput("build3")
new Build3Command()
.WithWorkingDirectory(testProjectDirectory)
.Execute()
.Should()
.Pass();