Skip to content

Commit

Permalink
Merge branch 'agc93-feature/gh-79' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
agc93 committed Mar 21, 2019
2 parents 7fafe2e + 7378694 commit 66f8f66
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 53 deletions.
1 change: 1 addition & 0 deletions src/Cake.VisualStudio.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
<Compile Include="Configuration\BindingParser.cs" />
<Compile Include="Configuration\ConfigurationExtensions.cs" />
<Compile Include="Configuration\ConfigurationParser.cs" />
<Compile Include="Configuration\ToolLocator.cs" />
<Compile Include="ContentType\CakeContentTypeDefinition.cs" />
<Compile Include="Editor\IndentationResult.cs" />
<Compile Include="Editor\LineExtensions.cs" />
Expand Down
50 changes: 50 additions & 0 deletions src/Configuration/ConfigurationParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Cake.VisualStudio.Helpers;
using IniParser;
using IniParser.Model.Configuration;
using IniParser.Parser;
using System.IO;
using System.Linq;

namespace Cake.VisualStudio.Configuration
{
internal sealed class ConfigurationParser
{
private static IniDataParser Parser => new IniDataParser(new IniParserConfiguration {AssigmentSpacer = ""});
internal string SectionName { get; set; } = "TaskRunnerBindings";

public ConfigurationParser(string filePath)
{
FilePath = filePath;
Expand Down Expand Up @@ -46,5 +50,51 @@ internal void RemoveBindings()
var removeSection = data.Sections.RemoveSection(SectionName);
parser.WriteFile(FilePath, data);
}

/// <summary>
/// Gets a key from the Paths section of cake.config
/// </summary>
/// <param name="key">The key to retrieve.</param>
/// <returns>The config value</returns>
/// <remarks>
/// This defaults the key to Tools since that's what we're using currently.
/// I've left this an argument in case we add a non-standard key to cake.config to specifically override VS.
/// </remarks>
internal string GetToolsPath(string key = "Tools")
{
var parser = new FileIniDataParser(Parser);
var data = parser.ReadFile(FilePath);
if (data.Sections.ContainsSection("Paths"))
{
return data["Paths"].ReadValues(key).LastOrDefault();
}
return null;
}

internal static string GetConfigFilePath(string configPath, bool create = false)
{
string bindingPath;
var path = CakePackage.Dte?.Solution?.FindProjectItem(Constants.ConfigFileName);
if (path != null && path.FileCount == 1)
{
bindingPath = path.FileNames[1];
}
else
{
var cpath = Path.Combine(Path.GetDirectoryName(configPath), Constants.ConfigFileName);
try
{

if (!File.Exists(cpath) && create) File.Create(cpath).Close();
if (File.Exists(cpath)) ProjectHelpers.GetSolutionItemsProject(CakePackage.Dte).AddFileToProject(cpath);
}
catch
{
// ignored
}
bindingPath = cpath;
}
return string.IsNullOrWhiteSpace(bindingPath) ? null : bindingPath; // remove the empty string scenario
}
}
}
67 changes: 67 additions & 0 deletions src/Configuration/ToolLocator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Cake.VisualStudio.Helpers;
using Microsoft.VisualStudio.Shell;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cake.VisualStudio.Configuration
{
internal sealed class ToolLocator
{
private readonly string _executable;
private List<string> KnownPaths { get; set; } = new List<string>();

public ToolLocator(string executableName)
{
_executable = executableName;
}

public ToolLocator AddEnvironmentVariables(string variable = "CAKE_PATHS_TOOLS")
{
var env = Environment.GetEnvironmentVariable(variable);
if (!string.IsNullOrWhiteSpace(env) && Directory.Exists(env))
{
KnownPaths.Add(env);
}
return this;
}

public ToolLocator AddKnownPaths(params string[] paths)
{
KnownPaths.AddRange(paths);
return this;
}

public ToolLocator AddConfigPath(Func<ConfigurationParser> configFunc)
{
var path = configFunc?.Invoke()?.GetToolsPath();
if (path != null)
{
KnownPaths.Add(path);
KnownPaths.Add(Path.Combine(path, "Cake"));
}
return this;
}

public string Locate(string workingDirectory)
{
foreach (var path in KnownPaths.Select(p => p.TrimPrefix("./")))
{
var fullPath = Path.Combine(workingDirectory, path, _executable);
if (File.Exists(fullPath)) return fullPath;
}
if (PathHelpers.ExistsOnPath(_executable))
{
return _executable; // assume PATH
}
return null;
}
}
}
35 changes: 11 additions & 24 deletions src/TaskRunner/TaskRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Cake.VisualStudio.Configuration;
using Cake.VisualStudio.Helpers;
using Microsoft.VisualStudio.TaskRunnerExplorer;

