phmonte / Buildalyzer

A utility to perform design-time builds of .NET projects without having to think too hard about it.
MIT License
589 stars 92 forks source link

Immutability #255

Closed Corniel closed 4 months ago

Corniel commented 4 months ago

I would like to change the data structures that are part of Buildalyzer's API to be Immutable. As part of that, data structures that should be equal by value like EnvironmentOptions should become records. For collections, IReadOnlyCollection<T> and IReadOnlyDictionary<TKey, TValue>should be used.

For EnvironmentOptions that should look something like this:

public sealed record EnvironmentOptions
{
    /// <summary>
    /// Indicates a preferences towards the build environment to use.
    /// The default is a preference for the .NET Core SDK.
    /// </summary>
    public EnvironmentPreference Preference { get; init; } = EnvironmentPreference.Core;

    /// <summary>
    /// The default targets to build.
    /// </summary>
    public IReadOnlyCollection<string> TargetsToBuild { get; init; } = ["Clean", "Build"];

    /// <summary>
    /// Indicates that a design-time build should be performed.
    /// The default value is <c>true</c>. Note that when performing
    /// a design-time build, the <see cref="TargetsToBuild"/> will
    /// be ignored and the design-time targets will be used instead.
    /// </summary>
    /// <remarks>
    /// See https://github.com/dotnet/project-system/blob/master/docs/design-time-builds.md.
    /// </remarks>
    public bool DesignTime { get; init; } = true;

    /// <summary>
    /// Runs the restore target prior to any other targets using the MSBuild <c>restore</c> switch.
    /// </summary>
    /// <remarks>
    /// See https://github.com/Microsoft/msbuild/pull/2414.
    /// </remarks>
    public bool Restore { get; init; } = true;

    /// <summary>
    /// The full path to the <c>dotnet</c> executable you want to use for the build when building
    /// projects using the .NET Core SDK. Defaults to <c>dotnet</c> which will look in folders
    /// specified in the path environment variable.
    /// </summary>
    /// <remarks>
    /// Set this to something else to customize the .NET Core runtime you want to use (I.e., preview versions).
    /// </remarks>
    public string DotnetExePath { get; init; } = "dotnet";

    /// <summary>
    /// The global MSBuild properties to set.
    /// </summary>
    public IDictionary<string, string> GlobalProperties { get; } = new Dictionary<string, string>();

    /// <summary>
    /// Environment variables to set.
    /// </summary>
    public IReadOnlyDictionary<string, string> EnvironmentVariables { get; init; } = new Dictionary<string, string>();

    /// <summary>
    /// Additional MSBuild command-line arguments to use.
    /// </summary>
    public IReadOnlyCollection<string> Arguments { get; init; } = [];

    /// <summary>
    /// Specifies an alternate working directory to use for the build instead of the project file directory.
    /// Set to (or keep as) null to use the directory of the project file being built as the working directory.
    /// </summary>
    public string? WorkingDirectory { get; init; }
}
phmonte commented 4 months ago

@Corniel would you leave EnvironmentVariables immutable?

Corniel commented 4 months ago

Currently they are mutable to, if I'm not mistaken?!

phmonte commented 4 months ago

Yes, it is currently mutable, when I commented I was thinking if it would make sense to leave it immutable, but I understand that it makes sense.