Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

report nice error message when dotnet is not installed or not valid #5477

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

chunyu3
Copy link
Contributor

@chunyu3 chunyu3 commented Jan 3, 2025

Fix #5364

  • add invalid-runtime-dependency diagnostic
  • When dotnet generation fail, check dotnet to filter out the failure because of runtime dependency is not valid
    • dotnet sdk is not installed
    • the installed dotnet sdk is not meet with the version requirement.

@microsoft-github-policy-service microsoft-github-policy-service bot added the emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp label Jan 3, 2025
@azure-sdk
Copy link
Collaborator

API change check

APIView has identified API level changes in this PR and created following API reviews.

@typespec/http-client-csharp

@chunyu3 chunyu3 requested a review from ArcturusZhang January 3, 2025 06:50
Copy link
Contributor

@JoshLove-msft JoshLove-msft left a comment

Choose a reason for hiding this comment

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

Added a few questions

@chunyu3 chunyu3 changed the title report nice error message when dotnet is not installed report nice error message when dotnet is not installed or not valid Jan 13, 2025
@chunyu3 chunyu3 requested a review from JoshLove-msft January 14, 2025 01:55
* @param program The typespec compiler program
* @param minVersionRequisite The minimum required version
*/
async function validateDotnet(program: Program, minVersionRequisite: string): Promise<boolean> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add a unit test of this function?

* @param program The typespec compiler program
* @param minVersionRequisite The minimum required version
*/
async function validateDotnet(program: Program, minVersionRequisite: string): Promise<boolean> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
async function validateDotnet(program: Program, minVersionRequisite: string): Promise<boolean> {
async function validateDotNet(program: Program, minVersionRequisite: string): Promise<boolean> {

@@ -7,6 +7,7 @@ import {
getDirectoryPath,
joinPaths,
logDiagnostics,
NoTarget,
Copy link
Contributor

Choose a reason for hiding this comment

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

Where is this used?

configurationFileName,
minVersionRequisiteForDotnet,
tspOutputFileName,
} from "./constants.js";
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be importing from the ts file?

const dotnetVersions = findDonetVersion(result.stdout) ?? findDonetVersion(result.stderr);
if (dotnetVersions) {
for (const version of dotnetVersions) {
if (semver.gt(version, minVersionRequisite)) return true;
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure that it is worth using the semver dependency for this simple check. We can even make the check simpler if we don't accept an arbitrary minVersion parameter and just check that the major version is 8.

Copy link
Contributor

@JoshLove-msft JoshLove-msft left a comment

Choose a reason for hiding this comment

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

Added a few additional comments, but overall looks like a nice improvement to the UX.

@@ -7,3 +7,4 @@ export const projectedNameClientKey = "client";
export const mockApiVersion = "0000-00-00";
export const tspOutputFileName = "tspCodeModel.json";
export const configurationFileName = "Configuration.json";
export const minVersionRequisiteForDotnet = "8.0.0";
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
export const minVersionRequisiteForDotnet = "8.0.0";
export const minSupportedDotNetSdkVersion = "8.0.0";

The name of this reads oddly and makes it hard to understand the purpose.

if (isValid) {
if (result.stderr) Logger.getInstance().error(result.stderr);
if (result.stdout) Logger.getInstance().verbose(result.stdout);
throw new Error(`Failed to generate SDK. Exit code: ${result.exitCode}`);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
throw new Error(`Failed to generate SDK. Exit code: ${result.exitCode}`);
throw new Error(`Failed to generate the library. Exit code: ${result.exitCode}`);

We generate .NET libraries. The "Azure SDK" is a branding for the entire collection of libraries. Even in the unbranded 3rd party space, we should stick to this terminology.

* @param program The typespec compiler program
* @param minVersionRequisite The minimum required version
*/
async function validateDotnet(program: Program, minVersionRequisite: string): Promise<boolean> {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
async function validateDotnet(program: Program, minVersionRequisite: string): Promise<boolean> {
async function validateDotNetSdk(program: Program, minVersion: string): Promise<boolean> {

We should be clear that we're validating the .NET SDK installed.

if (semver.gt(version, minVersionRequisite)) return true;
}
reportDiagnostic(program, {
code: "invalid-runtime-dependency",
Copy link
Member

Choose a reason for hiding this comment

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

This code is misleading, as we're validating the .NET SDK, not one of the runtimes.

return false;
}
try {
const result = await execAsync("dotnet", ["--list-sdks"]);
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is the right check. We could see .NET 8 as installed but have a global.json in the filesystem forcing us to use an earlier version. This check would pass, but we wouldn't be using v8+.

We should be running dotnet --version and evaluating the version used. If not otherwise constrained, this will be the latest on the system.

);
if (result.exitCode !== 0) {
const isValid = await validateDotnet(sdkContext.program, minVersionRequisiteForDotnet);
// if the dotnet runtime is valid, the error is not runtime issue, log it as normal
Copy link
Member

Choose a reason for hiding this comment

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

This comment is misleading. We're working with the .NET SDK, which is very different than a .NET runtime.

@@ -37,6 +37,14 @@ const $lib = createTypeSpecLibrary({
default: paramMessage`${"message"}`,
},
},
"invalid-runtime-dependency": {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"invalid-runtime-dependency": {
"invalid-dotnet-sdk-dependency": {

"invalid-runtime-dependency": {
severity: "error",
messages: {
default: paramMessage`invalid runtime dependency installed.`,
Copy link
Member

Choose a reason for hiding this comment

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

This is incorrect. We're talking about the .NET SDK, not a runtime. Those are different things.

severity: "error",
messages: {
default: paramMessage`invalid runtime dependency installed.`,
missing: paramMessage`Dotnet is not found in PATH. Please install DotNet ${"dotnetMajorVersion"} or above. Dotnet can be downloaded from ${"downloadUrl"}"`,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
missing: paramMessage`Dotnet is not found in PATH. Please install DotNet ${"dotnetMajorVersion"} or above. Dotnet can be downloaded from ${"downloadUrl"}"`,
missing: paramMessage`The dotnet command was not found in the PATH. Please install the .NET SDK version ${"dotnetMajorVersion"} or above. Guidance for installing the .NET SDK can be found at ${"downloadUrl"}"`,

We should not be linking to the download, but to the .NET SDK product page, which has instructions for installing in different environments and covers standard mechanisms like package managers, which are preferable to direct download.

messages: {
default: paramMessage`invalid runtime dependency installed.`,
missing: paramMessage`Dotnet is not found in PATH. Please install DotNet ${"dotnetMajorVersion"} or above. Dotnet can be downloaded from ${"downloadUrl"}"`,
invalidVersion: paramMessage`Dotnet SDK in PATH is version ${"installedVersion"}. Please install DotNet ${"dotnetMajorVersion"} or above. Dotnet can be downloaded from ${"downloadUrl"}"`,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
invalidVersion: paramMessage`Dotnet SDK in PATH is version ${"installedVersion"}. Please install DotNet ${"dotnetMajorVersion"} or above. Dotnet can be downloaded from ${"downloadUrl"}"`,
invalidVersion: paramMessage`The .NET SDK found is version ${"installedVersion"}. Please install the .NET SDK ${"dotnetMajorVersion"} or above and ensure there is no global.json in the file system requesting a lower version. Guidance for installing the .NET SDK can be found at ${"downloadUrl"}"`,

We should not be linking to the download, but to the .NET SDK product page, which has instructions for installing in different environments and covers standard mechanisms like package managers, which are preferable to direct download.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: C# emitter should explain simply that .NET needs to be installed
6 participants