Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 4, 2025

Simple file-based apps unexpectedly include **/*.resx files and other default items, causing issues when scripts are placed in repository roots or directories with unrelated project files (refs #51494, #49826, #12546).

Changes

  • VirtualProjectBuildingCommand: Set EnableDefaultEmbeddedResourceItems and EnableDefaultNoneItems to false when using only Microsoft.NET.Sdk (no additional SDK directives)
  • Behavior preserved: Non-default SDKs (e.g., Microsoft.NET.Sdk.Web) retain default item inclusion behavior
  • Opt-in available: Users can override via #:property EnableDefaultEmbeddedResourceItems=true

Example

// Default behavior - .resx files NOT included
// dotnet run Program.cs
Console.WriteLine("Hello");

// Override to include embedded resources
#:property EnableDefaultEmbeddedResourceItems=true
Console.WriteLine("Hello");

// Non-default SDK - .resx files included by default
#:sdk Microsoft.NET.Sdk.Web
Console.WriteLine("Hello");

Test Updates

Updated RunFileTests to verify:

  • Default SDK excludes embedded resources and none items
  • Property directive override works
  • Non-default SDKs preserve existing behavior
Original prompt

This section details on the original issue you should resolve

<issue_title>Consider setting EnableDefaultEmbeddedResourceItems to false by default for file-based apps</issue_title>
<issue_description>To help mitigate issues like

I think people don't expect a simple file-based app to include ./**/*.resx files. When their file-based app becomes more complex, it would be more acceptable to start including default items. For example, if one adds #:sdk Microsoft.NET.Sdk.Web it will include ./**/*.json files and that seems fine.

This might be considered a breaking change. Although not a very big one, since for simple file-based apps, if the CSC-only optimization kicks in, default items like ./**/*.resx are not considered anyway (see #50912).

dotnet project convert would not need to include this property in the generated project, it's enough if it doesn't copy the .resx files to the output directory (which should simply just work thanks to the logic to find default items via msbuild during the conversion).

This change could also help with perf: #50912 - when we fix that issue, we wouldn't need to glob for ./**/*.resx on every run just to check that inputs are up to date.

Open questions

  • Should EnableDefaultEmbeddedResourceItems become true when the file-based app becomes more "complex", e.g., includes an #:sdk directive? Or should it remain false by default for all file-based apps, and people would need to opt-in via #:property EnableDefaultEmbeddedResourceItems=true?
  • Should there be a feature gate (like LangVersion, TFM) for changes like this?
  • Should we have EnableDefaultNoneItems=false, too? These seem to be useful only for being displayed in Solution Explorer (which isn't applicable to file-based apps anyway) or copy to output directory (but that needs some customization of build anyway so if ./**/* is not included by default, one would just use <None Include/> instead of <None Update/>).

@dotnet/run-file @rainersigwald for thoughts</issue_description>

<agent_instructions>Let's set EnableDefaultEmbeddedResourceItems and EnableNoneItems to false if any other than the default sdk is being used.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@333fred I like it. I think that strikes a pragmatic balance between "I just want to write a quick script" and "I want to do something actually complicated". @DamianEdwards I think this is a reasonable compromise, i.e. setting it to false unless a specific SDK other than the default is opted in to. Would we take this in servicing, aka 10.0.101?

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits November 4, 2025 11:36
…eDefaultNoneItems to false for file-based apps

Co-authored-by: jjonescz <[email protected]>
…false for file-based apps with default SDK

Co-authored-by: jjonescz <[email protected]>
Copilot AI changed the title [WIP] Consider setting EnableDefaultEmbeddedResourceItems to false by default Set EnableDefaultEmbeddedResourceItems and EnableDefaultNoneItems to false for file-based apps using default SDK Nov 4, 2025
Copilot AI requested a review from jjonescz November 4, 2025 12:03
Copilot finished work on behalf of jjonescz November 4, 2025 12:03
@jjonescz jjonescz marked this pull request as ready for review November 4, 2025 17:51
@jjonescz jjonescz requested review from a team and Copilot November 4, 2025 17:51
@jjonescz jjonescz added the Area-run-file Items related to the "dotnet run <file>" effort label Nov 4, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR changes the default behavior for file-based programs to exclude embedded resources and "None" items when using the default SDK (Microsoft.NET.Sdk). This prevents unexpected file inclusions (like .resx files) in simple file-based apps while preserving the default SDK behavior for non-default SDKs like Microsoft.NET.Sdk.Web.

  • Modifies virtual project generation to conditionally set EnableDefaultEmbeddedResourceItems and EnableDefaultNoneItems to false only when using the default SDK
  • Updates tests to reflect the new behavior and verify both default SDK and non-default SDK scenarios
  • Adds documentation explaining the new customization

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/Cli/dotnet/Commands/Run/VirtualProjectBuildingCommand.cs Adds logic to conditionally disable default embedded resource and None items for the default SDK
test/dotnet.Tests/CommandTests/Run/RunFileTests.cs Updates tests to verify new behavior, adds explicit property settings where needed, removes obsolete test
test/dotnet.Tests/CommandTests/Project/Convert/DotnetProjectConvertTests.cs Updates tests to explicitly enable default items or use non-default SDK where needed
documentation/general/dotnet-run-file.md Documents the new behavior for default embedded resource and None items
Comments suppressed due to low confidence (1)

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

  • Corrected double negative 'doesn't support neither' to 'doesn't support either'.
// Licensed to the .NET Foundation under one or more agreements.

// Only set these to false when using the default SDK with no additional SDKs
// to avoid including .resx and other files that are typically not expected in simple file-based apps.
// When other SDKs are used (e.g., Microsoft.NET.Sdk.Web), keep the default behavior.
bool usingOnlyDefaultSdk = firstSdkName == defaultSdkName && sdkDirectives.Count() <= 1;
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition sdkDirectives.Count() <= 1 is counterintuitive. When there is exactly 1 SDK directive and it's the default SDK, this should still be treated as "only default SDK". Consider changing to sdkDirectives.Count() == 0 || (sdkDirectives.Count() == 1 && firstSdkName == defaultSdkName) or simplify to !sdkDirectives.Skip(1).Any() since when firstSdkName == defaultSdkName, either there are no directives (count=0) or the first one is the default SDK (and we want to check there are no additional ones).

Suggested change
bool usingOnlyDefaultSdk = firstSdkName == defaultSdkName && sdkDirectives.Count() <= 1;
bool usingOnlyDefaultSdk = sdkDirectives.Count() == 0 || (sdkDirectives.Count() == 1 && firstSdkName == defaultSdkName);

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current condition seems simpler and more robust to me.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't it just be sdkDirectives is [] or [defaultSdkName]?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sdkDirectives is an IEnumerable so it cannot be used with list patterns

@jjonescz jjonescz requested a review from 333fred November 5, 2025 11:03
@jjonescz
Copy link
Member

jjonescz commented Nov 6, 2025

@333fred @RikkiGibson @MiYanni for reviews please, we might want to take this through servicing

@jjonescz jjonescz merged commit 03bac48 into release/10.0.2xx Nov 6, 2025
33 of 34 checks passed
@jjonescz jjonescz deleted the copilot/set-enable-default-embedded-false branch November 6, 2025 20:05
@jjonescz
Copy link
Member

jjonescz commented Nov 6, 2025

/backport to release/10.0.1xx

@github-actions
Copy link
Contributor

github-actions bot commented Nov 6, 2025

Started backporting to release/10.0.1xx (link to workflow run)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-run-file Items related to the "dotnet run <file>" effort

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants