mirror of
https://github.com/hanzoai/code.git
synced 2026-09-30 20:53:35 +00:00
Merge upstream Void editor changes while preserving Hanzo Code branding
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
#!/bin/bash
|
||||
set -e # Exit on error
|
||||
set -x # Print commands as they are executed
|
||||
|
||||
# Configuration
|
||||
APP_NAME="void"
|
||||
APP_VERSION="1.0.0"
|
||||
ARCH="x86_64"
|
||||
|
||||
export ARCH
|
||||
|
||||
# Check if void binary exists in current directory
|
||||
if [ ! -f "./void" ]; then
|
||||
echo "Error: void binary not found in current directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if icon exists
|
||||
if [ ! -f "./void.png" ]; then
|
||||
echo "Error: void.png icon not found in current directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create temporary directory
|
||||
TEMP_DIR="$(mktemp -d)"
|
||||
echo "Created temporary directory: $TEMP_DIR"
|
||||
APP_DIR="$TEMP_DIR/$APP_NAME.AppDir"
|
||||
|
||||
# Create basic AppDir structure
|
||||
mkdir -pv "$APP_DIR/usr/bin"
|
||||
mkdir -pv "$APP_DIR/usr/lib"
|
||||
mkdir -pv "$APP_DIR/usr/share/applications"
|
||||
mkdir -pv "$APP_DIR/usr/share/icons/hicolor/256x256/apps"
|
||||
|
||||
# Exclude create-appimage.sh and appimagetool-x86_64.AppImage from being copied
|
||||
echo "Copying files excluding create-appimage.sh and appimagetool-x86_64.AppImage..."
|
||||
|
||||
cp -v ./void "$APP_DIR/usr/bin/"
|
||||
|
||||
# Copy the icon to required locations
|
||||
cp -v ./void.png "$APP_DIR/void.png"
|
||||
cp -v ./void.png "$APP_DIR/usr/share/icons/hicolor/256x256/apps/void.png"
|
||||
|
||||
# Copy dependencies with error checking
|
||||
echo "Copying dependencies..."
|
||||
for lib in $(ldd ./void | grep "=> /" | awk '{print $3}'); do
|
||||
if [ -f "$lib" ]; then
|
||||
cp -v "$lib" "$APP_DIR/usr/lib/" || echo "Failed to copy $lib"
|
||||
else
|
||||
echo "Warning: Library $lib not found"
|
||||
fi
|
||||
done
|
||||
|
||||
# Create desktop file with error checking
|
||||
echo "Creating desktop file..."
|
||||
if ! cat > "$APP_DIR/$APP_NAME.desktop" <<EOF
|
||||
[Desktop Entry]
|
||||
Name=$APP_NAME
|
||||
Exec=void
|
||||
Icon=void
|
||||
Type=Application
|
||||
Categories=Utility;
|
||||
Comment=Code Linux Application
|
||||
EOF
|
||||
then
|
||||
echo "Error creating desktop file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Make desktop file executable
|
||||
chmod +x "$APP_DIR/$APP_NAME.desktop"
|
||||
|
||||
# Copy the desktop file to the applications directory
|
||||
cp -v "$APP_DIR/$APP_NAME.desktop" "$APP_DIR/usr/share/applications/"
|
||||
|
||||
# Create AppRun with error checking
|
||||
echo "Creating AppRun..."
|
||||
if ! cat > "$APP_DIR/AppRun" <<EOF
|
||||
#!/bin/bash
|
||||
cd "\$(dirname "\$0")/usr/bin"
|
||||
export LD_LIBRARY_PATH="\$APPDIR/usr/lib:\$LD_LIBRARY_PATH"
|
||||
exec ./void "\$@"
|
||||
EOF
|
||||
then
|
||||
echo "Error creating AppRun"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Make AppRun executable
|
||||
chmod +x "$APP_DIR/AppRun"
|
||||
|
||||
# Download appimagetool if not present in the current directory
|
||||
if [ ! -f "./appimagetool-x86_64.AppImage" ]; then
|
||||
echo "Downloading appimagetool-x86_64.AppImage..."
|
||||
wget "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage"
|
||||
chmod +x appimagetool-x86_64.AppImage
|
||||
else
|
||||
echo "appimagetool-x86_64.AppImage is already present."
|
||||
fi
|
||||
|
||||
# Create the AppImage
|
||||
echo "Creating AppImage..."
|
||||
ARCH=x86_64 ./appimagetool-x86_64.AppImage "$APP_DIR" "${APP_NAME}-${APP_VERSION}-${ARCH}.AppImage"
|
||||
|
||||
# Cleanup
|
||||
echo "Cleaning up..."
|
||||
rm -rf "$TEMP_DIR"
|
||||
|
||||
echo "AppImage creation complete!"
|
||||
Executable
+168
@@ -0,0 +1,168 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit on error
|
||||
set -e
|
||||
|
||||
# Check platform
|
||||
platform=$(uname)
|
||||
|
||||
if [[ "$platform" == "Darwin" ]]; then
|
||||
echo "Running on macOS. Note that the AppImage created will only work on Linux systems."
|
||||
if ! command -v docker &> /dev/null; then
|
||||
echo "Docker Desktop for Mac is not installed. Please install it from https://www.docker.com/products/docker-desktop"
|
||||
exit 1
|
||||
fi
|
||||
elif [[ "$platform" == "Linux" ]]; then
|
||||
echo "Running on Linux. Proceeding with AppImage creation..."
|
||||
else
|
||||
echo "This script is intended to run on macOS or Linux. Current platform: $platform"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Enable BuildKit
|
||||
export DOCKER_BUILDKIT=1
|
||||
|
||||
BUILD_IMAGE_NAME="void-appimage-builder"
|
||||
|
||||
# Check if Docker is running
|
||||
if ! docker info >/dev/null 2>&1; then
|
||||
echo "Docker is not running. Please start Docker first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check and install Buildx if needed
|
||||
if ! docker buildx version >/dev/null 2>&1; then
|
||||
echo "Installing Docker Buildx..."
|
||||
mkdir -p ~/.docker/cli-plugins/
|
||||
curl -SL https://github.com/docker/buildx/releases/download/v0.13.1/buildx-v0.13.1.linux-amd64 -o ~/.docker/cli-plugins/docker-buildx
|
||||
chmod +x ~/.docker/cli-plugins/docker-buildx
|
||||
fi
|
||||
|
||||
# Download appimagetool if not present
|
||||
if [ ! -f "appimagetool" ]; then
|
||||
echo "Downloading appimagetool..."
|
||||
wget -O appimagetool "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage"
|
||||
chmod +x appimagetool
|
||||
fi
|
||||
|
||||
# Delete any existing AppImage to avoid bloating the build
|
||||
rm -f Void-x86_64.AppImage
|
||||
|
||||
# Create build Dockerfile
|
||||
echo "Creating build Dockerfile..."
|
||||
cat > Dockerfile.build << 'EOF'
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM ubuntu:20.04
|
||||
|
||||
# Install required dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libfuse2 \
|
||||
libglib2.0-0 \
|
||||
libgtk-3-0 \
|
||||
libx11-xcb1 \
|
||||
libxss1 \
|
||||
libxtst6 \
|
||||
libnss3 \
|
||||
libasound2 \
|
||||
libdrm2 \
|
||||
libgbm1 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
EOF
|
||||
|
||||
# Create .dockerignore file
|
||||
echo "Creating .dockerignore file..."
|
||||
cat > .dockerignore << EOF
|
||||
Dockerfile.build
|
||||
.dockerignore
|
||||
.git
|
||||
.gitignore
|
||||
.DS_Store
|
||||
*~
|
||||
*.swp
|
||||
*.swo
|
||||
*.tmp
|
||||
*.bak
|
||||
*.log
|
||||
*.err
|
||||
node_modules/
|
||||
venv/
|
||||
*.egg-info/
|
||||
*.tox/
|
||||
dist/
|
||||
EOF
|
||||
|
||||
# Build Docker image without cache
|
||||
echo "Building Docker image (no cache)..."
|
||||
docker build --no-cache -t "$BUILD_IMAGE_NAME" -f Dockerfile.build .
|
||||
|
||||
# Create AppImage using local appimagetool
|
||||
echo "Creating AppImage..."
|
||||
docker run --rm --privileged -v "$(pwd):/app" "$BUILD_IMAGE_NAME" bash -c '
|
||||
cd /app && \
|
||||
rm -rf VoidApp.AppDir && \
|
||||
mkdir -p VoidApp.AppDir/usr/bin VoidApp.AppDir/usr/lib VoidApp.AppDir/usr/share/applications && \
|
||||
find . -maxdepth 1 ! -name VoidApp.AppDir ! -name "." ! -name ".." -exec cp -r {} VoidApp.AppDir/usr/bin/ \; && \
|
||||
cp void.png VoidApp.AppDir/ && \
|
||||
echo "[Desktop Entry]" > VoidApp.AppDir/void.desktop && \
|
||||
echo "Name=Void" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Comment=Open source AI code editor." >> VoidApp.AppDir/void.desktop && \
|
||||
echo "GenericName=Text Editor" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Exec=void %F" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Icon=void" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Type=Application" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "StartupNotify=false" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "StartupWMClass=Void" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Categories=TextEditor;Development;IDE;" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "MimeType=application/x-void-workspace;" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Keywords=void;" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Actions=new-empty-window;" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "[Desktop Action new-empty-window]" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Name=New Empty Window" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Name[de]=Neues leeres Fenster" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Name[es]=Nueva ventana vacía" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Name[fr]=Nouvelle fenêtre vide" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Name[it]=Nuova finestra vuota" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Name[ja]=新しい空のウィンドウ" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Name[ko]=새 빈 창" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Name[ru]=Новое пустое окно" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Name[zh_CN]=新建空窗口" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Name[zh_TW]=開新空視窗" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Exec=void --new-window %F" >> VoidApp.AppDir/void.desktop && \
|
||||
echo "Icon=void" >> VoidApp.AppDir/void.desktop && \
|
||||
chmod +x VoidApp.AppDir/void.desktop && \
|
||||
cp VoidApp.AppDir/void.desktop VoidApp.AppDir/usr/share/applications/ && \
|
||||
echo "[Desktop Entry]" > VoidApp.AppDir/void-url-handler.desktop && \
|
||||
echo "Name=Void - URL Handler" > VoidApp.AppDir/void-url-handler.desktop && \
|
||||
echo "Comment=Open source AI code editor." > VoidApp.AppDir/void-url-handler.desktop && \
|
||||
echo "GenericName=Text Editor" > VoidApp.AppDir/void-url-handler.desktop && \
|
||||
echo "Exec=void --open-url %U" > VoidApp.AppDir/void-url-handler.desktop && \
|
||||
echo "Icon=void" > VoidApp.AppDir/void-url-handler.desktop && \
|
||||
echo "Type=Application" > VoidApp.AppDir/void-url-handler.desktop && \
|
||||
echo "NoDisplay=true" > VoidApp.AppDir/void-url-handler.desktop && \
|
||||
echo "StartupNotify=true" > VoidApp.AppDir/void-url-handler.desktop && \
|
||||
echo "Categories=Utility;TextEditor;Development;IDE;" > VoidApp.AppDir/void-url-handler.desktop && \
|
||||
echo "MimeType=x-scheme-handler/void;" > VoidApp.AppDir/void-url-handler.desktop && \
|
||||
echo "Keywords=void;" > VoidApp.AppDir/void-url-handler.desktop && \
|
||||
chmod +x VoidApp.AppDir/void-url-handler.desktop && \
|
||||
cp VoidApp.AppDir/void-url-handler.desktop VoidApp.AppDir/usr/share/applications/ && \
|
||||
echo "#!/bin/bash" > VoidApp.AppDir/AppRun && \
|
||||
echo "HERE=\$(dirname \"\$(readlink -f \"\${0}\")\")" >> VoidApp.AppDir/AppRun && \
|
||||
echo "export PATH=\${HERE}/usr/bin:\${PATH}" >> VoidApp.AppDir/AppRun && \
|
||||
echo "export LD_LIBRARY_PATH=\${HERE}/usr/lib:\${LD_LIBRARY_PATH}" >> VoidApp.AppDir/AppRun && \
|
||||
echo "exec \${HERE}/usr/bin/void --no-sandbox \"\$@\"" >> VoidApp.AppDir/AppRun && \
|
||||
chmod +x VoidApp.AppDir/AppRun && \
|
||||
chmod -R 755 VoidApp.AppDir && \
|
||||
|
||||
# Strip unneeded symbols from the binary to reduce size
|
||||
strip --strip-unneeded VoidApp.AppDir/usr/bin/void
|
||||
|
||||
ls -la VoidApp.AppDir/ && \
|
||||
ARCH=x86_64 ./appimagetool -n VoidApp.AppDir Void-x86_64.AppImage
|
||||
'
|
||||
|
||||
# Clean up
|
||||
rm -rf VoidApp.AppDir .dockerignore appimagetool
|
||||
|
||||
echo "AppImage creation complete! Your AppImage is: Void-x86_64.AppImage"
|
||||
@@ -0,0 +1,127 @@
|
||||
|
||||
|
||||
# README
|
||||
|
||||
This is a community-made AppImage creation script.
|
||||
|
||||
There are some reported bugs with it.
|
||||
|
||||
To generate an AppImage yourself, feel free to look at
|
||||
stable-linux.yml in the separate `void-builder/` repo,
|
||||
which runs a GitHub Action that builds the AppImage you see on our website.
|
||||
|
||||
|
||||
# Void AppImage Creation Script
|
||||
|
||||
This script automates the process of creating an AppImage for the Void Editor using Docker. It works on macOS and Linux platforms.
|
||||
## Requirements
|
||||
|
||||
* **Docker:** The script relies on Docker to build the AppImage inside a container.
|
||||
* **macOS or Linux:** The script is designed for these platforms. On macOS, it generates a Linux-compatible AppImage.
|
||||
* **Internet Connection:** Required for downloading necessary tools (like `docker-buildx` and `appimagetool` inside the Docker container).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Install Docker:**
|
||||
|
||||
* **macOS:** Download and install Docker Desktop from [docker.com](docker.com).
|
||||
* **Ubuntu:**
|
||||
```bash
|
||||
sudo apt install docker.io
|
||||
```
|
||||
* **Arch Linux:**
|
||||
```bash
|
||||
sudo pacman -S docker
|
||||
```
|
||||
* **Fedora:**
|
||||
```bash
|
||||
sudo dnf install docker
|
||||
```
|
||||
|
||||
2. **Set Docker User Group:**
|
||||
|
||||
Docker requires users to be part of the `docker` group to run Docker commands without `sudo`.
|
||||
|
||||
```bash
|
||||
sudo usermod -aG docker $USER
|
||||
```
|
||||
|
||||
After running this command, log out and log back in for the group changes to take effect.
|
||||
|
||||
3. **Enable and Start Docker:**
|
||||
|
||||
```bash
|
||||
sudo systemctl enable docker
|
||||
sudo systemctl start docker
|
||||
```
|
||||
|
||||
## Ubuntu Dependencies (Installed via Docker)
|
||||
|
||||
These dependencies are installed within the Docker container (Ubuntu 20.04 base). You generally don't need to install them manually:
|
||||
|
||||
* `libfuse2`
|
||||
* `libglib2.0-0`
|
||||
* `libgtk-3-0`
|
||||
* `libx11-xcb1`
|
||||
* `libxss1`
|
||||
* `libxtst6`
|
||||
* `libnss3`
|
||||
* `libasound2`
|
||||
* `libdrm2`
|
||||
* `libgbm1`
|
||||
|
||||
## Usage Instructions
|
||||
|
||||
1. **Clone or Download the Script:**
|
||||
|
||||
Save the script to your system as `create_appimage.sh`.
|
||||
|
||||
2. **Make the Script Executable:**
|
||||
|
||||
```bash
|
||||
chmod +x create_appimage.sh
|
||||
```
|
||||
|
||||
3. **Copy Required Files:**
|
||||
|
||||
Copy the following files to the directory where the app binary is being bundled (created during the build process):
|
||||
|
||||
* `create_appimage.sh`
|
||||
* `void.desktop`
|
||||
* `void.png`
|
||||
|
||||
4. **Run the Script:**
|
||||
|
||||
```bash
|
||||
./create_appimage.sh
|
||||
```
|
||||
|
||||
5. **Result:**
|
||||
|
||||
After the script completes, it will generate an AppImage named `Void-x86_64.AppImage` (or similar, depending on your architecture) in the current directory.
|
||||
|
||||
## Script Overview
|
||||
|
||||
* **Platform Check:** Checks for macOS or Linux. Exits if unsupported.
|
||||
* **Docker Checks:** Ensures Docker is installed and running.
|
||||
* **Buildx Installation:** Installs `docker buildx` if missing.
|
||||
* **`appimagetool` Download:** Downloads `appimagetool` inside the Docker container.
|
||||
* **Dockerfile Creation:** Creates a temporary `Dockerfile.build` for the Ubuntu-based environment.
|
||||
* **Docker Image Build:** Builds a Docker image and runs the build process.
|
||||
* **AppImage Creation:**
|
||||
* Creates the `VoidApp.AppDir` structure.
|
||||
* Copies binaries, resources, and the `.desktop` entry.
|
||||
* Copies `void.desktop` and `void.png`.
|
||||
* Strips unnecessary symbols from the binary.
|
||||
* Runs `appimagetool` to generate the AppImage.
|
||||
* **Cleanup:** Removes the temporary `Dockerfile.build`.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
* **Docker Not Running:** Ensure Docker is installed and running.
|
||||
* **Permission Issues:** Try running the script with `sudo` or check Docker permissions.
|
||||
* **Outdated Dependencies:** Ensure you have the minimum required versions.
|
||||
|
||||
## License
|
||||
|
||||
This script is provided "as is". It is free to use, modify, and distribute, but comes with no warranty.
|
||||
@@ -0,0 +1,12 @@
|
||||
[Desktop Entry]
|
||||
Name=Void - URL Handler
|
||||
Comment=Open source AI code editor.
|
||||
GenericName=Text Editor
|
||||
Exec=void --open-url %U
|
||||
Icon=void
|
||||
Type=Application
|
||||
NoDisplay=true
|
||||
StartupNotify=true
|
||||
Categories=Utility;TextEditor;Development;IDE;
|
||||
MimeType=x-scheme-handler/void;
|
||||
Keywords=void;
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
[Desktop Entry]
|
||||
Name=Void
|
||||
Comment=Open source AI code editor.
|
||||
GenericName=Text Editor
|
||||
Exec=void %F
|
||||
Icon=void
|
||||
Type=Application
|
||||
StartupNotify=false
|
||||
StartupWMClass=Void
|
||||
Categories=TextEditor;Development;IDE;
|
||||
MimeType=application/x-void-workspace;
|
||||
Keywords=void;
|
||||
Actions=new-empty-window;
|
||||
|
||||
[Desktop Action new-empty-window]
|
||||
Name=New Empty Window
|
||||
Name[de]=Neues leeres Fenster
|
||||
Name[es]=Nueva ventana vacía
|
||||
Name[fr]=Nouvelle fenêtre vide
|
||||
Name[it]=Nuova finestra vuota
|
||||
Name[ja]=新しい空のウィンドウ
|
||||
Name[ko]=새 빈 창
|
||||
Name[ru]=Новое пустое окно
|
||||
Name[zh_CN]=新建空窗口
|
||||
Name[zh_TW]=開新空視窗
|
||||
Exec=void --new-window %F
|
||||
Icon=void
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 795 KiB |
Regular → Executable
@@ -7,7 +7,7 @@
|
||||
|
||||
const cp = require('child_process');
|
||||
const path = require('path');
|
||||
const opn = require('opn');
|
||||
const open = require('open');
|
||||
const minimist = require('minimist');
|
||||
|
||||
async function main() {
|
||||
@@ -33,7 +33,7 @@ async function main() {
|
||||
const serverArgs = process.argv.slice(2).filter(v => v !== '--launch');
|
||||
const addr = await startServer(serverArgs);
|
||||
if (args['launch']) {
|
||||
opn(addr);
|
||||
open(addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Regular → Executable
+2
-6
@@ -14,7 +14,7 @@ const cp = require('child_process');
|
||||
const minimist = require('minimist');
|
||||
const fancyLog = require('fancy-log');
|
||||
const ansiColors = require('ansi-colors');
|
||||
const opn = require('opn');
|
||||
const open = require('open');
|
||||
const https = require('https');
|
||||
|
||||
const APP_ROOT = path.join(__dirname, '..');
|
||||
@@ -74,17 +74,13 @@ async function main() {
|
||||
openSystemBrowser = true;
|
||||
}
|
||||
|
||||
if (!fs.existsSync(path.join(APP_ROOT, 'src2')) && !fs.existsSync(path.join(APP_ROOT, 'out-build', 'amd'))) {
|
||||
serverArgs.push('--esm');
|
||||
}
|
||||
|
||||
serverArgs.push('--sourcesPath', APP_ROOT);
|
||||
|
||||
serverArgs.push(...process.argv.slice(2).filter(v => !v.startsWith('--playground') && v !== '--no-playground'));
|
||||
|
||||
startServer(serverArgs);
|
||||
if (openSystemBrowser) {
|
||||
opn(`http://${HOST}:${PORT}/`);
|
||||
open(`http://${HOST}:${PORT}/`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Regular → Executable
Vendored
-35
@@ -1,35 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
type RunFunction =
|
||||
| ((debugSession: IDebugSession, context: Context) => IDisposable)
|
||||
| ((debugSession: IDebugSession, context: Context) => Promise<IDisposable>);
|
||||
|
||||
interface IDebugSession {
|
||||
name: string;
|
||||
eval(expression: string): Promise<unknown>;
|
||||
evalJs<T extends any[], TResult>(
|
||||
bodyFn: (...args: T) => TResult,
|
||||
...args: T
|
||||
): Promise<TResult>;
|
||||
}
|
||||
|
||||
interface Context {
|
||||
vscode: typeof import('vscode');
|
||||
}
|
||||
|
||||
interface IDisposable {
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
interface HotReloadConfig {
|
||||
mode?: 'patch-prototype' | undefined;
|
||||
}
|
||||
|
||||
interface GlobalThisAddition {
|
||||
$hotReload_applyNewExports?(args: { oldExports: Record<string, unknown>; newSrc: string; config?: HotReloadConfig }): AcceptNewExportsFn | undefined;
|
||||
}
|
||||
|
||||
type AcceptNewExportsFn = (newExports: Record<string, unknown>) => boolean;
|
||||
Regular → Executable
@@ -1,483 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
// @ts-check
|
||||
/// <reference path='../src/vscode-dts/vscode.d.ts' />
|
||||
/// <reference path='debugger-scripts-api.d.ts' />
|
||||
|
||||
const path = require('path');
|
||||
const fsPromise = require('fs/promises');
|
||||
const parcelWatcher = require('@parcel/watcher');
|
||||
|
||||
// This file is loaded by the vscode-diagnostic-tools extension and injected into the debugger.
|
||||
|
||||
|
||||
/**
|
||||
* Represents a lazy evaluation container.
|
||||
* @template T
|
||||
* @template TArg
|
||||
*/
|
||||
class Lazy {
|
||||
/**
|
||||
* Creates a new instance of the Lazy class.
|
||||
* @param {(arg: TArg) => T} _fn - The function to be lazily evaluated.
|
||||
*/
|
||||
constructor(_fn) {
|
||||
this._fn = _fn;
|
||||
this._value = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lazily evaluated value.
|
||||
* @param {TArg} arg - The argument passed in to the evaluation function.
|
||||
* @return {T}
|
||||
*/
|
||||
getValue(arg) {
|
||||
if (!this._value) {
|
||||
this._value = this._fn(arg);
|
||||
}
|
||||
return this._value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Context['vscode']} vscode
|
||||
*/
|
||||
function setupGlobals(vscode) {
|
||||
/** @type {DisposableStore} */
|
||||
const store = globalThis['hot-reload-injected-script-disposables'] ?? (globalThis['hot-reload-injected-script-disposables'] = new DisposableStore());
|
||||
store.clear();
|
||||
|
||||
function getConfig() {
|
||||
const config = vscode.workspace.getConfiguration('vscode-diagnostic-tools').get('debuggerScriptsConfig', {
|
||||
'hotReload.sources': {}
|
||||
});
|
||||
if (!config['hotReload.sources']) {
|
||||
config['hotReload.sources'] = {};
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {Map<string, Set<() => void>>}
|
||||
*/
|
||||
const enabledRelativePaths = new Map();
|
||||
const api = {
|
||||
/**
|
||||
* @param {string} relativePath
|
||||
* @param {() => void} forceReloadFn
|
||||
*/
|
||||
reloadFailed: (relativePath, forceReloadFn) => {
|
||||
const set = enabledRelativePaths.get(relativePath) ?? new Set();
|
||||
set.add(forceReloadFn);
|
||||
enabledRelativePaths.set(relativePath, set);
|
||||
|
||||
update();
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} relativePath
|
||||
* @returns {HotReloadConfig}
|
||||
*/
|
||||
getConfig: (relativePath) => {
|
||||
const config = getConfig();
|
||||
return { mode: config['hotReload.sources'][relativePath] === 'patch-prototype' ? 'patch-prototype' : undefined };
|
||||
}
|
||||
};
|
||||
|
||||
const item = store.add(vscode.window.createStatusBarItem(undefined, 10000));
|
||||
|
||||
function update() {
|
||||
item.hide();
|
||||
const e = vscode.window.activeTextEditor;
|
||||
if (!e) { return; }
|
||||
|
||||
const part = e.document.fileName.replace(/\\/g, '/').replace(/\.ts/, '.js').split('/src/')[1];
|
||||
if (!part) { return; }
|
||||
|
||||
const isEnabled = api.getConfig(part)?.mode === 'patch-prototype';
|
||||
|
||||
if (!enabledRelativePaths.has(part) && !isEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isEnabled) {
|
||||
item.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground');
|
||||
item.text = '$(sync-ignored) hot reload disabled';
|
||||
} else {
|
||||
item.backgroundColor = undefined;
|
||||
item.text = '$(sync) hot reload enabled';
|
||||
}
|
||||
|
||||
item.command = {
|
||||
command: 'vscode-diagnostic-tools.hotReload.toggle',
|
||||
title: 'Toggle hot reload',
|
||||
arguments: [part],
|
||||
tooltip: 'Toggle hot reload'
|
||||
};
|
||||
item.tooltip = 'Toggle hot reload';
|
||||
item.show();
|
||||
}
|
||||
|
||||
store.add(vscode.window.onDidChangeActiveTextEditor(e => {
|
||||
update();
|
||||
}));
|
||||
|
||||
store.add(vscode.workspace.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration('vscode-diagnostic-tools.debuggerScriptsConfig')) {
|
||||
update();
|
||||
}
|
||||
}));
|
||||
|
||||
update();
|
||||
|
||||
store.add(vscode.commands.registerCommand('vscode-diagnostic-tools.hotReload.toggle', async (relativePath) => {
|
||||
let config = getConfig();
|
||||
const current = config['hotReload.sources'][relativePath];
|
||||
const newValue = current === 'patch-prototype' ? undefined : 'patch-prototype';
|
||||
config = { ...config, 'hotReload.sources': { ...config['hotReload.sources'], [relativePath]: newValue } };
|
||||
|
||||
await vscode.workspace.getConfiguration('vscode-diagnostic-tools').update('debuggerScriptsConfig', config, vscode.ConfigurationTarget.Global);
|
||||
|
||||
if (newValue === 'patch-prototype') {
|
||||
const reloadFns = enabledRelativePaths.get(relativePath);
|
||||
console.log(reloadFns);
|
||||
if (reloadFns) {
|
||||
for (const fn of reloadFns) {
|
||||
fn();
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
return api;
|
||||
}
|
||||
|
||||
const g = new Lazy(setupGlobals);
|
||||
|
||||
/** @type {RunFunction} */
|
||||
module.exports.run = async function (debugSession, ctx) {
|
||||
const store = new DisposableStore();
|
||||
|
||||
const global = ctx.vscode ? g.getValue(ctx.vscode) : undefined;
|
||||
|
||||
const watcher = store.add(await DirWatcher.watchRecursively(path.join(__dirname, '../out/')));
|
||||
|
||||
/**
|
||||
* So that the same file always gets the same reload fn.
|
||||
* @type {Map<string, () => void>}
|
||||
*/
|
||||
const reloadFns = new Map();
|
||||
|
||||
store.add(watcher.onDidChange(async changes => {
|
||||
const supportedChanges = changes
|
||||
.filter(c => c.path.endsWith('.js') || c.path.endsWith('.css'))
|
||||
.map(c => {
|
||||
const relativePath = c.path.replace(/\\/g, '/').split('/out/')[1];
|
||||
return { ...c, relativePath, config: global?.getConfig(relativePath) };
|
||||
});
|
||||
|
||||
const result = await debugSession.evalJs(function (changes, debugSessionName) {
|
||||
// This function is stringified and injected into the debuggee.
|
||||
|
||||
/** @type {{ count: number; originalWindowTitle: any; timeout: any; shouldReload: boolean }} */
|
||||
const hotReloadData = globalThis.$hotReloadData || (globalThis.$hotReloadData = { count: 0, messageHideTimeout: undefined, shouldReload: false });
|
||||
|
||||
/** @type {{ relativePath: string, path: string }[]} */
|
||||
const reloadFailedJsFiles = [];
|
||||
|
||||
for (const change of changes) {
|
||||
handleChange(change.relativePath, change.path, change.newContent, change.config);
|
||||
}
|
||||
|
||||
return { reloadFailedJsFiles };
|
||||
|
||||
/**
|
||||
* @param {string} relativePath
|
||||
* @param {string} path
|
||||
* @param {string} newSrc
|
||||
* @param {HotReloadConfig | undefined} config
|
||||
*/
|
||||
function handleChange(relativePath, path, newSrc, config) {
|
||||
if (relativePath.endsWith('.css')) {
|
||||
handleCssChange(relativePath);
|
||||
} else if (relativePath.endsWith('.js')) {
|
||||
handleJsChange(relativePath, path, newSrc, config);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} relativePath
|
||||
*/
|
||||
function handleCssChange(relativePath) {
|
||||
if (typeof document === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
const styleSheet = (/** @type {HTMLLinkElement[]} */ ([...document.querySelectorAll(`link[rel='stylesheet']`)]))
|
||||
.find(l => new URL(l.href, document.location.href).pathname.endsWith(relativePath));
|
||||
if (styleSheet) {
|
||||
setMessage(`reload ${formatPath(relativePath)} - ${new Date().toLocaleTimeString()}`);
|
||||
console.log(debugSessionName, 'css reloaded', relativePath);
|
||||
styleSheet.href = styleSheet.href.replace(/\?.*/, '') + '?' + Date.now();
|
||||
} else {
|
||||
setMessage(`could not reload ${formatPath(relativePath)} - ${new Date().toLocaleTimeString()}`);
|
||||
console.log(debugSessionName, 'ignoring css change, as stylesheet is not loaded', relativePath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} relativePath
|
||||
* @param {string} newSrc
|
||||
* @param {HotReloadConfig | undefined} config
|
||||
*/
|
||||
function handleJsChange(relativePath, path, newSrc, config) {
|
||||
const moduleIdStr = trimEnd(relativePath, '.js');
|
||||
|
||||
/** @type {any} */
|
||||
const requireFn = globalThis.require;
|
||||
const moduleManager = requireFn.moduleManager;
|
||||
if (!moduleManager) {
|
||||
console.log(debugSessionName, 'ignoring js change, as moduleManager is not available', relativePath);
|
||||
return;
|
||||
}
|
||||
|
||||
const moduleId = moduleManager._moduleIdProvider.getModuleId(moduleIdStr);
|
||||
const oldModule = moduleManager._modules2[moduleId];
|
||||
|
||||
if (!oldModule) {
|
||||
console.log(debugSessionName, 'ignoring js change, as module is not loaded', relativePath);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we can reload
|
||||
const g = /** @type {GlobalThisAddition} */ (globalThis);
|
||||
|
||||
// A frozen copy of the previous exports
|
||||
const oldExports = Object.freeze({ ...oldModule.exports });
|
||||
const reloadFn = g.$hotReload_applyNewExports?.({ oldExports, newSrc, config });
|
||||
|
||||
if (!reloadFn) {
|
||||
console.log(debugSessionName, 'ignoring js change, as module does not support hot-reload', relativePath);
|
||||
hotReloadData.shouldReload = true;
|
||||
|
||||
reloadFailedJsFiles.push({ relativePath, path });
|
||||
|
||||
setMessage(`hot reload not supported for ${formatPath(relativePath)} - ${new Date().toLocaleTimeString()}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Eval maintains source maps
|
||||
function newScript(/* this parameter is used by newSrc */ define) {
|
||||
// eslint-disable-next-line no-eval
|
||||
eval(newSrc); // CodeQL [SM01632] This code is only executed during development. It is required for the hot-reload functionality.
|
||||
}
|
||||
|
||||
newScript(/* define */ function (deps, callback) {
|
||||
// Evaluating the new code was successful.
|
||||
|
||||
// Redefine the module
|
||||
delete moduleManager._modules2[moduleId];
|
||||
moduleManager.defineModule(moduleIdStr, deps, callback);
|
||||
const newModule = moduleManager._modules2[moduleId];
|
||||
|
||||
|
||||
// Patch the exports of the old module, so that modules using the old module get the new exports
|
||||
Object.assign(oldModule.exports, newModule.exports);
|
||||
// We override the exports so that future reloads still patch the initial exports.
|
||||
newModule.exports = oldModule.exports;
|
||||
|
||||
const successful = reloadFn(newModule.exports);
|
||||
if (!successful) {
|
||||
hotReloadData.shouldReload = true;
|
||||
setMessage(`hot reload failed ${formatPath(relativePath)} - ${new Date().toLocaleTimeString()}`);
|
||||
console.log(debugSessionName, 'hot reload was not successful', relativePath);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(debugSessionName, 'hot reloaded', moduleIdStr);
|
||||
setMessage(`successfully reloaded ${formatPath(relativePath)} - ${new Date().toLocaleTimeString()}`);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} message
|
||||
*/
|
||||
function setMessage(message) {
|
||||
const domElem = /** @type {HTMLDivElement | undefined} */ (document.querySelector('.titlebar-center .window-title'));
|
||||
if (!domElem) { return; }
|
||||
if (!hotReloadData.timeout) {
|
||||
hotReloadData.originalWindowTitle = domElem.innerText;
|
||||
} else {
|
||||
clearTimeout(hotReloadData.timeout);
|
||||
}
|
||||
if (hotReloadData.shouldReload) {
|
||||
message += ' (manual reload required)';
|
||||
}
|
||||
|
||||
domElem.innerText = message;
|
||||
hotReloadData.timeout = setTimeout(() => {
|
||||
hotReloadData.timeout = undefined;
|
||||
// If wanted, we can restore the previous title message
|
||||
// domElem.replaceChildren(hotReloadData.originalWindowTitle);
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @returns {string}
|
||||
*/
|
||||
function formatPath(path) {
|
||||
const parts = path.split('/');
|
||||
parts.reverse();
|
||||
let result = parts[0];
|
||||
parts.shift();
|
||||
for (const p of parts) {
|
||||
if (result.length + p.length > 40) {
|
||||
break;
|
||||
}
|
||||
result = p + '/' + result;
|
||||
if (result.length > 20) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function trimEnd(str, suffix) {
|
||||
if (str.endsWith(suffix)) {
|
||||
return str.substring(0, str.length - suffix.length);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
}, supportedChanges, debugSession.name.substring(0, 25));
|
||||
|
||||
for (const failedFile of result.reloadFailedJsFiles) {
|
||||
const reloadFn = reloadFns.get(failedFile.relativePath) ?? (() => {
|
||||
console.log('force change');
|
||||
watcher.forceChange(failedFile.path);
|
||||
});
|
||||
reloadFns.set(failedFile.relativePath, reloadFn);
|
||||
global?.reloadFailed(failedFile.relativePath, reloadFn);
|
||||
}
|
||||
}));
|
||||
|
||||
return store;
|
||||
};
|
||||
|
||||
class DirWatcher {
|
||||
/**
|
||||
*
|
||||
* @param {string} dir
|
||||
* @returns {Promise<DirWatcher>}
|
||||
*/
|
||||
static async watchRecursively(dir) {
|
||||
/** @type {((changes: { path: string, newContent: string }[]) => void)[]} */
|
||||
const listeners = [];
|
||||
/** @type {Map<string, string> } */
|
||||
const fileContents = new Map();
|
||||
/** @type {Map<string, { path: string, newContent: string }>} */
|
||||
const changes = new Map();
|
||||
/** @type {(handler: (changes: { path: string, newContent: string }[]) => void) => IDisposable} */
|
||||
const event = (handler) => {
|
||||
listeners.push(handler);
|
||||
return {
|
||||
dispose: () => {
|
||||
const idx = listeners.indexOf(handler);
|
||||
if (idx >= 0) {
|
||||
listeners.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
const r = parcelWatcher.subscribe(dir, async (err, events) => {
|
||||
for (const e of events) {
|
||||
if (e.type === 'update') {
|
||||
const newContent = await fsPromise.readFile(e.path, 'utf8');
|
||||
if (fileContents.get(e.path) !== newContent) {
|
||||
fileContents.set(e.path, newContent);
|
||||
changes.set(e.path, { path: e.path, newContent });
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changes.size > 0) {
|
||||
debounce(() => {
|
||||
const uniqueChanges = Array.from(changes.values());
|
||||
changes.clear();
|
||||
listeners.forEach(l => l(uniqueChanges));
|
||||
})();
|
||||
}
|
||||
});
|
||||
const result = await r;
|
||||
return new DirWatcher(event, () => result.unsubscribe(), path => {
|
||||
const content = fileContents.get(path);
|
||||
if (content !== undefined) {
|
||||
listeners.forEach(l => l([{ path: path, newContent: content }]));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {(handler: (changes: { path: string, newContent: string }[]) => void) => IDisposable} onDidChange
|
||||
* @param {() => void} unsub
|
||||
* @param {(path: string) => void} forceChange
|
||||
*/
|
||||
constructor(onDidChange, unsub, forceChange) {
|
||||
this.onDidChange = onDidChange;
|
||||
this.unsub = unsub;
|
||||
this.forceChange = forceChange;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.unsub();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Debounce function calls
|
||||
* @param {() => void} fn
|
||||
* @param {number} delay
|
||||
*/
|
||||
function debounce(fn, delay = 50) {
|
||||
let timeoutId;
|
||||
return function (...args) {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = setTimeout(() => {
|
||||
fn.apply(this, args);
|
||||
}, delay);
|
||||
};
|
||||
}
|
||||
|
||||
class DisposableStore {
|
||||
constructor() {
|
||||
this._toDispose = new Set();
|
||||
this._isDisposed = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds an item to the collection.
|
||||
*
|
||||
* @template T
|
||||
* @param {T} t - The item to add.
|
||||
* @returns {T} The added item.
|
||||
*/
|
||||
add(t) {
|
||||
this._toDispose.add(t);
|
||||
return t;
|
||||
}
|
||||
dispose() {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
this._isDisposed = true;
|
||||
this.clear();
|
||||
}
|
||||
clear() {
|
||||
this._toDispose.forEach(item => item.dispose());
|
||||
this._toDispose.clear();
|
||||
}
|
||||
}
|
||||
Regular → Executable
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
set ELECTRON_RUN_AS_NODE=
|
||||
|
||||
pushd %~dp0\..
|
||||
|
||||
:: Get Code.exe location
|
||||
for /f "tokens=2 delims=:," %%a in ('findstr /R /C:"\"nameShort\":.*" product.json') do set NAMESHORT=%%~a
|
||||
set NAMESHORT=%NAMESHORT: "=%
|
||||
set NAMESHORT=%NAMESHORT:"=%.exe
|
||||
set CODE=".build\electron\%NAMESHORT%"
|
||||
|
||||
:: Download Electron if needed
|
||||
call node build\lib\electron.js
|
||||
if %errorlevel% neq 0 node .\node_modules\gulp\bin\gulp.js electron
|
||||
|
||||
:: Run tests
|
||||
set ELECTRON_ENABLE_LOGGING=1
|
||||
%CODE% .\test\unit\electron\index.amd.js --crash-reporter-directory=%~dp0\..\.build\crashes %*
|
||||
|
||||
popd
|
||||
|
||||
endlocal
|
||||
|
||||
:: app.exit(0) is exiting with code 255 in Electron 1.7.4.
|
||||
:: See https://github.com/microsoft/vscode/issues/28582
|
||||
echo errorlevel: %errorlevel%
|
||||
if %errorlevel% == 255 set errorlevel=0
|
||||
|
||||
exit /b %errorlevel%
|
||||
@@ -1,43 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; }
|
||||
ROOT=$(dirname $(dirname $(realpath "$0")))
|
||||
else
|
||||
ROOT=$(dirname $(dirname $(readlink -f $0)))
|
||||
# --disable-dev-shm-usage: when run on docker containers where size of /dev/shm
|
||||
# partition < 64MB which causes OOM failure for chromium compositor that uses the partition for shared memory
|
||||
LINUX_EXTRA_ARGS="--disable-dev-shm-usage"
|
||||
fi
|
||||
|
||||
cd $ROOT
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
NAME=`node -p "require('./product.json').nameLong"`
|
||||
CODE="./.build/electron/$NAME.app/Contents/MacOS/Electron"
|
||||
else
|
||||
NAME=`node -p "require('./product.json').applicationName"`
|
||||
CODE=".build/electron/$NAME"
|
||||
fi
|
||||
|
||||
VSCODECRASHDIR=$ROOT/.build/crashes
|
||||
|
||||
# Node modules
|
||||
test -d node_modules || npm i
|
||||
|
||||
# Get electron
|
||||
npm run electron
|
||||
|
||||
# Unit Tests
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
cd $ROOT ; ulimit -n 4096 ; \
|
||||
ELECTRON_ENABLE_LOGGING=1 \
|
||||
"$CODE" \
|
||||
test/unit/electron/index.amd.js --crash-reporter-directory=$VSCODECRASHDIR "$@"
|
||||
else
|
||||
cd $ROOT ; \
|
||||
ELECTRON_ENABLE_LOGGING=1 \
|
||||
"$CODE" \
|
||||
test/unit/electron/index.amd.js --crash-reporter-directory=$VSCODECRASHDIR $LINUX_EXTRA_ARGS "$@"
|
||||
fi
|
||||
@@ -5,7 +5,7 @@ echo Runs tests against the current documentation in https://github.com/microsof
|
||||
|
||||
pushd %~dp0\..
|
||||
|
||||
:: Endgame tests in AMD
|
||||
:: Endgame tests
|
||||
call .\scripts\test.bat --runGlob **\*.releaseTest.js %*
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
|
||||
Regular → Executable
+1
-1
@@ -14,7 +14,7 @@ cd $ROOT
|
||||
|
||||
echo "Runs tests against the current documentation in https://github.com/microsoft/vscode-docs/tree/vnext"
|
||||
|
||||
# Tests in AMD
|
||||
# Tests
|
||||
./scripts/test.sh --runGlob **/*.releaseTest.js "$@"
|
||||
|
||||
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
pushd %~dp0\..
|
||||
|
||||
set VSCODEUSERDATADIR=%TEMP%\vscodeuserfolder-%RANDOM%-%TIME:~6,2%
|
||||
set VSCODECRASHDIR=%~dp0\..\.build\crashes
|
||||
set VSCODELOGSDIR=%~dp0\..\.build\logs\integration-tests
|
||||
|
||||
:: Figure out which Electron to use for running tests
|
||||
if "%INTEGRATION_TEST_ELECTRON_PATH%"=="" (
|
||||
chcp 65001
|
||||
set INTEGRATION_TEST_ELECTRON_PATH=.\scripts\code.bat
|
||||
set VSCODE_BUILD_BUILTIN_EXTENSIONS_SILENCE_PLEASE=1
|
||||
|
||||
echo Running integration tests out of sources.
|
||||
) else (
|
||||
set VSCODE_CLI=1
|
||||
set ELECTRON_ENABLE_LOGGING=1
|
||||
|
||||
echo Running integration tests with '%INTEGRATION_TEST_ELECTRON_PATH%' as build.
|
||||
)
|
||||
|
||||
echo Storing crash reports into '%VSCODECRASHDIR%'.
|
||||
echo Storing log files into '%VSCODELOGSDIR%'.
|
||||
|
||||
|
||||
:: Tests standalone (AMD)
|
||||
|
||||
echo.
|
||||
echo ### node.js integration tests
|
||||
call .\scripts\test-amd.bat --runGlob **\*.integrationTest.js %*
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
|
||||
:: Tests in the extension host
|
||||
|
||||
set API_TESTS_EXTRA_ARGS=--disable-telemetry --skip-welcome --skip-release-notes --crash-reporter-directory=%VSCODECRASHDIR% --logsPath=%VSCODELOGSDIR% --no-cached-data --disable-updates --use-inmemory-secretstorage --disable-extensions --disable-workspace-trust --user-data-dir=%VSCODEUSERDATADIR%
|
||||
|
||||
echo.
|
||||
echo ### API tests (folder)
|
||||
call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\vscode-api-tests\testWorkspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\singlefolder-tests %API_TESTS_EXTRA_ARGS%
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### API tests (workspace)
|
||||
call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\vscode-api-tests\testworkspace.code-workspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\workspace-tests %API_TESTS_EXTRA_ARGS%
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### Colorize tests
|
||||
call npm run test-extension -l vscode-colorize-tests
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### TypeScript tests
|
||||
call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\typescript-language-features\test-workspace --extensionDevelopmentPath=%~dp0\..\extensions\typescript-language-features --extensionTestsPath=%~dp0\..\extensions\typescript-language-features\out\test\unit %API_TESTS_EXTRA_ARGS%
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### Markdown tests
|
||||
call npm run test-extension -l markdown-language-features
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### Emmet tests
|
||||
call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\emmet\test-workspace --extensionDevelopmentPath=%~dp0\..\extensions\emmet --extensionTestsPath=%~dp0\..\extensions\emmet\out\test %API_TESTS_EXTRA_ARGS%
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### Git tests
|
||||
for /f "delims=" %%i in ('node -p "require('fs').realpathSync.native(require('os').tmpdir())"') do set TEMPDIR=%%i
|
||||
set GITWORKSPACE=%TEMPDIR%\git-%RANDOM%
|
||||
mkdir %GITWORKSPACE%
|
||||
call "%INTEGRATION_TEST_ELECTRON_PATH%" %GITWORKSPACE% --extensionDevelopmentPath=%~dp0\..\extensions\git --extensionTestsPath=%~dp0\..\extensions\git\out\test %API_TESTS_EXTRA_ARGS%
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### Ipynb tests
|
||||
call npm run test-extension -l ipynb
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### Notebook Output tests
|
||||
call npm run test-extension -l notebook-renderers
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### Configuration editing tests
|
||||
set CFWORKSPACE=%TEMPDIR%\cf-%RANDOM%
|
||||
mkdir %CFWORKSPACE%
|
||||
call npm run test-extension -l configuration-editing
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### GitHub Authentication tests
|
||||
call npm run test-extension -l github-authentication
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
:: Tests standalone (CommonJS)
|
||||
|
||||
echo.
|
||||
echo ### CSS tests
|
||||
call %~dp0\node-electron.bat %~dp0\..\extensions\css-language-features/server/test/index.js
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### HTML tests
|
||||
call %~dp0\node-electron.bat %~dp0\..\extensions\html-language-features/server/test/index.js
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
|
||||
:: Cleanup
|
||||
|
||||
rmdir /s /q %VSCODEUSERDATADIR%
|
||||
|
||||
popd
|
||||
|
||||
endlocal
|
||||
@@ -1,136 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; }
|
||||
ROOT=$(dirname $(dirname $(realpath "$0")))
|
||||
else
|
||||
ROOT=$(dirname $(dirname $(readlink -f $0)))
|
||||
# --disable-dev-shm-usage: when run on docker containers where size of /dev/shm
|
||||
# partition < 64MB which causes OOM failure for chromium compositor that uses the partition for shared memory
|
||||
LINUX_EXTRA_ARGS="--disable-dev-shm-usage"
|
||||
fi
|
||||
|
||||
VSCODEUSERDATADIR=`mktemp -d 2>/dev/null`
|
||||
VSCODECRASHDIR=$ROOT/.build/crashes
|
||||
VSCODELOGSDIR=$ROOT/.build/logs/integration-tests
|
||||
|
||||
cd $ROOT
|
||||
|
||||
# Figure out which Electron to use for running tests
|
||||
if [ -z "$INTEGRATION_TEST_ELECTRON_PATH" ]
|
||||
then
|
||||
INTEGRATION_TEST_ELECTRON_PATH="./scripts/code.sh"
|
||||
|
||||
echo "Running integration tests out of sources."
|
||||
else
|
||||
export VSCODE_CLI=1
|
||||
export ELECTRON_ENABLE_LOGGING=1
|
||||
|
||||
echo "Running integration tests with '$INTEGRATION_TEST_ELECTRON_PATH' as build."
|
||||
fi
|
||||
|
||||
echo "Storing crash reports into '$VSCODECRASHDIR'."
|
||||
echo "Storing log files into '$VSCODELOGSDIR'."
|
||||
|
||||
|
||||
# Tests standalone (AMD)
|
||||
|
||||
echo
|
||||
echo "### node.js integration tests"
|
||||
echo
|
||||
./scripts/test-amd.sh --runGlob **/*.integrationTest.js "$@"
|
||||
|
||||
|
||||
# Tests in the extension host
|
||||
|
||||
API_TESTS_EXTRA_ARGS="--disable-telemetry --skip-welcome --skip-release-notes --crash-reporter-directory=$VSCODECRASHDIR --logsPath=$VSCODELOGSDIR --no-cached-data --disable-updates --use-inmemory-secretstorage --disable-extensions --disable-workspace-trust --user-data-dir=$VSCODEUSERDATADIR"
|
||||
|
||||
if [ -z "$INTEGRATION_TEST_APP_NAME" ]; then
|
||||
kill_app() { true; }
|
||||
else
|
||||
kill_app() { killall $INTEGRATION_TEST_APP_NAME || true; }
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "### API tests (folder)"
|
||||
echo
|
||||
"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $ROOT/extensions/vscode-api-tests/testWorkspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/singlefolder-tests $API_TESTS_EXTRA_ARGS
|
||||
kill_app
|
||||
|
||||
echo
|
||||
echo "### API tests (workspace)"
|
||||
echo
|
||||
"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $ROOT/extensions/vscode-api-tests/testworkspace.code-workspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/workspace-tests $API_TESTS_EXTRA_ARGS
|
||||
kill_app
|
||||
|
||||
echo
|
||||
echo "### Colorize tests"
|
||||
echo
|
||||
npm run test-extension -l vscode-colorize-tests
|
||||
kill_app
|
||||
|
||||
echo
|
||||
echo "### TypeScript tests"
|
||||
echo
|
||||
"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $ROOT/extensions/typescript-language-features/test-workspace --extensionDevelopmentPath=$ROOT/extensions/typescript-language-features --extensionTestsPath=$ROOT/extensions/typescript-language-features/out/test/unit $API_TESTS_EXTRA_ARGS
|
||||
kill_app
|
||||
|
||||
echo
|
||||
echo "### Markdown tests"
|
||||
echo
|
||||
npm run test-extension -l markdown-language-features
|
||||
kill_app
|
||||
|
||||
echo
|
||||
echo "### Emmet tests"
|
||||
echo
|
||||
"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $ROOT/extensions/emmet/test-workspace --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test $API_TESTS_EXTRA_ARGS
|
||||
kill_app
|
||||
|
||||
echo
|
||||
echo "### Git tests"
|
||||
echo
|
||||
"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $(mktemp -d 2>/dev/null) --extensionDevelopmentPath=$ROOT/extensions/git --extensionTestsPath=$ROOT/extensions/git/out/test $API_TESTS_EXTRA_ARGS
|
||||
kill_app
|
||||
|
||||
echo
|
||||
echo "### Ipynb tests"
|
||||
echo
|
||||
npm run test-extension -l ipynb
|
||||
kill_app
|
||||
|
||||
echo
|
||||
echo "### Notebook Output tests"
|
||||
echo
|
||||
npm run test-extension -l notebook-renderers
|
||||
kill_app
|
||||
|
||||
echo
|
||||
echo "### Configuration editing tests"
|
||||
echo
|
||||
npm run test-extension -l configuration-editing
|
||||
kill_app
|
||||
|
||||
echo
|
||||
echo "### GitHub Authentication tests"
|
||||
echo
|
||||
npm run test-extension -l github-authentication
|
||||
kill_app
|
||||
|
||||
# Tests standalone (CommonJS)
|
||||
|
||||
echo
|
||||
echo "### CSS tests"
|
||||
echo
|
||||
cd $ROOT/extensions/css-language-features/server && $ROOT/scripts/node-electron.sh test/index.js
|
||||
|
||||
echo
|
||||
echo "### HTML tests"
|
||||
echo
|
||||
cd $ROOT/extensions/html-language-features/server && $ROOT/scripts/node-electron.sh test/index.js
|
||||
|
||||
|
||||
# Cleanup
|
||||
|
||||
rm -rf $VSCODEUSERDATADIR
|
||||
@@ -25,7 +25,7 @@ echo Storing crash reports into '%VSCODECRASHDIR%'.
|
||||
echo Storing log files into '%VSCODELOGSDIR%'.
|
||||
|
||||
|
||||
:: Tests standalone (AMD)
|
||||
:: Unit tests
|
||||
|
||||
echo.
|
||||
echo ### node.js integration tests
|
||||
@@ -49,7 +49,12 @@ if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### Colorize tests
|
||||
call npm run test-extension -l vscode-colorize-tests
|
||||
call npm run test-extension -- -l vscode-colorize-tests
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### Terminal Suggest tests
|
||||
call npm run test-extension -- -l terminal-suggest --enable-proposed-api=vscode.vscode-api-tests
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
@@ -59,7 +64,7 @@ if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### Markdown tests
|
||||
call npm run test-extension -l markdown-language-features
|
||||
call npm run test-extension -- -l markdown-language-features
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
@@ -77,24 +82,24 @@ if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### Ipynb tests
|
||||
call npm run test-extension -l ipynb
|
||||
call npm run test-extension -- -l ipynb
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### Notebook Output tests
|
||||
call npm run test-extension -l notebook-renderers
|
||||
call npm run test-extension -- -l notebook-renderers
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### Configuration editing tests
|
||||
set CFWORKSPACE=%TEMPDIR%\cf-%RANDOM%
|
||||
mkdir %CFWORKSPACE%
|
||||
call npm run test-extension -l configuration-editing
|
||||
call npm run test-extension -- -l configuration-editing
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
echo.
|
||||
echo ### GitHub Authentication tests
|
||||
call npm run test-extension -l github-authentication
|
||||
call npm run test-extension -- -l github-authentication
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
:: Tests standalone (CommonJS)
|
||||
|
||||
Regular → Executable
+13
-7
@@ -34,7 +34,7 @@ echo "Storing crash reports into '$VSCODECRASHDIR'."
|
||||
echo "Storing log files into '$VSCODELOGSDIR'."
|
||||
|
||||
|
||||
# Tests standalone (AMD)
|
||||
# Unit tests
|
||||
|
||||
echo
|
||||
echo "### node.js integration tests"
|
||||
@@ -67,7 +67,13 @@ kill_app
|
||||
echo
|
||||
echo "### Colorize tests"
|
||||
echo
|
||||
npm run test-extension -l vscode-colorize-tests
|
||||
npm run test-extension -- -l vscode-colorize-tests
|
||||
kill_app
|
||||
|
||||
echo
|
||||
echo "### Terminal Suggest tests"
|
||||
echo
|
||||
npm run test-extension -- -l terminal-suggest --enable-proposed-api=vscode.vscode-api-tests
|
||||
kill_app
|
||||
|
||||
echo
|
||||
@@ -79,7 +85,7 @@ kill_app
|
||||
echo
|
||||
echo "### Markdown tests"
|
||||
echo
|
||||
npm run test-extension -l markdown-language-features
|
||||
npm run test-extension -- -l markdown-language-features
|
||||
kill_app
|
||||
|
||||
echo
|
||||
@@ -97,25 +103,25 @@ kill_app
|
||||
echo
|
||||
echo "### Ipynb tests"
|
||||
echo
|
||||
npm run test-extension -l ipynb
|
||||
npm run test-extension -- -l ipynb
|
||||
kill_app
|
||||
|
||||
echo
|
||||
echo "### Notebook Output tests"
|
||||
echo
|
||||
npm run test-extension -l notebook-renderers
|
||||
npm run test-extension -- -l notebook-renderers
|
||||
kill_app
|
||||
|
||||
echo
|
||||
echo "### Configuration editing tests"
|
||||
echo
|
||||
npm run test-extension -l configuration-editing
|
||||
npm run test-extension -- -l configuration-editing
|
||||
kill_app
|
||||
|
||||
echo
|
||||
echo "### GitHub Authentication tests"
|
||||
echo
|
||||
npm run test-extension -l github-authentication
|
||||
npm run test-extension -- -l github-authentication
|
||||
kill_app
|
||||
|
||||
# Tests standalone (CommonJS)
|
||||
|
||||
Regular → Executable
Regular → Executable
Regular → Executable
@@ -10,6 +10,8 @@ const moduleNames = [
|
||||
'@xterm/xterm',
|
||||
'@xterm/addon-clipboard',
|
||||
'@xterm/addon-image',
|
||||
'@xterm/addon-ligatures',
|
||||
'@xterm/addon-progress',
|
||||
'@xterm/addon-search',
|
||||
'@xterm/addon-serialize',
|
||||
'@xterm/addon-unicode11',
|
||||
|
||||
Reference in New Issue
Block a user