Creating Microsoft.AspNetCore.Server.IISIntegration.Tools package
See #95
This commit is contained in:
parent
5442cbe6a5
commit
5c50ba0898
|
|
@ -30,6 +30,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Server
|
|||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Server.IISIntegration.Tests", "test\Microsoft.AspNetCore.Server.IISIntegration.Tests\Microsoft.AspNetCore.Server.IISIntegration.Tests.xproj", "{4106DB10-E09F-480E-9CE6-B39235512EE6}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests", "test\Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests\Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests.xproj", "{D0FA003D-DE4C-480E-B4A4-BD38691B36AD}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Server.IISIntegration.Tools", "src\Microsoft.AspNetCore.Server.IISIntegration.Tools\Microsoft.AspNetCore.Server.IISIntegration.Tools.xproj", "{B1BC61B7-BA1D-4100-A2E8-49D00CE2771D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -68,6 +72,14 @@ Global
|
|||
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4106DB10-E09F-480E-9CE6-B39235512EE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D0FA003D-DE4C-480E-B4A4-BD38691B36AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D0FA003D-DE4C-480E-B4A4-BD38691B36AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D0FA003D-DE4C-480E-B4A4-BD38691B36AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D0FA003D-DE4C-480E-B4A4-BD38691B36AD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B1BC61B7-BA1D-4100-A2E8-49D00CE2771D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B1BC61B7-BA1D-4100-A2E8-49D00CE2771D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B1BC61B7-BA1D-4100-A2E8-49D00CE2771D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B1BC61B7-BA1D-4100-A2E8-49D00CE2771D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -81,5 +93,7 @@ Global
|
|||
{8B3446E8-E6A8-4591-AA63-A95837C6E97C} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
|
||||
{7F2F50C7-610F-4B69-B945-CA283511A587} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||
{4106DB10-E09F-480E-9CE6-B39235512EE6} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||
{D0FA003D-DE4C-480E-B4A4-BD38691B36AD} = {EF30B533-D715-421A-92B7-92FEF460AC9C}
|
||||
{B1BC61B7-BA1D-4100-A2E8-49D00CE2771D} = {04B1EDB6-E967-4D25-89B9-E6F8304038CD}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
"packages": {
|
||||
"dotnet-publish-iis": { },
|
||||
"Microsoft.AspNetCore.IISPlatformHandler": { },
|
||||
"Microsoft.AspNetCore.Server.IISIntegration": { }
|
||||
"Microsoft.AspNetCore.Server.IISIntegration": { },
|
||||
"Microsoft.AspNetCore.Server.IISIntegration.Tools": { }
|
||||
}
|
||||
},
|
||||
"Default": { // Rules to run for packages not listed in any other set.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0.24720" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.24720</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>b1bc61b7-ba1d-4100-a2e8-49d00ce2771d</ProjectGuid>
|
||||
<RootNamespace>Microsoft.AspNetCore.Server.IISIntegration.Tools</RootNamespace>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.Extensions.CommandLineUtils;
|
||||
|
||||
namespace Microsoft.AspNetCore.Tools.PublishIIS
|
||||
{
|
||||
public class Microsoft.AspNetCore.Server.IISIntegration.Tools
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
var app = new CommandLineApplication
|
||||
{
|
||||
Name = "dotnet publish-iis",
|
||||
FullName = "Asp.Net IIS Publisher",
|
||||
Description = "IIS Publisher for the Asp.Net web applications",
|
||||
};
|
||||
app.HelpOption("-h|--help");
|
||||
|
||||
var publishFolderOption = app.Option("--publish-folder|-p", "The path to the publish output folder", CommandOptionType.SingleValue);
|
||||
var webRootOption = app.Option("--webroot|-w", "The name of webroot folder", 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();
|
||||
|
||||
if (publishFolder == null)
|
||||
{
|
||||
app.ShowHelp();
|
||||
return 2;
|
||||
}
|
||||
|
||||
Reporter.Output.WriteLine($"Configuring the following project for use with IIS: '{publishFolder}'");
|
||||
|
||||
var exitCode = new PublishIISCommand(publishFolder, projectPath.Value, webRootOption.Value()).Run();
|
||||
|
||||
Reporter.Output.WriteLine("Configuring project completed successfully");
|
||||
|
||||
return exitCode;
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
return app.Execute(args);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Reporter.Error.WriteLine(e.Message.Red());
|
||||
Reporter.Verbose.WriteLine(e.ToString().Yellow());
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
|
||||
[assembly: AssemblyMetadata("Serviceable", "True")]
|
||||
[assembly: NeutralResourcesLanguage("en-us")]
|
||||
[assembly: AssemblyCompany("Microsoft Corporation.")]
|
||||
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
|
||||
[assembly: AssemblyProduct("Microsoft ASP.NET Core")]
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.Tools
|
||||
{
|
||||
public class PublishIISCommand
|
||||
{
|
||||
private readonly string _publishFolder;
|
||||
private readonly string _projectPath;
|
||||
private readonly string _webRoot;
|
||||
|
||||
public PublishIISCommand(string publishFolder, string projectPath, string webRoot)
|
||||
{
|
||||
_publishFolder = publishFolder;
|
||||
_projectPath = projectPath;
|
||||
_webRoot = webRoot;
|
||||
}
|
||||
|
||||
public int Run()
|
||||
{
|
||||
var applicationBasePath = GetApplicationBasePath();
|
||||
var webRoot = GetWebRoot(applicationBasePath);
|
||||
|
||||
XDocument webConfigXml = null;
|
||||
var webRootDirectory = Path.Combine(_publishFolder, webRoot);
|
||||
var webConfigPath = Path.Combine(webRootDirectory, "web.config");
|
||||
if (File.Exists(webConfigPath))
|
||||
{
|
||||
Reporter.Output.WriteLine($"Updating web.config at '{webConfigPath}'");
|
||||
|
||||
try
|
||||
{
|
||||
webConfigXml = XDocument.Load(webConfigPath);
|
||||
}
|
||||
catch (XmlException) { }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Directory.Exists(webRootDirectory))
|
||||
{
|
||||
Reporter.Output.WriteLine($"No webroot directory found. Creating '{webRootDirectory}'");
|
||||
Directory.CreateDirectory(webRootDirectory);
|
||||
}
|
||||
|
||||
Reporter.Output.WriteLine($"No web.config found. Creating '{webConfigPath}'");
|
||||
}
|
||||
|
||||
var applicationName = GetApplicationName(applicationBasePath) + ".exe";
|
||||
var transformedConfig = WebConfigTransform.Transform(webConfigXml, applicationName, ConfigureForAzure());
|
||||
|
||||
using (var f = new FileStream(webConfigPath, FileMode.Create))
|
||||
{
|
||||
transformedConfig.Save(f);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private string GetApplicationBasePath()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_projectPath))
|
||||
{
|
||||
var fullProjectPath = Path.GetFullPath(_projectPath);
|
||||
|
||||
return Path.GetFileName(fullProjectPath) == "project.json"
|
||||
? Path.GetDirectoryName(fullProjectPath)
|
||||
: fullProjectPath;
|
||||
}
|
||||
|
||||
return Directory.GetCurrentDirectory();
|
||||
}
|
||||
|
||||
private string GetApplicationName(string applicationBasePath)
|
||||
{
|
||||
return ProjectReader.GetProject(Path.Combine(applicationBasePath, "project.json")).Name;
|
||||
}
|
||||
|
||||
private string GetWebRoot(string applicationBasePath)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_webRoot))
|
||||
{
|
||||
return _webRoot;
|
||||
}
|
||||
|
||||
var builder = new ConfigurationBuilder()
|
||||
.AddJsonFile(Path.Combine(applicationBasePath, "hosting.json"), optional: true);
|
||||
|
||||
var webroot = builder.Build()["webroot"];
|
||||
|
||||
if (!string.IsNullOrEmpty(webroot))
|
||||
{
|
||||
return webroot;
|
||||
}
|
||||
|
||||
if (Directory.Exists(Path.Combine(applicationBasePath, "wwwroot")))
|
||||
{
|
||||
return "wwwroot";
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private static bool ConfigureForAzure()
|
||||
{
|
||||
var configureForAzureValue = Environment.GetEnvironmentVariable("DOTNET_CONFIGURE_AZURE");
|
||||
return string.Equals(configureForAzureValue, "true", StringComparison.Ordinal) ||
|
||||
string.Equals(configureForAzureValue, "1", StringComparison.Ordinal) ||
|
||||
!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.Tools
|
||||
{
|
||||
public static class WebConfigTransform
|
||||
{
|
||||
public static XDocument Transform(XDocument webConfig, string appName, bool configureForAzure)
|
||||
{
|
||||
const string HandlersElementName = "handlers";
|
||||
const string httpPlatformElementName = "httpPlatform";
|
||||
|
||||
webConfig = webConfig == null || webConfig.Root.Name.LocalName != "configuration"
|
||||
? XDocument.Parse("<configuration />")
|
||||
: webConfig;
|
||||
|
||||
var webServerSection = GetOrCreateChild(webConfig.Root, "system.webServer");
|
||||
|
||||
TransformHandlers(GetOrCreateChild(webServerSection, HandlersElementName));
|
||||
TransformHttpPlatform(GetOrCreateChild(webServerSection, httpPlatformElementName), appName, configureForAzure);
|
||||
|
||||
// make sure that the httpPlatform element is after handlers element
|
||||
var httpPlatformElement = webServerSection.Element(HandlersElementName)
|
||||
.ElementsBeforeSelf(httpPlatformElementName).SingleOrDefault();
|
||||
if (httpPlatformElement != null)
|
||||
{
|
||||
httpPlatformElement.Remove();
|
||||
webServerSection.Element(HandlersElementName).AddAfterSelf(httpPlatformElement);
|
||||
}
|
||||
|
||||
return webConfig;
|
||||
}
|
||||
|
||||
private static void TransformHandlers(XElement handlersElement)
|
||||
{
|
||||
var platformHandlerElement =
|
||||
handlersElement.Elements("add")
|
||||
.FirstOrDefault(e => string.Equals((string)e.Attribute("name"), "httpplatformhandler", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (platformHandlerElement == null)
|
||||
{
|
||||
platformHandlerElement = new XElement("add");
|
||||
handlersElement.Add(platformHandlerElement);
|
||||
}
|
||||
|
||||
platformHandlerElement.SetAttributeValue("name", "httpPlatformHandler");
|
||||
SetAttributeValueIfEmpty(platformHandlerElement, "path", "*");
|
||||
SetAttributeValueIfEmpty(platformHandlerElement, "verb", "*");
|
||||
SetAttributeValueIfEmpty(platformHandlerElement, "modules", "httpPlatformHandler");
|
||||
SetAttributeValueIfEmpty(platformHandlerElement, "resourceType", "Unspecified");
|
||||
}
|
||||
|
||||
private static void TransformHttpPlatform(XElement httpPlatformElement, string appName, bool configureForAzure)
|
||||
{
|
||||
var appPath = Path.Combine(configureForAzure ? @"%home%\site" : "..", appName);
|
||||
var logPath = Path.Combine(configureForAzure ? @"\\?\%home%\LogFiles" : @"..\logs", "stdout.log");
|
||||
|
||||
httpPlatformElement.SetAttributeValue("processPath", appPath);
|
||||
SetAttributeValueIfEmpty(httpPlatformElement, "stdoutLogEnabled", "false");
|
||||
SetAttributeValueIfEmpty(httpPlatformElement, "stdoutLogFile", logPath);
|
||||
SetAttributeValueIfEmpty(httpPlatformElement, "startupTimeLimit", "3600");
|
||||
|
||||
AddApplicationBase(httpPlatformElement);
|
||||
}
|
||||
|
||||
private static void AddApplicationBase(XElement httpPlatformElement)
|
||||
{
|
||||
const string appBaseKeyName = "ASPNET_APPLICATIONBASE";
|
||||
|
||||
var envVariables = GetOrCreateChild(httpPlatformElement, "environmentVariables");
|
||||
var appBaseElement = envVariables.Elements("environmentVariable").SingleOrDefault(e =>
|
||||
string.Equals((string)e.Attribute("name"), appBaseKeyName, StringComparison.CurrentCultureIgnoreCase));
|
||||
|
||||
if (appBaseElement == null)
|
||||
{
|
||||
appBaseElement = new XElement("environmentVariable", new XAttribute("name", appBaseKeyName));
|
||||
envVariables.AddFirst(appBaseElement);
|
||||
}
|
||||
|
||||
appBaseElement.SetAttributeValue("value", ".");
|
||||
}
|
||||
|
||||
private static XElement GetOrCreateChild(XElement parent, string childName)
|
||||
{
|
||||
var childElement = parent.Element(childName);
|
||||
if (childElement == null)
|
||||
{
|
||||
childElement = new XElement(childName);
|
||||
parent.Add(childElement);
|
||||
}
|
||||
return childElement;
|
||||
}
|
||||
|
||||
private static void SetAttributeValueIfEmpty(XElement element, string attributeName, string value)
|
||||
{
|
||||
element.SetAttributeValue(attributeName, (string)element.Attribute(attributeName) ?? value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"version": "1.0.0-*",
|
||||
"compilationOptions": {
|
||||
"emitEntryPoint": true,
|
||||
"warningsAsErrors": true,
|
||||
"keyFile": "../../tools/Key.snk",
|
||||
"nowarn": [ "CS1591" ],
|
||||
"xmlDoc": true
|
||||
},
|
||||
|
||||
"dependencies": {
|
||||
"NETStandard.Library": "1.0.0-*",
|
||||
"Microsoft.Extensions.CommandLineUtils": "1.0.0-*",
|
||||
"Microsoft.Extensions.Configuration.Json": "1.0.0-*",
|
||||
"Microsoft.DotNet.ProjectModel": "1.0.0-*",
|
||||
"Microsoft.DotNet.Cli.Utils": "1.0.0-*"
|
||||
},
|
||||
|
||||
"frameworks": {
|
||||
"dnxcore50": {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0.24720" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.24720</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>d0fa003d-de4c-480e-b4a4-bd38691b36ad</ProjectGuid>
|
||||
<RootNamespace>Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests</RootNamespace>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
using Xunit;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
||||
{
|
||||
public class PublishIISCommandFacts
|
||||
{
|
||||
private class Folders
|
||||
{
|
||||
public string TestRoot;
|
||||
public string PublishOutput;
|
||||
public string ProjectPath;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PublishIIS_uses_default_values_if_options_not_specified()
|
||||
{
|
||||
var webRoot = "wwwroot";
|
||||
var folders = CreateTestDir("{}", webRoot);
|
||||
|
||||
new PublishIISCommand(folders.PublishOutput, folders.ProjectPath, null).Run();
|
||||
|
||||
var processPath = (string)GetPublishedWebConfig(folders.PublishOutput, webRoot)
|
||||
.Descendants("httpPlatform").Attributes("processPath").Single();
|
||||
|
||||
Assert.Equal($@"..\projectDir.exe", processPath);
|
||||
|
||||
Directory.Delete(folders.TestRoot, recursive: true);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("awesomeApp")]
|
||||
[InlineData("awesome.App")]
|
||||
public void PublishIIS_reads_application_name_from_project_json_if_exists(string projectName)
|
||||
{
|
||||
var webRoot = "wwwroot";
|
||||
var folders = CreateTestDir($@"{{ ""name"": ""{projectName}"" }}", webRoot);
|
||||
|
||||
new PublishIISCommand(folders.PublishOutput, folders.ProjectPath, null).Run();
|
||||
|
||||
var processPath = (string)GetPublishedWebConfig(folders.PublishOutput, webRoot)
|
||||
.Descendants("httpPlatform").Attributes("processPath").Single();
|
||||
|
||||
Assert.Equal($@"..\{projectName}.exe", processPath);
|
||||
|
||||
Directory.Delete(folders.TestRoot, recursive: true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PublishIIS_uses_webroot_from_hosting_json()
|
||||
{
|
||||
var webRoot = "mywebroot";
|
||||
var folders = CreateTestDir("{}", webRoot);
|
||||
File.WriteAllText(Path.Combine(folders.ProjectPath, "hosting.json"), $"{{ \"webroot\": \"{webRoot}\"}}");
|
||||
|
||||
new PublishIISCommand(folders.PublishOutput, folders.ProjectPath, null).Run();
|
||||
|
||||
var processPath = (string)GetPublishedWebConfig(folders.PublishOutput, webRoot)
|
||||
.Descendants("httpPlatform").Attributes("processPath").Single();
|
||||
|
||||
Assert.Equal(@"..\projectDir.exe", processPath);
|
||||
|
||||
Directory.Delete(folders.TestRoot, recursive: true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PublishIIS_webroot_switch_takes_precedence_over_hosting_json()
|
||||
{
|
||||
var webRoot = "mywebroot";
|
||||
var folders = CreateTestDir("{}", webRoot);
|
||||
File.WriteAllText(Path.Combine(folders.ProjectPath, "hosting.json"), $"{{ \"webroot\": \"wwwroot\"}}");
|
||||
|
||||
new PublishIISCommand(folders.PublishOutput, folders.ProjectPath, webRoot).Run();
|
||||
|
||||
var processPath = (string)GetPublishedWebConfig(folders.PublishOutput, webRoot)
|
||||
.Descendants("httpPlatform").Attributes("processPath").Single();
|
||||
|
||||
Assert.Equal(@"..\projectDir.exe", processPath);
|
||||
|
||||
Directory.Delete(folders.TestRoot, recursive: true);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("projectDir")]
|
||||
[InlineData("project.Dir")]
|
||||
public void PublishIIS_accepts_path_to_project_json_as_project_path(string projectDir)
|
||||
{
|
||||
var webRoot = "wwwroot";
|
||||
var folders = CreateTestDir("{}", webRoot, projectDir);
|
||||
|
||||
new PublishIISCommand(folders.PublishOutput, Path.Combine(folders.ProjectPath, "project.json"), null).Run();
|
||||
|
||||
var processPath = (string)GetPublishedWebConfig(folders.PublishOutput, webRoot)
|
||||
.Descendants("httpPlatform").Attributes("processPath").Single();
|
||||
|
||||
Assert.Equal($@"..\{projectDir}.exe", processPath);
|
||||
|
||||
Directory.Delete(folders.TestRoot, recursive: true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PublishIIS_modifies_existing_web_config()
|
||||
{
|
||||
var webRoot = "wwwroot";
|
||||
var folders = CreateTestDir("{}", webRoot);
|
||||
|
||||
File.WriteAllText(Path.Combine(folders.PublishOutput, webRoot, "web.config"),
|
||||
@"<configuration>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<add name=""httpPlatformHandler"" path=""*"" verb=""*"" modules=""httpPlatformHandler"" resourceType=""Unspecified""/>
|
||||
</handlers>
|
||||
<httpPlatform processPath=""%________%"" stdoutLogEnabled=""false"" startupTimeLimit=""1234""/>
|
||||
</system.webServer>
|
||||
</configuration>");
|
||||
|
||||
new PublishIISCommand(folders.PublishOutput, Path.Combine(folders.ProjectPath, "project.json"), null).Run();
|
||||
|
||||
var httpPlatformElement = GetPublishedWebConfig(folders.PublishOutput, webRoot)
|
||||
.Descendants("httpPlatform").Single();
|
||||
|
||||
Assert.Equal(@"..\projectDir.exe", (string)httpPlatformElement.Attribute("processPath"));
|
||||
Assert.Equal(@"1234", (string)httpPlatformElement.Attribute("startupTimeLimit"));
|
||||
|
||||
Directory.Delete(folders.TestRoot, recursive: true);
|
||||
}
|
||||
|
||||
private XDocument GetPublishedWebConfig(string publishOut, string webRoot)
|
||||
{
|
||||
return XDocument.Load(Path.Combine(publishOut, webRoot, "web.config"));
|
||||
}
|
||||
|
||||
private Folders CreateTestDir(string projectJson, string webRoot, string projectDir = "projectDir")
|
||||
{
|
||||
var testRoot = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(testRoot);
|
||||
|
||||
var projectPath = Path.Combine(testRoot, projectDir);
|
||||
Directory.CreateDirectory(projectPath);
|
||||
Directory.CreateDirectory(Path.Combine(projectPath, webRoot));
|
||||
File.WriteAllText(Path.Combine(projectPath, "project.json"), projectJson);
|
||||
|
||||
var publishOut = Path.Combine(testRoot, "publishOut");
|
||||
Directory.CreateDirectory(publishOut);
|
||||
Directory.CreateDirectory(Path.Combine(publishOut, webRoot));
|
||||
|
||||
return new Folders { TestRoot = testRoot, ProjectPath = projectPath, PublishOutput = publishOut };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
using Xunit;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.IISIntegration.Tools.Tests
|
||||
{
|
||||
public class WebConfigTransformFacts
|
||||
{
|
||||
private XDocument WebConfigTemplate => XDocument.Parse(
|
||||
@"<configuration>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<add name=""httpPlatformHandler"" path=""*"" verb=""*"" modules=""httpPlatformHandler"" resourceType=""Unspecified""/>
|
||||
</handlers>
|
||||
<httpPlatform processPath=""..\test.exe"" stdoutLogEnabled=""false"" stdoutLogFile=""..\logs\stdout.log"" startupTimeLimit=""3600"">
|
||||
<environmentVariables>
|
||||
<environmentVariable name=""ASPNET_APPLICATIONBASE"" value=""."" />
|
||||
</environmentVariables>
|
||||
</httpPlatform>
|
||||
</system.webServer>
|
||||
</configuration>");
|
||||
|
||||
[Fact]
|
||||
public void WebConfigTransform_creates_new_config_if_one_does_not_exist()
|
||||
{
|
||||
Assert.True(XNode.DeepEquals(WebConfigTemplate,
|
||||
WebConfigTransform.Transform(null, "test.exe", configureForAzure: 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)));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(new object[] { new[] { "system.webServer" } })]
|
||||
[InlineData(new object[] { new[] { "add" } })]
|
||||
[InlineData(new object[] { new[] { "handlers" } })]
|
||||
[InlineData(new object[] { new[] { "httpPlatform" } })]
|
||||
[InlineData(new object[] { new[] { "environmentVariables" } })]
|
||||
[InlineData(new object[] { new[] { "environmentVariable" } })]
|
||||
[InlineData(new object[] { new[] { "handlers", "httpPlatform", "environmentVariables" } })]
|
||||
public void WebConfigTransform_adds_missing_elements(string[] elementNames)
|
||||
{
|
||||
var input = WebConfigTemplate;
|
||||
foreach (var elementName in elementNames)
|
||||
{
|
||||
input.Descendants(elementName).Remove();
|
||||
}
|
||||
|
||||
Assert.True(XNode.DeepEquals(WebConfigTemplate,
|
||||
WebConfigTransform.Transform(input, "test.exe", configureForAzure: false)));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("add", "path", "test")]
|
||||
[InlineData("add", "verb", "test")]
|
||||
[InlineData("add", "modules", "mods")]
|
||||
[InlineData("add", "resourceType", "Either")]
|
||||
[InlineData("httpPlatform", "stdoutLogEnabled", "true")]
|
||||
[InlineData("httpPlatform", "startupTimeLimit", "1200")]
|
||||
[InlineData("httpPlatform", "arguments", "arg1")]
|
||||
[InlineData("httpPlatform", "stdoutLogFile", "logfile.log")]
|
||||
public void WebConfigTransform_wont_override_custom_values(string elementName, string attributeName, string attributeValue)
|
||||
{
|
||||
var input = WebConfigTemplate;
|
||||
input.Descendants(elementName).Single().SetAttributeValue(attributeName, attributeValue);
|
||||
|
||||
var output = WebConfigTransform.Transform(input, "test.exe", configureForAzure: false);
|
||||
Assert.Equal(attributeValue, (string)output.Descendants(elementName).Single().Attribute(attributeName));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WebConfigTransform_overwrites_processPath()
|
||||
{
|
||||
var newProcessPath =
|
||||
(string)WebConfigTransform.Transform(WebConfigTemplate, "app.exe", configureForAzure: false)
|
||||
.Descendants("httpPlatform").Single().Attribute("processPath");
|
||||
|
||||
Assert.Equal(@"..\app.exe", newProcessPath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WebConfigTransform_fixes_httpPlatformHandler_casing()
|
||||
{
|
||||
var input = WebConfigTemplate;
|
||||
input.Descendants("add").Single().SetAttributeValue("name", "httpplatformhandler");
|
||||
|
||||
Assert.True(XNode.DeepEquals(WebConfigTemplate,
|
||||
WebConfigTransform.Transform(input, "test.exe", configureForAzure: false)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WebConfigTransform_does_not_remove_children_of_httpPlatform_element()
|
||||
{
|
||||
var envVarElement =
|
||||
new XElement("environmentVariable", new XAttribute("name", "ENVVAR"), new XAttribute("value", "123"));
|
||||
|
||||
var input = WebConfigTemplate;
|
||||
input.Descendants("environmentVariable").Single().Add(envVarElement);
|
||||
|
||||
Assert.True(XNode.DeepEquals(envVarElement,
|
||||
WebConfigTransform.Transform(input, "app.exe", configureForAzure: false)
|
||||
.Descendants("environmentVariable").SingleOrDefault(e => (string)e.Attribute("name") == "ENVVAR")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WebConfigTransform_adds_stdoutLogEnabled_if_attribute_is_missing()
|
||||
{
|
||||
var input = WebConfigTemplate;
|
||||
input.Descendants("httpPlatform").Attributes("stdoutLogEnabled").Remove();
|
||||
|
||||
Assert.Equal(
|
||||
"false",
|
||||
(string)WebConfigTransform.Transform(input, "test.exe", configureForAzure: false)
|
||||
.Descendants().Attributes("stdoutLogEnabled").Single());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("false")]
|
||||
[InlineData("true")]
|
||||
public void WebConfigTransform_adds_stdoutLogFile_if_attribute_is_missing(string stdoutLogFile)
|
||||
{
|
||||
var input = WebConfigTemplate;
|
||||
|
||||
var httpPlatformElement = input.Descendants("httpPlatform").Single();
|
||||
httpPlatformElement.Attribute("stdoutLogEnabled").Remove();
|
||||
if (stdoutLogFile != null)
|
||||
{
|
||||
httpPlatformElement.SetAttributeValue("stdoutLogEnabled", stdoutLogFile);
|
||||
}
|
||||
|
||||
Assert.Equal(
|
||||
@"..\logs\stdout.log",
|
||||
(string)WebConfigTransform.Transform(input, "test.exe", configureForAzure: false)
|
||||
.Descendants().Attributes("stdoutLogFile").Single());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("true")]
|
||||
[InlineData("false")]
|
||||
public void WebConfigTransform_does_not_change_existing_stdoutLogEnabled(string stdoutLogEnabledValue)
|
||||
{
|
||||
var input = WebConfigTemplate;
|
||||
var httpPlatformElement = input.Descendants("httpPlatform").Single();
|
||||
|
||||
httpPlatformElement.SetAttributeValue("stdoutLogFile", "mylog.txt");
|
||||
httpPlatformElement.Attributes("stdoutLogEnabled").Remove();
|
||||
if (stdoutLogEnabledValue != null)
|
||||
{
|
||||
input.Descendants("httpPlatform").Single().SetAttributeValue("stdoutLogEnabled", stdoutLogEnabledValue);
|
||||
}
|
||||
|
||||
Assert.Equal(
|
||||
"mylog.txt",
|
||||
(string)WebConfigTransform.Transform(input, "test.exe", configureForAzure: false)
|
||||
.Descendants().Attributes("stdoutLogFile").Single());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WebConfigTransform_correctly_configures_for_Azure()
|
||||
{
|
||||
var input = WebConfigTemplate;
|
||||
input.Descendants("httpPlatform").Attributes().Remove();
|
||||
|
||||
var httPlatformElement = WebConfigTransform.Transform(input, "test.exe", configureForAzure: true)
|
||||
.Descendants("httpPlatform").Single();
|
||||
httPlatformElement.Elements().Remove();
|
||||
|
||||
Assert.True(XNode.DeepEquals(
|
||||
XDocument.Parse(@"<httpPlatform processPath=""%home%\site\test.exe"" stdoutLogEnabled=""false""
|
||||
stdoutLogFile=""\\?\%home%\LogFiles\stdout.log"" startupTimeLimit=""3600""/>").Root,
|
||||
httPlatformElement));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WebConfigTransform_overrites_value_for_ASPNET_APPLICATIONBASE()
|
||||
{
|
||||
var input = WebConfigTemplate;
|
||||
input.Descendants("environmentVariable").Single().SetAttributeValue("value", "abc");
|
||||
|
||||
Assert.True(XNode.DeepEquals(WebConfigTemplate,
|
||||
WebConfigTransform.Transform(input, "test.exe", configureForAzure: false)));
|
||||
}
|
||||
|
||||
private bool VerifyMissingElementCreated(params string[] elementNames)
|
||||
{
|
||||
var input = WebConfigTemplate;
|
||||
foreach (var elementName in elementNames)
|
||||
{
|
||||
input.Descendants(elementName).Remove();
|
||||
}
|
||||
|
||||
return XNode.DeepEquals(WebConfigTemplate,
|
||||
WebConfigTransform.Transform(input, "test.exe", configureForAzure: false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"xunit": "2.1.0",
|
||||
"dotnet-publish-iis": "1.0.0-*",
|
||||
"Microsoft.NETCore.Platforms": "1.0.1-*"
|
||||
},
|
||||
"frameworks": {
|
||||
"dnxcore50": {
|
||||
"imports": "portable-net451+win8",
|
||||
"dependencies": {
|
||||
"dotnet-test-xunit": "1.0.0-dev-*"
|
||||
}
|
||||
}
|
||||
},
|
||||
"testRunner": "xunit"
|
||||
}
|
||||
Loading…
Reference in New Issue