Skip to content
Open
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
18 changes: 18 additions & 0 deletions src/dotnet/NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,21 @@ Installing prerelease builds. Supports `preview` and `daily` suffixes.
This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed.

`bash` is required to execute the `install.sh` script.

## Tab completions

When using .NET SDK 10 or newer, tab completions for the `dotnet` CLI are automatically installed for bash, zsh, and fish. The completion scripts are placed in the standard system-wide directories so they work for all users:

- **Bash**: `/usr/share/bash-completion/completions/dotnet`
- **Zsh**: `/usr/share/zsh/site-functions/_dotnet`
- **Fish**: `/usr/share/fish/vendor_completions.d/dotnet.fish`

To disable this, set `tabCompletions` to `false`:

``` json
"features": {
"ghcr.io/devcontainers/features/dotnet:2": {
"tabCompletions": false
}
}
```
9 changes: 7 additions & 2 deletions src/dotnet/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "dotnet",
"version": "2.4.2",
"version": "2.5.0",
"name": "Dotnet CLI",
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/dotnet",
"description": "This Feature installs the latest .NET SDK, which includes the .NET CLI and the shared runtime. Options are provided to choose a different version or additional versions.",
Expand Down Expand Up @@ -39,6 +39,11 @@
"type": "string",
"default": "",
"description": "Enter additional .NET SDK workloads, separated by commas. Use 'dotnet workload search' to learn what workloads are available to install."
},
"tabCompletions": {
"type": "boolean",
"default": true,
"description": "Install shell tab completions for the dotnet CLI. Requires SDK 10 or newer."
}
},
"containerEnv": {
Expand All @@ -64,4 +69,4 @@
"installsAfter": [
"ghcr.io/devcontainers/features/common-utils"
]
}
}
5 changes: 5 additions & 0 deletions src/dotnet/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS:-""}"
DOTNET_RUNTIME_VERSIONS="${DOTNETRUNTIMEVERSIONS:-""}"
ASPNETCORE_RUNTIME_VERSIONS="${ASPNETCORERUNTIMEVERSIONS:-""}"
WORKLOADS="${WORKLOADS:-""}"
TAB_COMPLETIONS="${TABCOMPLETIONS:-"true"}"

# Prevent "Welcome to .NET" message from dotnet
export DOTNET_NOLOGO=true
Expand Down Expand Up @@ -146,6 +147,10 @@ if [ ! -e /usr/bin/dotnet ]; then
ln --symbolic "$DOTNET_ROOT/dotnet" /usr/bin/dotnet
fi

if [ "$TAB_COMPLETIONS" = "true" ]; then
install_completions
fi

# Add .NET Core SDK tools to PATH for bash and zsh users
# This is where 'dotnet tool install --global <tool>' installs tools to
# Use single-quoted EOF to defer $PATH expansion until sourcing the file
Expand Down
42 changes: 42 additions & 0 deletions src/dotnet/scripts/dotnet-helpers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -184,4 +184,46 @@ parse_version_and_quality() {
quality=""
fi
echo "$clean_version" "$quality"
}

# Checks if the installed .NET SDK is at least the given major version.
# Returns 0 (true) if the SDK major version >= the specified version, 1 otherwise.
# Also returns 1 if no SDK is installed (e.g. runtime-only installs).
# Usage: is_at_least_sdk_version <major_version>
# Example: is_at_least_sdk_version 10
is_at_least_sdk_version() {
local required_major="$1"
local dotnet_version
dotnet_version=$("$DOTNET_ROOT/dotnet" --version 2>/dev/null || true)
local major_version="${dotnet_version%%.*}"
[[ "$major_version" =~ ^[0-9]+$ ]] && [ "$major_version" -ge "$required_major" ]
}

# Sets up dotnet tab completions for bash, zsh, and fish.
# The 'dotnet completions script' command is only available in .NET SDK 10+.
# Older SDKs and runtime-only installs will naturally skip this since the
# command won't be available.
# Reference: https://learn.microsoft.com/en-us/dotnet/core/tools/enable-tab-autocomplete
# Completion scripts are generated at install time and placed in the standard
# system-wide completion directories, which are auto-discovered by
# bash-completion, zsh, and fish without modifying any rc files.
install_completions() {
if ! is_at_least_sdk_version 10; then
echo "Skipping dotnet tab completions (requires SDK 10+)."
return
fi

echo "Setting up dotnet tab completions..."

# Bash: drop into the standard bash-completion directory
mkdir -p /usr/share/bash-completion/completions
"$DOTNET_ROOT/dotnet" completions script bash > /usr/share/bash-completion/completions/dotnet

# Zsh: drop into the standard site-functions directory
mkdir -p /usr/share/zsh/site-functions
"$DOTNET_ROOT/dotnet" completions script zsh > /usr/share/zsh/site-functions/_dotnet

# Fish: drop into the standard vendor completions directory
mkdir -p /usr/share/fish/vendor_completions.d
"$DOTNET_ROOT/dotnet" completions script fish > /usr/share/fish/vendor_completions.d/dotnet.fish
}
11 changes: 10 additions & 1 deletion test/dotnet/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,18 @@ test -L /usr/bin/dotnet -a "$(readlink -f /usr/bin/dotnet)" = "$DOTNET_ROOT/dotn

expected=$(fetch_latest_version)

check "Latest .NET SDK version installed" \
check "Latest .NET SDK version $expected installed" \
is_dotnet_sdk_version_installed "$expected"

check "Bash completion script installed" \
test -s /usr/share/bash-completion/completions/dotnet

check "Zsh completion script installed" \
test -s /usr/share/zsh/site-functions/_dotnet

check "Fish completion script installed" \
test -s /usr/share/fish/vendor_completions.d/dotnet.fish

# Report results
# If any of the checks above exited with a non-zero exit code, the test will fail.
reportResults