Skip to content

Instantly share code, notes, and snippets.

@sayedihashimi
Last active April 7, 2016 10:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sayedihashimi/ac1075451f07cd6f63a1593fd30b2cc9 to your computer and use it in GitHub Desktop.
Save sayedihashimi/ac1075451f07cd6f63a1593fd30b2cc9 to your computer and use it in GitHub Desktop.
Ideas for dotnet-new

Thoughts on command line project creation

Note: what you'll find below are just some ideas. I'm writing these down so that I can share it at https://github.com/dotnet/cli/issues/2052 with the goal to change how we are approaching templates. I'm not directly woring in this area. However, I am responsible for ASP.NET template content in Visual Studio and yo aspnet.

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.

  • ASP.NET templates in Visual Studio
  • ASP.NET templates in yo aspnet
  • ASP.NET templates in dotnet new (future)

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.

  • Yeoman has a lot of dependencies. This increases the download size, install time, and also introduces issues where each dependency needs to be reviewed to ensure we don't violate any licenses.
  • If a bug is found in a dependency it may take a while for that to get fixed, especially if it's a platform specific bug. For example OmniSharp/generator-aspnet#351, which was opened in Sept 2015, and we are just now able to get the fix out.
  • In addition to this, authoring templates can be made a lot easier than what's required with yeoman today.
@ealsur
Copy link

ealsur commented Apr 7, 2016

Awesome ideas!

I think two important points that Yeoman right now allows are:

  • User generated templates (by user-created generators)
  • Templates updates

The later is a bit tedious since there is no notification whatsoever if any given template has a new version, given that this would be a command-line tool maybe a dotnet new update sort of system could be allowed to trigger a global template update?

Not sure how user-created templates could be handled, but to toss an idea, when I author new Visual Studio Code Extensions, they have a publishing command-line tool so maybe something like that could be used? They have it tied to the marketplace too.

@SteveDesmond-ca
Copy link

Sounds great! One thing I'd hope for is the ability to specify any options/params from the CLI (a la OmniSharp/generator-aspnet#555) essentially skipping steps 1+3.

e.g. dotnet new {template_name}

Thanks!

@sayedihashimi
Copy link
Author

@ealsur, thanks for the notes.

My proposal doesn't make it clear but those are core components of this as well. Initial ideas:

  • templates are shipped in NuGet packages, users can add packages as new sources
  • updates will be covered as well, but I'm not sure the exact experience around that yet. For cli your suggestion sounds right.

Not sure how user-created templates could be handled, but to toss an idea, when I author new Visual Studio Code Extensions, they have a publishing command-line tool

I like that idea too. Npm works like this as well. I think we can add that on top of whatever story we create.

@sayedihashimi
Copy link
Author

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