Skip to content

Commit a90e4de

Browse files
Merging main into darc-main-79a14826-4de6-495d-82d4-923c7a5ae4a6
2 parents 1a2c7af + fe6a95a commit a90e4de

File tree

176 files changed

+4015
-1892
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

176 files changed

+4015
-1892
lines changed

.config/dotnet-tools.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"isRoot": true,
44
"tools": {
55
"microsoft.dotnet.darc": {
6-
"version": "1.1.0-beta.25305.3",
6+
"version": "1.1.0-beta.25312.2",
77
"commands": [
88
"darc"
99
]

documentation/general/dotnet-run-file.md

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ The command takes a path which can be either
4747
## Target path
4848

4949
The path passed to `dotnet run ./some/path.cs` is called *the target path*.
50-
The target path must be a file which has the `.cs` file extension.
50+
The target path must be a file which either has the `.cs` file extension,
51+
or a file whose contents start with `#!`.
5152
*The target directory* is the directory of the target file.
5253

5354
## Integration into the existing `dotnet run` command
@@ -57,13 +58,23 @@ specifically `file.cs` is passed as the first command-line argument to the targe
5758
We preserve this behavior to avoid a breaking change.
5859
The file-based build and run kicks in only when:
5960
- a project file cannot be found (in the current directory or via the `--project` option), and
60-
- if the target file exists and has the `.cs` file extension.
61+
- if the target file exists, and has the `.cs` file extension or contents that start with `#!`.
6162

6263
File-based programs are processed by `dotnet run` equivalently to project-based programs unless specified otherwise in this document.
6364
For example, the remaining command-line arguments after the first argument (the target path) are passed through to the target app
6465
(except for the arguments recognized by `dotnet run` unless they are after the `--` separator)
6566
and working directory is not changed (e.g., `cd /x/ && dotnet run /y/file.cs` runs the program in directory `/x/`).
6667

68+
`dotnet path.cs` is a shortcut for `dotnet run path.cs` provided that `path.cs` is a valid [target path](#target-path).
69+
70+
### Other commands
71+
72+
Commands `dotnet restore file.cs` and `dotnet build file.cs` are needed for IDE support and hence work for file-based programs.
73+
74+
Command `dotnet publish file.cs` is also supported for file-based programs.
75+
Note that file-based apps have implicitly set `PublishAot=true`, so publishing uses Native AOT (and building reports AOT warnings).
76+
To opt out, use `#:property PublishAot=false` directive in your `.cs` file.
77+
6778
## Entry points
6879

6980
If a file is given to `dotnet run`, it has to be an *entry-point file*, otherwise an error is reported.
@@ -86,6 +97,10 @@ other files in the target directory or its subdirectories are included in the co
8697
For example, other `.cs` files but also `.resx` (embedded resources).
8798
Similarly, implicit build files like `Directory.Build.props` or `Directory.Packages.props` are used during the build.
8899

100+
> [!CAUTION]
101+
> Multi-file support is postponed for .NET 11.
102+
> In .NET 10, only the single file passed as the command-line argument to `dotnet run` is part of the compilation.
103+
89104
### Nested files
90105

91106
If there are nested project files like
@@ -148,26 +163,32 @@ They are not cleaned immediately because they can be re-used on subsequent runs
148163

149164
It is possible to specify some project metadata via *file-level directives*
150165
which are [ignored][ignored-directives] by the C# language but recognized by the SDK CLI.
151-
Directives `sdk`, `package`, and `property` are translated into `<Project Sdk="...">`, `<PackageReference>`, and `<Property>` project elements, respectively.
166+
Directives `sdk`, `package`, `property`, and `project` are translated into
167+
`<Project Sdk="...">`, `<PackageReference>`, `<PropertyGroup>`, and `<ProjectReference>` project elements, respectively.
152168
Other directives result in an error, reserving them for future use.
153169

154170
```cs
155171
#:sdk Microsoft.NET.Sdk.Web
156-
#:property TargetFramework net11.0
157-
#:property LangVersion preview
172+
#:property TargetFramework=net11.0
173+
#:property LangVersion=preview
158174
#:package System.CommandLine@2.0.0-*
175+
#:project ../MyLibrary
159176
```
160177

161-
The value must be separated from the name of the directive by white space (`@` is additionally allowed separator for the package directive)
178+
The value must be separated from the kind (`package`/`sdk`/`property`) of the directive by whitespace
162179
and any leading and trailing white space is not considered part of the value.
163-
Any value can optionally have two parts separated by a space (more whitespace characters could be allowed in the future).
180+
Any value can optionally have two parts separated by `@` in case of `package`/`sdk` or `=` in case of `property`
181+
and whitespace is trimmed from the two parts around the separator.
164182
The value of the first `#:sdk` is injected into `<Project Sdk="{0}">` with the separator (if any) replaced with `/`,
165183
and the subsequent `#:sdk` directive values are split by the separator and injected as `<Sdk Name="{0}" Version="{1}" />` elements (or without the `Version` attribute if there is no separator).
166184
It is an error if the first part (name) is empty (the version is allowed to be empty, but that results in empty `Version=""`).
167185
The value of `#:property` is split by the separator and injected as `<{0}>{1}</{0}>` in a `<PropertyGroup>`.
168186
It is an error if no separator appears in the value or if the first part (property name) is empty (the property value is allowed to be empty) or contains invalid characters.
169187
The value of `#:package` is split by the separator and injected as `<PackageReference Include="{0}" Version="{1}">` (or without the `Version` attribute if there is no separator) in an `<ItemGroup>`.
170188
It is an error if the first part (package name) is empty (the package version is allowed to be empty, but that results in empty `Version=""`).
189+
The value of `#:project` is injected as `<ProjectReference Include="{0}" />` in an `<ItemGroup>`.
190+
If the value points to an existing directory, a project file is found inside that directory and its path is used instead
191+
(because `ProjectReference` items don't support directory paths).
171192

172193
Because these directives are limited by the C# language to only appear before the first "C# token" and any `#if`,
173194
dotnet CLI can look for them via a regex or Roslyn lexer without any knowledge of defined conditional symbols
@@ -280,31 +301,26 @@ Also, `InternalsVisibleTo` needs to be added into a C# file as an attribute, or
280301

281302
### Shebang support
282303

283-
It might be beneficial to also ship `dotnet-run` binary
284-
(or `dotnet-run-file` that would only work with file-based programs, not project-based ones, perhaps simply named `cs`)
285-
because some shells do not support multiple command-line arguments in the shebang
304+
Some shells do not support multiple command-line arguments in the shebang
286305
which is needed if one wants to use `/usr/bin/env` to find the `dotnet` executable
287-
(although `-S` argument can be sometimes used to enable multiple argument support):
306+
(although `-S` argument can be sometimes used to enable multiple argument support),
307+
so `dotnet file.cs` instead of `dotnet run file.cs` should be used in shebangs:
288308

289309
```cs
290310
#!/usr/bin/env dotnet run
291311
// ^ Might not work in all shells. "dotnet run" might be passed as a single argument to "env".
292312
```
293313
```cs
294-
#!/usr/bin/env dotnet-run
314+
#!/usr/bin/env dotnet
295315
// ^ Should work in all shells.
296316
```
297317
```cs
298318
#!/usr/bin/env -S dotnet run
299-
// ^ Workaround in some shells.
319+
// ^ Works in some shells.
300320
```
301321

302-
We could also consider making `dotnet file.cs` work because `dotnet file.dll` also works today
303-
but that would require changes to the native dotnet host.
304-
305-
### Other commands
322+
### Other possible commands
306323

307-
Commands `dotnet restore file.cs` and `dotnet build file.cs` are needed for IDE support and hence work for file-based programs.
308324
We can consider supporting other commands like `dotnet pack`, `dotnet watch`,
309325
however the primary scenario is `dotnet run` and we might never support additional commands.
310326

@@ -319,9 +335,8 @@ We could also add `dotnet compile` command that would be the equivalent of `dotn
319335
e.g., via `dotnet clean --file-based-program <path-to-entry-point>`
320336
or `dotnet clean --all-file-based-programs`.
321337

322-
323-
Adding package references via `dotnet package add` could be supported for file-based programs as well,
324-
i.e., the command would add a `#:package` directive to the top of a `.cs` file.
338+
Adding references via `dotnet package add`/`dotnet reference add` could be supported for file-based programs as well,
339+
i.e., the command would add a `#:package`/`#:project` directive to the top of a `.cs` file.
325340

326341
### Explicit importing
327342

0 commit comments

Comments
 (0)