parent
ab50213acd
commit
1410a5a096
|
|
@ -20,13 +20,15 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools
|
|||
app.HelpOption("-h|--help");
|
||||
|
||||
var publishFolderOption = app.Option("--publish-folder|-p", "The path to the publish output folder", CommandOptionType.SingleValue);
|
||||
var frameworkOption = app.Option("-f|--framework <FRAMEWORK>", "Target framework of application being published", CommandOptionType.SingleValue);
|
||||
var projectPath = app.Argument("<PROJECT>", "The path to the project (project folder or project.json) being published. If empty the current directory is used.");
|
||||
|
||||
app.OnExecute(() =>
|
||||
{
|
||||
var publishFolder = publishFolderOption.Value();
|
||||
var framework = frameworkOption.Value();
|
||||
|
||||
if (publishFolder == null)
|
||||
if (publishFolder == null || framework == null)
|
||||
{
|
||||
app.ShowHelp();
|
||||
return 2;
|
||||
|
|
@ -34,7 +36,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools
|
|||
|
||||
Reporter.Output.WriteLine($"Configuring the following project for use with IIS: '{publishFolder}'");
|
||||
|
||||
var exitCode = new PublishIISCommand(publishFolder, projectPath.Value).Run();
|
||||
var exitCode = new PublishIISCommand(publishFolder, framework, projectPath.Value).Run();
|
||||
|
||||
Reporter.Output.WriteLine("Configuring project completed successfully");
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,12 @@
|
|||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using Microsoft.Extensions.Cli.Utils;
|
||||
using NuGet.Frameworks;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.Tools
|
||||
{
|
||||
|
|
@ -14,11 +16,13 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools
|
|||
{
|
||||
private readonly string _publishFolder;
|
||||
private readonly string _projectPath;
|
||||
private readonly string _framework;
|
||||
|
||||
public PublishIISCommand(string publishFolder, string projectPath)
|
||||
public PublishIISCommand(string publishFolder, string framework, string projectPath)
|
||||
{
|
||||
_publishFolder = publishFolder;
|
||||
_projectPath = projectPath;
|
||||
_framework = framework;
|
||||
}
|
||||
|
||||
public int Run()
|
||||
|
|
@ -42,8 +46,10 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools
|
|||
Reporter.Output.WriteLine($"No web.config found. Creating '{webConfigPath}'");
|
||||
}
|
||||
|
||||
var applicationName = GetApplicationName(applicationBasePath) + ".exe";
|
||||
var transformedConfig = WebConfigTransform.Transform(webConfigXml, applicationName, ConfigureForAzure());
|
||||
var projectContext = GetProjectContext(applicationBasePath, _framework);
|
||||
var isPortable = !projectContext.TargetFramework.IsDesktop() && projectContext.IsPortable;
|
||||
var applicationName = projectContext.ProjectFile.Name + (isPortable ? ".dll" : ".exe");
|
||||
var transformedConfig = WebConfigTransform.Transform(webConfigXml, applicationName, ConfigureForAzure(), isPortable);
|
||||
|
||||
using (var f = new FileStream(webConfigPath, FileMode.Create))
|
||||
{
|
||||
|
|
@ -67,9 +73,14 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools
|
|||
return Directory.GetCurrentDirectory();
|
||||
}
|
||||
|
||||
private string GetApplicationName(string applicationBasePath)
|
||||
private static ProjectContext GetProjectContext(string applicationBasePath, string framework)
|
||||
{
|
||||
return ProjectReader.GetProject(Path.Combine(applicationBasePath, "project.json")).Name;
|
||||
var project = ProjectReader.GetProject(Path.Combine(applicationBasePath, "project.json"));
|
||||
|
||||
return new ProjectContextBuilder()
|
||||
.WithProject(project)
|
||||
.WithTargetFramework(framework)
|
||||
.Build();
|
||||
}
|
||||
|
||||
private static bool ConfigureForAzure()
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools
|
|||
{
|
||||
public static class WebConfigTransform
|
||||
{
|
||||
public static XDocument Transform(XDocument webConfig, string appName, bool configureForAzure)
|
||||
public static XDocument Transform(XDocument webConfig, string appName, bool configureForAzure, bool isPortable)
|
||||
{
|
||||
const string HandlersElementName = "handlers";
|
||||
const string aspNetCoreElementName = "aspNetCore";
|
||||
|
|
@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools
|
|||
var webServerSection = GetOrCreateChild(webConfig.Root, "system.webServer");
|
||||
|
||||
TransformHandlers(GetOrCreateChild(webServerSection, HandlersElementName));
|
||||
TransformAspNetCore(GetOrCreateChild(webServerSection, aspNetCoreElementName), appName, configureForAzure);
|
||||
TransformAspNetCore(GetOrCreateChild(webServerSection, aspNetCoreElementName), appName, configureForAzure, isPortable);
|
||||
|
||||
// make sure that the aspNetCore element is after handlers element
|
||||
var aspNetCoreElement = webServerSection.Element(HandlersElementName)
|
||||
|
|
@ -55,14 +55,32 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools
|
|||
SetAttributeValueIfEmpty(aspNetCoreElement, "resourceType", "Unspecified");
|
||||
}
|
||||
|
||||
private static void TransformAspNetCore(XElement aspNetCoreElement, string appName, bool configureForAzure)
|
||||
private static void TransformAspNetCore(XElement aspNetCoreElement, string appName, bool configureForAzure, bool isPortable)
|
||||
{
|
||||
// Forward slashes currently work neither in AspNetCoreModule nor in dotnet so they need to be
|
||||
// replaced with backwards slashes when the application is published on a non-Windows machine
|
||||
var appPath = Path.Combine(configureForAzure ? @"%home%\site" : ".", appName).Replace("/", "\\");
|
||||
var logPath = Path.Combine(configureForAzure ? @"\\?\%home%\LogFiles" : @".\logs", "stdout").Replace("/", "\\");
|
||||
|
||||
aspNetCoreElement.SetAttributeValue("processPath", appPath);
|
||||
if (!isPortable)
|
||||
{
|
||||
aspNetCoreElement.SetAttributeValue("processPath", appPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
aspNetCoreElement.SetAttributeValue("processPath", "dotnet");
|
||||
|
||||
// In Xml the order of attributes does not matter but it is nice to have
|
||||
// the `arguments` attribute next to the `processPath` attribute
|
||||
aspNetCoreElement.Attribute("arguments")?.Remove();
|
||||
var attributes = aspNetCoreElement.Attributes().ToList();
|
||||
var processPathIndex = attributes.FindIndex(a => a.Name.LocalName == "processPath");
|
||||
attributes.Insert(processPathIndex + 1, new XAttribute("arguments", appPath));
|
||||
|
||||
aspNetCoreElement.Attributes().Remove();
|
||||
aspNetCoreElement.Add(attributes);
|
||||
}
|
||||
|
||||
SetAttributeValueIfEmpty(aspNetCoreElement, "stdoutLogEnabled", "false");
|
||||
SetAttributeValueIfEmpty(aspNetCoreElement, "stdoutLogFile", logPath);
|
||||
SetAttributeValueIfEmpty(aspNetCoreElement, "startupTimeLimit", "3600");
|
||||
|
|
|
|||
|
|
@ -15,17 +15,48 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
|||
public string ProjectPath;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PublishIIS_uses_default_values_if_options_not_specified()
|
||||
[Theory]
|
||||
[InlineData("netcoreapp1.0")]
|
||||
[InlineData("netstandard1.5")]
|
||||
public void PublishIIS_uses_default_values_if_options_not_specified(string targetFramework)
|
||||
{
|
||||
var folders = CreateTestDir("{}");
|
||||
var folders = CreateTestDir($@"{{ ""frameworks"": {{ ""{targetFramework}"": {{ }} }} }}");
|
||||
|
||||
new PublishIISCommand(folders.PublishOutput, folders.ProjectPath).Run();
|
||||
new PublishIISCommand(folders.PublishOutput, targetFramework, folders.ProjectPath).Run();
|
||||
|
||||
var processPath = (string)GetPublishedWebConfig(folders.PublishOutput)
|
||||
.Descendants("aspNetCore").Attributes("processPath").Single();
|
||||
|
||||
Assert.Equal($@".\projectDir.exe", processPath);
|
||||
Assert.Equal(@".\projectDir.exe", processPath);
|
||||
|
||||
Directory.Delete(folders.TestRoot, recursive: true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PublishIIS_can_publish_for_portable_app()
|
||||
{
|
||||
var folders = CreateTestDir(
|
||||
@"
|
||||
{
|
||||
""frameworks"": {
|
||||
""netcoreapp1.0"": {
|
||||
""dependencies"": {
|
||||
""Microsoft.NETCore.App"": {
|
||||
""version"": ""1.0.0-*"",
|
||||
""type"": ""platform""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}");
|
||||
|
||||
new PublishIISCommand(folders.PublishOutput, "netcoreapp1.0", folders.ProjectPath).Run();
|
||||
|
||||
var aspNetCoreElement = GetPublishedWebConfig(folders.PublishOutput)
|
||||
.Descendants("aspNetCore").Single();
|
||||
|
||||
Assert.Equal(@"dotnet", (string)aspNetCoreElement.Attribute("processPath"));
|
||||
Assert.Equal(@".\projectDir.dll", (string)aspNetCoreElement.Attribute("arguments"));
|
||||
|
||||
Directory.Delete(folders.TestRoot, recursive: true);
|
||||
}
|
||||
|
|
@ -35,9 +66,9 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
|||
[InlineData("awesome.App")]
|
||||
public void PublishIIS_reads_application_name_from_project_json_if_exists(string projectName)
|
||||
{
|
||||
var folders = CreateTestDir($@"{{ ""name"": ""{projectName}"" }}");
|
||||
var folders = CreateTestDir($@"{{ ""name"": ""{projectName}"", ""frameworks"": {{ ""netcoreapp1.0"": {{}} }} }}");
|
||||
|
||||
new PublishIISCommand(folders.PublishOutput, folders.ProjectPath).Run();
|
||||
new PublishIISCommand(folders.PublishOutput, "netcoreapp1.0", folders.ProjectPath).Run();
|
||||
|
||||
var processPath = (string)GetPublishedWebConfig(folders.PublishOutput)
|
||||
.Descendants("aspNetCore").Attributes("processPath").Single();
|
||||
|
|
@ -52,9 +83,10 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
|||
[InlineData("project.Dir")]
|
||||
public void PublishIIS_accepts_path_to_project_json_as_project_path(string projectDir)
|
||||
{
|
||||
var folders = CreateTestDir("{}", projectDir);
|
||||
var folders = CreateTestDir(@"{ ""frameworks"": { ""netcoreapp1.0"": { } } }", projectDir);
|
||||
|
||||
new PublishIISCommand(folders.PublishOutput, Path.Combine(folders.ProjectPath, "project.json")).Run();
|
||||
new PublishIISCommand(folders.PublishOutput, "netcoreapp1.0",
|
||||
Path.Combine(folders.ProjectPath, "project.json")).Run();
|
||||
|
||||
var processPath = (string)GetPublishedWebConfig(folders.PublishOutput)
|
||||
.Descendants("aspNetCore").Attributes("processPath").Single();
|
||||
|
|
@ -67,7 +99,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
|||
[Fact]
|
||||
public void PublishIIS_modifies_existing_web_config()
|
||||
{
|
||||
var folders = CreateTestDir("{}");
|
||||
var folders = CreateTestDir(@"{ ""frameworks"": { ""netcoreapp1.0"": { } } }");
|
||||
|
||||
File.WriteAllText(Path.Combine(folders.PublishOutput, "web.config"),
|
||||
@"<configuration>
|
||||
|
|
@ -79,7 +111,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
|||
</system.webServer>
|
||||
</configuration>");
|
||||
|
||||
new PublishIISCommand(folders.PublishOutput, Path.Combine(folders.ProjectPath, "project.json")).Run();
|
||||
new PublishIISCommand(folders.PublishOutput, "netcoreapp1.0",
|
||||
Path.Combine(folders.ProjectPath, "project.json")).Run();
|
||||
|
||||
var aspNetCoreElement = GetPublishedWebConfig(folders.PublishOutput)
|
||||
.Descendants("aspNetCore").Single();
|
||||
|
|
|
|||
|
|
@ -20,14 +20,14 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
|||
public void WebConfigTransform_creates_new_config_if_one_does_not_exist()
|
||||
{
|
||||
Assert.True(XNode.DeepEquals(WebConfigTemplate,
|
||||
WebConfigTransform.Transform(null, "test.exe", configureForAzure: false)));
|
||||
WebConfigTransform.Transform(null, "test.exe", configureForAzure: false, isPortable: false)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WebConfigTransform_creates_new_config_if_one_has_unexpected_format()
|
||||
{
|
||||
Assert.True(XNode.DeepEquals(WebConfigTemplate,
|
||||
WebConfigTransform.Transform(XDocument.Parse("<unexpected />"), "test.exe", configureForAzure: false)));
|
||||
WebConfigTransform.Transform(XDocument.Parse("<unexpected />"), "test.exe", configureForAzure: false, isPortable: false)));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
|||
}
|
||||
|
||||
Assert.True(XNode.DeepEquals(WebConfigTemplate,
|
||||
WebConfigTransform.Transform(input, "test.exe", configureForAzure: false)));
|
||||
WebConfigTransform.Transform(input, "test.exe", configureForAzure: false, isPortable: false)));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
|||
var input = WebConfigTemplate;
|
||||
input.Descendants(elementName).Single().SetAttributeValue(attributeName, attributeValue);
|
||||
|
||||
var output = WebConfigTransform.Transform(input, "test.exe", configureForAzure: false);
|
||||
var output = WebConfigTransform.Transform(input, "test.exe", configureForAzure: false, isPortable: false);
|
||||
Assert.Equal(attributeValue, (string)output.Descendants(elementName).Single().Attribute(attributeName));
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
|||
public void WebConfigTransform_overwrites_processPath()
|
||||
{
|
||||
var newProcessPath =
|
||||
(string)WebConfigTransform.Transform(WebConfigTemplate, "app.exe", configureForAzure: false)
|
||||
(string)WebConfigTransform.Transform(WebConfigTemplate, "app.exe", configureForAzure: false, isPortable: false)
|
||||
.Descendants("aspNetCore").Single().Attribute("processPath");
|
||||
|
||||
Assert.Equal(@".\app.exe", newProcessPath);
|
||||
|
|
@ -85,7 +85,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
|||
input.Descendants("add").Single().SetAttributeValue("name", "aspnetcore");
|
||||
|
||||
Assert.True(XNode.DeepEquals(WebConfigTemplate,
|
||||
WebConfigTransform.Transform(input, "test.exe", configureForAzure: false)));
|
||||
WebConfigTransform.Transform(input, "test.exe", configureForAzure: false, isPortable: false)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -98,7 +98,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
|||
input.Descendants("aspNetCore").Single().Add(envVarElement);
|
||||
|
||||
Assert.True(XNode.DeepEquals(envVarElement,
|
||||
WebConfigTransform.Transform(input, "app.exe", configureForAzure: false)
|
||||
WebConfigTransform.Transform(input, "app.exe", configureForAzure: false, isPortable: false)
|
||||
.Descendants("environmentVariable").SingleOrDefault(e => (string)e.Attribute("name") == "ENVVAR")));
|
||||
}
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
|||
|
||||
Assert.Equal(
|
||||
"false",
|
||||
(string)WebConfigTransform.Transform(input, "test.exe", configureForAzure: false)
|
||||
(string)WebConfigTransform.Transform(input, "test.exe", configureForAzure: false, isPortable: false)
|
||||
.Descendants().Attributes("stdoutLogEnabled").Single());
|
||||
}
|
||||
|
||||
|
|
@ -131,7 +131,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
|||
|
||||
Assert.Equal(
|
||||
@".\logs\stdout",
|
||||
(string)WebConfigTransform.Transform(input, "test.exe", configureForAzure: false)
|
||||
(string)WebConfigTransform.Transform(input, "test.exe", configureForAzure: false, isPortable: false)
|
||||
.Descendants().Attributes("stdoutLogFile").Single());
|
||||
}
|
||||
|
||||
|
|
@ -153,7 +153,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
|||
|
||||
Assert.Equal(
|
||||
"mylog.txt",
|
||||
(string)WebConfigTransform.Transform(input, "test.exe", configureForAzure: false)
|
||||
(string)WebConfigTransform.Transform(input, "test.exe", configureForAzure: false, isPortable: false)
|
||||
.Descendants().Attributes("stdoutLogFile").Single());
|
||||
}
|
||||
|
||||
|
|
@ -163,7 +163,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
|||
var input = WebConfigTemplate;
|
||||
input.Descendants("aspNetCore").Attributes().Remove();
|
||||
|
||||
var aspNetCoreElement = WebConfigTransform.Transform(input, "test.exe", configureForAzure: true)
|
||||
var aspNetCoreElement = WebConfigTransform.Transform(input, "test.exe", configureForAzure: true, isPortable: false)
|
||||
.Descendants("aspNetCore").Single();
|
||||
aspNetCoreElement.Elements().Remove();
|
||||
|
||||
|
|
@ -173,6 +173,35 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
|||
aspNetCoreElement));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WebConfigTransform_configures_portable_apps_correctly()
|
||||
{
|
||||
var aspNetCoreElement =
|
||||
WebConfigTransform.Transform(WebConfigTemplate, "test.exe", configureForAzure: false, isPortable: true)
|
||||
.Descendants("aspNetCore").Single();
|
||||
|
||||
Assert.True(XNode.DeepEquals(
|
||||
XDocument.Parse(@"<aspNetCore processPath=""dotnet"" arguments="".\test.exe"" stdoutLogEnabled=""false""
|
||||
stdoutLogFile="".\logs\stdout"" startupTimeLimit=""3600""/>").Root,
|
||||
aspNetCoreElement));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WebConfigTransform_overwrites_existing_arguments_attribute_for_portable_apps()
|
||||
{
|
||||
var input = WebConfigTemplate;
|
||||
input.Descendants("aspNetCore").Single().SetAttributeValue("arguments", "42");
|
||||
|
||||
var aspNetCoreElement =
|
||||
WebConfigTransform.Transform(input, "test.exe", configureForAzure: false, isPortable: true)
|
||||
.Descendants("aspNetCore").Single();
|
||||
|
||||
Assert.True(XNode.DeepEquals(
|
||||
XDocument.Parse(@"<aspNetCore processPath=""dotnet"" arguments="".\test.exe"" stdoutLogEnabled=""false""
|
||||
stdoutLogFile="".\logs\stdout"" startupTimeLimit=""3600""/>").Root,
|
||||
aspNetCoreElement));
|
||||
}
|
||||
|
||||
private bool VerifyMissingElementCreated(params string[] elementNames)
|
||||
{
|
||||
var input = WebConfigTemplate;
|
||||
|
|
@ -182,7 +211,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
|||
}
|
||||
|
||||
return XNode.DeepEquals(WebConfigTemplate,
|
||||
WebConfigTransform.Transform(input, "test.exe", configureForAzure: false));
|
||||
WebConfigTransform.Transform(input, "test.exe", configureForAzure: false, isPortable: false));
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue