Skip to content

Commit

Permalink
Parse console output to return search result
Browse files Browse the repository at this point in the history
  • Loading branch information
Marusyk authored and devlead committed Apr 3, 2022
1 parent 4cb0a7a commit d22cc84
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,32 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Collections.Generic;
using Cake.Common.Tools.DotNet.Workload.Search;

namespace Cake.Common.Tests.Fixtures.Tools.DotNet.Workload.Search
{
internal sealed class DotNetWorkloadSearcherFixture : DotNetFixture<DotNetWorkloadSearchSettings>
{
public string SearchString { get; set; }
public IEnumerable<DotNetWorkload> Workloads { get; set; }

public void GivenAvailableWorkloadsResult()
{
ProcessRunner.Process.SetStandardOutput(new string[]
{
"Workload ID Description",
"-----------------------------------------------------",
"maui .NET MAUI SDK for all platforms",
"maui-desktop .NET MAUI SDK for Desktop",
"maui-mobile .NET MAUI SDK for Mobile"
});
}

protected override void RunTool()
{
var tool = new DotNetWorkloadSearcher(FileSystem, Environment, ProcessRunner, Tools);
tool.Search(SearchString);
Workloads = tool.Search(SearchString, Settings);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,36 @@ public void Should_Add_SearchString_Argument()
// Then
Assert.Equal("workload search maui", result.Args);
}

[Fact]
public void Should_Return_Correct_List_Of_Workloads()
{
// Given
var fixture = new DotNetWorkloadSearcherFixture();
fixture.SearchString = "maui";
fixture.GivenAvailableWorkloadsResult();

// When
var result = fixture.Run();

// Then
Assert.Collection(fixture.Workloads,
item =>
{
Assert.Equal(item.Id, "maui");
Assert.Equal(item.Description, ".NET MAUI SDK for all platforms");
},
item =>
{
Assert.Equal(item.Id, "maui-desktop");
Assert.Equal(item.Description, ".NET MAUI SDK for Desktop");
},
item =>
{
Assert.Equal(item.Id, "maui-mobile");
Assert.Equal(item.Description, ".NET MAUI SDK for Mobile");
});
}
}
}
}
58 changes: 52 additions & 6 deletions src/Cake.Common/Tools/DotNet/DotNetAliases.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1851,41 +1851,87 @@ public static void DotNetSDKCheck(this ICakeContext context)
/// Lists available workloads.
/// </summary>
/// <param name="context">The context.</param>
/// <returns>The list of available workloads.</returns>
/// <example>
/// <code>
/// DotNetWorkloadSearch();
/// var workloads = DotNetWorkloadSearch();
///
/// foreach (var workload in workloads)
/// {
/// Information($"Id: {workload.Id}, Description: {workload.Description}");
/// }
/// </code>
/// </example>
[CakeMethodAlias]
[CakeAliasCategory("Workload")]
[CakeNamespaceImport("Cake.Common.Tools.DotNet.Workload.Search")]
public static IEnumerable<DotNetWorkload> DotNetWorkloadSearch(this ICakeContext context)
{
return context.DotNetWorkloadSearch(null);
}

/// <summary>
/// Lists available workloads by specifying all or part of the workload ID.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="searchString">The workload ID to search for, or part of it.</param>
/// <returns>The list of available workloads.</returns>
/// <example>
/// <code>
/// var workloads = DotNetWorkloadSearch("maui");
///
/// foreach (var workload in workloads)
/// {
/// Information($"Id: {workload.Id}, Description: {workload.Description}");
/// }
/// </code>
/// </example>
[CakeMethodAlias]
[CakeAliasCategory("Workload")]
[CakeNamespaceImport("Cake.Common.Tools.DotNet.Workload.Search")]
public static void DotNetWorkloadSearch(this ICakeContext context)
public static IEnumerable<DotNetWorkload> DotNetWorkloadSearch(this ICakeContext context, string searchString)
{
context.DotNetWorkloadSearch(null);
return context.DotNetWorkloadSearch(searchString, null);
}

