question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Proposal to Expand the TemplateEngine / CLI Interface

See original GitHub issue

Motivation

The primary motivation for this proposal is to eliminate unnecessary process creation overhead when communicating from the template engine back to the SDK. Not only does this allow for reduction in additional “chaining” processes when performing actions in the SDK, but this also allows us to remove the managed overhead (JIT, R2R initialization, etc.) associated with these additional processes.

The most immediate use of this proposal would be to eliminate extra processes required to restore new templates during DotNetRestorePostActionProcessor.Process.

Current State

As it stands today, there is communication between the template engine and the CLI in both directions.

SDK --> Template Engine: This works by allowing the SDK to pass arguments to the template engine as part of the template engine entrypoint - New3Command.Run.

public static int Run(string commandName, ITemplateEngineHost host, ITelemetryLogger telemetryLogger, Action<IEngineEnvironmentSettings, IInstaller> onFirstRun, string[] args, string hivePath)

Template Engine --> SDK: The template engine can communicate with the SDK in two ways today. The first is by invoking delegate arguments that were passed to the template engine from the SDK when calling New3Command.Run. A good example here is the onFirstRun delegate which implements what the SDK would like done when the template engine determines that it is being run for the first time. The second mechanism is by allowing the template engine to invoke dotnet.exe directly which spawns a new SDK process and allows the template engine to ask the SDK to perform operations on behalf of the template engine. An example of where this is used is in DotNetRestorePostActionProcessor.Process, which invokes dotnet.exe directly to call dotnet restore on the newly instantiated template.

Proposal

I would like to propose that we expand on the mechanisms that the template engine has to communicate with the SDK by allowing for more delegates to be implemented by the SDK, such that the template engine no longer has to call dotnet.exe in order to ask the SDK to perform actions on its behalf. For the most part, the extra process creation should be unnecessary, and materially increases the time required to complete the action. This comes from both the cost of spawning the new process, as well as new managed process overhead, such as JIT and R2R initialization time.

Strawman Code Pattern

Rather than passing individual delegates, I propose replacing the onFirstRun argument with a callbacks argument of type DotNetNew3Callbacks that lives in the template engine codebase (today the SDK depends on the template engine, not the other way around):

public sealed class DotNetNew3Callbacks
{
	public Action<IEngineEnvironmentSettings, IInstaller> OnFirstRun { get; set; }
}

From here, we can add a new callback whenever one is needed. The workflow for adding a new callback is the following:

  1. Add the new callback to DotNetNew3Callbacks, and optionally allow its use in the template engine, as long as the template engine can handle if the callback is null (it will be null until step 3).
  2. Merge the new callback and wait for the change to propagate to the SDK repo.
  3. Implement the callback in the SDK.
  4. If necessary, change the usage of the delegate in the template engine now that the SDK implements the delegate unconditionally (step 3).

First Proposed Usage

The first proposed usage of this mechanism is to replace the call to dotnet restore that is made in DotNetRestorePostActionProcessor.Process to avoid the extra process overhead.

public sealed class DotNetNew3Callbacks
{
	public Action<IEngineEnvironmentSettings, IInstaller> OnFirstRun { get; set; }
	
	// string argument: Path to restore
	public Action<string> RestoreProject { get; set; }
}

RestoreProject will be called by DotNetRestorePostActionProcessor.Process instead of calling Dotnet.Restore(pathToRestore) at https://github.com/dotnet/templating/blob/master/src/Microsoft.TemplateEngine.Cli/PostActionProcessors/DotnetRestorePostActionProcessor.cs#L78.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:12 (11 by maintainers)

github_iconTop GitHub Comments

1reaction
phenningcommented, Apr 7, 2020

We want to be very careful about changing the onFirstRun mechanism. The template engine interfaces are used by more than just dotnet new. Visual Studio and and Visual Studio for Mac both use these interfaces, from multiple entry points, by multiple teams.

The new mechanism should be implemented on a separate or updated interface which could be opted into by the new command so that we could maintain compatibility across the other consumers of the API, especially considering that the IDEs would get very little benefit from this update since they don’t invoke restore at project creation, but instead via solution build.

Edit: I just realized as long as we only update the signature in the New3Command and not in the. Microsoft.TemplateEngine.IDE we should be fine here, so the above does not really apply in this case. We should keep the other consumers in mind though for any other proposed API signature changes.

1reaction
brianrobcommented, Apr 2, 2020

@donJoseLuis, @dsplaisted I’d like to get your feedback on this. cc: @DamianEdwards, @davidfowl, @KathleenDollard

Note: Right now, in order to restore a newly instantiated template, there are 3 processes involved:

  1. dotnet new <template>: The user typed this.
  2. dotnet restore new-project.csproj: Started by process 1 because there isn’t currently a clean way to call back into the SDK to do the restore. This proposal would allow for elimination of this process.
  3. dotnet exec MSBuild.dll: This is invoked by process 2. A separate effort is required to eliminate this process.
Read more comments on GitHub >

github_iconTop Results From Across the Web

20200511-clusterctl-extensible-template-processing.md
This proposal aims to extend clusterctl's current templating mechanism of simple variable substitution to support other templating formats ...
Read more >
Add interactive mode to the CLI #179 - dotnet/templating
Our current plan for this is to release the portion that calls the API as a separate tool & have it produce an...
Read more >
منشور Dan Selman - accordproject/template-cli
A busy week of progress on the Accord Project Template Engine and CLI. ... GitHub - accordproject/template-cli: Command Line Interface for template engine...
Read more >
Using Templates
OpenAPI Generator applies user-defined templates via options: CLI: -t/--template CLI options; Maven Plugin: templateDirectory; Gradle Plugin: ...
Read more >
How To Use Templates in a Flask Application
Make sure you're inside the flask_app directory and run the following command to create the templates directory: mkdir templates.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found