Skip to content

Instantly share code, notes, and snippets.

@DamianEdwards
Last active November 25, 2018 20:25
Show Gist options
  • Save DamianEdwards/f6c704230d71e0315fb4 to your computer and use it in GitHub Desktop.
Save DamianEdwards/f6c704230d71e0315fb4 to your computer and use it in GitHub Desktop.
Proposal for .NET Core CLI "new" command

.NET Core CLI: new

The new command is used to create new .NET Core projects. Projects are created using templates installed via NuGet packages.

Templates are laid out in their NuGet packages in a hierarchical fashion that enables the creation of simple trees of templates with categories that are then merged across the installed template packages to create an overall template tree. This tree allows the display of an interactive menu when creating new projects, while also allowing for direct project creation using a template node's full path, e.g. dotnet new -t aspnetcore/mvc/empty

As templates are in normal NuGet packages and installed into the standard NuGet packages folder, they can depend on other NuGet packages that are used in their templates, such that when they're installed, all the required packages to create new projects using the contained templates are installed too.

Using the Command Line

Displaying help:

~/code> dotnet new --help
    Usage:
        dotnet new
        dotnet new -t|--template <template/path> [-n|--name <ProjectName>] [[-v|--variable <Name> <Value>] [-v|--variable <Name> <Value>]]
        dotnet new <arguments>
    
    Arguments:
        -t|--template <template/path>                 The path of the template to use
        -n|--name <ProjectName>                       The name of the new project, created in current folder if not specified
        -v|--variable <Name> <Value>                  Variable to be passed to the template (can be specified more than once)
        
        -l|--list                                     Lists installed templates
        -i|--install <TemplatePackageId> [version]    Installs templates from a package with optional version
        -i|--install <TemplatePackagePath>            Installs templates from a package
        -u|--uninstall <TemplatePackageId>            Uninstalls a templates package
        -r|--restore                                  Restores installed template packages

Listing installed templates:

~/code> dotnet new --list

MS.DotNetCore.New.Templates 1.0.0
  - Console Application    [console]
  - Class Library          [classlib]

~/code> 

Installing new templates from a package:

~/code> dotnet new --install MS.DotNetCore.New.Templates.AspNetCore 1.0.0
Installing templates from MS.DotNetCore.New.Templates.AspNetCore

Installed 3 templates:
  - ASP.NET Core Empty Application          [aspnetcore/empty]
  - ASP.NET Core MVC Web Site               [aspnetcore/mvc/website]
  - ASP.NET Core MVC Web API Application    [aspnetcore/mvc/webapi]

~/code> dotnet new --list

MS.DotNetCore.New.Templates 1.0.0
  - Console Application    [console]
  - Class Library          [classlib]

MS.DotNetCore.New.Templates.AspNetCore 1.0.0
  - ASP.NET Core Empty Application          [aspnetcore/empty]
  - ASP.NET Core MVC Web Site               [aspnetcore/mvc/website]
  - ASP.NET Core MVC Web API Application    [aspnetcore/mvc/webapi]

~/code> 

Creating a new project with a specific template:

~/code> mkdir MyApp && cd MyApp
~/code/MyApp> dotnet new --template console

Created project "MyApp" in ~/code/MyApp

~/code/MyApp> cd ../
~/code> dotnet new -t console --name MyApp2

Created project "MyApp2" in ~/code/MyApp2

~/code> dotnet new -t aspnetcore/mvc/website --name MyWebApp

Created project "MyWebApp" in ~/code/MyWebApp

~/code> 

Creating a new project using the template menu:

~/code> dotnet new

  Templates
  -----------------------------------
  1. Console Application [console]
  2. Class Library       [classlib]
  3. ASP.NET Core        [aspnetcore]
  
Select a template [1]: 1
Enter a project name [Project1]: MyApp
Enter a target framework [netstandardapp1.5]: 
  
Created project "MyApp" in ~/code/MyApp

~/code/MyApp> cd../
~/code> dotnet new

  Templates
  -----------------------------------
  1. Console Application [console]
  2. Class Library       [classlib]
  3. ASP.NET Core        [aspnetcore]
  
Select a template [1]: 3

  ASP.NET Core Templates
  -----------------------------------
  1. ASP.NET Core Empty Application [aspnetcore/empty]
  2. ASP.NET Core MVC               [aspnetcore/mvc]

Select an ASP.NET Core template [1]: 2

  ASP.NET Core MVC Templates
  -----------------------------------
  1. ASP.NET Core MVC Empty               [aspnetcore/mvc/empty]
  2. ASP.NET Core MVC Web Site            [aspnetcore/mvc/website]
  3. ASP.NET Core MVC Web API Application [aspnetcore/mvc/webapi]

Select an ASP.NET Core MVC template [1]: 2
Enter a project name [Project1]: MyWebApp
Enter a target framework [netstandardapp1.5]: 
  
Created "MyWebApp" in ~/code/MyWebApp

~/code/MyWebApp> 

Authoring Templates

Templates are placed in NuGet packages in the content/templates folder. Optionally, in the root of the folder is a templates.json file that describes the templates contained and if present is used to enhance the project creation experience.

The layout allows for multi-level category nodes with template nodes as the leaves. In the case a category node contains just a single template node, that template will be automatically selected when the category is chosen.

Variables

Template files support basic variable substitution, with the only variables automatically supplied being $ProjectName$ and $RuntimeId$. Other variables can be added via the templates.json file.

Variables have an ID, question text, optional default value, and optionally conditions that must be true for the variable to be prompted for. In the case it isn't, the default value is used. The only condition supported is "rid", which checks for a match against the machine's runtime ID.

Example templates.json

Example templates.json for the default templates:

{
    "projectTemplates": {
        "console": {
            "title": "Console Application",
            "children": {
                "csharp": {
                    "title": "Console Application (C#)",
                    "variables": {
                        "framework": {
                            "question": "Please select a target framework",
                            "default": "netstandardapp1.5",
                            "conditions": {
                                "rid": ["win7"]
                            }
                        }
                    }
                }
            }
        },
        "classlib": {
            "title": "Class Library",
            "children": {
                "csharp": {
                    "title": "Class Library (C#)",
                    "variables": {
                        "framework": {
                            "question": "Please select a target framework",
                            "default": "netstandardapp1.5",
                            "conditions": {
                                "rid": ["win7"]   
                            }
                        }
                    }
                }
            }
        }
    }
}

Package Files Layout

The following demonstrates the layout of template NuGet packages. Note how templates from separate packages can share their structure such that they're templates can occupy the same parts of the resultant installed template "tree".

~/.nuget/
    packages/
        MS.DotNetCore.New.Templates/
            content/
                templates/
                    templates.json
                    console/
                        csharp/
                            title.txt
                            files/
                                Program.cs
                    classlib/
                        csharp/
                            files/
                                project.json
                                Program.cs
        MS.DotNetCore.New.Templates.VB/
            content/
                templates/
                    templates.json
                    console/
                        vb/
                            files/
                                project.json
                                Program.vb
                    classlib/
                        vb/
                            files/
                                projext.json
                                Program.vb
        MS.DotNetCore.New.Templates.AspNetCore/
            content/
                templates/
                    templates.json
                    aspnetcore/
                        empty/
                            csharp/
                                files/
                                    project.json
                                    Program.cs
                        mvc/
                            empty/
                                csharp/
                                    files/
                                        project.json
                                        Program.cs
                                        Startup.cs
                                        Controllers/
                                            HomeController.cs
                                        wwwroot/
                            website/
                                csharp/
                            webapi/
                                csharp/
    tools/
@blackdwarf
Copy link

Ah, ok. :) So I was overthinking it. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment