Skip to content

Commit 5130be5

Browse files
committed
Enforce .NET 8 SDK for new C# modules
This fixes an issue where users with .NET 9 SDK installed can't build C# modules even if .NET 8 SDK is installed as well. Unfortunately, this covers only new projects created with `spacetime init` as that's the only place where we control the project directory. For everyone else, we print instructions with a link to the official configuration docs.
1 parent 96a3871 commit 5130be5

File tree

3 files changed

+29
-14
lines changed

3 files changed

+29
-14
lines changed

crates/cli/src/subcommands/init.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ pub async fn exec_init_csharp(args: &ArgMatches) -> anyhow::Result<()> {
178178
(include_str!("project/csharp/StdbModule._csproj"), "StdbModule.csproj"),
179179
(include_str!("project/csharp/Lib._cs"), "Lib.cs"),
180180
(include_str!("project/csharp/_gitignore"), ".gitignore"),
181+
// Reuse global.json from modules instead of a separate template to ensure that we stay in sync.
182+
(include_str!("../../../../modules/global.json"), "global.json"),
181183
];
182184

183185
// Check all dependencies

crates/cli/src/tasks/csharp.rs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use anyhow::Context;
2-
use duct::cmd;
32
use std::fs;
43
use std::path::{Path, PathBuf};
54

@@ -8,27 +7,37 @@ fn parse_major_version(version: &str) -> Option<u8> {
87
}
98

109
pub(crate) fn build_csharp(project_path: &Path, build_debug: bool) -> anyhow::Result<PathBuf> {
10+
// All `dotnet` commands must execute in the project directory, otherwise
11+
// global.json won't have any effect and wrong .NET SDK might be picked.
12+
macro_rules! dotnet {
13+
($($arg:expr),*) => {
14+
duct::cmd!("dotnet", $($arg),*).dir(project_path)
15+
};
16+
}
17+
1118
// Check if the `wasi-experimental` workload is installed. Unfortunately, we
1219
// have to do this by inspecting the human-readable output. There is a
1320
// hidden `--machine-readable` flag but it also mixes in human-readable
1421
// output as well as unnecessarily updates various unrelated manifests.
15-
match cmd!("dotnet", "workload", "list").read() {
22+
match dotnet!("workload", "list").read() {
1623
Ok(workloads) if workloads.contains("wasi-experimental") => {}
1724
Ok(_) => {
1825
// If wasi-experimental is not found, first check if we're running
19-
// on .NET 8.0. We can't even install that workload on older
20-
// versions, so this helps to provide a nicer message than "Workload
21-
// ID wasi-experimental is not recognized.".
22-
let version = cmd!("dotnet", "--version").read().unwrap_or_default();
23-
if parse_major_version(&version) < Some(8) {
24-
anyhow::bail!(".NET 8.0 is required, but found {version}.");
26+
// on .NET SDK 8.0. We can't even install that workload on older
27+
// versions, and we don't support .NET 9.0 yet, so this helps to
28+
// provide a nicer message than "Workload ID wasi-experimental is not recognized.".
29+
let version = dotnet!("--version").read().unwrap_or_default();
30+
if parse_major_version(&version) != Some(8) {
31+
anyhow::bail!(concat!(
32+
".NET SDK 8.0 is required, but found {version}.\n",
33+
"If you have multiple versions of .NET SDK installed, configure your project using https://learn.microsoft.com/en-us/dotnet/core/tools/global-json."
34+
));
2535
}
2636

2737
// Finally, try to install the workload ourselves. On some systems
2838
// this might require elevated privileges, so print a nice error
2939
// message if it fails.
30-
cmd!(
31-
"dotnet",
40+
dotnet!(
3241
"workload",
3342
"install",
3443
"wasi-experimental",
@@ -41,7 +50,7 @@ pub(crate) fn build_csharp(project_path: &Path, build_debug: bool) -> anyhow::Re
4150
))?;
4251
}
4352
Err(error) if error.kind() == std::io::ErrorKind::NotFound => {
44-
anyhow::bail!("dotnet not found in PATH. Please install .NET 8.0.")
53+
anyhow::bail!("dotnet not found in PATH. Please install .NET SDK 8.0.")
4554
}
4655
Err(error) => anyhow::bail!("{error}"),
4756
};
@@ -57,9 +66,7 @@ pub(crate) fn build_csharp(project_path: &Path, build_debug: bool) -> anyhow::Re
5766
})?;
5867

5968
// run dotnet publish using cmd macro
60-
cmd!("dotnet", "publish", "-c", config_name, "-v", "quiet")
61-
.dir(project_path)
62-
.run()?;
69+
dotnet!("publish", "-c", config_name, "-v", "quiet").run()?;
6370

6471
// check if file exists
6572
let subdir = if std::env::var_os("EXPERIMENTAL_WASM_AOT").map_or(false, |v| v == "1") {

modules/global.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"sdk": {
3+
"version": "8.0.400",
4+
"rollForward": "latestMinor"
5+
}
6+
}

0 commit comments

Comments
 (0)