Skip to content

Commit 8517d5b

Browse files
committed
Exclude default items from file-based apps in project dirs
1 parent a6d225e commit 8517d5b

File tree

5 files changed

+97
-25
lines changed

5 files changed

+97
-25
lines changed

documentation/general/dotnet-run-file.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ Additionally, the implicit project file has the following customizations:
4747

4848
- `FileBasedProgram` property is set to `true` and can be used by SDK targets to detect file-based apps.
4949

50+
- `DisableDefaultItemsInProjectFolder` property is set to `true` which results in `EnableDefaultItems=false` by default
51+
in case there is a project or solution in the same directory as the file-based app.
52+
This ensures that items from nested projects and artifacts are not included by the app.
53+
5054
## Grow up
5155

5256
When file-based programs reach an inflection point where build customizations in a project file are needed,
@@ -326,7 +330,7 @@ When disabled, [grow up](#grow-up) would generate projects in subdirectories
326330
similarly to [multi-entry-point scenarios](#multiple-entry-points) to preserve the program's behavior.
327331

328332
Including `.cs` files from nested folders which contain `.csproj`s might be unexpected,
329-
hence we could consider reporting an error in such situations.
333+
hence we could consider excluding items from nested project folders.
330334

331335
Similarly, we could report an error if there are many nested directories and files,
332336
so for example, if someone puts a C# file into `C:/sources` and executes `dotnet run C:/sources/file.cs` or opens that in the IDE,

src/Cli/dotnet/Commands/Run/VirtualProjectBuildingCommand.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,7 @@ public static void WriteProjectFile(
933933
{
934934
writer.WriteLine("""
935935
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
936+
<DisableDefaultItemsInProjectFolder>true</DisableDefaultItemsInProjectFolder>
936937
""");
937938
}
938939

src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.DefaultItems.targets

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ Copyright (c) .NET Foundation. All rights reserved.
1313

1414
<!-- Don't get the default item globs by default when the flag is not set. -->
1515
<PropertyGroup Condition="'$(UsingNETSdkDefaults)' == 'true'">
16+
<!-- Given DisableDefaultItemsInProjectFolder=true, set EnableDefaultItems=false
17+
in case there is a solution/project in the current directory. -->
18+
<EnableDefaultItems Condition="'$(EnableDefaultItems)' == '' And
19+
'$(DisableDefaultItemsInProjectFolder)' == 'true' And
20+
('$([System.IO.Directory]::GetFiles($(MSBuildProjectDirectory), &quot;*.sln&quot;))' != '' Or
21+
$([System.IO.Directory]::GetFiles($(MSBuildProjectDirectory), &quot;*.slnx&quot;)) != '' Or
22+
$([System.IO.Directory]::GetFiles($(MSBuildProjectDirectory), &quot;*.*proj&quot;)) != '')">false</EnableDefaultItems>
23+
1624
<EnableDefaultItems Condition=" '$(EnableDefaultItems)' == '' ">true</EnableDefaultItems>
1725
<EnableDefaultCompileItems Condition=" '$(EnableDefaultCompileItems)' == '' ">true</EnableDefaultCompileItems>
1826
<EnableDefaultEmbeddedResourceItems Condition=" '$(EnableDefaultEmbeddedResourceItems)' == '' ">true</EnableDefaultEmbeddedResourceItems>

test/dotnet.Tests/CommandTests/Project/Convert/DotnetProjectConvertTests.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,36 @@ class Util { public static string GetText() => "Hi from Util"; }
537537
.And.HaveStdOut(expectedOutput);
538538
}
539539

540+
/// <summary>
541+
/// Scripts in repo root should not include default items.
542+
/// Part of <see href="https://github.com/dotnet/sdk/issues/49826"/>.
543+
/// </summary>
544+
[Fact]
545+
public void DefaultItems_AlongsideSln()
546+
{
547+
var testInstance = _testAssetsManager.CreateTestDirectory();
548+
File.WriteAllText(Path.Join(testInstance.Path, "Program.cs"), """
549+
Console.WriteLine();
550+
""");
551+
File.WriteAllText(Path.Join(testInstance.Path, "my.json"), "");
552+
File.WriteAllText(Path.Join(testInstance.Path, "Resources.resx"), "");
553+
File.WriteAllText(Path.Join(testInstance.Path, "Util.cs"), "");
554+
File.WriteAllText(Path.Join(testInstance.Path, "repo.sln"), "");
555+
556+
new DotnetCommand(Log, "project", "convert", "Program.cs")
557+
.WithWorkingDirectory(testInstance.Path)
558+
.Execute()
559+
.Should().Pass();
560+
561+
new DirectoryInfo(testInstance.Path)
562+
.EnumerateFileSystemInfos().Select(f => f.Name).Order()
563+
.Should().BeEquivalentTo(["Program", "Program.cs", "Resources.resx", "Util.cs", "my.json", "repo.sln"]);
564+
565+
new DirectoryInfo(Path.Join(testInstance.Path, "Program"))
566+
.EnumerateFileSystemInfos().Select(f => f.Name).Order()
567+
.Should().BeEquivalentTo(["Program.csproj", "Program.cs"]);
568+
}
569+
540570
/// <summary>
541571
/// When processing fails due to invalid directives, no conversion should be performed
542572
/// (e.g., the target directory should not be created).

test/dotnet.Tests/CommandTests/Run/RunFileTests.cs

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace Microsoft.DotNet.Cli.Run.Tests;
1515

1616
public sealed class RunFileTests(ITestOutputHelper log) : SdkTest(log)
1717
{
18-
private static readonly string s_program = """
18+
private static readonly string s_program = /* lang=C#-Test */ """
1919
if (args.Length > 0)
2020
{
2121
Console.WriteLine("echo args:" + string.Join(";", args));
@@ -29,15 +29,15 @@ public sealed class RunFileTests(ITestOutputHelper log) : SdkTest(log)
2929
#endif
3030
""";
3131

32-
private static readonly string s_programDependingOnUtil = """
32+
private static readonly string s_programDependingOnUtil = /* lang=C#-Test */ """
3333
if (args.Length > 0)
3434
{
3535
Console.WriteLine("echo args:" + string.Join(";", args));
3636
}
3737
Console.WriteLine("Hello, " + Util.GetMessage());
3838
""";
3939

40-
private static readonly string s_util = """
40+
private static readonly string s_util = /* lang=C#-Test */ """
4141
static class Util
4242
{
4343
public static string GetMessage()
@@ -47,6 +47,29 @@ public static string GetMessage()
4747
}
4848
""";
4949

50+
private static readonly string s_programReadingEmbeddedResource = /* lang=C#-Test */ """
51+
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
52+
var resourceName = assembly.GetManifestResourceNames().SingleOrDefault();
53+
54+
if (resourceName is null)
55+
{
56+
Console.WriteLine("Resource not found");
57+
return;
58+
}
59+
60+
using var stream = assembly.GetManifestResourceStream(resourceName)!;
61+
using var reader = new System.Resources.ResourceReader(stream);
62+
Console.WriteLine(reader.Cast<System.Collections.DictionaryEntry>().Single());
63+
""";
64+
65+
private static readonly string s_resx = """
66+
<root>
67+
<data name="MyString">
68+
<value>TestValue</value>
69+
</data>
70+
</root>
71+
""";
72+
5073
private static readonly string s_consoleProject = $"""
5174
<Project Sdk="Microsoft.NET.Sdk">
5275
<PropertyGroup>
@@ -1062,26 +1085,8 @@ public void BinaryLog_EvaluationData()
10621085
public void EmbeddedResource()
10631086
{
10641087
var testInstance = _testAssetsManager.CreateTestDirectory();
1065-
string code = """
1066-
using var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("Program.Resources.resources");
1067-
1068-
if (stream is null)
1069-
{
1070-
Console.WriteLine("Resource not found");
1071-
return;
1072-
}
1073-
1074-
using var reader = new System.Resources.ResourceReader(stream);
1075-
Console.WriteLine(reader.Cast<System.Collections.DictionaryEntry>().Single());
1076-
""";
1077-
File.WriteAllText(Path.Join(testInstance.Path, "Program.cs"), code);
1078-
File.WriteAllText(Path.Join(testInstance.Path, "Resources.resx"), """
1079-
<root>
1080-
<data name="MyString">
1081-
<value>TestValue</value>
1082-
</data>
1083-
</root>
1084-
""");
1088+
File.WriteAllText(Path.Join(testInstance.Path, "Program.cs"), s_programReadingEmbeddedResource);
1089+
File.WriteAllText(Path.Join(testInstance.Path, "Resources.resx"), s_resx);
10851090

10861091
new DotnetCommand(Log, "run", "Program.cs")
10871092
.WithWorkingDirectory(testInstance.Path)
@@ -1094,7 +1099,7 @@ public void EmbeddedResource()
10941099
// This behavior can be overridden.
10951100
File.WriteAllText(Path.Join(testInstance.Path, "Program.cs"), $"""
10961101
#:property EnableDefaultEmbeddedResourceItems=false
1097-
{code}
1102+
{s_programReadingEmbeddedResource}
10981103
""");
10991104

11001105
new DotnetCommand(Log, "run", "Program.cs")
@@ -1106,6 +1111,27 @@ Resource not found
11061111
""");
11071112
}
11081113

1114+
/// <summary>
1115+
/// Scripts in repo root should not include <c>.resx</c> files.
1116+
/// Part of <see href="https://github.com/dotnet/sdk/issues/49826"/>.
1117+
/// </summary>
1118+
[Fact]
1119+
public void EmbeddedResource_AlongsideSln()
1120+
{
1121+
var testInstance = _testAssetsManager.CreateTestDirectory();
1122+
File.WriteAllText(Path.Join(testInstance.Path, "Program.cs"), s_programReadingEmbeddedResource);
1123+
File.WriteAllText(Path.Join(testInstance.Path, "Resources.resx"), s_resx);
1124+
File.WriteAllText(Path.Join(testInstance.Path, "repo.sln"), "");
1125+
1126+
new DotnetCommand(Log, "run", "Program.cs")
1127+
.WithWorkingDirectory(testInstance.Path)
1128+
.Execute()
1129+
.Should().Pass()
1130+
.And.HaveStdOut("""
1131+
Resource not found
1132+
""");
1133+
}
1134+
11091135
[Fact]
11101136
public void NoRestore_01()
11111137
{
@@ -2660,6 +2686,7 @@ public void Api()
26602686
<Nullable>enable</Nullable>
26612687
<PublishAot>true</PublishAot>
26622688
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
2689+
<DisableDefaultItemsInProjectFolder>true</DisableDefaultItemsInProjectFolder>
26632690
<TargetFramework>net11.0</TargetFramework>
26642691
<LangVersion>preview</LangVersion>
26652692
<Features>$(Features);FileBasedProgram</Features>
@@ -2730,6 +2757,7 @@ public void Api_Diagnostic_01()
27302757
<Nullable>enable</Nullable>
27312758
<PublishAot>true</PublishAot>
27322759
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
2760+
<DisableDefaultItemsInProjectFolder>true</DisableDefaultItemsInProjectFolder>
27332761
<Features>$(Features);FileBasedProgram</Features>
27342762
</PropertyGroup>
27352763
@@ -2797,6 +2825,7 @@ public void Api_Diagnostic_02()
27972825
<Nullable>enable</Nullable>
27982826
<PublishAot>true</PublishAot>
27992827
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
2828+
<DisableDefaultItemsInProjectFolder>true</DisableDefaultItemsInProjectFolder>
28002829
<Features>$(Features);FileBasedProgram</Features>
28012830
</PropertyGroup>
28022831

0 commit comments

Comments
 (0)