-
-
Save aldrichtr/7ea38b79d51e27f3cfe35188368394cd to your computer and use it in GitHub Desktop.
Update Tree Sitter langs to latest for Windows #ps1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.SYNOPSIS | |
Downloads, extracts, renames, and symlinks the latest Emacs Tree-sitter grammars for Windows. | |
.DESCRIPTION | |
This script performs the following actions: | |
1. Fetches the latest "Release" from https://github.com/emacs-tree-sitter/tree-sitter-langs/releases. | |
2. Identifies and downloads the `tree-sitter-grammars-windows-0.XX.YYY.tar.gz` file to the system's TEMP directory. | |
3. Creates a new directory (e.g., `tree-sitter-v0.XX.YYY`) in the current working directory. | |
4. Extracts the contents of the downloaded archive into this new directory. | |
5. Renames all `*.dll` files within the extracted directory from `FOO.dll` to `libtree-sitter-FOO.dll`. | |
6. Navigates up one directory. | |
7. Deletes any existing junction named "tree-sitter" in the current directory. | |
8. Creates a new junction named "tree-sitter" pointing to the newly extracted and renamed directory. | |
.NOTES | |
- Requires internet connectivity to download the release. | |
- Assumes 'tar' command is available in the system's PATH. | |
- The script will create a new directory and a junction in the directory where it is executed. | |
#> | |
try { | |
Write-Host "Purpose: Update the tree-sitter DLLs by downloading the latest build from`ngithub.com/emacs-tree-sitter/tree-sitter-langs/, extracting and renaming." -ForegroundColor Green | |
Start-Sleep -Seconds 5 | |
# Define the GitHub API URL for releases | |
$githubApiUrl = "https://api.github.com/repos/emacs-tree-sitter/tree-sitter-langs/releases/latest" | |
Write-Host "Fetching latest release information from GitHub API: $githubApiUrl" -ForegroundColor Cyan | |
# Fetch the latest release information | |
$releaseInfo = Invoke-RestMethod -Uri $githubApiUrl -ErrorAction Stop | |
# Extract the tag name (e.g., v0.XX.YYY) | |
$tagName = $releaseInfo.tag_name | |
Write-Host "Latest release tag found: $tagName" -ForegroundColor Green | |
# Find the asset URL for the Windows tar.gz file | |
$downloadAsset = $releaseInfo.assets | Where-Object { $_.name -match "^tree-sitter-grammars-windows-.*\.tar\.gz$" } | |
if (-not $downloadAsset) { | |
Write-Error "Could not find the expected 'tree-sitter-grammars-windows-0.XX.YYY.tar.gz' asset in the latest release." | |
exit 1 | |
} | |
$downloadUrl = $downloadAsset.browser_download_url | |
$fileName = $downloadAsset.name | |
Write-Host "Found download URL: $downloadUrl" -ForegroundColor Green | |
Write-Host "File to download: $fileName" -ForegroundColor Green | |
# Define the path to store the downloaded file in TEMP directory | |
$tempDir = [System.IO.Path]::GetTempPath() | |
$downloadPath = Join-Path -Path $tempDir -ChildPath $fileName | |
Write-Host "Download path: $downloadPath" -ForegroundColor Cyan | |
# Check for existence of the file to be downloaded here. If the file | |
# already exists in the $tempDir, remove it, before downloading the file | |
# again. | |
if (Test-Path -Path $downloadPath) { | |
Write-Host "Existing file '$fileName' found in TEMP directory. Removing it..." -ForegroundColor Yellow | |
Remove-Item -Path $downloadPath -Force -ErrorAction SilentlyContinue | |
Write-Host "Existing file removed." -ForegroundColor Green | |
} | |
# Download the file | |
Write-Host "Downloading $fileName to $downloadPath..." -ForegroundColor Yellow | |
Invoke-WebRequest -Uri $downloadUrl -OutFile $downloadPath -ErrorAction Stop | |
Write-Host "Download complete." -ForegroundColor Green | |
# Extract version from the filename for the new directory name | |
# Example: tree-sitter-grammars-windows-0.20.0.tar.gz -> 0.20.0 | |
$versionMatch = $fileName -match "tree-sitter-grammars-windows-(\d+\.\d+\.\d+)\.tar\.gz" | |
if (-not $versionMatch) { | |
Write-Error "Could not parse version from filename: $fileName. Exiting." | |
exit 1 | |
} | |
$version = $Matches[1] | |
$newDirName = "tree-sitter-v$version" | |
Write-Host "Detected version: $version. New directory name will be: $newDirName" -ForegroundColor Cyan | |
# Store the current location to return to it later in the finally block | |
$originalLocation = Get-Location | |
# Change into the ~/.emacs.d directory | |
$emacsDPath = Join-Path -Path $env:USERPROFILE -ChildPath ".emacs.d" | |
if (-not (Test-Path -Path $emacsDPath -PathType Container)) { | |
Write-Host "Creating ~/.emacs.d directory: $emacsDPath" -ForegroundColor Cyan | |
New-Item -Path $emacsDPath -ItemType Directory -Force | Out-Null | |
} | |
Set-Location -Path $emacsDPath | |
Write-Host "Changed current directory to: $(Get-Location)" -ForegroundColor Green | |
# Define the full path for the new directory | |
$currentLocation = Get-Location | |
$newDirPath = Join-Path -Path $currentLocation.Path -ChildPath $newDirName | |
# Check for existence of the $newDirPath here. If it already exists, | |
# remove it. Then re-create it. | |
if (Test-Path -Path $newDirPath) { | |
Write-Host "Existing directory '$newDirName' found at '$newDirPath'. Removing it..." -ForegroundColor Yellow | |
Remove-Item -Path $newDirPath -Recurse -Force -ErrorAction SilentlyContinue | |
Write-Host "Existing directory removed." -ForegroundColor Green | |
} | |
Write-Host "Creating new directory: $newDirPath" -ForegroundColor Cyan | |
# Create the new directory and change into it | |
New-Item -Path $newDirPath -ItemType Directory -Force | Out-Null # -Force overwrites if exists | |
Set-Location -Path $newDirPath | |
Write-Host "Changed current directory to: $(Get-Location)" -ForegroundColor Green | |
# Extract the files using tar | |
Write-Host "Extracting files from $downloadPath to $(Get-Location)..." -ForegroundColor Yellow | |
& "$env:WINDIR\System32\tar.exe" -xvf $downloadPath | |
Write-Host "Extraction complete." -ForegroundColor Green | |
# Iterate over extracted files and rename DLLs | |
Write-Host "Renaming DLL files (FOO.dll to libtree-sitter-FOO.dll)..." -ForegroundColor Yellow | |
Get-ChildItem -Path . -Filter "*.dll" | Where-Object { -not $_.Name.StartsWith("libtree-sitter-") } | ForEach-Object { | |
$oldName = $_.Name | |
$newName = "libtree-sitter-$oldName" | |
Rename-Item -Path $_.FullName -NewName $newName -Force | |
Write-Host "Renamed '$oldName' to '$newName'" -ForegroundColor DarkGreen | |
} | |
Write-Host "DLL renaming complete." -ForegroundColor Green | |
# Change directory up one level (back to ~/.emacs.d) | |
Set-Location -Path .. | |
Write-Host "Changed current directory to: $(Get-Location)" -ForegroundColor Green | |
# Define the junction name and its target (fully qualified path) | |
$junctionName = "tree-sitter" | |
$junctionTarget = $newDirPath # This is already a fully qualified path | |
Write-Host "Creating new junction: $junctionName -> $junctionTarget" -ForegroundColor Yellow | |
# Delete existing junction if it exists | |
if (Test-Path -Path $junctionName) { | |
Write-Host "Deleting existing junction: $junctionName" -ForegroundColor Yellow | |
Remove-Item -Path $junctionName -Recurse -Force | |
Write-Host "Existing junction deleted." -ForegroundColor Green | |
} else { | |
Write-Host "No existing junction '$junctionName' found. Skipping deletion." -ForegroundColor Gray | |
} | |
Write-Host "\nIn Windows, users with the 'Create symbolic links' privilege (also known as SeCreateSymbolicLinkPrivilege) are permitted to create Junctions.\nIf you lack this privilege, the following may fail." -ForegroundColor Yellow | |
Start-Sleep -Seconds 3 | |
# Create new junction | |
try { | |
New-Item -Path $junctionName -ItemType Junction -Value $junctionTarget -Force | Out-Null | |
Write-Host "Junction '$junctionName' created successfully, pointing to '$junctionTarget'." -ForegroundColor Green | |
Write-Host "Script execution completed successfully!" -ForegroundColor Green | |
} | |
catch { | |
Write-Error "Failed to create junction '$junctionName'." | |
Write-Error "Error message: $($_.Exception.Message)" | |
Write-Error " " | |
Write-Error "To avoid this message in the future, you can grant the 'Create symbolic links' privilege (SeCreateSymbolicLinkPrivilege) to your user account using gpedit.msc. Granting this right requires Administrator privilege." | |
Write-Error " " | |
Write-Error "Alternatively, you can manually create the junction by running the following command with elevated (Administrator) permissions:" | |
Write-Error " New-Item -Path '$junctionName' -ItemType Junction -Value '$junctionTarget' -Force" | |
exit 1 # Exit with an error code | |
} | |
} | |
catch { | |
Write-Error "An error occurred during script execution:" | |
Write-Error $_.Exception.Message | |
Write-Error "Please ensure you have internet access and 'tar' is in your system's PATH." | |
exit 1 | |
} | |
finally { | |
# Clean up: Remove the downloaded file from the TEMP directory | |
if (Test-Path -Path $downloadPath) { | |
Write-Host "Cleaning up: Removing downloaded file '$fileName' from TEMP directory..." -ForegroundColor DarkGray | |
Remove-Item -Path $downloadPath -Force -ErrorAction SilentlyContinue | |
Write-Host "Downloaded file removed." -ForegroundColor DarkGray | |
} | |
# Return to the original directory where the script was executed | |
if (Test-Path -Path $originalLocation) { | |
Set-Location -Path $originalLocation -ErrorAction SilentlyContinue | |
Write-Host "Returned to original directory: $(Get-Location)" -ForegroundColor DarkGray | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment