diff --git a/docs/architecture-tests.md b/docs/architecture-tests.md index cf7c02f9..79dacbc4 100644 --- a/docs/architecture-tests.md +++ b/docs/architecture-tests.md @@ -31,7 +31,7 @@ Current rules: | File | Rule(s) | |---|---| -| `LayeringSpecs` | `Core` / `Utilities` are foundations (no in-repo deps); utility satellites depend only on `Utilities`; `Tooling` / `ProjectModel` / `Build.Shared` don't reach upward; `Solution` is a thin facade; nothing depends on the `Cli` composition root; `Fallout.*` never depends on the `Nuke.*` shims. | +| `LayeringSpecs` | `Core` / `Utilities` and the `Application.Tooling.Execution` / `Application.Tooling.Requirements` contract leaves are foundations (no in-repo deps); utility satellites depend only on `Utilities`; `Tooling` / `ProjectModel` / `Build.Shared` don't reach upward; `Solution` is a thin facade; nothing depends on the `Cli` composition root; `Fallout.*` never depends on the `Nuke.*` shims. | | `PuritySpecs` | `Fallout.Core` takes no dependency on `System.IO`, `System.Diagnostics.Process`, `System.Console`, or Serilog (issue #88). | | `NamingSpecs` | A type's namespace should be rooted at its assembly name. The main debt-bearing rule. | diff --git a/fallout.slnx b/fallout.slnx index 927adef1..d6058e85 100644 --- a/fallout.slnx +++ b/fallout.slnx @@ -26,6 +26,8 @@ + + diff --git a/src/Fallout.Application.Tooling.Execution/Fallout.Application.Tooling.Execution.csproj b/src/Fallout.Application.Tooling.Execution/Fallout.Application.Tooling.Execution.csproj new file mode 100644 index 00000000..3750545b --- /dev/null +++ b/src/Fallout.Application.Tooling.Execution/Fallout.Application.Tooling.Execution.csproj @@ -0,0 +1,8 @@ + + + + netstandard2.0;net10.0 + Application-layer process-execution contract for Fallout tools — the IProcess abstraction and its Output model. No I/O, no logging. Targets netstandard2.0 so the source-generator and MSBuild-task layers can consume it. + + + diff --git a/src/Fallout.Tooling/IProcess.cs b/src/Fallout.Application.Tooling.Execution/IProcess.cs similarity index 100% rename from src/Fallout.Tooling/IProcess.cs rename to src/Fallout.Application.Tooling.Execution/IProcess.cs diff --git a/src/Fallout.Tooling/Output.cs b/src/Fallout.Application.Tooling.Execution/Output.cs similarity index 100% rename from src/Fallout.Tooling/Output.cs rename to src/Fallout.Application.Tooling.Execution/Output.cs diff --git a/src/Fallout.Tooling/OutputType.cs b/src/Fallout.Application.Tooling.Execution/OutputType.cs similarity index 100% rename from src/Fallout.Tooling/OutputType.cs rename to src/Fallout.Application.Tooling.Execution/OutputType.cs diff --git a/src/Fallout.Application.Tooling.Requirements/Fallout.Application.Tooling.Requirements.csproj b/src/Fallout.Application.Tooling.Requirements/Fallout.Application.Tooling.Requirements.csproj new file mode 100644 index 00000000..7d7dd195 --- /dev/null +++ b/src/Fallout.Application.Tooling.Requirements/Fallout.Application.Tooling.Requirements.csproj @@ -0,0 +1,8 @@ + + + + netstandard2.0;net10.0 + Application-layer tool-requirement marker interfaces — how a target declares the tools/packages it needs present before it runs. No I/O, no logging. Targets netstandard2.0 so the source-generator and MSBuild-task layers can consume it. + + + diff --git a/src/Fallout.Application.Tooling.Requirements/ToolRequirements.cs b/src/Fallout.Application.Tooling.Requirements/ToolRequirements.cs new file mode 100644 index 00000000..7ecd57bd --- /dev/null +++ b/src/Fallout.Application.Tooling.Requirements/ToolRequirements.cs @@ -0,0 +1,13 @@ +namespace Fallout.Common.Tooling; + +public interface IRequireTool; +public interface IRequireToolWithVersion; + + +public interface IRequirePathTool : IRequireTool; + +public interface IRequireNuGetPackage : IRequireTool, IRequireToolWithVersion; + +public interface IRequireNpmPackage : IRequireTool, IRequireToolWithVersion; + +public interface IRequireAptGetPackage : IRequireTool; diff --git a/src/Fallout.Tooling/Fallout.Tooling.csproj b/src/Fallout.Tooling/Fallout.Tooling.csproj index 2200aa63..1e871d08 100644 --- a/src/Fallout.Tooling/Fallout.Tooling.csproj +++ b/src/Fallout.Tooling/Fallout.Tooling.csproj @@ -5,6 +5,8 @@ + + diff --git a/src/Fallout.Tooling/ToolRequirement.cs b/src/Fallout.Tooling/ToolRequirement.cs index 21e591c3..70e5fe3b 100644 --- a/src/Fallout.Tooling/ToolRequirement.cs +++ b/src/Fallout.Tooling/ToolRequirement.cs @@ -3,19 +3,6 @@ namespace Fallout.Common.Tooling; -public interface IRequireTool; -public interface IRequireToolWithVersion; - - -public interface IRequirePathTool : IRequireTool; - -public interface IRequireNuGetPackage : IRequireTool, IRequireToolWithVersion; - -public interface IRequireNpmPackage : IRequireTool, IRequireToolWithVersion; - -public interface IRequireAptGetPackage : IRequireTool; - - public class ToolRequirement; public class PathToolRequirement(string pathExecutable) : ToolRequirement diff --git a/tests/Fallout.Architecture.Specs/Fallout.Architecture.Specs.csproj b/tests/Fallout.Architecture.Specs/Fallout.Architecture.Specs.csproj index 64047c19..f554c916 100644 --- a/tests/Fallout.Architecture.Specs/Fallout.Architecture.Specs.csproj +++ b/tests/Fallout.Architecture.Specs/Fallout.Architecture.Specs.csproj @@ -26,6 +26,8 @@ + + diff --git a/tests/Fallout.Architecture.Specs/FalloutArchitecture.cs b/tests/Fallout.Architecture.Specs/FalloutArchitecture.cs index 6b56baf5..773d7529 100644 --- a/tests/Fallout.Architecture.Specs/FalloutArchitecture.cs +++ b/tests/Fallout.Architecture.Specs/FalloutArchitecture.cs @@ -26,6 +26,8 @@ internal static class FalloutArchitecture public const string UtilitiesTextJson = "Fallout.Utilities.Text.Json"; public const string UtilitiesTextYaml = "Fallout.Utilities.Text.Yaml"; public const string Solution = "Fallout.Solution"; + public const string ToolingExecution = "Fallout.Application.Tooling.Execution"; + public const string ToolingRequirements = "Fallout.Application.Tooling.Requirements"; public const string Tooling = "Fallout.Tooling"; public const string ProjectModel = "Fallout.ProjectModel"; public const string BuildShared = "Fallout.Build.Shared"; @@ -52,8 +54,8 @@ internal static class FalloutArchitecture public static readonly string[] RuntimeLibraries = [ Core, Utilities, UtilitiesIoCompression, UtilitiesIoGlobbing, UtilitiesNet, UtilitiesTextJson, - UtilitiesTextYaml, Solution, Tooling, ProjectModel, BuildShared, Build, Common, Components, Cli, - NukeCommon, NukeBuild, NukeComponents, + UtilitiesTextYaml, Solution, ToolingExecution, ToolingRequirements, Tooling, ProjectModel, BuildShared, + Build, Common, Components, Cli, NukeCommon, NukeBuild, NukeComponents, ]; private static readonly IReadOnlyDictionary Loaded = LoadProductionAssemblies(); diff --git a/tests/Fallout.Architecture.Specs/LayeringSpecs.cs b/tests/Fallout.Architecture.Specs/LayeringSpecs.cs index 29a7f414..9e1ccd4e 100644 --- a/tests/Fallout.Architecture.Specs/LayeringSpecs.cs +++ b/tests/Fallout.Architecture.Specs/LayeringSpecs.cs @@ -42,6 +42,16 @@ public void Utility_satellite_depends_only_on_Fallout_Utilities(string satellite $"{satellite} is a utility satellite and may depend only on Fallout.Utilities", KnownViolations.None); + [Theory] + [InlineData(Arch.ToolingExecution)] + [InlineData(Arch.ToolingRequirements)] + public void Tooling_contract_leaf_is_a_foundation(string leaf) => + Ratchet.Enforce( + Arch.TypesIn(leaf) + .Should().NotDependOnAny(Arch.TypesIn(Arch.AllAssembliesExcept(leaf))), + $"{leaf} is a pure Application-layer tooling-contract leaf and must reference no other Fallout/Nuke assembly", + KnownViolations.None); + [Fact] public void Tooling_does_not_depend_on_upper_layers() => Ratchet.Enforce(