dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.66k stars 1.06k forks source link

Reimagine dotnet-new (dotnet new enhanchements 2) #5470

Closed blackdwarf closed 4 years ago

blackdwarf commented 8 years ago

As it currently stands, dotnet new is a good command for people to get started with simple projects. However, it suffers from several things:

This issue suggests a new form of dotnet new that solves the above problems. It also replaces the old dotnet/sdk#4695 that will be closed in favor of this one.

/cc @DamianEdwards @piotrpMSFT @Eilon @enricosada

.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

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

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.

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/
        Microsoft.NETCore.New.Templates/
            templates/
                templates.json
                console/
                    csharp/
                        files/
                            Program.cs
                classlib/
                    csharp/
                        files/
                            project.json
                            Program.cs
        Microsoft.NETCore.New.Templates.VB/
            templates/
                templates.json
                console/
                    vb/
                        files/
                            project.json
                            Program.vb
                classlib/
                    vb/
                        files/
                            projext.json
                            Program.vb
        Microsoft.NETCore.New.Templates.AspNetCore/
            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/
DamianEdwards commented 8 years ago

There is a functional prototype at https://github.com/DamianEdwards/dotnet-new2

Eilon commented 8 years ago

@ajaybhargavb this is for you.

enricosada commented 8 years ago

nice having a way for templates outside instead of embedded resources :+1:

I'd like to add the feedback from old thread dotnet/sdk#4695:

Make the common use case short using positional arguments (in addition to named arg)

the most common use case: dotnet new name type ( about --lang, see next comment )

so these are equivalent:

some examples in https://github.com/dotnet/cli/pull/1124#issue-129854435

Using another language is ok with --lang ( or -l )

dotnet new hello_world console --lang f#

or if you want, the old proposal was [lang]/[type] like

dotnet new hello_world fsharp/console

enricosada commented 8 years ago

About other languages support ( just to check my use case ):

That's useful not only for people who use only one language, but for poliglot who have multiple languages installed (i use c# and f#, both a lot)

Now the bonus points (suggestions) for a better cross language experience. The c# is the default language, np about that, there is --lang and it's ok (was already discussed and it's ok). But i think we can improve experience for others without changing c# experience:

~/code> dotnet new --list

MS.DotNetCore.New.Templates 1.0.0
  - Console Application    [console] (C#, F#)
  - Class Library              [classlib]  (C#, F#)

MS.DotNetCore.New.Templates.AspNetCore 1.0.0
  - ASP.NET Core Empty Application          [aspnetcore/empty]   (C#, VB)
Created C# project "MyApp" in ~/code/MyApp
Created F# project "MyApp" in ~/code/MyApp
enricosada commented 8 years ago

about the issue load templates from nuget (last feedback i promise).

The following is more a request, and maybe it's already like that.

Not everyone use nuget always, or publish to default nuget.org feed I understand the pro, it's nice for discoverability/versioning/tag/author etc but it's a big requirement a zip files with some static template files inside (and no dependencies).

i see --install <TemplatePackagePath> i hope that mean i can install from a package directly (using url or file path).

It's possibile to not bind the implementation to nuget packages only? templates are only a zip file with a structure and a template.json, we can consume it as zip file, no need to parse as nuget packages.

It's nice if i can just install a zip from url (from example from a github repo zip like https://github.com/dotnet/cli/archive/rel/1.0.0.zip ) or a local directory zipped. Offline help a lot too, no need for directory + project.json + dotnet pack.

jchannon commented 8 years ago

Pinging @sayedihashimi just in case he hasn't seen this...(although I'm sure he has)

muratg commented 8 years ago

:eyes:

sayedihashimi commented 8 years ago

Thoughts on command line project creation

With dotnew new we are interested in enabling an experience for users to create new projects from the command line. Creating projects from the command line is not a new concept, it's been around for a while especially on the web development side. One example of a successful command line project generator is yeoman. Yeoman is a super popular tool for developers, and if dotnet new is as successful as yeoman, IMO, that would be a really wonderful thing. To enable a meaningful discussion on dotnet new let's start by taking a look at a typical user experience when using yeoman to create a new project. Below are typical steps a user would take to create a new project from the command line.

Steps to create a new project from yeoman

  1. Install yeoman and it's dependencies
  2. Search for generator
  3. Install desired generator
  4. Invoke generator
  5. Enter info about the project; i.e. project name, dest dir and other options
  6. Generate the project (happens automatically after the previous step)

From the set of steps above, we can break this down into the following categories.

  1. Template discovery (local and remote)
  2. Command line user interaction - For example; selecting a generator, project name, dest dir, other project options, displaying help, etc.
  3. Going from template -> generated project

I think that dotnet new should focus on the overall end user experience. Which consists of the following, Template discovery and Command line interaction. When the user selects and invokes a template, dotnet new will handle prompting for project properties and then call the generator (with a consistent way to pass project properties). The template should be able to use any "template generator" that it desires. dotnet new will have a template generator available out of the box which can be used. For scenarios in which the default template generator doesn't meet the needs, it can always be switched out for a different implementation.

In my case I work on delivering templates in the following areas.

Today for VS and yo aspnet we have to author templates once for VS and once for yo aspnet. In addition the template infrastructure that we use for the VS side is very fragile and difficult to maintain. Once we enable templates in dotnet new it's yet another place for us to invest in creating templates. Instead of maintaining three different templates I'd like to have one way to create templates from the command line, and then reuse that tool everywhere. So we author templates once in dotnet new which enables the command line experience with dotnet new. Then in Visual Studio we create "shim templates" which will allow us to present the UI to gather parameters and then call into dotnet new for the project creation process. For yo aspnet we would do a similar thing.

Ideas for implementation

diagram

Brokers are decoupled from specific generators via a set of C# interfaces. This will allow us to maximize reusability of generators in different scenarios including; command line, Visual Studio, yeoman, etc.

Here is a typical user session when creating a new project and a high level of what happens.

Setup

When dotnet-new or Visual Studio are installed the following happens.

  1. Broker add template sources
  2. Broker adds generators

Users can add additional sources to enable using additional generators.

Project Creation

  1. Use uses broker to list templates
    1. Broker "collects" template sources
    2. Broker asks each generator for info on available templates for each template source
  2. User asks broker to create using a selected template (X)
    1. Broker "collects" template sources
    2. Broker finds generator for X
      1. Broker asks each generator if it supports X and stops when a match is found (or some other heuristic to find the single generator to use)
    3. Broker gets info on the given template from the generator
      • Contains metadata to display about the template
      • Contains info about template parameters
  3. Broker gathers info for generation
    1. Get info from the user (i.e. project name, destination, etc.)
    2. Get info from the environment and target
  4. Broker asks the generator to create using a given template
    1. Broker passes the properties acquired from the previous step to the generator to start generation
  5. Broker completes experience
    • VS Broker opens the project in Visual Studio
    • Command line broker displays a success message and more info on next steps

FAQ

Q: Does this mean yo aspnet will go away?

A: Absolutely not. yo aspnet has had some wonderful success it's not going anywhere. The idea is that we will create a self-contained template tool and then plug that into: VS, dotnet new, yo aspnet, etc. By allowing us to author templates once it will allow us to bring a better experience in yo aspnet. And it will enable us to keep templates in sync at all times across all end-user experiences.

Q: Why not just use yeoman here?

A: Yeoman has a lot of dependencies which are required to use it. It makes sense to have an entry point in yeoman because many people already have it installed (or some of it's dependencies). There are drawbacks from shipping/using yeoman directly by Visual Studio include the following.

rschiefer commented 8 years ago

@sayedihashimi I like this approach, supporting existing solutions with a new abstraction (dotnet new) and making VS templates easier by providing a shim to dotnet new templates. Also agree Yeoman has too much baggage to be the official solution. Well documented and thought out!

blackdwarf commented 8 years ago

@sayedihashimi can you add some examples of invocation of this new dotnet new you imagined on the command line? I'm fine with VS, but would love to see how complex/simple this would be in the shell.

sayedihashimi commented 8 years ago

@blackdwarf the specific user interaction is orthogonal to my ideas. What you have above should work with my proposal. Since there is an abstraction between the broker (dotnet new) and the template generator, you should be able to define the end user experience completely.

I'd like to make sure the local template story is good, so we may need to add more to what you have.

blackdwarf commented 8 years ago

@sayedihashimi ah, I see. When you say a "local template story", you mean templates that are installed with the SDK/other?

sayedihashimi commented 8 years ago

@blackdwarf

@sayedihashimi ah, I see. When you say a "local template story", you mean templates that are installed with the SDK/other?

I should have said "local template dev story". Let me explain by example.

When developing templates in Visual Studio with SideWaffle/TemplateBuilder I can CTRL+F5 (or F5) to start the VS experimental instance with my template vsix loaded.

When developing templates with yeoman I can use npm link to point to my local copy of yo aspnet so that I can try the templates via yo aspnet during development.

When developing templates for dotnet new there should be a similar story. Requiring users to create a .nupkg to share their templates widely is fine (similar to yo with npm packages), but users shouldn't have to create templates from .nupkg files locally during template development.

I think what we have here is a good start but for a complete template story we need more details like.

shanselman commented 8 years ago

What about "dotnet new http://github/shanselman/whatever/something.git" where a repo has the template

svick commented 8 years ago

@shanselman Would that effectively be just git clone http://github/shanselman/whatever/something.git && rm .git?

shanselman commented 8 years ago

@svick I'm thinking it'd be more like the Uppercut project years back. You'd say dotnet new "foo" gitrepo and then {{classname}} would be replaced with foo. So a clone, then a global search and replace. Brainstorming.

blackdwarf commented 8 years ago

@shanselman @sayedihashimi's design actually allows for that, I think. Honestly, the more I think about it, the more it sounds like a good idea. But then why not go the full monty here and allow something like dotnet new http://tempuri.org/template/thing or similar for file shares? Brainstorming (I like this notation :))

enricosada commented 8 years ago

@shanselman we can directly use github zip link as url, instead of git repo so is a dumb zip (no deps on git or github). also easier to host in S3. The proposed format define arguments/parameters/questions, so can be used by gui or command line. That's nice (arguments) because it's not bound on a specific language.

@blackdwarf it's something someone is implementing now or can be up-for-grab from community? last time i think i read about was in progress. Maybe a simple iteration first (zip+url) because it can help a lot to show new developer (new of .netcore) how to do something. atm are embedded in dotnet new , so each new tempalte is waiting merge (i'd like to merge F# lib for example, it's confusing for new users)

blackdwarf commented 8 years ago

@enricosada at this point we are hashing out the design. Once design is in place, we will figure out the next level of details. :smiley:

But it is interesting to do the ZIP thing. However, do take into account that not all people use GH for hosting, that is, maybe someone would like to point this to a random git repo hosted somewhere/somehow and have it work.

enricosada commented 8 years ago

do take into account that not all people use GH for hosting, that is ..

@blackdwarf i was proposing zip from github repo, instead of git repo. I dont understand why we need to add git, because we dont need to manage versions or branch. Just download a zip, unzip, done. If someone doesnt want to use github, can just upload a zip somewhere. Really useful for bootstrap things for new users (i'd like to add http://suave.io template for example).

in v1 we can do unzip only of package. In v2 add arguments/replacements. etc. So it's working asap (i really love do have it :smile: )

shanselman commented 8 years ago

We should only do the Zip thing if it's a GIT thing and not a GitHub thing. We don't want a design that is tied to a single provider.

enricosada commented 8 years ago

@shanselman it's a github thing ( but git archive exists). I dont see how a design tied to git, a versioning tool, instead of a dump zip files may be more complex. btw it's easier to support both scenarios.

dotnet new --from-zip "http://example.com/fable-template.zip"

and

dotnet new --from-git-repo "http://example.com/fable-templates.git"
factormystic commented 8 years ago

:-1: on zip simply because it might accidentally imply that someone should throw their code up on a server somewhere in a zip file. This behavior is awful. Use of source control should be encouraged at every opportunity. Free source control providers exist, so this really isn't a test of means.

enricosada commented 8 years ago

@factormystic the nuget packages are zip files, the .docx are zip files. It's an artifact. i can create it from git archive. clone a git repo mean you need a git command line, and usually you need to specifiy a branch or tag. I am not against it, but not as the only option.

sayedihashimi commented 8 years ago

Thanks for all the great comments. I'm loving the discussions here. We are designing this so that we can accept templates from different sources. We will likely start with:

Hopefully in the long term we can come with a story where 3rd parties can implement different template sources. We have discussed git, and I think that's a very interesting idea, which likely has a lot of potential. With that said we have to make progress in some other areas before we tackle the sources problem fully.

@enricosada

@blackdwarf it's something someone is implementing now or can be up-for-grab from community? last time i think i read about was in progress.

We are just now getting started (we are meeting today to take a deep dive on design) with the RTM (tooling) version of dotnet new. There is nothing to send a PR to at this time, but hopefully in a few weeks we will have something.

theBoringCoder commented 8 years ago

We are designing this so that we can accept templates from different sources. We will likely start with: •NuGet package •.zip file •Folder

Will the NuGet package support include the ability to pass a Uri to a package? My organization (county government), like many I am sure, has its' own internal NuGet server. We already get some benefit by sharing our packaged code internally between dev teams. The ability to post our project & item templates there as well would be a great benefit.

mlorbetske commented 8 years ago

@theBoringCoder the current design relies on the package existing on one of the configured feeds (managable via a nuget.config file). In your case, the private feed containing the packages of interest would just be present in that file. When the template gets "installed", the .nupkg matching the package id (maximum version) would get copied into the local cache and the contents would be usable from that location for the purposes of template creation. Updates to the templates would work in a similar way - you'd either be notified (or just have the option to update) about newer versions of the template package being discovered on the feed and have the ability to acquire and use the new template content instead of the currently cached version.

RehanSaeed commented 8 years ago

I work on the ASP.NET MVC Boilerplate project template which:

  1. Shows a feature selection UI to enable/disable things like 'HTTPS Everywhere' and 'TypeScript' etc.
  2. Heavily modifies the project based on the features selected.

All of the above is done after project creation using hooks in VS. I'd love to bring this to dotnet new but:

  1. I needs hooks post project creation to run something to modify the project. I'm not clear on whether this would be possible with dotnet new.
  2. Instead of a UI for feature selection, I could switch to a console app but is that a hard requirement? Could I write a cross-platform electron shell app or even a ASP.NET Core app for feature selection instead? Given that I have a few dozen features being offered, a console app experience would be sub-optimal.
  3. Eventually I expect that VS would just call into dotnet new. There must be some sort of UI story there?
  4. It looks like the template.json file is being used to ask the user questions about which target framework they want to use. Is this file essentially acting as a manifest of features in the template?
factormystic commented 8 years ago

@RehanSaeed look at eslint for an example of how to implement multi step configuration decisions on the command line. Not having a GUI is fine.

sayedihashimi commented 8 years ago

@RehanSaeed good to see you here.

@RehanSaeed your needs are very similar to our own (ASP.NET team). I think everything that you mentioned will be covered, but it may be difficult for me to explain without the code samples to go along with it. We should have that in a few weeks I think but not totally sure. I'll explain how we are planning to approach this from the One ASP.NET side and then you can comment if it makes sense for you.

From a design perspective gathering inputs is on the broker side of the house. For the CLI there will be a common broker that will be used. It will run through the parameters defined by the template and then prompt the user for the values. This can be done in a generic fashion. For the same template when used in VS, the broker will be in the form of a custom wizard (we may have one that can be used but miminally we'll provide code samples for the short term and a better plan long term). The custom wizard will be responsible for showing the right UI and getting input from the user. After input is gathered it will call the generator.

Now, how does this work when a template support options like:

So the UI will gather the input. After that it will invoke a generator. In the One ASP.NET case we are planning to create a single template which covers the different auth options. Then in the code we will add sections to indicate whether it should apply for each auth option. For example you may see something like the following in .cs files.

#if NO_AUTH
// code here for no auth
#endif NO_AUTH
#if ORG_AUTH
// code here for org auth
#endif ORG_AUTH
#if WIN_AUTH
// code here for win auth
#endif WIN_AUTH

We will have similar expressions for files that are not code files, so you'll be able to use this same technique across all file types.

Then when you invoke the generator and pass the parameter for Individual Auth the resulting code in the template will be whatever is in the #if for IND_AUTH (minus the #if and #endif lines of course).

We will also support a model where you can have files that are dropped for a specific set of options.

Regarding shared UI code, I'm not sure if that makes sense. For example when plugging in a template into yeoman, you need to run through normal yeoman prompts for gathering input. When running in VS we need to implement with a wizard and maybe custom UI with WPF, when adding it to VS Code you'll need to create an extension which uses HTML/JS/CSS for the UI. So I don't see much benefit in trying to create a shared UI experience. There are technical challanges there as well as user experience consistency issues.

I'm confident that what we are creating will meet your needs.

RehanSaeed commented 8 years ago

Hi @sayedihashimi. Agreed it's difficult to discuss without a code sample but a few comments anyway:

CLI

If the CLI broker component which asks the user questions is common, it needs to be flexible enough to support Yes/No questions, Multiple choice questions (Looks to be supported according to your Auth example) and perhaps free text questions (I don't use this one yet but I have considered adding something like this to ask for the site name as an example).

Conditional Logic

So you are using pre-processor directives for conditionally adding/removing logic. I do a lot of this and have some comments. I think it is very important that the project should still compile and be usable even though you have conditional logic in there.

Using your example, a C# or JavaScript file uses:

// $Start-Auth-NoAuth$
// code here for no auth
// $End-Auth-NoAuth$
// $Start-Auth-Org$
// code here for org auth
// $End-Auth-Org$
// $Start-Auth-Windows$
// code here for win auth
// $End-Auth-Windows$

However, a Razor file would oook like this:

@* $Start-Auth-NoAuth$ *@
code here for no auth
@* $End-Auth-NoAuth$ *@
@* $Start-Auth-Org$ *@
code here for org auth 
@* $End-Auth-Org$ *@
@* $Start-Auth-Windows$ *@
code here for win auth
@* $End-Auth-Windows$ *@
// $Start-Auth-NoAuth$
int i = 1;          // Not commented and used in the development time compilation of the template.
// $End-Auth-NoAuth$
// $Start-Auth-Org$
// int i = 2          // This code is uncommented if Org is selected.
// $End-Auth-Org$
// $Start-Auth-Windows$
int i = 3;          // This code is uncommented if Windows is selected.
// $End-Auth-Windows$

UI

If you are creating a manifest of features and the CLI is a shared component, then I suppose that means UI can also be a standard component provided by Microsoft. I'm not sure how I feel about that, it would be nice to have some UI customization:

SteveSandersonMS commented 8 years ago

This all looks great!

One further (but minor) point that you're probably already considered but I didn't see mentioned: restoring dependencies.

Obviously, after creating the initial project file layout, templates will need to invoke dotnet restore. But also they'll often need to invoke other tools like npm install or webpack --config <somefile> so that the generated app will run correctly.

If the templates can execute arbitrary C# code (as in @RehanSaeed's comment above) then that's sufficient. I'm guessing this is pretty inevitable because you couldn't configure something like this declaratively (the actions you need to take might vary according to options chosen by the user).

RehanSaeed commented 8 years ago

As @SteveSandersonMS mentions, running arbitrary code is essential.

This https://github.com/ligershark/microsoft-templateengine/issues/56#issuecomment-239863106 issue is also relevant to this topic. In it, I add two more issues that a templating engine must support:

//#if FOO
// Some comment
int i = 0;
//#else
// // Some comment
// int i = 0
//#endif
mlorbetske commented 8 years ago

@RehanSaeed @SteveSandersonMS we're still looking at if and how running arbitrary code during template instantiation specifically should work - in almost all cases, it's a step before the creation (collect some information to supply as parameters to the actual create operation) or a step after (to install dependencies or configure things on the user's machine to give a better development experience). Both of these often would require dependencies to be installed/present on the machine running the command without a particularly clear way of expressing that they're required (or how to obtain/install them - performing some npm commands after the template has been instantiated for example requires npm and would have to either detect it/install it before running it or fail gracefully and provide instructions no matter what OS you're on). That's not to say it won't happen, just that it needs a bit more design before it does.

With regard to the conditional syntaxes, these can be accomplished without running arbitrary code per se. The update that brings the automatic uncommenting of blocks is nearly ready (first commit for it was https://github.com/seancpeters/microsoft-templateengine/commit/60f7f149b7e1e81b9deb0e758002e56f9cdadec8 more tests are being added to make sure it's all right, the default preprocessor markers will be added/updated before it's pulled in)

TheRealPiotrP commented 7 years ago

dupe of dotnet/cli#5387