Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorLluis Sanchez <lluis@xamarin.com>2019-07-16 16:51:26 +0300
committerGitHub <noreply@github.com>2019-07-16 16:51:26 +0300
commitd2a3faf68c0dfc5cd00f0a7362f4ba1775f15529 (patch)
tree6942c640ebd6d1e9a11bee30dcf948fed7bd76d9 /main
parent0faf50a228bea29af5ede50b3401ac045b59ca43 (diff)
parent68fb9b7fd998dbb11cf9e19645477a223a18000b (diff)
Merge pull request #8104 from mono/Fixes-810355
[Ide][Core] Adds support for AppendTargetFrameworkToOutputPath
Diffstat (limited to 'main')
-rw-r--r--main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkExtensions.cs3
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProjectConfiguration.cs94
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/OutputOptionsPanel.cs208
-rw-r--r--main/tests/Ide.Tests/MonoDevelop.Ide.Projects.OptionPanels/OutputOptionsPanelTests.cs141
-rw-r--r--main/tests/Ide.Tests/MonoDevelop.Ide.Tests.csproj2
5 files changed, 343 insertions, 105 deletions
diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkExtensions.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkExtensions.cs
index 364701d36d..1674138267 100644
--- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkExtensions.cs
+++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkExtensions.cs
@@ -82,8 +82,7 @@ namespace MonoDevelop.DotNetCore
public static bool IsNetCoreAppOrHigher (this TargetFramework framework, DotNetCoreVersion version)
{
- DotNetCoreVersion dotNetCoreVersion;
- DotNetCoreVersion.TryParse (framework.Id.Version, out dotNetCoreVersion);
+ DotNetCoreVersion.TryParse (framework.Id.Version, out var dotNetCoreVersion);
if (dotNetCoreVersion == null)
return false;
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProjectConfiguration.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProjectConfiguration.cs
index 764d5d67a3..77068bab52 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProjectConfiguration.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProjectConfiguration.cs
@@ -27,15 +27,11 @@
//
using System;
-using System.Collections;
-using System.IO;
using System.Linq;
using MonoDevelop.Core;
-using MonoDevelop.Core.Serialization;
using MonoDevelop.Core.Assemblies;
using MonoDevelop.Core.StringParsing;
using System.Collections.Generic;
-using MonoDevelop.Projects.MSBuild;
namespace MonoDevelop.Projects
{
@@ -50,8 +46,12 @@ namespace MonoDevelop.Projects
{
string assembly;
string sourcePath;
+
DotNetCompilerParameters compilationParameters;
+ public bool? AppendTargetFrameworkToOutputPath { get; set; }
+ public string TargetFrameworkShortName { get; internal set; } = string.Empty;
+
public DotNetProjectConfiguration (string id): base (id)
{
}
@@ -60,13 +60,16 @@ namespace MonoDevelop.Projects
{
base.Read (pset);
+ //we are assuming that if AppendTargetFrameworkToOutputPath has a value is .NET Core / .NET Standard proj.
+ AppendTargetFrameworkToOutputPath = pset.GetValue<bool?> ("AppendTargetFrameworkToOutputPath", defaultValue: null);
+ TargetFrameworkShortName = pset.GetValue ("TargetFramework");
assembly = pset.GetValue ("AssemblyName");
- signAssembly = pset.GetValue<bool> ("SignAssembly");
- delaySign = pset.GetValue<bool> ("DelaySign");
+ SignAssembly = pset.GetValue<bool> ("SignAssembly");
+ DelaySign = pset.GetValue<bool> ("DelaySign");
PublicSign = pset.GetValue<bool> (nameof(PublicSign));
- assemblyKeyFile = pset.GetPathValue ("AssemblyOriginatorKeyFile", FilePath.Empty);
- if (string.IsNullOrEmpty (assemblyKeyFile))
- assemblyKeyFile = pset.GetPathValue ("AssemblyKeyFile", FilePath.Empty);
+ AssemblyKeyFile = pset.GetPathValue ("AssemblyOriginatorKeyFile", FilePath.Empty);
+ if (string.IsNullOrEmpty (AssemblyKeyFile))
+ AssemblyKeyFile = pset.GetPathValue ("AssemblyKeyFile", FilePath.Empty);
if (compilationParameters != null)
compilationParameters.Read (pset);
}
@@ -75,38 +78,30 @@ namespace MonoDevelop.Projects
{
base.Write (pset);
pset.SetValue ("AssemblyName", assembly, mergeToMainGroup: true);
- pset.SetValue ("SignAssembly", signAssembly, defaultValue:false, mergeToMainGroup: true);
- pset.SetValue ("DelaySign", delaySign, defaultValue:false, mergeToMainGroup:true);
+ pset.SetValue ("SignAssembly", SignAssembly, defaultValue:false, mergeToMainGroup: true);
+ pset.SetValue ("DelaySign", DelaySign, defaultValue:false, mergeToMainGroup:true);
pset.SetValue (nameof(PublicSign), PublicSign, defaultValue: false, mergeToMainGroup: true);
- pset.SetValue ("AssemblyOriginatorKeyFile", assemblyKeyFile, defaultValue:FilePath.Empty, mergeToMainGroup:true);
+ pset.SetValue ("AssemblyOriginatorKeyFile", AssemblyKeyFile, defaultValue:FilePath.Empty, mergeToMainGroup:true);
if (compilationParameters != null)
compilationParameters.Write (pset);
- }
- private bool signAssembly = false;
- public bool SignAssembly {
- get { return signAssembly; }
- set { signAssembly = value; }
- }
-
- private bool delaySign = false;
- public bool DelaySign {
- get { return delaySign; }
- set { delaySign = value; }
+ if (AppendTargetFrameworkToOutputPath ?? true) {
+ pset.RemoveProperty (nameof (AppendTargetFrameworkToOutputPath));
+ } else {
+ pset.SetValue (nameof (AppendTargetFrameworkToOutputPath), false);
+ }
}
+ public bool SignAssembly { get; set; } = false;
+ public bool DelaySign { get; set; } = false;
public bool PublicSign { get; set; }
internal string OldAssemblyKeyFile {
- set { assemblyKeyFile = value; }
+ set { AssemblyKeyFile = value; }
}
- private FilePath assemblyKeyFile = FilePath.Empty;
- public FilePath AssemblyKeyFile {
- get { return assemblyKeyFile; }
- set { assemblyKeyFile = value; }
- }
-
+ public FilePath AssemblyKeyFile { get; set; } = FilePath.Empty;
+
public virtual string OutputAssembly {
get { return assembly; }
set { assembly = value; }
@@ -114,11 +109,10 @@ namespace MonoDevelop.Projects
public virtual CompileTarget CompileTarget {
get {
- DotNetProject prj = ParentItem as DotNetProject;
- if (prj != null)
+ if (ParentItem is DotNetProject prj)
return prj.CompileTarget;
- else
- return CompileTarget.Library;
+
+ return CompileTarget.Library;
}
}
@@ -139,21 +133,19 @@ namespace MonoDevelop.Projects
public TargetFramework TargetFramework {
get {
- DotNetProject prj = ParentItem as DotNetProject;
- if (prj != null)
+ if (ParentItem is DotNetProject prj)
return prj.TargetFramework;
- else
- return Services.ProjectService.DefaultTargetFramework;
+
+ return Services.ProjectService.DefaultTargetFramework;
}
}
public TargetRuntime TargetRuntime {
get {
- DotNetProject prj = ParentItem as DotNetProject;
- if (prj != null)
+ if (ParentItem is DotNetProject prj)
return prj.TargetRuntime;
- else
- return Runtime.SystemAssemblyService.DefaultRuntime;
+
+ return Runtime.SystemAssemblyService.DefaultRuntime;
}
}
@@ -189,8 +181,10 @@ namespace MonoDevelop.Projects
protected override void OnCopyFrom (ItemConfiguration configuration, bool isRename)
{
base.OnCopyFrom (configuration, isRename);
- DotNetProjectConfiguration conf = (DotNetProjectConfiguration) configuration;
-
+ var conf = (DotNetProjectConfiguration) configuration;
+
+ AppendTargetFrameworkToOutputPath = conf.AppendTargetFrameworkToOutputPath;
+ TargetFrameworkShortName = conf.TargetFrameworkShortName ?? "unknown";
assembly = conf.assembly;
sourcePath = conf.sourcePath;
bool notifyParentItem = ParentItem != null;
@@ -199,15 +193,13 @@ namespace MonoDevelop.Projects
CompilationParameters = conf.compilationParameters != null ? conf.compilationParameters.Clone () : null;
if (notifyParentItem)
ParentItem?.NotifyModified ("CompilerParameters");
- signAssembly = conf.signAssembly;
- delaySign = conf.delaySign;
- assemblyKeyFile = conf.assemblyKeyFile;
- }
-
- public new DotNetProject ParentItem {
- get { return (DotNetProject) base.ParentItem; }
+ SignAssembly = conf.SignAssembly;
+ DelaySign = conf.DelaySign;
+ AssemblyKeyFile = conf.AssemblyKeyFile;
}
+ public new DotNetProject ParentItem => (DotNetProject)base.ParentItem;
+
public virtual IEnumerable<string> GetDefineSymbols ()
{
if (CompilationParameters != null)
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/OutputOptionsPanel.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/OutputOptionsPanel.cs
index 8e9ea17f25..c89a7c79d7 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/OutputOptionsPanel.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/OutputOptionsPanel.cs
@@ -24,9 +24,8 @@
// THE SOFTWARE.
using System;
-using System.Collections;
using System.Collections.Generic;
-using Gtk;
+using IO = System.IO;
using MonoDevelop.Components;
using MonoDevelop.Components.AtkCocoaHelper;
using MonoDevelop.Core;
@@ -66,13 +65,8 @@ namespace MonoDevelop.Ide.Projects.OptionPanels
protected override bool ConfigurationsAreEqual (IEnumerable<ItemConfiguration> configs)
{
- string outAsm = null;
- string outDir = null;
- string outDirTemplate = null;
- OutputOptionsPanelWidget.GetCommonData (configs, out outAsm, out outDir, out outDirTemplate);
- return outAsm.Length != 0 && (outDir.Length != 0 || outDirTemplate.Length != 0);
+ return !string.IsNullOrEmpty (configs.GetCommonOutDirTemplate ());
}
-
public override void ApplyChanges()
{
@@ -80,7 +74,6 @@ namespace MonoDevelop.Ide.Projects.OptionPanels
}
}
-
partial class OutputOptionsPanelWidget : Gtk.Bin
{
ItemConfiguration[] configurations;
@@ -108,46 +101,17 @@ namespace MonoDevelop.Ide.Projects.OptionPanels
public void Load (Project project, ItemConfiguration[] configs)
{
- this.configurations = configs;
- string outAsm = null;
- string outDir = null;
- string outDirTemplate = null;
-
- GetCommonData (configs, out outAsm, out outDir, out outDirTemplate);
-
- assemblyNameEntry.Text = outAsm;
+ configurations = configs;
+
+ var outDirTemplate = configs.GetCommonOutDirTemplate ();
+ assemblyNameEntry.Text = configs.GetAssemblyName ();
outputPathEntry.DefaultPath = project.BaseDirectory;
- outputPathEntry.Path = !string.IsNullOrEmpty (outDir) ? outDir : outDirTemplate;
- }
-
- internal static void GetCommonData (IEnumerable<ItemConfiguration> configs, out string outAsm, out string outDir, out string outDirTemplate)
- {
- outAsm = null;
- outDir = null;
- outDirTemplate = null;
-
- foreach (DotNetProjectConfiguration conf in configs) {
- if (outAsm == null)
- outAsm = conf.OutputAssembly;
- else if (outAsm != conf.OutputAssembly)
- outAsm = "";
-
- string dirTemplate = conf.OutputDirectory.ToString ().Replace (conf.Name, "$(Configuration)");
- if (conf.Platform.Length > 0)
- dirTemplate = dirTemplate.Replace (conf.Platform, "$(Platform)");
-
- if (outDir == null) {
- outDir = conf.OutputDirectory;
- outDirTemplate = dirTemplate;
- }
- else {
- if (outDir != conf.OutputDirectory)
- outDir = "";
- if (outDirTemplate != dirTemplate)
- outDirTemplate = "";
- }
- }
+
+ if (configs.Length == 1 && configs [0] is DotNetProjectConfiguration dotNetConfig) {
+ outDirTemplate = dotNetConfig.ParseOutDirectoryTemplate (outDirTemplate);
+ }
+ outputPathEntry.Path = outDirTemplate;
}
public bool ValidateChanges ()
@@ -163,6 +127,7 @@ namespace MonoDevelop.Ide.Projects.OptionPanels
string dir = outputPathEntry.Path;
dir = dir.Replace ("$(Configuration)", conf.Name);
dir = dir.Replace ("$(Platform)", conf.Platform);
+ dir = dir.Replace ("@(TargetFramework)", conf.TargetFrameworkShortName);
if (!string.IsNullOrEmpty (dir) && !FileService.IsValidPath (dir)) {
MessageService.ShowError (GettextCatalog.GetString ("Invalid output directory: {0}", dir));
return false;
@@ -180,13 +145,152 @@ namespace MonoDevelop.Ide.Projects.OptionPanels
foreach (DotNetProjectConfiguration conf in configurations) {
if (assemblyNameEntry.Text.Length > 0)
conf.OutputAssembly = assemblyNameEntry.Text;
- string dir = outputPathEntry.Path;
- dir = dir.Replace ("$(Configuration)", conf.Name);
- dir = dir.Replace ("$(Platform)", conf.Platform);
- if (!string.IsNullOrEmpty (dir))
+
+ var dir = conf.ResolveOutDirectoryTemplate (outputPathEntry.Path);
+
+ if (!string.IsNullOrEmpty (dir)) {
conf.OutputDirectory = dir;
+ } else {
+ //in case outputPathEntry.Path is empty we set DefaultPath
+ if (string.IsNullOrEmpty (outputPathEntry.Path) && configurations.Length == 1) {
+ conf.OutputDirectory = IO.Path.Combine (outputPathEntry.DefaultPath, "bin", conf.Name);
+ }
+ if (conf.AppendTargetFrameworkToOutputPath != null) { //if it is null is because of it's not a .NET Core project
+ conf.AppendTargetFrameworkToOutputPath = true;
+ }
+ }
}
}
}
-}
+ internal static class DotNetProjectConfigurationExtensions
+ {
+ /// <summary>
+ /// Given a DotNetProjectConfiguration returns final output directory with no msbuild variables
+ /// </summary>
+ /// <param name="conf"></param>
+ /// <param name="dir"></param>
+ /// <returns></returns>
+ internal static string ParseOutDirectoryTemplate (this DotNetProjectConfiguration conf, string dir)
+ {
+ dir = dir.Replace ("$(Configuration)", conf.Name);
+ dir = dir.Replace ("$(Platform)", conf.Platform);
+ dir = dir.Replace ("$(TargetFramework)", conf.TargetFrameworkShortName);
+ return dir;
+ }
+
+ /// <summary>
+ /// Given a DotNetProjectConfiguration returns temporary output directory for OutputOptionsPanelWidget
+ /// </summary>
+ /// <param name="conf"></param>
+ /// <param name="dir"></param>
+ /// <returns></returns>
+ internal static string ResolveOutDirectoryTemplate (this DotNetProjectConfiguration conf, string dir)
+ {
+ dir = dir.Replace ("$(Configuration)", conf.Name);
+ dir = dir.Replace ("$(Platform)", conf.Platform);
+
+ if (conf.AppendTargetFrameworkToOutputPath == null)
+ return dir;
+
+ dir = dir.Replace ("$(TargetFramework)", conf.TargetFrameworkShortName);
+
+ // if outputDirectory does not contain the targetFramework.Id, AppendTargetFrameworkToOutputPath is false for that config
+ conf.AppendTargetFrameworkToOutputPath = dir.EndsWithTargetFramework (conf.TargetFrameworkShortName) || dir.EndsWithTargetFramework ();
+
+ // check if the outputDirectory has been modified
+ var outputModified = conf.OutputDirectory.FullPath.ToString ().IndexOf (dir, StringComparison.InvariantCulture) != 0;
+ if (outputModified) {
+ // if so, we have to remove $(TargetFramework) at the end since msbuild will add it due to AppendTargetFrameworkToOutputPath == true
+ if (dir.EndsWithTargetFramework ()) {
+ dir = dir.Remove (dir.Length - "$(TargetFramework)".Length);
+ }
+ // in case we are in a specific configuration i.e. Debug, Release, there will be no msbuild variable $(TargetFramework)
+ // but TargetFrameworkId values, therefore we have to apply the same logic checking the end of the dir template
+ if (dir.EndsWithTargetFramework (conf.TargetFrameworkShortName)) {
+ dir = dir.Remove (dir.Length - conf.TargetFrameworkShortName.Length);
+ }
+ }
+
+ return dir.TrimEnd (IO.Path.DirectorySeparatorChar);
+ }
+
+ /// <summary>
+ /// Returns common name of AssemblyName for all configs; otherwise returns string.Empty
+ /// </summary>
+ /// <param name="configs"></param>
+ /// <returns></returns>
+ internal static string GetAssemblyName (this IEnumerable<ItemConfiguration> configs)
+ {
+ var outAsm = string.Empty;
+
+ foreach (DotNetProjectConfiguration conf in configs) {
+ if (string.IsNullOrEmpty (outAsm)) {
+ outAsm = conf.OutputAssembly;
+ continue;
+ }
+
+ if (outAsm != conf.OutputAssembly) {
+ outAsm = "";
+ break;
+ }
+ }
+
+ return outAsm;
+ }
+
+ /// <summary>
+ /// If exists returns template pattern for all configs
+ /// </summary>
+ /// <param name="configs"></param>
+ /// <returns>String.Empty if there is no common pattern otherwise the template pattern</returns>
+ internal static string GetCommonOutDirTemplate (this IEnumerable<ItemConfiguration> configs)
+ {
+ var baseTemplate = string.Empty;
+ foreach (DotNetProjectConfiguration config in configs) {
+ var template = GetTemplate (config);
+ if (string.IsNullOrEmpty (baseTemplate)) {
+ baseTemplate = template;
+ continue;
+ }
+ if (template != baseTemplate) {
+ return string.Empty;
+ }
+ }
+
+ return baseTemplate;
+ }
+
+ /// <summary>
+ /// Given a DotNetProjectConfiguration returns output directory template with msbuild variables
+ /// </summary>
+ /// <param name="conf"></param>
+ /// <returns></returns>
+ internal static string GetTemplate (this DotNetProjectConfiguration conf)
+ {
+ var dirTemplate = conf.OutputDirectory.ToString ();
+
+ if (conf.AppendTargetFrameworkToOutputPath == true) {
+ //default output directory ends with TargetFrameworkId but if the output directory
+ //has been previously modified then it does not, however we have to append it to dir template since will be part of
+ //the output part due to AppendTargetFrameworkToOutputPath == true
+ if (!dirTemplate.EndsWithTargetFramework (conf.TargetFrameworkShortName)) {
+ dirTemplate = IO.Path.Combine (dirTemplate, conf.TargetFrameworkShortName);
+ }
+
+ dirTemplate = dirTemplate.Replace ($"{conf.TargetFrameworkShortName}", $"$(TargetFramework)");
+ }
+
+ dirTemplate = dirTemplate.Replace ($"{conf.Name}", $"$(Configuration)");
+ if (conf.Platform.Length > 0)
+ dirTemplate = dirTemplate.Replace ($"{conf.Platform}", $"$(Platform)");
+
+ return dirTemplate;
+ }
+
+ static bool EndsWithTargetFramework (this string directory, string targetFramework = "$(TargetFramework)")
+ {
+ return directory.TrimEnd (IO.Path.DirectorySeparatorChar).EndsWith (targetFramework, StringComparison.InvariantCulture);
+ }
+ }
+}
diff --git a/main/tests/Ide.Tests/MonoDevelop.Ide.Projects.OptionPanels/OutputOptionsPanelTests.cs b/main/tests/Ide.Tests/MonoDevelop.Ide.Projects.OptionPanels/OutputOptionsPanelTests.cs
new file mode 100644
index 0000000000..662300c0ce
--- /dev/null
+++ b/main/tests/Ide.Tests/MonoDevelop.Ide.Projects.OptionPanels/OutputOptionsPanelTests.cs
@@ -0,0 +1,141 @@
+//
+// OutputOptionsPanelTests.cs
+//
+// Author:
+// josemiguel <jostor@microsoft.com>
+//
+// Copyright (c) 2019
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System.Linq;
+using System.Threading.Tasks;
+using MonoDevelop.Core;
+using MonoDevelop.Projects;
+using NUnit.Framework;
+using UnitTests;
+
+namespace MonoDevelop.Ide.Projects.OptionPanels
+{
+ [TestFixture]
+ public class OutputOptionsPanelTests
+ {
+ [Test]
+ public async Task When_OutputDir_Is_Modified_Then_It_Should_Hand_AppendTargetFrameworkToOutputPath_Accordingly ()
+ {
+ FilePath projFile = Util.GetSampleProject ("dotnetcore-console", "dotnetcore-console", "dotnetcore-sdk-console.csproj");
+
+ using (var p = (DotNetProject) await Services.ProjectService.ReadSolutionItem (Util.GetMonitor (), projFile)) {
+ var debug = (DotNetProjectConfiguration)p.Configurations [0]; //Debug
+ var release = (DotNetProjectConfiguration)p.Configurations [1]; //Release
+
+ //gets the dir template for both configs
+ var configs = new ItemConfiguration [] { debug, release };
+ var outDirTemplate = configs.GetCommonOutDirTemplate ();
+
+ Assert.That (outDirTemplate, Is.Not.Empty);
+
+ //modify it
+ outDirTemplate = outDirTemplate.Replace ("bin/$(Configuration)/$(TargetFramework)", "build-$(Configuration)/$(TargetFramework)/$(Configuration)/$(TargetFramework)");
+
+ // parses configs according to AppendTargetFrameworkToOutputPath
+ debug.OutputDirectory = debug.ParseOutDirectoryTemplate (outDirTemplate);
+ Assert.That (debug.OutputDirectory.FullPath.ToString (), Is.StringEnding (debug.TargetFrameworkShortName));
+
+ outDirTemplate = outDirTemplate.Replace ("/$(TargetFramework)", string.Empty);
+ release.OutputDirectory = release.ResolveOutDirectoryTemplate (outDirTemplate);
+ Assert.That (release.OutputDirectory.FullPath.ToString ().TrimEnd (System.IO.Path.DirectorySeparatorChar), Is.StringEnding (release.Name));
+ Assert.That (release.AppendTargetFrameworkToOutputPath, Is.False);
+ }
+ }
+
+ [TestCase ("/output/$(Configuration)/$(TargetFramework)", "foo", "/output/foo")]
+ [TestCase ("/output/$(Configuration)", "foo", "/output/foo")]
+ [TestCase ("/output/$(TargetFramework)/$(Configuration)/$(TargetFramework)", "foo", "/output/netcore22/foo")]
+ [TestCase ("/output-$(Configuration)", "foo", "/output-foo")]
+ public void ResolveOutDirectoryTemplateTest (string template, string id, string expected)
+ {
+ var dotnetConfig = new DotNetProjectConfiguration (id) {
+ AppendTargetFrameworkToOutputPath = true,
+ TargetFrameworkShortName = "netcore22"
+ };
+
+ var result = dotnetConfig.ResolveOutDirectoryTemplate (template);
+
+ Assert.That (result, Is.EqualTo (expected));
+ }
+
+ [Test]
+ public void ParseOutDirectoryTemplateTest ()
+ {
+ string expectedOutput = System.IO.Path.Combine ("Users", "ProjectFoo", "Foo", "netcore22");
+ var conf = new DotNetProjectConfiguration ("Foo") {
+ TargetFrameworkShortName = "netcore22"
+ };
+
+ string outputTemplate = System.IO.Path.Combine ("Users", "ProjectFoo", "$(Configuration)", "$(TargetFramework)");
+ var parsed = conf.ParseOutDirectoryTemplate (outputTemplate);
+
+ Assert.That (parsed, Is.EqualTo (expectedOutput));
+ }
+
+ [Test]
+ public void GetTemplateTest ()
+ {
+ string expectedTemplate = System.IO.Path.Combine ("Users", "Project", "$(Configuration)", "$(TargetFramework)");
+ var conf = new DotNetProjectConfiguration ("Foo") {
+ TargetFrameworkShortName = "netcore22",
+ OutputDirectory = System.IO.Path.Combine ("Users", "Project", "Foo", "netcore22"),
+ AppendTargetFrameworkToOutputPath = true
+ };
+
+ var template = conf.GetTemplate ();
+
+ Assert.That (template, Is.EqualTo (expectedTemplate));
+ }
+
+ [Test]
+ public void GetAssemblyNameTest ()
+ {
+ var debug = new DotNetProjectConfiguration ("Debug");
+ var release = new DotNetProjectConfiguration ("Release");
+
+ debug.OutputAssembly = "assembly_debug";
+ release.OutputAssembly = "assembly_release";
+ Assert.That (new ItemConfiguration [] { debug, release }.GetAssemblyName (), Is.Empty);
+
+ debug.OutputAssembly = release.OutputAssembly = "assembly";
+ Assert.That (new ItemConfiguration [] { debug, release }.GetAssemblyName (), Is.EqualTo ("assembly"));
+ }
+
+ [Test]
+ public void GetCommonOutDirTemplateTest ()
+ {
+ var debug = new DotNetProjectConfiguration ("Debug");
+ var release = new DotNetProjectConfiguration ("Release");
+
+ debug.OutputDirectory = new FilePath ("/Users/project/bin/Debug");
+ release.OutputDirectory = new FilePath ("/Users/project/bin/Release");
+ Assert.That (new ItemConfiguration [] { debug, release }.GetCommonOutDirTemplate (), Is.EqualTo ("/Users/project/bin/$(Configuration)"));
+
+ debug.OutputDirectory = new FilePath ("/Users/project/build/Debug");
+ release.OutputDirectory = new FilePath ("/Users/project/bin/Release");
+ Assert.That (new ItemConfiguration [] { debug, release }.GetCommonOutDirTemplate (), Is.Empty);
+ }
+ }
+}
diff --git a/main/tests/Ide.Tests/MonoDevelop.Ide.Tests.csproj b/main/tests/Ide.Tests/MonoDevelop.Ide.Tests.csproj
index 34c527f75a..9d66fab460 100644
--- a/main/tests/Ide.Tests/MonoDevelop.Ide.Tests.csproj
+++ b/main/tests/Ide.Tests/MonoDevelop.Ide.Tests.csproj
@@ -130,6 +130,7 @@
<Compile Include="MonoDevelop.Ide.FindInFiles\PatternMatcherTests.cs" />
<Compile Include="MonoDevelop.Ide.Composition\CompositionManagerTests.cs" />
<Compile Include="MonoDevelop.Ide.Gui\GLibLoggingTests.cs" />
+ <Compile Include="MonoDevelop.Ide.Projects.OptionPanels\OutputOptionsPanelTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\core\MonoDevelop.Ide\MonoDevelop.Ide.csproj">
@@ -196,6 +197,7 @@
<ItemGroup>
<Folder Include="MonoDevelop.Ide.Gui.DocumentModels\" />
<Folder Include="MonoDevelop.Ide.Gui.Documents\" />
+ <Folder Include="MonoDevelop.Ide.Projects.OptionPanels\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>