|
| 1 | +# Unix Environment Setup for dotnetup |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +This document describes the design for setting up the .NET environment via initialization scripts using the `dotnetup print-env-script` command. This is the first step toward enabling automatic user profile configuration for Unix as described in [issue #51582](https://github.com/dotnet/sdk/issues/51582). Note that this also supports PowerShell and thus Windows, but on Windows the main method of configuring the environment will be to set environment variables which are stored in the registry instead of written by initialization scripts. |
| 6 | + |
| 7 | +## Background |
| 8 | + |
| 9 | +The dotnetup tool manages multiple .NET installations in a local user hive. For .NET to be accessible from the command line, the installation directory must be: |
| 10 | +1. Added to the `PATH` environment variable |
| 11 | +2. Set as the `DOTNET_ROOT` environment variable |
| 12 | + |
| 13 | +On Unix systems, this requires modifying shell configuration files (like `.bashrc`, `.zshrc`, etc.) or sourcing environment setup scripts. |
| 14 | + |
| 15 | +## Design Goals |
| 16 | + |
| 17 | +1. **Non-invasive**: Don't automatically modify user shell configuration files without explicit consent |
| 18 | +2. **Flexible**: Support multiple shells (bash, zsh, PowerShell) |
| 19 | +3. **Reversible**: Users should be able to easily undo environment changes |
| 20 | +4. **Single-file execution**: Generate scripts that can be sourced or saved for later use |
| 21 | +5. **Discoverable**: Make it easy for users to understand how to configure their environment |
| 22 | + |
| 23 | +## The `dotnetup print-env-script` Command |
| 24 | + |
| 25 | +### Command Structure |
| 26 | + |
| 27 | +```bash |
| 28 | +dotnetup print-env-script [--shell <shell>] [--dotnet-install-path <path>] |
| 29 | +``` |
| 30 | + |
| 31 | +### Options |
| 32 | + |
| 33 | +- `--shell` / `-s`: The target shell for which to generate the environment script |
| 34 | + - Supported values: `bash`, `zsh`, `pwsh` |
| 35 | + - Optional: If not specified, automatically detects the current shell from the `$SHELL` environment variable |
| 36 | + - On Windows, defaults to PowerShell (`pwsh`) |
| 37 | + |
| 38 | +- `--dotnet-install-path` / `-d`: The path to the .NET installation directory |
| 39 | + - Optional: If not specified, uses the default user install path (`~/.local/share/dotnet` on Unix) |
| 40 | + |
| 41 | +### Usage Examples |
| 42 | + |
| 43 | +#### Auto-detect current shell |
| 44 | +```bash |
| 45 | +dotnetup print-env-script |
| 46 | +``` |
| 47 | + |
| 48 | +#### Generate and source in one command |
| 49 | +```bash |
| 50 | +source <(dotnetup print-env-script) |
| 51 | +``` |
| 52 | + |
| 53 | +#### Explicitly specify shell |
| 54 | +```bash |
| 55 | +dotnetup print-env-script --shell zsh |
| 56 | +``` |
| 57 | + |
| 58 | +#### Save script for later use |
| 59 | +```bash |
| 60 | +dotnetup print-env-script --shell bash > ~/.dotnet-env.sh |
| 61 | +# Later, in .bashrc or manually: |
| 62 | +source ~/.dotnet-env.sh |
| 63 | +``` |
| 64 | + |
| 65 | +#### Use custom installation path |
| 66 | +```bash |
| 67 | +dotnetup print-env-script --dotnet-install-path /opt/dotnet |
| 68 | +``` |
| 69 | + |
| 70 | +## Generated Script Format |
| 71 | + |
| 72 | +The command generates shell-specific scripts that: |
| 73 | +1. Set the `DOTNET_ROOT` environment variable to the installation path |
| 74 | +2. Prepend the installation path to the `PATH` environment variable |
| 75 | + |
| 76 | +### Bash/Zsh Example |
| 77 | +```bash |
| 78 | +#!/usr/bin/env bash |
| 79 | +# This script configures the environment for .NET installed at /home/user/.local/share/dotnet |
| 80 | +# Source this script to add .NET to your PATH and set DOTNET_ROOT |
| 81 | + |
| 82 | +export DOTNET_ROOT='/home/user/.local/share/dotnet' |
| 83 | +export PATH='/home/user/.local/share/dotnet':$PATH |
| 84 | +``` |
| 85 | + |
| 86 | +### PowerShell Example |
| 87 | +```powershell |
| 88 | +# This script configures the environment for .NET installed at /home/user/.local/share/dotnet |
| 89 | +# Source this script (dot-source) to add .NET to your PATH and set DOTNET_ROOT |
| 90 | +# Example: . ./dotnet-env.ps1 |
| 91 | +
|
| 92 | +$env:DOTNET_ROOT = '/home/user/.local/share/dotnet' |
| 93 | +$env:PATH = '/home/user/.local/share/dotnet' + [IO.Path]::PathSeparator + $env:PATH |
| 94 | +``` |
| 95 | + |
| 96 | +## Implementation Details |
| 97 | + |
| 98 | +### Provider Model |
| 99 | + |
| 100 | +The implementation uses a provider model similar to `System.CommandLine.StaticCompletions`, making it easy to add support for additional shells in the future. |
| 101 | + |
| 102 | +**Interface**: `IEnvShellProvider` |
| 103 | +```csharp |
| 104 | +public interface IEnvShellProvider |
| 105 | +{ |
| 106 | + string ArgumentName { get; } // Shell name for CLI (e.g., "bash") |
| 107 | + string Extension { get; } // File extension (e.g., "sh") |
| 108 | + string? HelpDescription { get; } // Help text for the shell |
| 109 | + string GenerateEnvScript(string dotnetInstallPath); |
| 110 | +} |
| 111 | +``` |
| 112 | + |
| 113 | +**Implementations**: |
| 114 | +- `BashEnvShellProvider`: Generates bash-compatible scripts |
| 115 | +- `ZshEnvShellProvider`: Generates zsh-compatible scripts |
| 116 | +- `PowerShellEnvShellProvider`: Generates PowerShell Core scripts |
| 117 | + |
| 118 | +### Shell Detection |
| 119 | + |
| 120 | +The command automatically detects the current shell when the `--shell` option is not provided: |
| 121 | + |
| 122 | +1. **On Unix**: Reads the `$SHELL` environment variable and extracts the shell name from the path |
| 123 | + - Example: `/bin/bash` → `bash` |
| 124 | +2. **On Windows**: Defaults to PowerShell (`pwsh`) |
| 125 | + |
| 126 | +### Security Considerations |
| 127 | + |
| 128 | +**Path Escaping**: All installation paths are properly escaped to prevent shell injection vulnerabilities: |
| 129 | +- **Bash/Zsh**: Uses single quotes with `'\''` escaping for embedded single quotes |
| 130 | +- **PowerShell**: Uses single quotes with `''` escaping for embedded single quotes |
| 131 | + |
| 132 | +This ensures that paths containing special characters, spaces, or shell metacharacters are handled safely. |
| 133 | + |
| 134 | +## Advantages of Generated Scripts |
| 135 | + |
| 136 | +As noted in the discussion, generating scripts dynamically has several advantages over using embedded resource files: |
| 137 | + |
| 138 | +1. **Single-file execution**: Users can source the script directly from the command output without needing to extract files |
| 139 | +2. **Flexibility**: Easy to customize the installation path or add future features |
| 140 | +3. **No signing required**: Generated text doesn't require code signing, unlike downloaded executables or scripts |
| 141 | +4. **Immediate availability**: No download or extraction step needed |
| 142 | +5. **Transparency**: Users can easily inspect what the script does by running the command |
| 143 | + |
| 144 | +## Future Work |
| 145 | + |
| 146 | +This command provides the foundation for future enhancements: |
| 147 | + |
| 148 | +1. **Automatic profile modification**: Add a command to automatically update shell configuration files (`.bashrc`, `.zshrc`, etc.) with user consent |
| 149 | +2. **Profile backup**: Create backups of shell configuration files before modification |
| 150 | +3. **Uninstall/removal**: Add commands to remove dotnetup configuration from shell profiles |
| 151 | +4. **Additional shells**: Support for fish, tcsh, and other shells |
| 152 | +5. **Environment validation**: Commands to verify that the environment is correctly configured |
| 153 | + |
| 154 | +## Related Issues |
| 155 | + |
| 156 | +- [Issue #51582](https://github.com/dotnet/sdk/issues/51582): Parent issue tracking user profile modification on Unix |
| 157 | +- [dotnet/designs dnvm-e2e-experience](https://github.com/dotnet/designs/tree/dnvm-e2e-experience/proposed): Design proposal for local .NET hive management |
| 158 | + |
| 159 | +## Testing |
| 160 | + |
| 161 | +The implementation includes comprehensive tests: |
| 162 | +- Parser tests for command validation |
| 163 | +- Shell provider tests for script generation |
| 164 | +- Security tests for special character handling |
| 165 | +- Help documentation tests |
| 166 | + |
| 167 | +All tests ensure that the generated scripts are syntactically correct and properly escape paths. |
0 commit comments