Skip to content

Commit

Permalink
Add DotNetSlnAdd alias for dotnet sln add command
Browse files Browse the repository at this point in the history
  • Loading branch information
Marusyk authored and devlead committed Nov 12, 2024
1 parent e08b39b commit 1d40c7c
Show file tree
Hide file tree
Showing 6 changed files with 475 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// 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 System.Collections.Generic;
using Cake.Common.Tools.DotNet.Sln.Add;
using Cake.Core.IO;

namespace Cake.Common.Tests.Fixtures.Tools.DotNet.Sln.Add
{
internal sealed class DotNetSlnAdderFixture : DotNetFixture<DotNetSlnAddSettings>
{
public FilePath Solution { get; set; }

public IEnumerable<FilePath> ProjectPath { get; set; }

protected override void RunTool()
{
var tool = new DotNetSlnAdder(FileSystem, Environment, ProcessRunner, Tools);
tool.Add(Solution, ProjectPath, Settings);
}
}
}
220 changes: 220 additions & 0 deletions src/Cake.Common.Tests/Unit/Tools/DotNet/Sln/Add/DotNetSlnAdderTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
// 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 System;
using Cake.Common.Tests.Fixtures.Tools.DotNet.Sln.Add;
using Cake.Common.Tools.DotNet;
using Cake.Core.IO;
using Cake.Testing;
using Xunit;

namespace Cake.Common.Tests.Unit.Tools.DotNet.Sln.Add
{
public sealed class DotNetSlnAdderTests
{
public sealed class TheAddMethod
{
[Fact]
public void Should_Throw_If_Process_Was_Not_Started()
{
// Given
var fixture = new DotNetSlnAdderFixture();
fixture.ProjectPath = new[] { (FilePath)"./lib1.csproj" };
fixture.GivenProcessCannotStart();

// When
var result = Record.Exception(() => fixture.Run());

// Then
AssertEx.IsCakeException(result, ".NET CLI: Process was not started.");
}

[Fact]
public void Should_Throw_If_Process_Has_A_Non_Zero_Exit_Code()
{
// Given
var fixture = new DotNetSlnAdderFixture();
fixture.ProjectPath = new[] { (FilePath)"./lib1.csproj" };
fixture.GivenProcessExitsWithCode(1);

// When
var result = Record.Exception(() => fixture.Run());

// Then
AssertEx.IsCakeException(result, ".NET CLI: Process returned an error (exit code 1).");
}

[Fact]
public void Should_Throw_If_ProjectPath_Is_Null()
{
// Given
var fixture = new DotNetSlnAdderFixture();
fixture.ProjectPath = null;

// When
var result = Record.Exception(() => fixture.Run());

// Then
AssertEx.IsArgumentNullException(result, "projectPath");
}

[Fact]
public void Should_Throw_If_ProjectPath_Is_Empty()
{
// Given
var fixture = new DotNetSlnAdderFixture();
fixture.ProjectPath = [];

// When
var result = Record.Exception(() => fixture.Run());

// Then
AssertEx.IsArgumentNullException(result, "projectPath");
}

[Fact]
public void Should_Throw_If_Settings_Are_Null()
{
// Given
var fixture = new DotNetSlnAdderFixture();
fixture.ProjectPath = new[] { (FilePath)"./lib1.csproj" };
fixture.Settings = null;

// When
var result = Record.Exception(() => fixture.Run());

// Then
AssertEx.IsArgumentNullException(result, "settings");
}

[Fact]
public void Should_Throw_If_InRoot_And_SolutionFolder_Are_Used_Together()
{
// Given
var fixture = new DotNetSlnAdderFixture();
fixture.ProjectPath = new[] { (FilePath)"./lib1.csproj" };
fixture.Settings.InRoot = true;
fixture.Settings.SolutionFolder = "mylibs";

// When
var result = Record.Exception(() => fixture.Run());

// Then
Assert.IsType<ArgumentException>(result);
Assert.Equal("InRoot and SolutionFolder cannot be used together.", result.Message);
}

[Fact]
public void Should_Add_Solution_Argument()
{
// Given
var fixture = new DotNetSlnAdderFixture();
fixture.Solution = (FilePath)"test.sln";
fixture.ProjectPath = new[] { (FilePath)"./lib1.csproj" };

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

// Then
Assert.NotNull(result);
Assert.Equal("sln \"/Working/test.sln\" add \"/Working/lib1.csproj\"", result.Args);
}

[Fact]
public void Should_Not_Add_Solution_Argument()
{
// Given
var fixture = new DotNetSlnAdderFixture();
fixture.Solution = null;
fixture.ProjectPath = new[] { (FilePath)"./lib1.csproj" };

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

// Then
Assert.NotNull(result);
Assert.Equal("sln add \"/Working/lib1.csproj\"", result.Args);
}

[Fact]
public void Should_Add_ProjectPath_Argument()
{
// Given
var fixture = new DotNetSlnAdderFixture();
fixture.ProjectPath = new[] { (FilePath)"./lib1.csproj" };

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

// Then
Assert.NotNull(result);
Assert.Equal("sln add \"/Working/lib1.csproj\"", result.Args);
}

[Fact]
public void Should_Add_All_ProjectPath()
{
// Given
var fixture = new DotNetSlnAdderFixture();
fixture.ProjectPath = new[] { (FilePath)"./lib1.csproj", "./lib2.csproj", "./lib3.csproj" };

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

// Then
Assert.NotNull(result);
Assert.Equal("sln add \"/Working/lib1.csproj\" \"/Working/lib2.csproj\" \"/Working/lib3.csproj\"", result.Args);
}

[Fact]
public void Should_Add_InRoot_Argument()
{
// Given
var fixture = new DotNetSlnAdderFixture();
fixture.ProjectPath = new[] { (FilePath)"./lib1.csproj" };
fixture.Settings.InRoot = true;

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

// Then
Assert.NotNull(result);
Assert.Equal("sln add --in-root \"/Working/lib1.csproj\"", result.Args);
}

[Fact]
public void Should_Add_SolutionFolder_Argument()
{
// Given
var fixture = new DotNetSlnAdderFixture();
fixture.ProjectPath = new[] { (FilePath)"./lib1.csproj" };
fixture.Settings.SolutionFolder = "mylibs";

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

// Then
Assert.NotNull(result);
Assert.Equal("sln add --solution-folder \"/Working/mylibs\" \"/Working/lib1.csproj\"", result.Args);
}

[Fact]
public void Should_Add_Additional_Arguments()
{
// Given
var fixture = new DotNetSlnAdderFixture();
fixture.Solution = (FilePath)"test.sln";
fixture.ProjectPath = new[] { (FilePath)"./lib1.csproj" };
fixture.Settings.Verbosity = DotNetVerbosity.Detailed;

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

// Then
Assert.NotNull(result);
Assert.Equal("sln \"/Working/test.sln\" add \"/Working/lib1.csproj\" --verbosity detailed", result.Args);
}
}
}
}
98 changes: 98 additions & 0 deletions src/Cake.Common/Tools/DotNet/DotNetAliases.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
using Cake.Common.Tools.DotNet.Restore;
using Cake.Common.Tools.DotNet.Run;
using Cake.Common.Tools.DotNet.SDKCheck;
using Cake.Common.Tools.DotNet.Sln.Add;
using Cake.Common.Tools.DotNet.Sln.List;
using Cake.Common.Tools.DotNet.Test;
using Cake.Common.Tools.DotNet.Tool;
Expand Down Expand Up @@ -2972,5 +2973,102 @@ public static IEnumerable<string> DotNetSlnList(this ICakeContext context, FileP
var lister = new DotNetSlnLister(context.FileSystem, context.Environment, context.ProcessRunner, context.Tools);
return lister.List(solution, settings);
}

/// <summary>
/// Adds one or more projects to the solution file.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="projectPath">The path to the project or projects to add to the solution. Glob patterns are supported on Unix/Linux-based systems.</param>
/// <example>
/// <code>
/// DotNetSlnAdd(GetFiles("./*.csproj"));
/// </code>
/// </example>
[CakeMethodAlias]
[CakeAliasCategory("Sln")]
[CakeNamespaceImport("Cake.Common.Tools.DotNet.Sln.Add")]
public static void DotNetSlnAdd(this ICakeContext context, IEnumerable<FilePath> projectPath)
{
context.DotNetSlnAdd(null, projectPath);
}

/// <summary>
/// Adds one or more projects to the solution file.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="solution">The solution file to use. If it is unspecified, the command searches the current directory for one and fails if there are multiple solution files.</param>
/// <param name="projectPath">The path to the project or projects to add to the solution. Glob patterns are supported on Unix/Linux-based systems.</param>
/// <example>
/// <code>
/// DotNetSlnAdd("app.sln", GetFiles("./*.csproj"));
/// </code>
/// </example>
[CakeMethodAlias]
[CakeAliasCategory("Sln")]
[CakeNamespaceImport("Cake.Common.Tools.DotNet.Sln.Add")]
public static void DotNetSlnAdd(this ICakeContext context, FilePath solution, IEnumerable<FilePath> projectPath)
{
context.DotNetSlnAdd(solution, projectPath, null);
}

/// <summary>
/// Adds one or more projects to the solution file.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="projectPath">The path to the project or projects to add to the solution. Glob patterns are supported on Unix/Linux-based systems.</param>
/// <param name="settings">The settings.</param>
/// <example>
/// <code>
/// var settings = new DotNetSlnAddSettings
/// {
/// SolutionFolder = "libs/math"
/// };
///
/// DotNetSlnAdd(GetFiles("./*.csproj"), settings);
/// </code>
/// </example>
[CakeMethodAlias]
[CakeAliasCategory("Sln")]
[CakeNamespaceImport("Cake.Common.Tools.DotNet.Sln.Add")]
public static void DotNetSlnAdd(this ICakeContext context, IEnumerable<FilePath> projectPath, DotNetSlnAddSettings settings)
{
context.DotNetSlnAdd(null, projectPath, settings);
}

/// <summary>
/// Adds one or more projects to the solution file.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="solution">The solution file to use. If it is unspecified, the command searches the current directory for one and fails if there are multiple solution files.</param>
/// <param name="projectPath">The path to the project or projects to add to the solution. Glob patterns are supported on Unix/Linux-based systems.</param>
/// <param name="settings">The settings.</param>
/// <example>
/// <code>
/// var settings = new DotNetSlnAddSettings
/// {
/// SolutionFolder = "libs/math"
/// };
///
/// DotNetSlnAdd("app.sln", GetFiles("./*.csproj"), settings);
/// </code>
/// </example>
[CakeMethodAlias]
[CakeAliasCategory("Sln")]
[CakeNamespaceImport("Cake.Common.Tools.DotNet.Sln.Add")]
public static void DotNetSlnAdd(this ICakeContext context, FilePath solution, IEnumerable<FilePath> projectPath, DotNetSlnAddSettings settings)
{
if (context is null)
{
throw new ArgumentNullException(nameof(context));
}

if (settings is null)
{
settings = new DotNetSlnAddSettings();
}

var adder = new DotNetSlnAdder(context.FileSystem, context.Environment, context.ProcessRunner, context.Tools);
adder.Add(solution, projectPath, settings);
}
}
}
25 changes: 25 additions & 0 deletions src/Cake.Common/Tools/DotNet/Sln/Add/DotNetSlnAddSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// 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.Core.IO;

namespace Cake.Common.Tools.DotNet.Sln.Add
{
/// <summary>
/// Contains settings used by <see cref="DotNetSlnAdder" />.
/// </summary>
public sealed class DotNetSlnAddSettings : DotNetSettings
{
/// <summary>
/// Gets or sets a value indicating whether to place the projects in the root of the solution, rather than creating a solution folder.
/// Can't be used with <see cref="SolutionFolder" />.
/// </summary>
public bool InRoot { get; set; }

/// <summary>
/// Gets or sets the destination solution folder path to add the projects to. Can't be used with <see cref="InRoot" />.
/// </summary>
public DirectoryPath SolutionFolder { get; set; }
}
}
Loading

0 comments on commit 1d40c7c

Please sign in to comment.