Expand Down Expand Up @@ -82,19 +83,6 @@ private ITaskRunnerNode NotFoundNode(string configPath)
Description = message,
Command = new TaskRunnerCommand(Path.GetDirectoryName(configPath), "echo", message),
};
/*
* return new TaskRunnerNode("Cake")
{
Children =
{
new TaskRunnerNode("Cake.exe not found", true)
{
Description = message,
Command = new TaskRunnerCommand(Path.GetDirectoryName(configPath), "echo", message),
}
}
};
*/
}

private ITaskRunnerNode LoadHierarchy(string configPath)
Expand Down Expand Up @@ -141,17 +129,16 @@ private ITaskRunnerCommand GetCommand(string cwd, string arguments)

private static string GetCakePath(string cwd)
{
var knownPaths = new[] {"tools/Cake/Cake.exe", "Cake/Cake.exe", "Cake.exe"};
foreach (var path in knownPaths)
{
var fullPath = Path.Combine(cwd, path);
if (File.Exists(fullPath)) return fullPath;
}
if (PathHelpers.ExistsOnPath("cake.exe") || PathHelpers.ExistsOnPath("cake"))
{
return "cake"; // assume PATH
}
return null;
var locator = new ToolLocator("cake.exe")
.AddConfigPath(() => new ConfigurationParser(ConfigurationParser.GetConfigFilePath(cwd)))
.AddEnvironmentVariables()
.AddKnownPaths("tools/Cake", "Cake", ".");
var path = locator.Locate(cwd);
return string.IsNullOrWhiteSpace(path)
? PathHelpers.ExistsOnPath("cake.exe")
? "cake"
: null
: path;
}

private static string GetExecutableFolder()
Expand Down
31 changes: 2 additions & 29 deletions src/TaskRunner/TaskRunnerConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,40 +35,13 @@ public void Dispose()

public string LoadBindings(string configPath)
{
string bindingPath = GetBindingPath(configPath) ?? configPath + ".bindings";

string bindingPath = ConfigurationParser.GetConfigFilePath(configPath) ?? configPath + ".bindings";
return File.Exists(bindingPath) ? new ConfigurationParser(bindingPath).LoadBinding().ToXml() : "<binding />";
}

private string GetBindingPath(string configPath, bool create = false)
{
string bindingPath;
var path = CakePackage.Dte.Solution?.FindProjectItem(Constants.ConfigFileName);
if (path != null && path.FileCount == 1)
{
bindingPath = path.FileNames[1];
}
else
{
var cpath = Path.Combine(Path.GetDirectoryName(configPath), Constants.ConfigFileName);
try
{

if (!File.Exists(cpath) && create) File.Create(cpath).Close();
if (File.Exists(cpath)) ProjectHelpers.GetSolutionItemsProject(CakePackage.Dte).AddFileToProject(cpath);
}
catch
{
// ignored
}
bindingPath = cpath;
}
return string.IsNullOrWhiteSpace(bindingPath) ? null : bindingPath; // remove the empty string scenario
}

public bool SaveBindings(string configPath, string bindingsXml)
{
string bindingPath = GetBindingPath(configPath, true) ?? configPath + ".bindings";
string bindingPath = ConfigurationParser.GetConfigFilePath(configPath, true) ?? configPath + ".bindings";
var config = new ConfigurationParser(bindingPath);
try
{
Expand Down

0 comments on commit 66f8f66

Please sign in to comment.