Skip to content

Adjust and document exit codes #4787

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

Merged
merged 10 commits into from
Jun 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
268 changes: 268 additions & 0 deletions docs/Exit-Codes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
# `dotnet new` exit codes and their meaning

Exit codes are chosen to conform to existing standards or standardization attempts and well known exit code. See [Related resources](#related) for more details

| Exit Code | Reason |
|:-----|----------|
| 0 | Success |
| [70](#70) | Unexpected internal software issue. |
| [73](#73) | Can't create output file. |
| [100](#100) | Instantiation Failed - Processing issues. |
| [101](#101) | Invalid template or template package. |
| [102](#102) | Missing required option(s) and/or argument(s) for the command. |
| [103](#103) | The template or the template package was not found. |
| [104](#104) | PostAction operation was cancelled. |
| [105](#105) | Instantiation Failed - Post action failed. |
| [106](#106) | Template/Package management operation Failed. |
| [107 - 113](#107) | Reserved. |
| [127](#127) | Unrecognized option(s) and/or argument(s) for a command. |
| [130](#130) | Command terminated by user. |


To enable verbose logging in order to troubleshoot issue(s), set the `DOTNET_CLI_CONTEXT_VERBOSE` environment variable to `true`

_PowerShell:_
```PowerShell
$env:DOTNET_CLI_CONTEXT_VERBOSE = 'true'
```

_Cmd:_
```cmd
set DOTNET_CLI_CONTEXT_VERBOSE=true
```

## <a name="70"></a>70 - Unexpected internal software issue

Unexpected result or issue. [File a bug](https://github.com/dotnet/templating/issues/new?title=Unexpected%20Internal%20Software%20Issue%20(EX_SOFTWARE)) if you encounter this exit code.

This is a semi-standardized exit code (see [EX_SOFTWARE in /usr/include/sysexits.h](https://github.com/openbsd/src/blob/master/include/sysexits.h#L107))


## <a name="73"></a>73 - Can't create output file.

The operation was cancelled due to detection of an attempt to perform destructive changes to existing files. This can happen if you are attempting to instantiate template into the same folder where it was previously instantiated under same target name (specified via `--name` option or defaults to the target directory name)

_Example:_
```console
> dotnet new console

The template "Console App" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on C:\tmp\tmp.csproj...
Determining projects to restore...
Restored C:\tmp\tmp.csproj (in 47 ms).
Restore succeeded.

> dotnet new console

Creating this template will make changes to existing files:
Overwrite ./tmp.csproj
Overwrite ./Program.cs

Rerun the command and pass --force to accept and create.

For details on current exit code please visit https://aka.ms/templating-exit-codes#73
```

Destructive changes can be forced by passing `--force` option

This is a semi-standardized exit code (see [EX_CANTCREAT in /usr/include/sysexits.h](https://github.com/openbsd/src/blob/master/include/sysexits.h#L110))


## <a name="100"></a>100 - Instantiation Failed - Processing issues

The template instantiation failed due to error(s). Caused by environment (failure to read/write template(s) or cache) or

## <a name="101"></a>101 - Invalid template or template package

_Reserved for future usage - described behavior is yet not implemented. [Feature is tracked](https://github.com/dotnet/templating/issues/4801)_

Caused by errorneous template(s) (incomplete conditions, symbols or macros etc.). Exact error reason will be output to stderr.

_Examples:_

Missing mandatory properties in template.json
```json
{
"author": "John Doe",
"name": "name",
}
```


## <a name="102"></a>102 - Missing required option(s) and/or argument(s) for the command
Copy link
Member

Choose a reason for hiding this comment

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

i'm still not convinced here. For example below, the command misses required argument, and exit code is 127; as it is managed by parser.

PS > dotnet new install
Required argument missing for command: install



Description:
Installs a template package.



Usage:
dotnet new install [<package>...] [options]



Arguments:
<package> NuGet package ID or path to folder or NuGet package to install.
To install the NuGet package of certain version, use <package ID>::<version>.



Options:
--interactive Allows the command to stop and wait for user input or action (for
example to complete authentication).
--add-source, --nuget-source <nuget-source> Specifies a NuGet source to use during install.
--force Allows installing template packages from the specified sources even if
they would override a template package from another source.
-?, -h, --help Show command line help.





PS > $LASTEXITCODE
127

Search command validation should be moved as the validator. I can work on it next month in scope of parser migration.


_Reserved for future usage - described behavior is only partially implemented. Some cases that should fall under this exit code are now leading to code [127](#127) [Issue is tracked](https://github.com/dotnet/templating/issues/4806)_

The exit code is used when one or more required options or/and arguments used for the command were not passed. Applicable to `search` command with not enough information as well.

Applicable as well if template option [marked as required](Reference-for-template.json.md#isrequired) was not passed during the template instantiation.

_Examples:_
```console
> dotnet new my-template
Mandatory option '--MyMandatoryParam' is missing for the template 'My Template'.

For details on current exit code please visit https://aka.ms/templating-exit-codes#102
```

```console
> dotnet new search
Search failed: not enough information specified for search.
To search for templates, specify partial template name or use one of the supported filters: '--author', '--baseline', '--language', '--type', '--tag', '--package'.
Examples:
dotnet new search web
dotnet new search --author Microsoft
dotnet new search web --language C#

For details on current exit code please visit https://aka.ms/templating-exit-codes#102
```


## <a name="103"></a>103 - The template or the template package was not found

Applicable to instantiation, listing, remote sources searching and installation.

_Examples:_
```console
> dotnet new xyz
No templates found matching: 'xyz'.

To list installed templates, run:
dotnet new list
To search for the templates on NuGet.org, run:
dotnet new search xyz

For details on current exit code please visit https://aka.ms/templating-exit-codes#103
```

```console
> dotnet new list xyz
No templates found matching: 'xyz'.

To search for the templates on NuGet.org, run:
dotnet new search xyz

For details on current exit code please visit https://aka.ms/templating-exit-codes#103
```

```console
> dotnet new search xyz
Searching for the templates...
Matches from template source: NuGet.org
No templates found matching: 'xyz'.

For details on current exit code please visit https://aka.ms/templating-exit-codes#103
```

```console
> dotnet new install foobarbaz
The following template packages will be installed:
foobarbaz

foobarbaz could not be installed, no NuGet feeds are configured or they are invalid.

For details on current exit code please visit https://aka.ms/templating-exit-codes#103
```

## <a name="104"></a>104 - PostAction operation was cancelled

Applicable to a case when user aborts custom post action.


## <a name="105"></a>105 - Instantiation Failed - Post action failed

Applicable to a case when PostAction fails - unless it is configured to [continue on errors](Post-Action-Registry.md#continueOnError).

## <a name="106"></a>106 - Template/Package management operation failed

The exit code is used for errors during templates installation, uninstallation or updates.
Failure to download packages, read/write templates or cache, erorrneous or corrupted template, or an attempt to install same package multiple times.

_Example:_
```console
>dotnet nuget disable source nuget.org
Package source with Name: nuget.org disabled successfully.

> dotnet new install webapi2
The following template packages will be installed:
webapi2

Error: No NuGet sources are defined or enabled.
webapi2 could not be installed, the package does not exist.

For details on current exit code please visit https://aka.ms/templating-exit-codes#106
```

## <a name="107"></a><a name="108"></a><a name="109"></a><a name="110"></a><a name="111"></a><a name="112"></a><a name="113"></a>107 - 113

Reserved for future use.

[File a bug](https://github.com/dotnet/templating/issues/new?title=Unexpected%20Exit%20Code) if you encounter any of these exit codes.


## <a name="127"></a>127 - Unrecognized option(s) and/or argument(s) for a command

The exit code is used when one or more options or/and arguments used in the command not recognized or invalid.

Usually a mismatch in type of the specified template option or unrecognized choice value.

_Examples:_

```console
> dotnet new console --framework xyz
Error: Invalid option(s):
--framework xyz
'xyz' is not a valid value for --framework. The possible values are:
net6.0 - Target net6.0
net7.0 - Target net7.0

For details on current exit code please visit https://aka.ms/templating-exit-codes#127
```

```console
dotnet new update --smth
Unrecognized command or argument '--smth'



Description:
Checks the currently installed template packages for update, and install the updates.



Usage:
dotnet new update [options]



Options:
--interactive Allows the command to stop and wait for user input or action (for
example to complete authentication).
--add-source, --nuget-source <nuget-source> Specifies a NuGet source to use during install.
--check-only, --dry-run Only check for updates and display the template packages to be updated
without applying update.
-?, -h, --help Show command line help.

For details on current exit code please visit https://aka.ms/templating-exit-codes#127
```

This is a semi-standardized exit code (see [127 - "command not found" in 'The Linux Documentation Project'](https://tldp.org/LDP/abs/html/exitcodes.html))


## <a name="130"></a>130 - Command terminated by user.

_Reserved for future usage - described behavior is yet not implemented. [Feature is tracked](https://github.com/dotnet/templating/issues/4799)_

The exit code is used if command is terminated after user non-forceful termination request (e.g. `Ctrl-C`, `Ctrl-Break`).

This is a semi-standardized exit code (see [130 - Script terminated by Control-C in 'The Linux Documentation Project'](https://tldp.org/LDP/abs/html/exitcodes.html))

<BR/>
<BR/>
<BR/>

### Related Resources
* [`BSD sysexit.h`](https://github.com/openbsd/src/blob/master/include/sysexits.h)
* [`Special exit codes - The Linux Documentation Project`](https://tldp.org/LDP/abs/html/exitcodes.html)
2 changes: 1 addition & 1 deletion docs/Post-Action-Registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The standard properties are listed below.
- `condition` (string) (optional): A C++ style boolean expression defining if post action should be run. This expression may use any symbols that have been defined.
- `description` (string) (optional): A human-readable description of the action.
- `configFile` (string) (optional): Additional configuration for the associated post action. The structure & content will vary based on the post action.
- `continueOnError` (bool) (optional): If this action fails, the value of continueOnError indicates whether to process the next action, or stop processing the post actions. Should be set to true when subsequent actions rely on the result of the current action. The default value is false.
- <a name="continueOnError"></a>`continueOnError` (bool) (optional): If this action fails, the value of continueOnError indicates whether to process the next action, or stop processing the post actions. Should be set to true when subsequent actions rely on the result of the current action. The default value is false.
- `manualInstructions` (array) (optional): An ordered list of possible instructions to display if the action cannot be performed. Each element in the list must contain a key named "text", whose value contains the instructions. Each element may also optionally provide a key named "condition" - a boolean expression. The first instruction with blank condition is considered a default. If true conditions are present, the last one of them will be considered valid, all other ignored. It is recommended not to have more than one true condition at the time.

# Restore NuGet packages
Expand Down
2 changes: 1 addition & 1 deletion docs/Reference-for-template.json.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ A symbol for which the config provides literal and/or default values.
|`replaces`|The text to be replaced by the symbol value in the template files content|
|`fileRename`|The portion of template filenames to be replaced by the symbol value.|
|`description`|Human readable text describing the meaning of the symbol. This has no effect on template generation.|
|`isRequired`|Indicates if the parameter is required or not.|
|<a name="isRequired"></a>`isRequired`|Indicates if the parameter is required or not.|
|`choices`|Applicable only when `datatype=choice.`<br />List of available choices. Contains array of the elements: <br />- `choice`: possible value of the symbol.<br />- `description`: human readable text describing the meaning of the choice. This has no effect on template generation. <br /> If not provided, there are no valid choices for the symbol, so it can never be assigned a value.|
|`allowMultipleValues`|Applicable only when `datatype=choice.`<br />. Enables ability to specify multiple values for single symbol.|
|<a id="enableQuotelessLiterals"></a>`enableQuotelessLiterals`|Applicable only when `datatype=choice.`<br />. Enables ability to specify choice literals in conditions without quotation.|
Expand Down
14 changes: 12 additions & 2 deletions src/Microsoft.TemplateEngine.Cli/Commands/BaseCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,14 @@ public async Task<int> InvokeAsync(InvocationContext context)

CancellationToken cancellationToken = context.GetCancellationToken();

NewCommandStatus returnCode;

try
{
using (Timing.Over(environmentSettings.Host.Logger, "Execute"))
{
await HandleGlobalOptionsAsync(args, environmentSettings, cancellationToken).ConfigureAwait(false);
return (int)await ExecuteAsync(args, environmentSettings, telemetryLogger, context).ConfigureAwait(false);
returnCode = await ExecuteAsync(args, environmentSettings, telemetryLogger, context).ConfigureAwait(false);
}
}
catch (Exception ex)
Expand Down Expand Up @@ -136,8 +138,16 @@ public async Task<int> InvokeAsync(InvocationContext context)
{
Reporter.Error.WriteLine(ex.StackTrace.Bold().Red());
}
return 1;
returnCode = NewCommandStatus.Unexpected;
}

if (returnCode != NewCommandStatus.Success)
{
Reporter.Error.WriteLine();
Reporter.Error.WriteLine(string.Format(LocalizableStrings.BaseCommand_ExitCodeHelp, (int)returnCode));
}

return (int)returnCode;
}

public int Invoke(InvocationContext context) => InvokeAsync(context).GetAwaiter().GetResult();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ private static NewCommandStatus HandleNoTemplateFoundResult(
.WithHelpOption());
}

return NewCommandStatus.InvalidParamValues;
return invalidOptionsList.Any() ? NewCommandStatus.InvalidOption : NewCommandStatus.NotFound;
}

private static void HandleNoMatchOnTemplateBaseOptions(IEnumerable<TemplateResult> matchInfos, InstantiateCommandArgs args, TemplateGroup templateGroup)
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion src/Microsoft.TemplateEngine.Cli/LocalizableStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@
<value>Language</value>
</data>
<data name="MissingRequiredParameter" xml:space="preserve">
<value>Mandatory option {0} missing for template {1}.</value>
<value>Mandatory option '{0}' is missing for the template '{1}'.</value>
</data>
<data name="MountPointFactories" xml:space="preserve">
<value>Mount Point Factories</value>
Expand Down Expand Up @@ -813,6 +813,10 @@ The header is followed by the list of parameters and their errors (might be seve
<value>To reinstall the same version of the template package, use '{0}' option:</value>
<comment>{0} - option name (--force). Followed by command example on new line.</comment>
</data>
<data name="BaseCommand_ExitCodeHelp" xml:space="preserve">
<value>For details on the exit code, refer to https://aka.ms/templating-exit-codes#{0}</value>
<comment>{0} is the exit code</comment>
</data>
<data name="TemplateCommand_DisplayConstraintResults_Error" xml:space="preserve">
<value>Failed to instatiate template '{0}', the following constraints are not met:</value>
<comment>{0} - template name (user friendly)</comment>
Expand Down
Loading