Skip to content

Instantly share code, notes, and snippets.

@instance-id
Last active January 17, 2025 22:59
Show Gist options
  • Save instance-id/4c22359bb87859ed1574c1bd0900310b to your computer and use it in GitHub Desktop.
Save instance-id/4c22359bb87859ed1574c1bd0900310b to your computer and use it in GitHub Desktop.
Update JetBrains github copilot plugin to allow current Rider EAP version
#!/usr/bin/env -S pwsh -noProfile -nologo
<#
.NOTES
============================================================
Last Edit: 10/20/2024
Created by: instance.id (https://github.com/instance-id)
Platform: Linux/Windows
Filename: github_copilot_eap.ps1
PSVersion: Last tested with 7.4.x
============================================================
.DESCRIPTION
Edit the github copilot Jetbrains plugin to allow it to work in the current Rider EAP
If the current version is 243.* but the plugin only allows 242.*, setting the parameter `-eapVersion '3'` will update the plugin to 243.*
10/20/24 - If no source path is provided, downloads the latest nightly into the current directory and updates it
.EXAMPLE
./github_copilot_eap.ps1 -sourcePath 'github-copilot-intellij-1.5.25.21-nightly.zip' -eapVersion '3'
#>
param(
[string]$sourcePath = '',
[string]$eapVersion = '3'
)
$currentPath = $PSScriptRoot
function DownloadNightly() {
$latestNightly = $(curl -s "https://plugins.jetbrains.com/api/plugins/17718/updates?channel=nightly&page=1&size=8") | ConvertFrom-Json
$latestPlugin = "https://downloads.marketplace.jetbrains.com/files/$($latestNightly[0].file)"
$pluginBaseName = $latestNightly[0].file -replace '17718/\d*/', ''
write-host "Downloading ${pluginBaseName} from $latestPlugin"
# Download the latest nightly version
Invoke-WebRequest -Uri $latestPlugin -OutFile $pluginBaseName
return $pluginBaseName
}
if (-not (Test-Path $sourcePath)) {
write-host "Downloading the latest nightly version of the github copilot plugin"
$downloadedPath = [System.IO.Path]::Combine($currentPath, $(DownloadNightly))
if (-not (Test-Path $downloadedPath)) {
throw "Could not download the latest nightly version of the github copilot plugin"
} else {
$sourcePath = $downloadedPath
}
}
$sourceFile = [System.IO.Path]::GetFileName($sourcePath)
if (($sourceFile -notmatch 'github-copilot-intellij') -or ($sourceFile.EndsWith('.zip') -eq $false)) {
throw "Source file must be a github-copilot-intellij zip file"
}
$fileBaseName = [System.IO.Path]::GetFileNameWithoutExtension($sourceFile)
$fileNameJar = "${fileBaseName}.jar"
$pluginJar = "github-copilot-intellij/lib/${fileNameJar}"
$innerFilePathInJar = "META-INF/plugin.xml"
$sourceZip = $null
$jarFile = $null
$jarStream = $null
$jarArchive = $null
$pluginXmlStream = $null
$pluginXmlWriter = $null
try {
$sourceZip = [System.IO.Compression.ZipFile]::Open($sourcePath, 'Update')
$jarFile = $sourceZip.GetEntry($pluginJar)
if ($jarFile -eq $null) {
throw "Could not find ${pluginJar} in ${sourceFile}"
}
$jarStream = $jarFile.Open()
if ($jarStream -eq $null) {
throw "Could not open ${pluginJar} in ${sourceFile}"
}
$jarArchive = [System.IO.Compression.ZipArchive]::new($jarStream, [System.IO.Compression.ZipArchiveMode]::Update)
if ($jarArchive -eq $null) {
throw "Could not open ${pluginJar} in ${sourceFile}"
}
$pluginXml = $jarArchive.GetEntry($innerFilePathInJar)
if ($pluginXml -eq $null) {
throw "Could not find ${innerFilePathInJar} in ${pluginJar}"
}
$pluginXmlStream = $pluginXml.Open()
$pluginXmlReader = [System.IO.StreamReader]::new($pluginXmlStream)
$pluginXmlContent = $pluginXmlReader.ReadToEnd()
$pluginXmlReader.Close()
$pluginXmlStream.Close()
[xml]$xmlDoc = $pluginXmlContent
$ideaVersionNode = $xmlDoc.'idea-plugin'.'idea-version'
if ($null -eq $ideaVersionNode) {
throw "Could not find 'idea-version' node in ${innerFilePathInJar}"
}
$untilBuildAttr = $ideaVersionNode.'until-build'
if ($null -eq $untilBuildAttr) {
throw "Could not find 'until-build' attribute in 'idea-version' node"
}
$untilBuildValue = $ideaVersionNode.'until-build'
if ($untilBuildValue -match '(\d)(\d)(\d)(\.\*)') {
$firstPart = [int]$matches[1]
$secondPart = [int]$matches[2]
$fourthPart = $matches[4]
$newUntilBuildValue = "${firstPart}$(($secondPart+1))$eapVersion$($fourthPart)"
if ($newUntilBuildValue -eq $untilBuildValue) {
write-host "The 'until-build' attribute value is already set to the expected value"
exit 0
}
$ideaVersionNode.'until-build' = $newUntilBuildValue
} else {
throw "The 'until-build' attribute value does not match the expected pattern"
}
$pluginXmlStream = $pluginXml.Open()
$pluginXmlWriter = [System.IO.StreamWriter]::new($pluginXmlStream)
$xmlDoc.Save($pluginXmlWriter)
$pluginXmlWriter.Close()
$pluginXmlStream.Close()
$jarArchive.Dispose()
$jarStream.Close()
$sourceZip.Dispose()
write-host "Updated the 'until-build' attribute value in ${innerFilePathInJar} to ${newUntilBuildValue}"
} catch { $_ }
finally {
if ($null -ne $jarArchive) { $jarArchive.Dispose() }
if ($null -ne $jarStream) { $jarStream.Close() }
if ($null -ne $pluginXmlStream) { $pluginXmlStream.Close() }
if ($null -ne $pluginXmlWriter) { $pluginXmlWriter.Close() }
if ($null -ne $sourceZip) { $sourceZip.Dispose() }
}
@instance-id
Copy link
Author

I took this and made it generic so that it should be able to accept any Jetbrains plugin and update it to allow newer EAP versions, not just copilot.

https://gist.github.com/instance-id/ab95e9f8e5aecd60051660998700c0ce

@instance-id
Copy link
Author

Updated: If no source path is provided, downloads the latest nightly into the current directory and patches it

@julioarguello
Copy link

Mac version

#!/bin/bash

# ==============================================================================
# Last Edit:    10/20/2024
# Created by:   instance.id (https://github.com/instance-id)
# Platform:     Linux/Mac
# Filename:     github_copilot_eap.sh
# ==============================================================================
# Description:
# Edit the GitHub Copilot JetBrains plugin to allow it to work in the current Rider EAP.
# Example: ./github_copilot_eap.sh -sourcePath 'github-copilot-intellij-1.5.25.21-nightly.zip' -eapVersion '3'
# ==============================================================================

# Default parameters
sourcePath=""
eapVersion="3"

# Parse command line arguments
while [[ $# -gt 0 ]]; do
    case "$1" in
        -sourcePath)
            sourcePath="$2"
            shift 2
            ;;
        -eapVersion)
            eapVersion="$2"
            shift 2
            ;;
        *)
            echo "Unknown parameter passed: $1"
            exit 1
            ;;
    esac
done

currentPath="$(pwd)"

# Function to download the latest nightly build
downloadNightly() {
    latestNightly=$(curl -s "https://plugins.jetbrains.com/api/plugins/17718/updates?channel=nightly&page=1&size=8")
    latestPlugin=$(echo "$latestNightly" | jq -r '.[0].file')
    pluginBaseName=$(echo "$latestPlugin" | sed -E 's|17718/[0-9]+/||')

    # echo "Downloading ${pluginBaseName} from https://downloads.marketplace.jetbrains.com/files/${latestPlugin}"
    
    curl -L -o "$pluginBaseName" "https://downloads.marketplace.jetbrains.com/files/${latestPlugin}"

    echo "$pluginBaseName"
}

# Check if sourcePath is provided, if not download the latest nightly
if [[ ! -f "$sourcePath" ]]; then
    echo "Downloading the latest nightly version of the GitHub Copilot plugin"
    downloadedPath="$currentPath/$(downloadNightly)"
    echo $downloadedPath
    
    if [[ ! -f "$downloadedPath" ]]; then
        echo "Could not download the latest nightly version of the GitHub Copilot plugin"
        exit 1
    else
        sourcePath="$downloadedPath"
    fi
fi

sourceFile=$(basename "$sourcePath")

# Verify the file is a GitHub Copilot plugin zip
if [[ "$sourceFile" != github-copilot-intellij* ]] || [[ "$sourceFile" != *.zip ]]; then
    echo "Source file must be a GitHub Copilot IntelliJ zip file"
    exit 1
fi

fileBaseName="${sourceFile%.zip}"
fileNameJar="${fileBaseName}.jar"
pluginJar="github-copilot-intellij/lib/${fileNameJar}"

innerFilePathInJar="META-INF/plugin.xml"

# Unzip, modify, and re-zip the plugin
tempDir=$(mktemp -d)
unzip -q "$sourcePath" -d "$tempDir"
cd "$tempDir" || exit 1

if [[ ! -f "$pluginJar" ]]; then
    echo "Could not find ${pluginJar} in ${sourceFile}"
    exit 1
fi

unzip -q "$pluginJar" -d "jar_contents"

if [[ ! -f "jar_contents/$innerFilePathInJar" ]]; then
    echo "Could not find ${innerFilePathInJar} in ${pluginJar}"
    exit 1
fi

# Modify the plugin.xml
pluginXml="jar_contents/$innerFilePathInJar"
untilBuild=$(xmllint --xpath "string(//idea-version/@until-build)" "$pluginXml")

if [[ "$untilBuild" =~ ([0-9]{3})\.(\*) ]]; then
    newUntilBuild="${BASH_REMATCH[1]:0:2}${eapVersion}.${BASH_REMATCH[2]}"

    if [[ "$newUntilBuild" == "$untilBuild" ]]; then
        echo "The 'until-build' attribute value is already set to the expected value"
        exit 0
    fi

    # Update the XML file
    # For compatibility across macOS and Linux
    if [[ "$OSTYPE" == "darwin"* ]]; then
        sed -i '' "s/until-build=\"$untilBuild\"/until-build=\"$newUntilBuild\"/" "$pluginXml"
    else
        sed -i "s/until-build=\"$untilBuild\"/until-build=\"$newUntilBuild\"/" "$pluginXml"
    fi

    echo "Updated the 'until-build' attribute value in ${innerFilePathInJar} to ${newUntilBuild}"

    # Repack the jar and zip
    cd jar_contents || exit 1
    zip -qr "../$pluginJar" .
    cd ..

    # Recreate the main zip file
    zip -qr "$currentPath/$sourceFile" *
else
    echo "The 'until-build' attribute value does not match the expected pattern"
    exit 1
fi

# Cleanup
cd "$currentPath" || exit 1
rm -rf "$tempDir"

echo "Update completed successfully."

@instance-id
Copy link
Author

Updated to support going from Ex: 243.* to 251.*

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment