Skip to content
This repository has been archived by the owner on Oct 10, 2023. It is now read-only.

feat: add support for .net recognition (#51) #52

Merged
merged 9 commits into from
Feb 9, 2022

Conversation

lstocchi
Copy link
Collaborator

@lstocchi lstocchi commented Dec 21, 2021

it resolves #51

I changed the way to detect a devfile. Now it first uses component detection and then, if nothing is found, language detection.
This way i give priority to languages with frameworks and it seems the results are more stable.

P.S: Many of those 213 changed files are projects (c#/vb.net) for testing.

dotnetreco

Signed-off-by: Luca Stocchi <lstocchi@redhat.com>
Signed-off-by: Luca Stocchi <lstocchi@redhat.com>
Signed-off-by: Luca Stocchi <lstocchi@redhat.com>
@lstocchi lstocchi marked this pull request as ready for review December 22, 2021 09:49
@lstocchi lstocchi requested a review from jeffmaury December 22, 2021 09:49
Copy link
Member

@jeffmaury jeffmaury left a comment

Choose a reason for hiding this comment

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

See comments inline.
Also a question: it this a breaking change for the API point of view. Because the latest change causes a lot of issues for JBoss Tools

Signed-off-by: Luca Stocchi <lstocchi@redhat.com>
@omajid
Copy link
Member

omajid commented Jan 13, 2022

Hey folks!

I have some thoughts and suggestions on this.

For some background, the ".NET" umbrella includes a bunch of different things, and it's easy to mix them up. I am still not sure I understand all the moving parts myself, especially for older (proprietary, not cross platform) .NET.

  • Language, eg C# and VB.NET, but also F#. For a Java analogy, think of this as Java ecosystem supporting multiple languages: Java, Clojure, Kotlin and Scala among others.
  • Runtime, eg .NET Framework 4.x, .NET Core 3.1, .NET 6. As an analogy think of this as Java ME vs Java 8 vs Java 11 vs 17. Some Runtimes are compatible with others, some are not.
  • SDK, which roughly corresponds to the Runtime. Think of the JDK here, except if one JDK could target multiple, possibly incompatible versions of Java (ME and 17).
  • Project Build System (msbuild) which is roughly along the lines of a hybrid ant/maven system.
  • Project Type, eg, ASP.NET ("Classic"), ASP.NET Core. Think of JBoss AS vs Spring. But also includes things like "Desktop Application" and Android applications.

You can probably guess the language from the file extension. .cs is C#, .vb is VB.NET and .fs is F#.

There's only one build system: msbuild.

Project files use a bit of a flexible extension system. They pretty much always end with proj suffix, but the part before that is flexible. C# mostly uses .csproj, VB.NET mostly uses .vbproj and F# uses .fsproj. But those are not set in stone and people often use other extensions like .dockerproj or even .publishproj.

.sln (solution) files are a group of projects. They just include a path to other projects to build and don't really contain any logic other than that. slnf files (solution filters) allow narrowing down a .sln file further.

The Runtime is specified in the project file with things like TargetFrameworkVersion and TargetFramework. I see that the PR already handles that well.

The older runtime versions (.NET Framework 3.x and 4.x) are proprietary and Windows only. They are not supported on Linux. If you wanted to build/run this on OpenShift, you would need to run Windows, somehow. The cross-platform versions are .NET Core (all versions) with the TargetFramework of netcoreappX.Y and .NET version 5 and later (TargetFramework of net5.0, net6.0). There's suffixes possible in the TargetFarmework version to indicate project types too (see below).

The project type is a little tricky. It might be listed in the project file as a simple dependency, but the most common framework for recent .NET projects (ASP.NET Core) is implied by <Project Sdk="Microsoft.NET.Sdk.Web"> in the project file (docs). There's also the "Desktop Application" and other types, which are indicated by a suffix to the TargetFramework. See https://docs.microsoft.com/en-us/dotnet/standard/frameworks#supported-target-frameworks.

C#:
configuration_files:
- ".csproj"
- "appsettings.json"
Copy link
Member

@omajid omajid Jan 13, 2022

Choose a reason for hiding this comment

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

This file could be named appsettings.${SOMETHING}.json as well, where ${SOMETHING} could be pretty much anything, with Development and Production being common values.

Copy link
Collaborator Author

@lstocchi lstocchi Jan 14, 2022

Choose a reason for hiding this comment

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

So my question is ... is this file really useful for us? From your explanation it looks to me we would be good by only using .(cs/fs/vb/something)proj to detect frameworks (.netcore, .net5/6), right?
The other thing would be to find out which are the project dependencies but they should be stored into packages.config which is read by nuget, no? So what appsettings is usually used for? Could it contain some infos useful for us or can we avoid checking for it?

The same for app.config and Web.config. I added them to the list because when i was looking at some vb.net project online i saw they contained some infos but maybe they are not necessary anymore if we target .net 5/6/core?

Copy link
Member

Choose a reason for hiding this comment

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

My understanding is that appsettings*.json files only contain application-specific runtime configuration. Some common examples are logging configuration and database connection strings (which provide a good hint to which database, if any, is being used). They aren't used at build time by the SDK.

Project dependencies are generally stored in the project file (.csproj, etc) with modern .NET (.NET Core, .NET >= 5). The build system reads it from there and uses nuget under the hood to download them.

AFAIK, app.config and web.config are older .NET files. They are used by classic ASP.NET which I am not familiar with at all. If alizer wants to support only modern .NET, it probably doesn't need to look at them.

Signed-off-by: Luca Stocchi <lstocchi@redhat.com>
@omajid
Copy link
Member

omajid commented Jan 14, 2022

I have some thoughts and suggestions on this.

After sleeping on this, a few other things to watch out for.:

It's possible to have a single project that target multiple runtimes. The SDK will build your source code multiple times, each time targeting a different runtime. This generally involves using a semicolon-delimeted list in the TargetFrameworks (note the extra s) element in the project file. docs.

Project files can contain embedded snippets of code, such as Property Functions. A very common use looks like this:

<Import Project="$([MSBuild]::GetPathOfFileAbove(dir.props))" Condition=" '$([MSBuild]::GetPathOfFileAbove(dir.props))' != '' " />

Which uses [MSBuild]::GetPathOfFileAbove(dir.props) to find the path to a dir.props file somewhere up above in the parent directory (recursively).

And that brings me to Import. It works like #include in C, embedding another project file (which is often not a .csproj-style file, but commonly uses .props or .targets extensions). It's common to, for example, define a Directory.Build.props file which contains some constants and then use them in individual project files, for example, to define TargetFrameworks being targeted by all the different projects in a repository.

If you really want to fully parse project files, I am not sure you can do that without either calling msbuild (dotnet msbuild /pp to fully parse, expand and dump, but not evaluate/build the project) or duplicating much of the parsing logic.

Signed-off-by: Luca Stocchi <lstocchi@redhat.com>
Signed-off-by: Luca Stocchi <lstocchi@redhat.com>
Signed-off-by: Luca Stocchi <lstocchi@redhat.com>
Signed-off-by: Luca Stocchi <lstocchi@redhat.com>
@lstocchi
Copy link
Collaborator Author

@jeffmaury i updated the PR and I added almost everything suggested by @omajid but the Property functions. This requires a deeper investigation and i think this is not required for a first release and for the current state of .net devfiles. I'm going to opena
new issue for it. WDYT? Can you give this PR a look again and see if it work for you? Thanks!!

Thanks @omajid for all your useful infos, really appreciated!! 🙏 I'm going to look at your comments again and again in future to improve the detection.

@lstocchi lstocchi requested a review from jeffmaury January 24, 2022 19:23
Copy link
Member

@jeffmaury jeffmaury left a comment

Choose a reason for hiding this comment

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

LGTM

@lstocchi lstocchi merged commit b68d005 into redhat-developer:main Feb 9, 2022
@lstocchi lstocchi deleted the i51 branch February 9, 2022 09:12
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for .Net project detection
3 participants