Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/source-code-inclusion.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Configuration keys are case-insensitive. Nested command-line keys use `:`, for e
| `SourceFolder` | Repository `src/Light.GuardClauses` | Directory containing the source files |
| `TargetFile` | Root `Light.GuardClauses.SingleFile.cs` | Generated output path |
| `TargetFramework` | `NetStandard2_0` | Selects `NetStandard2_0` or `Net10_0` |
| `ValidateGeneratedFileBuild` | `true` | Builds the generated file after export; set to `false` to skip validation |
| `ChangePublicTypesToInternalTypes` | `true` | Makes exported public types internal |
| `BaseNamespace` | `Light.GuardClauses` | Rewrites the base namespace |
| `RemoveContractAnnotations` | `false` | Removes JetBrains contract annotations from members |
Expand Down Expand Up @@ -119,6 +120,6 @@ The exporter fails loudly if a `Check.<Name>.cs` assertion file has no correspon

## Validation and failures

After writing the target file, the tool builds it through [`Light.GuardClauses.SourceValidation`](../tools/source-export/Light.GuardClauses.SourceValidation/) using `netstandard2.0` or `net10.0` to match the selected source target.
After writing the target file, the tool builds it through [`Light.GuardClauses.SourceValidation`](../tools/source-export/Light.GuardClauses.SourceValidation/) using `netstandard2.0` or `net10.0` to match the selected source target. Set `ValidateGeneratedFileBuild` to `false` to skip this validation when the caller will validate the output separately.

If generation throws, the tool prints the exception and returns a non-zero exit code. If validation fails, it prints the captured build output and returns the build's non-zero exit code. In either case, a file already generated is left in place for diagnosis. Do not publish or commit custom output unless the command and matching validation complete successfully.
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@ public static void TryFindSourceValidationProjectFindsProjectFromRepositoryRoot(
);

GeneratedFileBuildValidator.TryFindSourceValidationProject([TestEnvironment.RepositoryRoot.FullName])
.Should().Be(expectedProjectPath);
.Should().Be(expectedProjectPath);
}

[Fact]
public static void TryFindSourceValidationProjectFindsProjectFromTestOutputDirectory()
{
public static void TryFindSourceValidationProjectFindsProjectFromTestOutputDirectory() =>
GeneratedFileBuildValidator.TryFindSourceValidationProject([AppContext.BaseDirectory])
.Should().NotBeNull();
}
.Should().NotBeNull();

[Fact]
public static void SourceFileMergeOptionsUseRepositoryLayoutDefaults()
Expand All @@ -38,6 +36,7 @@ public static void SourceFileMergeOptionsUseRepositoryLayoutDefaults()
options.TargetFile.Should().Be(
Path.Combine(TestEnvironment.RepositoryRoot.FullName, "Light.GuardClauses.SingleFile.cs")
);
options.ValidateGeneratedFileBuild.Should().BeTrue();
}

[Fact]
Expand Down Expand Up @@ -90,4 +89,45 @@ public static void ProgramRunsNonWhitelistNetStandardTransformationAndValidates(

File.Exists(targetFile).Should().BeTrue();
}

[Fact]
public static void ProgramCanSkipGeneratedFileBuildValidation()
{
using var temporaryDirectory = new TemporaryDirectory();
var sourceFolder = Path.Combine(temporaryDirectory.DirectoryPath, "Source");
Directory.CreateDirectory(sourceFolder);
File.WriteAllText(
Path.Combine(sourceFolder, "Check.cs"),
"namespace Light.GuardClauses; public static partial class Check { }"
);
File.WriteAllText(
Path.Combine(sourceFolder, "Check.Invalid.cs"),
"""
namespace Light.GuardClauses;
public static partial class Check
{
public static UndefinedType Invalid() => null;
}
"""
);
File.WriteAllText(
Path.Combine(sourceFolder, "Throw.cs"),
"namespace Light.GuardClauses.ExceptionFactory; public static partial class Throw { }"
);
var targetFile = Path.Combine(temporaryDirectory.DirectoryPath, "Generated.cs");

Program.Main(
[
$"SourceFolder={sourceFolder}",
$"TargetFile={targetFile}",
"IncludeVersionComment=false",
"IncludeJetBrainsAnnotations=false",
"IncludeJetBrainsAnnotationsUsing=false",
"TargetFramework=Net10_0",
"ValidateGeneratedFileBuild=false",
]
).Should().Be(0);

File.ReadAllText(targetFile).Should().Contain("UndefinedType");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ public static int Main(string[] args)
{
Console.WriteLine("Merging source files...");
SourceFileMerger.CreateSingleSourceFile(options);
var buildValidationExitCode =
GeneratedFileBuildValidator.Validate(options.TargetFramework, options.TargetFile);
if (buildValidationExitCode != 0)
if (options.ValidateGeneratedFileBuild)
{
return buildValidationExitCode;
var buildValidationExitCode =
GeneratedFileBuildValidator.Validate(options.TargetFramework, options.TargetFile);
if (buildValidationExitCode != 0)
{
return buildValidationExitCode;
}
}

Console.WriteLine("Source file export completed successfully.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public SourceFileMergeOptions()

public SourceTargetFramework TargetFramework { get; init; } = SourceTargetFramework.NetStandard2_0;

public bool ValidateGeneratedFileBuild { get; init; } = true;

public AssertionWhitelist AssertionWhitelist { get; init; } = new ();

public bool ChangePublicTypesToInternalTypes { get; init; } = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"SourceFolder": "",
"TargetFile": "",
"TargetFramework": "NetStandard2_0",
"ValidateGeneratedFileBuild": true,
"ChangePublicTypesToInternalTypes": true,
"BaseNamespace": "Light.GuardClauses",
"RemoveContractAnnotations": false,
Expand Down
Loading