-
Notifications
You must be signed in to change notification settings - Fork 79
add support pre-install plugins #571
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
base: main
Are you sure you want to change the base?
Changes from all commits
5b29270
429b629
b7df74c
408eaee
2b616fc
a95f904
8c98af6
3b6c743
c261779
c6ae736
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| { | ||
| "lockfileVersion": 1, | ||
| "configVersion": 0, | ||
| "workspaces": { | ||
| "": { | ||
| "name": "registry", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -137,6 +137,43 @@ module "jetbrains" { | |
| } | ||
| ``` | ||
|
|
||
| ### Plugin Auto‑Installer | ||
|
|
||
| This module now supports automatic JetBrains plugin installation inside your workspace. | ||
|
|
||
| To get a plugin ID, open the plugin’s page on the JetBrains Marketplace. Scroll down to Additional Information and look for Plugin ID. Use that value in the configuration below. | ||
|
|
||
| ```tf | ||
| module "jetbrains" { | ||
| count = data.coder_workspace.me.start_count | ||
| source = "registry.coder.com/coder/jetbrains/coder" | ||
| version = "1.2.1" | ||
|
||
| agent_id = coder_agent.main.id | ||
| folder = "/home/coder/project" | ||
| default = ["IU", "PY"] | ||
|
|
||
| jetbrains_plugins = { | ||
| "PY" = ["com.koxudaxi.pydantic", "com.intellij.kubernetes"] | ||
| "IU" = ["<Plugin-ID>", "<Plugin-ID>"] | ||
| "WS" = ["<Plugin-ID>", "<Plugin-ID>"] | ||
| "GO" = ["<Plugin-ID>", "<Plugin-ID>"] | ||
| "CL" = ["<Plugin-ID>", "<Plugin-ID>"] | ||
| "PS" = ["<Plugin-ID>", "<Plugin-ID>"] | ||
| "RD" = ["<Plugin-ID>", "<Plugin-ID>"] | ||
| "RM" = ["<Plugin-ID>", "<Plugin-ID>"] | ||
| "RR" = ["<Plugin-ID>", "<Plugin-ID>"] | ||
| } | ||
| } | ||
|
Comment on lines
+155
to
+166
|
||
| ``` | ||
|
|
||
| > [!IMPORTANT]\ | ||
| > This module prerequisites and limitations | ||
| > | ||
| > 1. Requires JetBrains Toolbox to be installed | ||
| > 2. Requires jq to be available | ||
| > 3. Only works on Debian/Ubuntu-based systems (due to apt-get usage) | ||
| > 4. Plugins are installed when workspace starts, but may take time depending on IDE availability | ||
|
|
||
| ### Accessing the IDE Metadata | ||
|
|
||
| You can now reference the output `ide_metadata` as a map. | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -173,6 +173,13 @@ variable "ide_config" { | |||||
| } | ||||||
| } | ||||||
|
|
||||||
| variable "jetbrains_plugins" { | ||||||
| type = map(list(string)) | ||||||
| description = "Map of IDE product codes to plugin ID lists. Example: { IU = [\"com.foo\"], GO = [\"org.bar\"] }." | ||||||
|
||||||
| description = "Map of IDE product codes to plugin ID lists. Example: { IU = [\"com.foo\"], GO = [\"org.bar\"] }." | |
| description = "Map of JetBrains IDE product codes to plugin ID lists. Valid codes: CL (CLion), GO (GoLand), IU (IntelliJ IDEA Ultimate), PS (PhpStorm), PY (PyCharm), RD (Rider), RM (RubyMine), RR (ReSharper), WS (WebStorm). Example: { IU = [\"com.foo\"], GO = [\"org.bar\"] }. Find plugin IDs at https://plugins.jetbrains.com/." |
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,167 @@ | ||||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||||
| set -euo pipefail | ||||||||||||||||
|
|
||||||||||||||||
| LOGFILE="$HOME/.config/jetbrains/install_plugins.log" | ||||||||||||||||
| TOOLBOX_BASE="$HOME/.local/share/JetBrains/Toolbox/apps" | ||||||||||||||||
| PLUGIN_MAP_FILE="$HOME/.config/jetbrains/plugins.json" | ||||||||||||||||
|
|
||||||||||||||||
| if command -v apt-get > /dev/null 2>&1; then | ||||||||||||||||
| sudo apt-get update | ||||||||||||||||
| sudo apt-get install -y libfreetype6 | ||||||||||||||||
| else | ||||||||||||||||
| echo "Warning: 'apt-get' not found. Please ensure 'libfreetype6' is installed manually for your distribution." >&2 | ||||||||||||||||
| fi | ||||||||||||||||
|
|
||||||||||||||||
| mkdir -p "$(dirname "$LOGFILE")" | ||||||||||||||||
|
|
||||||||||||||||
| exec > >(tee -a "$LOGFILE") 2>&1 | ||||||||||||||||
|
|
||||||||||||||||
| log() { | ||||||||||||||||
| printf '%s %s\n' "$(date --iso-8601=seconds)" "$*" | tee -a "$LOGFILE" | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| # -------- Read plugin JSON -------- | ||||||||||||||||
| get_enabled_codes() { | ||||||||||||||||
| jq -r 'keys[]' "$PLUGIN_MAP_FILE" | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| get_plugins_for_code() { | ||||||||||||||||
| jq -r --arg CODE "$1" '.[$CODE][]?' "$PLUGIN_MAP_FILE" 2> /dev/null || true | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| # -------- Product code mapping -------- | ||||||||||||||||
| map_folder_to_code() { | ||||||||||||||||
| case "$1" in | ||||||||||||||||
| *pycharm*) echo "PY" ;; | ||||||||||||||||
| *idea*) echo "IU" ;; | ||||||||||||||||
| *webstorm*) echo "WS" ;; | ||||||||||||||||
|
Comment on lines
+33
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The folder mapping uses lowercase globs ( Useful? React with 👍 / 👎. |
||||||||||||||||
| *goland*) echo "GO" ;; | ||||||||||||||||
| *clion*) echo "CL" ;; | ||||||||||||||||
| *phpstorm*) echo "PS" ;; | ||||||||||||||||
| *rider*) echo "RD" ;; | ||||||||||||||||
| *rubymine*) echo "RM" ;; | ||||||||||||||||
| *rustrover*) echo "RR" ;; | ||||||||||||||||
| *) echo "" ;; | ||||||||||||||||
| esac | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| # -------- CLI launcher names -------- | ||||||||||||||||
| launcher_for_code() { | ||||||||||||||||
| case "$1" in | ||||||||||||||||
| PY) echo "pycharm" ;; | ||||||||||||||||
| IU) echo "idea" ;; | ||||||||||||||||
| WS) echo "webstorm" ;; | ||||||||||||||||
| GO) echo "goland" ;; | ||||||||||||||||
| CL) echo "clion" ;; | ||||||||||||||||
| PS) echo "phpstorm" ;; | ||||||||||||||||
| RD) echo "rider" ;; | ||||||||||||||||
| RM) echo "rubymine" ;; | ||||||||||||||||
| RR) echo "rustrover" ;; | ||||||||||||||||
| *) return 1 ;; | ||||||||||||||||
| esac | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| find_cli_launcher() { | ||||||||||||||||
| local exe | ||||||||||||||||
| exe="$(launcher_for_code "$1")" || return 1 | ||||||||||||||||
|
|
||||||||||||||||
| # Look for the newest version directory | ||||||||||||||||
| local latest_version | ||||||||||||||||
| latest_version=$(find "$2" -maxdepth 2 -type d -name "ch-*" 2> /dev/null | sort -V | tail -1) | ||||||||||||||||
|
|
||||||||||||||||
| if [ -n "$latest_version" ] && [ -f "$latest_version/bin/$exe" ]; then | ||||||||||||||||
| echo "$latest_version/bin/$exe" | ||||||||||||||||
| else | ||||||||||||||||
| return 1 | ||||||||||||||||
| fi | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| install_plugin() { | ||||||||||||||||
| log "Installing plugin: $2" | ||||||||||||||||
| if "$1" installPlugins "$2"; then | ||||||||||||||||
| log "Successfully installed plugin: $2" | ||||||||||||||||
| else | ||||||||||||||||
| log "Failed to install plugin: $2" | ||||||||||||||||
| return 1 | ||||||||||||||||
| fi | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| # -------- Main -------- | ||||||||||||||||
| log "Plugin installer started" | ||||||||||||||||
|
|
||||||||||||||||
| if [ ! -f "$PLUGIN_MAP_FILE" ]; then | ||||||||||||||||
| log "No plugins.json found. Exiting." | ||||||||||||||||
| exit 0 | ||||||||||||||||
| fi | ||||||||||||||||
|
|
||||||||||||||||
| # Load list of IDE codes user actually needs | ||||||||||||||||
| mapfile -t pending_codes < <(get_enabled_codes) | ||||||||||||||||
|
|
||||||||||||||||
| if [ ${#pending_codes[@]} -eq 0 ]; then | ||||||||||||||||
| log "No plugin entries found. Exiting." | ||||||||||||||||
|
Comment on lines
+97
to
+101
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
pending_codes is populated from every key in plugins.json, regardless of which IDEs were actually selected or installed. If a user supplies plugin lists for more products than they enable (e.g., the README example lists all codes while Useful? React with 👍 / 👎. |
||||||||||||||||
| exit 0 | ||||||||||||||||
| fi | ||||||||||||||||
|
|
||||||||||||||||
| log "Waiting for IDE installation. Pending codes: ${pending_codes[*]}" | ||||||||||||||||
|
|
||||||||||||||||
| MAX_ATTEMPTS=60 # 10 minutes | ||||||||||||||||
| attempt=0 | ||||||||||||||||
|
|
||||||||||||||||
| # Loop until all plugins installed | ||||||||||||||||
| while [ ${#pending_codes[@]} -gt 0 ] && [ $attempt -lt $MAX_ATTEMPTS ]; do | ||||||||||||||||
|
|
||||||||||||||||
| if [ ! -d "$TOOLBOX_BASE" ]; then | ||||||||||||||||
| log "Toolbox directory not found yet, waiting..." | ||||||||||||||||
| sleep 10 | ||||||||||||||||
| continue | ||||||||||||||||
| fi | ||||||||||||||||
|
|
||||||||||||||||
|
||||||||||||||||
| if [ ! -d "$TOOLBOX_BASE" ]; then | |
| log "Toolbox directory not found yet, waiting..." | |
| sleep 10 | |
| continue | |
| fi |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The script looks for the CLI launcher in $product_dir/bin/$exe, but this path might not match the actual Toolbox installation structure. JetBrains Toolbox typically installs IDEs in versioned subdirectories like ~/.local/share/JetBrains/Toolbox/apps/PyCharm-P/ch-0/242.23726.102/bin/pycharm. The script needs to find the correct version directory. Consider:
find_cli_launcher() {
local exe
exe="$(launcher_for_code "$1")" || return 1
# Look for the newest version directory
local latest_version
latest_version=$(find "$2" -maxdepth 2 -type d -name "ch-*" 2>/dev/null | sort -V | tail -1)
if [ -n "$latest_version" ] && [ -f "$latest_version/bin/$exe" ]; then
echo "$latest_version/bin/$exe"
else
return 1
fi
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The section title uses a non-breaking hyphen character (U+2011) instead of a standard hyphen. While this may render correctly in most contexts, it could cause issues with some text editors or search functionality. Consider using a standard hyphen:
### Plugin Auto-Installer