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

[One .NET] dotnet new project and item templates #5348

Merged
merged 1 commit into from
Dec 4, 2020

Conversation

jonathanpeppers
Copy link
Member

@jonathanpeppers jonathanpeppers commented Dec 1, 2020

Context: https://docs.microsoft.com/dotnet/core/tutorials/cli-templates-create-template-pack
Context: https://github.com/dotnet/templating/wiki
Context: dotnet/designs#120

This implements basic Android templates that are contained in a
Microsoft.Android.Templates.nupkg file.

We can define a template pack in WorkloadManifest.json:

"Microsoft.Android.Templates": {
  "kind": "template",
  "version": "@TEMPLATE_PACK_VERSION@"
}

This allows the workload to locate the *.nupkg file in:

C:\Program Files\dotnet\template-packs
/usr/local/share/dotnet/template-packs

Our .NET 6 preview installers simply have to place the *.nupkg files
in the right place for them to be picked up by dotnet new.

Some example project templates:

dotnet new android            --output MyAndroidApp     --packageName com.mycompany.myandroidapp
dotnet new androidlib         --output MyAndroidLibrary
dotnet new android-bindinglib --output MyJavaBinding

And item templates:

dotnet new android-activity --name LoginActivity --namespace MyAndroidApp
dotnet new android-layout   --name MyLayout      --output Resources/layout

Note that the android-bindinglib template is not a special project
type. It has additional help files for writing bindings as we have in
the current Xamarin.Android templates.

I also updated the XASdkTests to dotnet new each template and
dotnet build the resulting output.

jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this pull request Dec 1, 2020
When implementing dotnet#5348, I noticed that we could add a wildcard to
make Java bindings simpler:

    <TransformFile Include="Transforms\*.xml" />

This way you can just put `.xml` files in the `Transforms` folder so
they will be picked up automatically.

I updated a test that adds a `Metadata.xml` and relies on the wildcard
working.
@dellis1972
Copy link
Contributor

Can we add the following do you think? I'm not sure how we'd go about merging this stuff into existing files. I suspect it requires a sln file.

.vscode/tasks.json

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "msbuild",
            "args": [
                // Ask msbuild to generate full paths for file names.
                "/property:GenerateFullPaths=true",
                "/t:Install",
                // Do not generate summary otherwise it leads to duplicate errors in Problems panel
                "/consoleloggerparameters:NoSummary",
                "/p:Configuration=${input:configuration}",
                "/v:diag",
            ],
            "group": "build",
            "presentation": {
                // Reveal the output only if unrecognized errors occur.
                "reveal": "silent"
            },
            // Use the standard MS compiler pattern to detect errors, warnings and infos
            "problemMatcher": "$msCompile"
        },
        {
            "label": "_run",
            "type": "shell",
            "command": "msbuild",
            "args": [
                // Ask msbuild to generate full paths for file names.
                "/property:GenerateFullPaths=true",
                "/t:_Run",
                // Do not generate summary otherwise it leads to duplicate errors in Problems panel
                "/consoleloggerparameters:NoSummary",
                "/p:AndroidAttachDebugger=true",
                "/p:Configuration=${input:configuration}"
            ],
            "group": "build",
            "presentation": {
                // Reveal the output only if unrecognized errors occur.
                "reveal": "silent"
            },
            // Use the standard MS compiler pattern to detect errors, warnings and infos
            "problemMatcher": "$msCompile"
        }
    ],
    "inputs": [
        {
          "id": "configuration",
          "type": "pickString",
          "default": "Debug",
          "description": "The Build Configuration",
          "options": [ "Debug", "Release"]
        }
      ]
}

.vscode\launch.json

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch",
            "type": "mono",
            "request": "attach",
            "address": "localhost",
            "port": 10000,
            "preLaunchTask": "_run"
        }
    ]
}

@jonathanpeppers
Copy link
Member Author

I was looking through the other templates in .NET 6 and none of them create VS Code files -- I don't think we want to be the first?

If I do: dotnet new webapp && code there is a UI when I click create a launch.json file:

image

Maybe it would be better to add iOS and Android to this list for .NET 6? It's probably in VS Code's repo somewhere?

@dellis1972
Copy link
Contributor

dellis1972 commented Dec 2, 2020

I was looking through the other templates in .NET 6 and none of them create VS Code files -- I don't think we want to be the first?

Probably a good idea :)

If I do: dotnet new webapp && code there is a UI when I click create a launch.json file:
Maybe it would be better to add iOS and Android to this list for .NET 6? It's probably in VS Code's repo somewhere?

It would be nice to have these pre setup. There are a few issues, Intellisense does not work for android projects at the moment in vs code because OmniSharp crashes trying to find the Xamarin targets.

Microsoft.Build.Exceptions.InvalidProjectFileException: The imported project "/Users/dean/.vscode/extensions/ms-dotnettools.csharp-1.23.6/.omnisharp/1.37.3/omnisharp/.msbuild/Xamarin/Android/Xamarin.Android.CSharp.targets" was not found.