/// <summary>
/// Lists available workloads by specifying all or part of the workload ID.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="searchString">The workload ID to search for, or part of it.</param>
/// <returns>The list of available workloads.</returns>
/// <example>
/// <code>
/// DotNetWorkloadSearch("maui");
/// var settings = new DotNetWorkloadSearchSettings
/// {
/// Verbosity = Detailed
/// };
///
/// var workloads = DotNetWorkloadSearch("maui", settings);
///
/// foreach (var workload in workloads)
/// {
/// Information($"Id: {workload.Id}, Description: {workload.Description}");
/// }
/// </code>
/// </example>
[CakeMethodAlias]
[CakeAliasCategory("Workload")]
[CakeNamespaceImport("Cake.Common.Tools.DotNet.Workload.Search")]
public static void DotNetWorkloadSearch(this ICakeContext context, string searchString)
public static IEnumerable<DotNetWorkload> DotNetWorkloadSearch(this ICakeContext context, string searchString, DotNetWorkloadSearchSettings settings)
{
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}

if (settings == null)
{
settings = new DotNetWorkloadSearchSettings();
}

var searcher = new DotNetWorkloadSearcher(context.FileSystem, context.Environment, context.ProcessRunner, context.Tools);
searcher.Search(searchString);
return searcher.Search(searchString, settings);
}
}
}
33 changes: 33 additions & 0 deletions src/Cake.Common/Tools/DotNet/Workload/Search/DotNetWorkload.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// 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.

namespace Cake.Common.Tools.DotNet.Workload.Search
{
/// <summary>
/// Workload information.
/// </summary>
public class DotNetWorkload
{
/// <summary>
/// Initializes a new instance of the <see cref="DotNetWorkload" /> class.
/// </summary>
/// <param name="id">The workload Id.</param>
/// <param name="description">The workload description.</param>
public DotNetWorkload(string id, string description)
{
Id = id;
Description = description;
}

/// <summary>
/// Gets the workload Id.
/// </summary>
public string Id { get; }

/// <summary>
/// Gets the workload description.
/// </summary>
public string Description { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Linq;
using Cake.Core;
using Cake.Core.IO;
using Cake.Core.Tooling;
Expand Down Expand Up @@ -32,10 +35,25 @@ public DotNetWorkloadSearcher(
/// Lists the latest available version of the .NET SDK and .NET Runtime, for each feature band.
/// </summary>
/// <param name="searchString">The workload ID to search for, or part of it.</param>
public void Search(string searchString)
/// <param name="settings">The settings.</param>
/// <returns>The list of available workloads.</returns>
public IEnumerable<DotNetWorkload> Search(string searchString, DotNetWorkloadSearchSettings settings)
{
var settings = new DotNetWorkloadSearchSettings();
RunCommand(settings, GetArguments(searchString, settings));
if (settings == null)
{
throw new ArgumentNullException(nameof(settings));
}

var processSettings = new ProcessSettings
{
RedirectStandardOutput = true
};

IEnumerable<string> result = null;
RunCommand(settings, GetArguments(searchString, settings), processSettings,
process => result = process.GetStandardOutput());

return ParseResult(result).ToList();
}

private ProcessArgumentBuilder GetArguments(string searchString, DotNetWorkloadSearchSettings settings)
Expand All @@ -51,5 +69,39 @@ private ProcessArgumentBuilder GetArguments(string searchString, DotNetWorkloadS

return builder;
}

private static IEnumerable<DotNetWorkload> ParseResult(IEnumerable<string> result)
{
bool first = true;
int descriptionIndex = -1;
foreach (var line in result)
{
if (first)
{
if (line?.StartsWith("Workload ID") == true
&& (descriptionIndex = line?.IndexOf("Description") ?? -1) > 11)
{
first = false;
}
continue;
}

if (string.IsNullOrWhiteSpace(line))
{
continue;
}

var trimmedLine = line.Trim();

if (trimmedLine.Trim().All(c => c == '-'))
{
continue;
}

yield return new DotNetWorkload(
string.Concat(trimmedLine.Take(descriptionIndex)).TrimEnd(),
string.Concat(trimmedLine.Skip(descriptionIndex)));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,14 @@ Task("Cake.Common.Tools.DotNet.DotNetAliases.DotNetWorkloadSearch")
var searchString = "maui";

// When
DotNetWorkloadSearch(searchString);
var workloads = DotNetWorkloadSearch(searchString);

// Then
foreach(var workload in workloads)
{
Assert.Contains(workload.Id, "maui");
Assert.Contains(workload.Description, ".NET MAUI SDK");
}
});

Task("Cake.Common.Tools.DotNet.DotNetAliases.DotNetBuildServerShutdown")
Expand Down

0 comments on commit d22cc84

Please sign in to comment.