vscode: Refactor manifest and align registry scripts with official installer#16868
vscode: Refactor manifest and align registry scripts with official installer#16868SorYoshino wants to merge 1 commit intoScoopInstaller:masterfrom
Conversation
WalkthroughAdds portable-mode orchestration to the VS Code manifest and rewrites registry scripts to unify context/association keys under a VSCode namespace; expands manifest public surface (env_add_path, pre_install, post_install, shortcuts, persist) and changes checkver.jsonpath to use $.productVersion. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Installer
participant Manifest as "bucket/vscode.json"
participant PreInstall as "pre_install script"
participant PostInstall as "post_install script"
participant Registry
participant FS as "Filesystem (extensions/user data)"
Installer->>Manifest: read manifest (env_add_path, pre_install, post_install, persist, shortcuts)
Manifest->>PreInstall: invoke pre_install sequence
PreInstall->>FS: detect & migrate extensions/user data -> portable data dir
PreInstall->>PostInstall: emit path mappings / transformed scripts
Installer->>PostInstall: run post_install
PostInstall->>Registry: generate & apply rewritten registry scripts (context, associations, uninstall entries)
PostInstall->>FS: patch extensions.json and normalize paths to portable dir
Registry-->>Installer: registry keys created/updated
FS-->>Installer: extensions/user data relocated
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
All changes look good. Wait for review from human collaborators. vscode
|
There was a problem hiding this comment.
Actionable comments posted: 4
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
bucket/vscode.jsonscripts/vscode/install-associations.regscripts/vscode/install-context.regscripts/vscode/register-installed-program.regscripts/vscode/uninstall-associations.regscripts/vscode/uninstall-context.regscripts/vscode/unregister-installed-program.reg
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-10-13T09:37:06.093Z
Learnt from: o-l-a-v
Repo: ScoopInstaller/Extras PR: 16328
File: bucket/winutil.json:0-0
Timestamp: 2025-10-13T09:37:06.093Z
Learning: When reviewing code in Scoop manifests, always verify the actual file content if the diff appears incomplete or unusual, as diff context can be truncated or displayed incorrectly. The pattern `[string[]](...).ForEach{...}` is commonly used in post_uninstall scripts across the Extras repository.
Applied to files:
scripts/vscode/uninstall-associations.reg
📚 Learning: 2025-10-16T13:42:43.224Z
Learnt from: o-l-a-v
Repo: ScoopInstaller/Extras PR: 16349
File: bucket/debugviewpp.json:14-21
Timestamp: 2025-10-16T13:42:43.224Z
Learning: In the DebugViewPP project (CobaltFusion/DebugViewPP), the executable name changed from "DebugView++.exe" (in v1.8.0.103 and earlier) to "Debugviewpp.exe" (in v1.9.0.28 and later). The manifest bucket/debugviewpp.json correctly uses "Debugviewpp.exe" for current versions.
Applied to files:
bucket/vscode.json
📚 Learning: 2025-10-14T11:24:17.524Z
Learnt from: SorYoshino
Repo: ScoopInstaller/Extras PR: 16333
File: bucket/potplayer.json:55-64
Timestamp: 2025-10-14T11:24:17.524Z
Learning: In PotPlayer manifests (bucket/potplayer.json), the Capture and Playlist folders are created at runtime (after running the application), not included in the installer, so they should only be in the persist list and not in post_install scripts.
Applied to files:
bucket/vscode.json
📚 Learning: 2025-10-14T11:15:55.229Z
Learnt from: SorYoshino
Repo: ScoopInstaller/Extras PR: 16333
File: bucket/potplayer.json:55-64
Timestamp: 2025-10-14T11:15:55.229Z
Learning: In PotPlayer manifests (bucket/potplayer.json), the Model and Engine folders are created at runtime (not included in the installer), so they should only be in the persist list and not in post_install scripts that handle .original directories.
Applied to files:
bucket/vscode.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: WindowsPowerShell
🔇 Additional comments (8)
scripts/vscode/unregister-installed-program.reg (1)
1-3: LGTM!The registry deletion file correctly uses the
[-KEY]syntax to remove the installed program entry, and the GUID matches the registration file.scripts/vscode/register-installed-program.reg (1)
1-10: LGTM!The registry template correctly creates an installed-program entry that enables integration with other applications. The
{{vscode_dir}}placeholder will be replaced during post_install. OmittingUninstallStringis appropriate since Scoop manages uninstallation.scripts/vscode/uninstall-context.reg (1)
3-9: LGTM!The uninstall registry correctly removes all four context menu entries (
*,Directory\Background,Directory,Drive) that are created byinstall-context.reg.scripts/vscode/uninstall-associations.reg (1)
973-979: Good coverage of additional file types.The file now includes uninstall entries for the additional file types mentioned in the PR objectives (
.json5,.jsonc,.zshrc, etc.), and properly cleans up theVSCodeSourceFileclass at the end.scripts/vscode/install-context.reg (1)
3-32: LGTM!The context menu registrations are well-structured:
- Correct use of
%1for files and%Vfor directories/drives- Consistent
{{vscode_dir}}placeholder for Code.exe paths- Keyboard accelerator (
&i) properly placed in "Open w&ith Code"bucket/vscode.json (3)
70-77: LGTM - Standard Scoop manifest fields.The
env_add_path,shortcuts, andpersistfields are correctly configured for portable mode operation.
87-89: LGTM - Version detection improvement.Changing from
$.nameto$.productVersionfor checkver is a reliable improvement, asproductVersiondirectly provides the semantic version string.
27-42: No changes needed for thereturnstatement on line 30.The
returnstatement in the pre_install script behaves as intended. In Scoop's script execution model, manifest scripts are invoked as separate script blocks wherereturnexits the script execution without affecting parent scope—this is the correct and standard behavior for PowerShell in this context.
|
/verify |
|
All changes look good. Wait for review from human collaborators. vscode
|
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
bucket/vscode.json (2)
44-44: Backslash escaping is still incorrect for .reg file format.The pattern
-replace '\\\\', '\\\\'matches two literal backslashes and replaces with two - effectively a no-op for standard Windows paths likeC:\Users\.... The intent is to escape each single backslash for.regfile format (e.g.,C:\Users\...→C:\\Users\\...).🔎 Recommended fix using .Replace() method
- "$vscode_path = $dir -replace '\\\\', '\\\\'", + "$vscode_path = $dir.Replace('\\', '\\\\')",Using the string
.Replace()method avoids regex escaping complexity and correctly replaces each single backslash with a double backslash for the.regfile format.
60-61: Unconditional cleanup risks data loss if migration fails.Lines 60-61 unconditionally delete the original data locations (
$env:USERPROFILE\.vscode\argv.json,$env:USERPROFILE\.vscode\extensions,$env:AppData\Code) immediately after the copy operations on lines 52-58. If a copy fails silently (e.g., due to permissions, disk space, or I/O errors), user extensions and settings will be permanently lost.🔎 Recommended approaches
Option 1: Verify before cleanup
+ "# Verify migration succeeded before cleanup", + "$migration_ok = (Test-Path \"$dir\\data\\user-data\\User\\settings.json\") -or (Test-Path \"$dir\\data\\extensions\\extensions.json\")", + "if (-not $migration_ok) {", + " warn 'Migration verification failed - original data preserved in AppData and .vscode'", + " return", + "}", "$remove_list = 'argv.json', 'extensions' | ForEach-Object { \"$env:USERPROFILE\\.vscode\\$_\" }", "$remove_list + @(\"$env:AppData\\Code\") | Remove-Item -Force -Recurse -ErrorAction SilentlyContinue"Option 2: Skip automatic cleanup (safer)
- "$remove_list = 'argv.json', 'extensions' | ForEach-Object { \"$env:USERPROFILE\\.vscode\\$_\" }", - "$remove_list + @(\"$env:AppData\\Code\") | Remove-Item -Force -Recurse -ErrorAction SilentlyContinue" + "info 'Migration complete. Original data preserved in:'", + "info ' - $env:USERPROFILE\\.vscode (argv.json, extensions)'", + "info ' - $env:AppData\\Code (user-data)'", + "info 'You may remove these manually after verifying the portable installation.'"
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
bucket/vscode.jsonscripts/vscode/install-associations.regscripts/vscode/install-context.regscripts/vscode/register-installed-program.regscripts/vscode/uninstall-associations.regscripts/vscode/uninstall-context.regscripts/vscode/unregister-installed-program.reg
✅ Files skipped from review due to trivial changes (1)
- scripts/vscode/unregister-installed-program.reg
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-10-13T09:37:06.093Z
Learnt from: o-l-a-v
Repo: ScoopInstaller/Extras PR: 16328
File: bucket/winutil.json:0-0
Timestamp: 2025-10-13T09:37:06.093Z
Learning: When reviewing code in Scoop manifests, always verify the actual file content if the diff appears incomplete or unusual, as diff context can be truncated or displayed incorrectly. The pattern `[string[]](...).ForEach{...}` is commonly used in post_uninstall scripts across the Extras repository.
Applied to files:
scripts/vscode/uninstall-context.regbucket/vscode.jsonscripts/vscode/uninstall-associations.reg
📚 Learning: 2025-10-14T11:24:17.524Z
Learnt from: SorYoshino
Repo: ScoopInstaller/Extras PR: 16333
File: bucket/potplayer.json:55-64
Timestamp: 2025-10-14T11:24:17.524Z
Learning: In PotPlayer manifests (bucket/potplayer.json), the Capture and Playlist folders are created at runtime (after running the application), not included in the installer, so they should only be in the persist list and not in post_install scripts.
Applied to files:
bucket/vscode.json
📚 Learning: 2025-10-14T11:15:55.229Z
Learnt from: SorYoshino
Repo: ScoopInstaller/Extras PR: 16333
File: bucket/potplayer.json:55-64
Timestamp: 2025-10-14T11:15:55.229Z
Learning: In PotPlayer manifests (bucket/potplayer.json), the Model and Engine folders are created at runtime (not included in the installer), so they should only be in the persist list and not in post_install scripts that handle .original directories.
Applied to files:
bucket/vscode.json
🔇 Additional comments (8)
scripts/vscode/install-context.reg (1)
1-32: LGTM! Registry syntax and structure are correct.The consolidation under the
VSCodenamespace with{{vscode_dir}}templates is well-structured. The context menu entries for files, directories, backgrounds, and drives follow Windows registry conventions correctly.scripts/vscode/uninstall-context.reg (1)
1-9: LGTM! Uninstall entries correctly match installation.The deletion entries properly remove all four VSCode context menu keys using correct registry syntax. This ensures complete cleanup of context menu integration.
scripts/vscode/uninstall-associations.reg (1)
1-969: LGTM! Comprehensive file association cleanup.The uninstall registry entries correctly remove VSCode file associations using proper
.regsyntax. The pattern is consistent throughout: remove OpenWithProgIDs entries, then delete associated VSCode.* class keys. The final removal ofVSCodeSourceFilecompletes the cleanup.bucket/vscode.json (4)
3-16: LGTM! Improved description and clearer registry integration notes.The enhanced description better captures VS Code's capabilities, and the updated notes clearly explain the purpose of each registry file. The rename from
install-github-integration.regtoregister-installed-program.regaccurately reflects its actual function.
78-86: LGTM! Uninstaller now properly removes all registry entries.The uninstaller correctly imports all three registry cleanup files:
uninstall-context.reg- removes context menu entriesuninstall-associations.reg- removes file associationsunregister-installed-program.reg- removes installed program entryThis addresses the previous issue where
uninstall-context.regwas duplicated and file associations were not removed.
70-77: The manifest fields at lines 70-77 are correctly configured. VS Code includes a bin directory, and Scoop's env_add_path functionality adds the specified directory to the system path, where the directory is relative to the install location. The shortcut and persist settings are also appropriate for portable mode. No issues found.
87-90: Verify that the VS Code update API actually returns aproductVersionfield.The checkver jsonpath changed from
$.nameto$.productVersion. Since I cannot directly test the endpoint in this environment, you should confirm that the update API returns theproductVersionfield and that it contains the version string in the expected format.scripts/vscode/register-installed-program.reg (1)
3-3: GUID is correct.The GUID
{771FD6B0-FA20-440A-A002-3B3BAC16DC50}_is1matches the official VS Code 64-bit user installation and is properly registered underHKEY_CURRENT_USERfor user-scope detection by other installers and applications.
|
/verify |
|
All changes look good. Wait for review from human collaborators. vscode
|
|
/verify |
|
All changes look good. Wait for review from human collaborators. vscode
|
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In @bucket/vscode.json:
- Around line 53-64: The migration currently copies with Copy-Item and then
unconditionally deletes originals via $remove_list | Remove-Item, risking data
loss; change the flow so each Copy-Item uses -ErrorAction Stop, verify success
(e.g., compare existence and item counts or sizes of "$dir\\data\\$_" vs source
after copy), optionally create a timestamped backup of the source (e.g., copy to
a ".bak" folder) before deletion, prompt the user to confirm deletion (or
support a --force flag), and only call Remove-Item for that specific source if
verification passes; update the blocks that handle "$env:AppData\\Code" and the
"'argv.json','extensions'" loop accordingly.
- Around line 9-16: The manifest's notes list references six registry files
(install-associations.reg, install-context.reg, register-installed-program.reg
and their uninstall counterparts) but those files are missing, causing
post_install and the uninstaller to fail; add the six .reg files into the
expected location (bucket/scripts/vscode/) with the registry entries referenced
by the post_install script and the uninstaller, ensure filenames exactly match
the names in the notes array and the scripts (install-associations.reg,
install-context.reg, register-installed-program.reg, uninstall-associations.reg,
uninstall-context.reg, unregister-installed-program.reg), and verify the
post_install script and uninstaller can read/import them without silent no-ops.
- Around line 27-42: The current regex used to rewrite extension paths in the
pre_install block (applied to $_.location.path) only replaces the middle segment
and preserves the leading drive letter, producing malformed paths like duplicate
drive letters; update the replacement to target the entire prefix before the
.vscode/extensions portion so the whole original root is replaced with $data_dir
(e.g., replace the existing '(?<=/).+(?=/extensions)' usage on $_.location.path
with a pattern or explicit full-path replacement that matches the full leading
path and substitutes it with $data_dir).
🧹 Nitpick comments (1)
bucket/vscode.json (1)
3-3: Consider shortening the description.The description is quite lengthy. Scoop manifest descriptions are typically more concise. Consider simplifying to the essential information.
✍️ Suggested concise description
- "description": "Visual Studio Code is a lightweight yet powerful, cross-platform source code editor providing rich support for development, debugging, and extension-based customization for modern web and cloud workloads.", + "description": "Lightweight but powerful source code editor with rich extension ecosystem and debugging support.",
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
bucket/vscode.json
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-10-13T09:37:06.093Z
Learnt from: o-l-a-v
Repo: ScoopInstaller/Extras PR: 16328
File: bucket/winutil.json:0-0
Timestamp: 2025-10-13T09:37:06.093Z
Learning: When reviewing code in Scoop manifests, always verify the actual file content if the diff appears incomplete or unusual, as diff context can be truncated or displayed incorrectly. The pattern `[string[]](...).ForEach{...}` is commonly used in post_uninstall scripts across the Extras repository.
Applied to files:
bucket/vscode.json
📚 Learning: 2025-10-14T11:24:17.524Z
Learnt from: SorYoshino
Repo: ScoopInstaller/Extras PR: 16333
File: bucket/potplayer.json:55-64
Timestamp: 2025-10-14T11:24:17.524Z
Learning: In PotPlayer manifests (bucket/potplayer.json), the Capture and Playlist folders are created at runtime (after running the application), not included in the installer, so they should only be in the persist list and not in post_install scripts.
Applied to files:
bucket/vscode.json
📚 Learning: 2025-10-14T11:15:55.229Z
Learnt from: SorYoshino
Repo: ScoopInstaller/Extras PR: 16333
File: bucket/potplayer.json:55-64
Timestamp: 2025-10-14T11:15:55.229Z
Learning: In PotPlayer manifests (bucket/potplayer.json), the Model and Engine folders are created at runtime (not included in the installer), so they should only be in the persist list and not in post_install scripts that handle .original directories.
Applied to files:
bucket/vscode.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: WindowsPowerShell
🔇 Additional comments (8)
bucket/vscode.json (8)
37-39: Good defensive coding for uuid migration.Adding the
uuidproperty when it's missing butmetadata.idexists ensures compatibility with VS Code's extension management. This handles legacy extension installations gracefully.
44-52: Registry template processing logic is well-designed.The post_install script correctly:
- Escapes backslashes for Windows registry paths
- Dynamically processes registry template files
- Handles both user-level and global installations by replacing registry hives and GUIDs
- Uses Unicode encoding for registry files (required by Windows)
This approach provides good flexibility for supporting different installation contexts.
74-79: Shortcut creation looks correct.The shortcut properly references
Code.exeand uses a clear, user-friendly name.
80-80: Persist configuration is correct for portable mode.Persisting the
datadirectory ensures user settings, extensions, and workspace data survive updates and reinstalls, which is essential for a portable VS Code installation.
83-87: Uninstaller logic is well-structured.The uninstaller:
- Correctly gates registry cleanup behind
$cmd -eq 'uninstall'to prevent running during updates- Imports corresponding uninstall registry files to clean up file associations, context menu, and installed program entries
- Appropriately suppresses output with
*> $nullThis ensures clean removal of registry entries when the application is uninstalled.
90-92: The productVersion field exists in the API response and is appropriate for version detection. The API endpoint reliably returns"productVersion": "1.108.0", confirming the jsonpath change from$.nameto$.productVersionis valid and semantically correct.
65-71: [rewritten review comment]
[exactly ONE classification tag]
73-73: No action needed—the bin directory exists in VS Code's archive.The VS Code win32-x64 archive includes a
bin/directory at the top level containing launcher wrappers (code.cmd,code,code-tunnel.exe). Addingbinto PATH is correct and allows these scripts to be accessible from the command line. The mainCode.exeexecutable is at the archive root, not inbin/, so this configuration is appropriate.Likely an incorrect or invalid review comment.
|
/verify |
|
All changes look good. Wait for review from human collaborators. vscode
|
Summary
Refactors the
vscodemanifest to improve portability, data migration, and maintainability.Separately, the registry (
.reg) scripts have been updated to better align with entries and behavior observed in the official Visual Studio Code installer.Related issues or pull requests
Changes
.reg) scripts based on entries generated by the official VS Code installer, ensuring:notesto better reflect available registry integration optionspost_installlogic to dynamically apply registry templates and support both user-level and global installsuninstallerbehavior to properly unregister registry entriescheckverto rely onproductVersionfor more reliable version detectionNotes
pre_installscript to ensure extension paths are adjusted correctly. The rationale behind this logic is as follows:_sep,fsPath, andexternalfields within thelocationobject inextensions.json.locationobject no longer contains the above fields, and auuidfield is added to itsidentifierobject, with the value equal tometadata.id.extensions.json; the previously modified metadata for extension A remains unchanged.pre_installscript intentionally emulates this behavior. It assumes that the application can derive the other two path representations fromlocation.pathalone (as evidenced by the current structure ofextensions.json). Updating all three path variants would introduce unnecessary complexity, so the script limits itself to normalizinglocation.pathonly, which is sufficient and consistent with observed behavior.install-associations.regare derived from the official installer. In addition to the existing associations, this update adds support for.json5,.jsonc,.zshrc, and other related file types.install-context.regare also based on the official installer. The only difference is that the official installer registers the relevant values asREG_EXPAND_SZ, whereas this PR usesREG_SZ. Both registry value types function correctly in this context.install-github-integration.regis potentially misleading. It has therefore been renamed toregister-installed-program.reg, and the corresponding entries in thenotesfield have been updated accordingly.Testing
The test results are as follows:
<manifest-name[@version]|chore>: <general summary of the pull request>Summary by CodeRabbit
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.