@jonpryor
Copy link
Member

jonpryor commented Dec 2, 2020

Naming quibble: when I look at my local dotnet new --list output:

Templates                                         Short Name               Language          Tags                  
--------------------------------------------      -------------------      ------------      ----------------------
Console Application                               console                  [C#], F#, VB      Common/Console        
Class library                                     classlib                 [C#], F#, VB      Common/Library        
WPF Application                                   wpf                      [C#]              Common/WPF            
WPF Class library                                 wpflib                   [C#]              Common/WPF            
WPF Custom Control Library                        wpfcustomcontrollib      [C#]              Common/WPF            
WPF User Control Library                          wpfusercontrollib        [C#]              Common/WPF            
Windows Forms (WinForms) Application              winforms                 [C#]              Common/WinForms       
Windows Forms (WinForms) Class library            winformslib              [C#]              Common/WinForms       
Worker Service                                    worker                   [C#], F#          Common/Worker/Web     
Unit Test Project                                 mstest                   [C#], F#, VB      Test/MSTest           
NUnit 3 Test Project                              nunit                    [C#], F#, VB      Test/NUnit            
NUnit 3 Test Item                                 nunit-test               [C#], F#, VB      Test/NUnit            
xUnit Test Project                                xunit                    [C#], F#, VB      Test/xUnit            
Razor Component                                   razorcomponent           [C#]              Web/ASP.NET           
Razor Page                                        page                     [C#]              Web/ASP.NET           
MVC ViewImports                                   viewimports              [C#]              Web/ASP.NET           
MVC ViewStart                                     viewstart                [C#]              Web/ASP.NET           
Blazor Server App                                 blazorserver             [C#]              Web/Blazor            
Blazor WebAssembly App                            blazorwasm               [C#]              Web/Blazor/WebAssembly
ASP.NET Core Empty                                web                      [C#], F#          Web/Empty             
ASP.NET Core Web App (Model-View-Controller)      mvc                      [C#], F#          Web/MVC               
ASP.NET Core Web App                              webapp                   [C#]              Web/MVC/Razor Pages   
ASP.NET Core with Angular                         angular                  [C#]              Web/MVC/SPA           
ASP.NET Core with React.js                        react                    [C#]              Web/MVC/SPA           
ASP.NET Core with React.js and Redux              reactredux               [C#]              Web/MVC/SPA           
Razor Class Library                               razorclasslib            [C#]              Web/Razor/Library     
ASP.NET Core Web API                              webapi                   [C#], F#          Web/WebAPI            
ASP.NET Core gRPC Service                         grpc                     [C#]              Web/gRPC              
dotnet gitignore file                             gitignore                                  Config                
global.json file                                  globaljson                                 Config                
NuGet Config                                      nugetconfig                                Config                
Dotnet local tool manifest file                   tool-manifest                              Config                
Web Config                                        webconfig                                  Config                
Solution File                                     sln                                        Solution              
Protocol Buffer File                              proto                                      Web/gRPC              

Two patterns stick out to me:

  • App vs. Library: wpf vs. wpflib, winforms vs winformslib
  • Otherwise, multi-word names use - to separate: unit-test, tool-manifest

Thus, I think the names might better be:

  • android: Android Application (compare to wpf, winforms)
  • androidlib: Android Class Library
  • android-bindinglib: Android Java Library Binding
  • android-activity: new Activity template
  • android-layout: new Layout template

jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this pull request Dec 2, 2020
When implementing dotnet#5348, I noticed that we could add a wildcard to
make Java bindings simpler:

    <TransformFile Include="Transforms\**\*.xml" />

This way you can just put `.xml` files in the `Transforms` folder so
they will be picked up automatically.

We also need to include some additional wildcards:

    <AndroidLibrary       Include="**\*.jar" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
    <AndroidLibrary       Include="**\*.aar" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
    <AndroidNativeLibrary Include="**\*.so"  Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />

To make sure we exclude folders like `bin` and `obj`, we can rely on
`$(DefaultItemExcludes)` and `$(DefaultExcludesInProjectFolder)` as
the dotnet/sdk does:

https://github.com/dotnet/sdk/blob/3e9e1d1e3082cab14593b54562c956b155881658/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.DefaultItems.props#L37

I updated a test that uses a `Metadata.xml`, and it now relies on the
new defaults.
@jonathanpeppers jonathanpeppers force-pushed the dotnet-new branch 2 times, most recently from 2ac196d to 8710b25 Compare December 2, 2020 21:15
jonpryor pushed a commit that referenced this pull request Dec 3, 2020
Context: #5348

While implementing PR #5348, I noticed that we could add a wildcard
to make Java bindings simpler:

	<TransformFile Include="Transforms\**\*.xml" />

This way you can just put `.xml` files into the `Transforms` folder
so that they will be picked up automatically.

We also need to include some additional wildcards:

	<AndroidLibrary       Include="**\*.jar" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
	<AndroidLibrary       Include="**\*.aar" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
	<AndroidNativeLibrary Include="**\*.so"  Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />

To make sure we exclude folders like `bin` and `obj`, we can rely on
`$(DefaultItemExcludes)` and `$(DefaultExcludesInProjectFolder)`
[as the dotnet/sdk does][0].

I updated the `XASdkTests.DotNetBuildBinding()` test to use
`Metadata.xml`, and it now relies on the new defaults.

[0]: https://github.com/dotnet/sdk/blob/3e9e1d1e3082cab14593b54562c956b155881658/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.DefaultItems.props#L37
@jonathanpeppers jonathanpeppers marked this pull request as ready for review December 3, 2020 22:01
@jonathanpeppers
Copy link
Member Author

This is now using templates properly in a .NET workload, so this is ready for review now.

Android Layout template android-layout [C#] Android
Android Class library androidlib [C#] Android
Android Application android [C#] Android
Console Application console [C#],F#,VB Common/Console
Copy link
Member

Choose a reason for hiding this comment

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

May want to omit the entries that don't appear to follow convention, so skip console and classlib & the rest, but include wpf and wpflib.

Copy link
Member Author

Choose a reason for hiding this comment

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

I included wpf, wpflib, nunit, and nunit-test. I don't think we should drop console or classlib from this example, because those are the most basic templates.

@@ -108,9 +108,22 @@ public override bool Execute ()
packWriter.WriteStartElement ("Directory");
packWriter.WriteAttributeString ("Id", "packs");
packWriter.WriteAttributeString ("Name", "packs");
packWriter.WriteAttributeString ("FileSource", packs_dir);
Copy link
Member

Choose a reason for hiding this comment

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

Would it be possible to include a "snippet" of what the new XML output looks like with these changes?

Copy link
Member Author

Choose a reason for hiding this comment

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

This line adds the full path such as:

<Directory Id="packs" Name="packs" FileSource="C:\Users\myuser\android-toolchain\dotnet\packs">

It was not explicitly needed before because RecurseDirectory() adds sub-directories with FileSource, but I added it because the rest of the elements specify FileSource.

The second block looks like:

<Directory Id="templatepacks" Name="template-packs" FileSource="C:\Users\myuser\android-toolchain\dotnet\template-packs">
  <Component Id="SC983E605827BDDA589CA4DFF082E29CDFEC2CD059B4AF3C01421CC95568A8D74">
    <File Id="SC983E605827BDDA589CA4DFF082E29CDFEC2CD059B4AF3C01421CC95568A8D74" Name="Microsoft.Android.Templates.11.0.100-ci.dotnet-new.259.nupkg" KeyPath="yes" />
  </Component>
</Directory>

MSI has weird rules around the Id, which is why I used hashes for files.

<Import Project="..\..\Configuration.props" />

<ItemGroup>
<Content Include="**\*" Exclude="**\bin\**;**\obj\**" />
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this use Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)"?

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually we can't use these in a template pack...

$(DefaultItemExcludes) excludes .csproj files, which are needed in templates.

https://github.com/dotnet/sdk/blob/44f381b62d466565639d51847c9127afbe7062a9/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.DefaultItems.targets#L33

$(DefaultExcludesInProjectFolder) will exclude folders that start with a ., so we can't use it because of .templateconfig/template.json.

Context: https://docs.microsoft.com/dotnet/core/tutorials/cli-templates-create-template-pack
Context: https://github.com/dotnet/templating/wiki
Context: dotnet/designs#120

This implements basic Android templates that are contained in a
`Microsoft.Android.Templates.nupkg` file.

We can define a template pack in `WorkloadManifest.json`:

    "Microsoft.Android.Templates": {
      "kind": "template",
      "version": "@TEMPLATE_PACK_VERSION@"
    }

This allows the workload to locate the `*.nupkg` file in:

    C:\Program Files\dotnet\template-packs
    /usr/local/share/dotnet/template-packs

Our .NET 6 preview installers simply have to place the `*.nupkg` files
in the right place for them to be picked up by `dotnet new`.

Some example project templates:

    dotnet new android            --output MyAndroidApp     --packageName com.mycompany.myandroidapp
    dotnet new androidlib         --output MyAndroidLibrary
    dotnet new android-bindinglib --output MyJavaBinding

And item templates:

    dotnet new android-activity --name LoginActivity --namespace MyAndroidApp
    dotnet new android-layout   --name MyLayout      --output Resources/layout

Note that the `android-bindinglib` template is not a special project
type. It has additional help files for writing bindings as we have in
the current Xamarin.Android templates.

I also updated the `XASdkTests` to `dotnet new` each template and
`dotnet build` the resulting output.
@github-actions github-actions bot locked and limited conversation to collaborators Jan 24, 2024
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.

3 participants