Merge pull request #5582 from continuedev/pe/ripgrep-download
feat: manual ripgrep downloads for JB
This commit is contained in:
commit
6953fc8ecd
|
@ -8,13 +8,15 @@ const {
|
|||
execCmdSync,
|
||||
autodetectPlatformAndArch,
|
||||
} = require("../scripts/util");
|
||||
const { downloadRipgrep } = require("./utils/ripgrep");
|
||||
const { ALL_TARGETS, TARGET_TO_LANCEDB } = require("./utils/targets");
|
||||
|
||||
const bin = path.join(__dirname, "bin");
|
||||
const out = path.join(__dirname, "out");
|
||||
const build = path.join(__dirname, "build");
|
||||
|
||||
function cleanSlate() {
|
||||
// Clean slate
|
||||
// Clean slate
|
||||
rimrafSync(bin);
|
||||
rimrafSync(out);
|
||||
rimrafSync(build);
|
||||
|
@ -25,13 +27,7 @@ function cleanSlate() {
|
|||
}
|
||||
|
||||
const esbuildOutputFile = "out/index.js";
|
||||
let targets = [
|
||||
"darwin-x64",
|
||||
"darwin-arm64",
|
||||
"linux-x64",
|
||||
"linux-arm64",
|
||||
"win32-x64",
|
||||
];
|
||||
let targets = [...ALL_TARGETS];
|
||||
|
||||
const [currentPlatform, currentArch] = autodetectPlatformAndArch();
|
||||
|
||||
|
@ -50,15 +46,6 @@ for (let i = 2; i < process.argv.length; i++) {
|
|||
}
|
||||
}
|
||||
|
||||
const targetToLanceDb = {
|
||||
"darwin-arm64": "@lancedb/vectordb-darwin-arm64",
|
||||
"darwin-x64": "@lancedb/vectordb-darwin-x64",
|
||||
"linux-arm64": "@lancedb/vectordb-linux-arm64-gnu",
|
||||
"linux-x64": "@lancedb/vectordb-linux-x64-gnu",
|
||||
"win32-x64": "@lancedb/vectordb-win32-x64-msvc",
|
||||
"win32-arm64": "@lancedb/vectordb-win32-arm64-msvc",
|
||||
};
|
||||
|
||||
// Bundles the extension into one file
|
||||
async function buildWithEsbuild() {
|
||||
console.log("[info] Building with esbuild...");
|
||||
|
@ -89,7 +76,6 @@ async function buildWithEsbuild() {
|
|||
inject: ["./importMetaUrl.js"],
|
||||
define: { "import.meta.url": "importMetaUrl" },
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
async function installNodeModuleInTempDirAndCopyToCurrent(packageName, toCopy) {
|
||||
|
@ -153,13 +139,31 @@ async function installNodeModuleInTempDirAndCopyToCurrent(packageName, toCopy) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads and installs ripgrep binaries for the specified target
|
||||
*
|
||||
* @param {string} target - Target platform-arch (e.g., 'darwin-x64')
|
||||
* @param {string} targetDir - Directory to install ripgrep to
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function downloadRipgrepForTarget(target, targetDir) {
|
||||
console.log(`[info] Downloading ripgrep for ${target}...`);
|
||||
try {
|
||||
await downloadRipgrep(target, targetDir);
|
||||
console.log(`[info] Successfully installed ripgrep for ${target}`);
|
||||
} catch (error) {
|
||||
console.error(`[error] Failed to download ripgrep for ${target}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
(async () => {
|
||||
if (esbuildOnly) {
|
||||
await buildWithEsbuild();
|
||||
return;
|
||||
}
|
||||
|
||||
cleanSlate()
|
||||
cleanSlate();
|
||||
|
||||
// Informs of where to look for node_sqlite3.node https://www.npmjs.com/package/bindings#:~:text=The%20searching%20for,file%20is%20found
|
||||
// This is only needed for our `pkg` command at build time
|
||||
|
@ -179,10 +183,10 @@ async function installNodeModuleInTempDirAndCopyToCurrent(packageName, toCopy) {
|
|||
|
||||
console.log("[info] Downloading prebuilt lancedb...");
|
||||
for (const target of targets) {
|
||||
if (targetToLanceDb[target]) {
|
||||
if (TARGET_TO_LANCEDB[target]) {
|
||||
console.log(`[info] Downloading for ${target}...`);
|
||||
await installNodeModuleInTempDirAndCopyToCurrent(
|
||||
targetToLanceDb[target],
|
||||
TARGET_TO_LANCEDB[target],
|
||||
"@lancedb",
|
||||
);
|
||||
}
|
||||
|
@ -290,10 +294,13 @@ async function installNodeModuleInTempDirAndCopyToCurrent(packageName, toCopy) {
|
|||
// copy @lancedb to bin folders
|
||||
console.log("[info] Copying @lancedb files to bin");
|
||||
fs.copyFileSync(
|
||||
`node_modules/${targetToLanceDb[target]}/index.node`,
|
||||
`node_modules/${TARGET_TO_LANCEDB[target]}/index.node`,
|
||||
`${targetDir}/index.node`,
|
||||
);
|
||||
|
||||
// Download and install ripgrep for the target
|
||||
await downloadRipgrepForTarget(target, targetDir);
|
||||
|
||||
// Informs the `continue-binary` of where to look for node_sqlite3.node
|
||||
// https://www.npmjs.com/package/bindings#:~:text=The%20searching%20for,file%20is%20found
|
||||
fs.writeFileSync(`${targetDir}/package.json`, "");
|
||||
|
@ -310,6 +317,7 @@ async function installNodeModuleInTempDirAndCopyToCurrent(packageName, toCopy) {
|
|||
`${targetDir}/continue-binary${exe}`,
|
||||
`${targetDir}/index.node`, // @lancedb
|
||||
`${targetDir}/build/Release/node_sqlite3.node`,
|
||||
`${targetDir}/rg${exe}`, // ripgrep binary
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@octokit/rest": "^20.0.2",
|
||||
"adm-zip": "^0.5.16",
|
||||
"commander": "^12.0.0",
|
||||
"core": "file:../core",
|
||||
"follow-redirects": "^1.15.5",
|
||||
|
@ -18,6 +19,7 @@
|
|||
"node-fetch": "^3.3.2",
|
||||
"posthog-node": "^3.6.3",
|
||||
"system-ca": "^1.0.2",
|
||||
"tar": "^7.4.3",
|
||||
"uuid": "^9.0.1",
|
||||
"vectordb": "^0.4.20",
|
||||
"win-ca": "^3.5.1"
|
||||
|
@ -49,7 +51,7 @@
|
|||
"@aws-sdk/credential-providers": "^3.778.0",
|
||||
"@continuedev/config-types": "^1.0.13",
|
||||
"@continuedev/config-yaml": "file:../packages/config-yaml",
|
||||
"@continuedev/fetch": "^1.0.4",
|
||||
"@continuedev/fetch": "^1.0.6",
|
||||
"@continuedev/llm-info": "^1.0.8",
|
||||
"@continuedev/openai-adapters": "^1.0.19",
|
||||
"@modelcontextprotocol/sdk": "^1.5.0",
|
||||
|
@ -1526,6 +1528,18 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/fs-minipass": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
|
||||
"integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"minipass": "^7.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
||||
|
@ -2434,6 +2448,15 @@
|
|||
"ncc": "dist/ncc/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/adm-zip": {
|
||||
"version": "0.5.16",
|
||||
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz",
|
||||
"integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||
|
@ -5222,14 +5245,41 @@
|
|||
}
|
||||
},
|
||||
"node_modules/minipass": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.1.tgz",
|
||||
"integrity": "sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==",
|
||||
"dev": true,
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
|
||||
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/minizlib": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz",
|
||||
"integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"minipass": "^7.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/mkdirp": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
|
||||
"integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"mkdirp": "dist/cjs/src/bin.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/mkdirp-classic": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
||||
|
@ -5340,6 +5390,7 @@
|
|||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
|
||||
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"data-uri-to-buffer": "^4.0.0",
|
||||
"fetch-blob": "^3.1.4",
|
||||
|
@ -6410,6 +6461,23 @@
|
|||
"node": ">=12.17"
|
||||
}
|
||||
},
|
||||
"node_modules/tar": {
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz",
|
||||
"integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@isaacs/fs-minipass": "^4.0.0",
|
||||
"chownr": "^3.0.0",
|
||||
"minipass": "^7.1.2",
|
||||
"minizlib": "^3.0.1",
|
||||
"mkdirp": "^3.0.1",
|
||||
"yallist": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/tar-fs": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz",
|
||||
|
@ -6453,6 +6521,24 @@
|
|||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/tar/node_modules/chownr": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
|
||||
"integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/tar/node_modules/yallist": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
|
||||
"integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@octokit/rest": "^20.0.2",
|
||||
"adm-zip": "^0.5.16",
|
||||
"commander": "^12.0.0",
|
||||
"core": "file:../core",
|
||||
"follow-redirects": "^1.15.5",
|
||||
|
@ -50,6 +51,7 @@
|
|||
"node-fetch": "^3.3.2",
|
||||
"posthog-node": "^3.6.3",
|
||||
"system-ca": "^1.0.2",
|
||||
"tar": "^7.4.3",
|
||||
"uuid": "^9.0.1",
|
||||
"vectordb": "^0.4.20",
|
||||
"win-ca": "^3.5.1"
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const { rimrafSync } = require("rimraf");
|
||||
const tar = require("tar");
|
||||
const { RIPGREP_VERSION, TARGET_TO_RIPGREP_RELEASE } = require("./targets");
|
||||
const AdmZip = require("adm-zip");
|
||||
|
||||
const RIPGREP_BASE_URL = `https://github.com/BurntSushi/ripgrep/releases/download/${RIPGREP_VERSION}`;
|
||||
|
||||
/**
|
||||
* Downloads a file from a URL to a specified path
|
||||
*
|
||||
* @param {string} url - The URL to download from
|
||||
* @param {string} destPath - The destination path for the downloaded file
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function downloadFile(url, destPath) {
|
||||
// Use the built-in fetch API instead of node-fetch
|
||||
const response = await fetch(url, {
|
||||
redirect: "follow", // Automatically follow redirects
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to download file, status code: ${response.status}`);
|
||||
}
|
||||
|
||||
// Get the response as an array buffer and write it to the file
|
||||
const buffer = await response.arrayBuffer();
|
||||
fs.writeFileSync(destPath, Buffer.from(buffer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts an archive to a specified directory
|
||||
*
|
||||
* @param {string} archivePath - Path to the archive file
|
||||
* @param {string} targetDir - Directory to extract the archive to
|
||||
* @param {string} platform - Platform identifier (e.g., 'darwin', 'linux', 'win32')
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function extractArchive(archivePath, targetDir, platform) {
|
||||
if (platform === "win32" || archivePath.endsWith(".zip")) {
|
||||
// Simple zip extraction for Windows - extract rg.exe
|
||||
const zip = new AdmZip(archivePath);
|
||||
|
||||
const rgEntry = zip
|
||||
.getEntries()
|
||||
.find((entry) => entry.entryName.endsWith("rg.exe"));
|
||||
|
||||
if (!rgEntry) {
|
||||
throw new Error("Could not find rg.exe in the downloaded archive");
|
||||
}
|
||||
|
||||
// Extract the found rg.exe file to the target directory
|
||||
const entryData = rgEntry.getData();
|
||||
fs.writeFileSync(path.join(targetDir, "rg.exe"), entryData);
|
||||
} else {
|
||||
await tar.extract({
|
||||
file: archivePath,
|
||||
cwd: targetDir,
|
||||
strip: 1, // Strip the top-level directory
|
||||
filter: (path) => path.endsWith("/rg"),
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Downloads and installs ripgrep for the specified target
|
||||
*
|
||||
* @param {string} target - Target platform-arch (e.g., 'darwin-x64')
|
||||
* @param {string} targetDir - Directory to install ripgrep to
|
||||
* @returns {Promise<string>} - Path to the installed ripgrep binary
|
||||
*/
|
||||
async function downloadRipgrep(target, targetDir) {
|
||||
// Get the ripgrep release file name for the target
|
||||
const releaseFile = TARGET_TO_RIPGREP_RELEASE[target];
|
||||
if (!releaseFile) {
|
||||
throw new Error(`Unsupported target: ${target}`);
|
||||
}
|
||||
|
||||
const platform = target.split("-")[0];
|
||||
const downloadUrl = `${RIPGREP_BASE_URL}/${releaseFile}`;
|
||||
const tempDir = path.join(targetDir, "temp");
|
||||
|
||||
// Create temp directory
|
||||
fs.mkdirSync(tempDir, { recursive: true });
|
||||
|
||||
const archivePath = path.join(tempDir, releaseFile);
|
||||
|
||||
try {
|
||||
// Download the ripgrep release
|
||||
console.log(`[info] Downloading ripgrep from ${downloadUrl}`);
|
||||
await downloadFile(downloadUrl, archivePath);
|
||||
|
||||
// Extract the archive
|
||||
console.log(`[info] Extracting ripgrep to ${targetDir}`);
|
||||
await extractArchive(archivePath, targetDir, platform);
|
||||
|
||||
// Make the binary executable on Unix-like systems
|
||||
if (platform !== "win32") {
|
||||
const rgPath = path.join(targetDir, "rg");
|
||||
fs.chmodSync(rgPath, 0o755);
|
||||
}
|
||||
|
||||
// Clean up
|
||||
rimrafSync(tempDir);
|
||||
|
||||
// Return the path to the ripgrep binary
|
||||
const binName = platform === "win32" ? "rg.exe" : "rg";
|
||||
return path.join(targetDir, binName);
|
||||
} catch (error) {
|
||||
console.error(`[error] Failed to download ripgrep for ${target}:`, error);
|
||||
// Clean up temp directory on error
|
||||
rimrafSync(tempDir);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
downloadRipgrep,
|
||||
RIPGREP_VERSION,
|
||||
};
|
|
@ -0,0 +1,42 @@
|
|||
const RIPGREP_VERSION = "14.1.1";
|
||||
|
||||
/**
|
||||
* All supported platform-architecture targets
|
||||
*/
|
||||
const ALL_TARGETS = [
|
||||
"darwin-x64",
|
||||
"darwin-arm64",
|
||||
"linux-x64",
|
||||
"linux-arm64",
|
||||
"win32-x64",
|
||||
];
|
||||
|
||||
/**
|
||||
* Mapping from target triplets to ripgrep release file names
|
||||
*/
|
||||
const TARGET_TO_RIPGREP_RELEASE = {
|
||||
"darwin-x64": `ripgrep-${RIPGREP_VERSION}-x86_64-apple-darwin.tar.gz`,
|
||||
"darwin-arm64": `ripgrep-${RIPGREP_VERSION}-aarch64-apple-darwin.tar.gz`,
|
||||
"linux-x64": `ripgrep-${RIPGREP_VERSION}-x86_64-unknown-linux-musl.tar.gz`,
|
||||
"linux-arm64": `ripgrep-${RIPGREP_VERSION}-aarch64-unknown-linux-gnu.tar.gz`,
|
||||
"win32-x64": `ripgrep-${RIPGREP_VERSION}-x86_64-pc-windows-msvc.zip`,
|
||||
};
|
||||
|
||||
/**
|
||||
* Mapping from target triplets to LanceDB package names
|
||||
*/
|
||||
const TARGET_TO_LANCEDB = {
|
||||
"darwin-arm64": "@lancedb/vectordb-darwin-arm64",
|
||||
"darwin-x64": "@lancedb/vectordb-darwin-x64",
|
||||
"linux-arm64": "@lancedb/vectordb-linux-arm64-gnu",
|
||||
"linux-x64": "@lancedb/vectordb-linux-x64-gnu",
|
||||
"win32-x64": "@lancedb/vectordb-win32-x64-msvc",
|
||||
"win32-arm64": "@lancedb/vectordb-win32-arm64-msvc",
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
ALL_TARGETS,
|
||||
TARGET_TO_RIPGREP_RELEASE,
|
||||
TARGET_TO_LANCEDB,
|
||||
RIPGREP_VERSION,
|
||||
};
|
|
@ -6,7 +6,6 @@ fun environment(key: String) = providers.environmentVariable(key)
|
|||
|
||||
fun Sync.prepareSandbox() {
|
||||
from("../../binary/bin") { into("${intellij.pluginName.get()}/core/") }
|
||||
from("../vscode/node_modules/@vscode/ripgrep") { into("${intellij.pluginName.get()}/ripgrep/") }
|
||||
}
|
||||
|
||||
val remoteRobotVersion = "0.11.23"
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package com.github.continuedev.continueintellijextension.constants
|
||||
|
||||
/**
|
||||
* Constants related to the Continue plugin.
|
||||
*/
|
||||
object ContinueConstants {
|
||||
/**
|
||||
* The unique identifier for the Continue plugin.
|
||||
*/
|
||||
const val PLUGIN_ID = "com.github.continuedev.continueintellijextension"
|
||||
}
|
|
@ -2,12 +2,10 @@ package com.github.continuedev.continueintellijextension.`continue`
|
|||
|
||||
import com.github.continuedev.continueintellijextension.services.TelemetryService
|
||||
import com.github.continuedev.continueintellijextension.utils.castNestedOrNull
|
||||
import com.github.continuedev.continueintellijextension.utils.getContinueBinaryPath
|
||||
import com.github.continuedev.continueintellijextension.utils.getMachineUniqueID
|
||||
import com.intellij.ide.plugins.PluginManager
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.extensions.PluginId
|
||||
import com.intellij.openapi.project.Project
|
||||
import java.nio.file.Paths
|
||||
import kotlinx.coroutines.*
|
||||
|
||||
class CoreMessengerManager(
|
||||
|
@ -21,38 +19,8 @@ class CoreMessengerManager(
|
|||
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
val myPluginId = "com.github.continuedev.continueintellijextension"
|
||||
val pluginDescriptor =
|
||||
PluginManager.getPlugin(PluginId.getId(myPluginId)) ?: throw Exception("Plugin not found")
|
||||
|
||||
val pluginPath = pluginDescriptor.pluginPath
|
||||
val osName = System.getProperty("os.name").toLowerCase()
|
||||
val os =
|
||||
when {
|
||||
osName.contains("mac") || osName.contains("darwin") -> "darwin"
|
||||
osName.contains("win") -> "win32"
|
||||
osName.contains("nix") || osName.contains("nux") || osName.contains("aix") -> "linux"
|
||||
else -> "linux"
|
||||
}
|
||||
val osArch = System.getProperty("os.arch").toLowerCase()
|
||||
val arch =
|
||||
when {
|
||||
osArch.contains("aarch64") || (osArch.contains("arm") && osArch.contains("64")) ->
|
||||
"arm64"
|
||||
|
||||
osArch.contains("amd64") || osArch.contains("x86_64") -> "x64"
|
||||
else -> "x64"
|
||||
}
|
||||
val target = "$os-$arch"
|
||||
|
||||
println("Identified OS: $os, Arch: $arch")
|
||||
|
||||
val corePath = Paths.get(pluginPath.toString(), "core").toString()
|
||||
val targetPath = Paths.get(corePath, target).toString()
|
||||
val continueCorePath =
|
||||
Paths.get(targetPath, "continue-binary" + (if (os == "win32") ".exe" else "")).toString()
|
||||
|
||||
setupCoreMessenger(continueCorePath)
|
||||
val continueBinaryPath = getContinueBinaryPath()
|
||||
setupCoreMessenger(continueBinaryPath)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import com.github.continuedev.continueintellijextension.*
|
||||
import com.github.continuedev.continueintellijextension.constants.getContinueGlobalPath
|
||||
import com.github.continuedev.continueintellijextension.constants.ContinueConstants
|
||||
import com.github.continuedev.continueintellijextension.`continue`.GitService
|
||||
import com.github.continuedev.continueintellijextension.services.ContinueExtensionSettings
|
||||
import com.github.continuedev.continueintellijextension.services.ContinuePluginService
|
||||
|
@ -46,20 +47,12 @@ class IntelliJIDE(
|
|||
|
||||
private val gitService = GitService(project, continuePluginService)
|
||||
|
||||
private val ripgrep: String
|
||||
private val ripgrep: String = getRipgrepPath()
|
||||
|
||||
init {
|
||||
val myPluginId = "com.github.continuedev.continueintellijextension"
|
||||
val pluginDescriptor =
|
||||
PluginManager.getPlugin(PluginId.getId(myPluginId)) ?: throw Exception("Plugin not found")
|
||||
|
||||
val pluginPath = pluginDescriptor.pluginPath
|
||||
val os = getOS()
|
||||
ripgrep =
|
||||
Paths.get(pluginPath.toString(), "ripgrep", "bin", "rg" + if (os == OS.WINDOWS) ".exe" else "").toString()
|
||||
|
||||
// Make ripgrep executable if on Unix-like systems
|
||||
try {
|
||||
val os = getOS()
|
||||
|
||||
if (os == OS.LINUX || os == OS.MAC) {
|
||||
val file = File(ripgrep)
|
||||
if (!file.canExecute()) {
|
||||
|
@ -69,7 +62,6 @@ class IntelliJIDE(
|
|||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,7 +83,7 @@ class IntelliJIDE(
|
|||
remoteName = "ssh"
|
||||
}
|
||||
|
||||
val pluginId = "com.github.continuedev.continueintellijextension"
|
||||
val pluginId = ContinueConstants.PLUGIN_ID
|
||||
val plugin = PluginManagerCore.getPlugin(PluginId.getId(pluginId))
|
||||
val extensionVersion = plugin?.version ?: "Unknown"
|
||||
|
||||
|
@ -330,109 +322,62 @@ class IntelliJIDE(
|
|||
override suspend fun getFileResults(pattern: String): List<String> {
|
||||
val ideInfo = this.getIdeInfo()
|
||||
if (ideInfo.remoteName == "local") {
|
||||
val command = GeneralCommandLine(
|
||||
ripgrep,
|
||||
"--files",
|
||||
"--iglob",
|
||||
pattern,
|
||||
"--ignore-file",
|
||||
".continueignore",
|
||||
"--ignore-file",
|
||||
".gitignore",
|
||||
)
|
||||
|
||||
command.setWorkDirectory(project.basePath)
|
||||
val results = ExecUtil.execAndGetOutput(command).stdout
|
||||
return results.split("\n")
|
||||
try {
|
||||
val command = GeneralCommandLine(
|
||||
ripgrep,
|
||||
"--files",
|
||||
"--iglob",
|
||||
pattern,
|
||||
"--ignore-file",
|
||||
".continueignore",
|
||||
"--ignore-file",
|
||||
".gitignore",
|
||||
)
|
||||
|
||||
command.setWorkDirectory(project.basePath)
|
||||
val results = ExecUtil.execAndGetOutput(command).stdout
|
||||
return results.split("\n")
|
||||
} catch (e: Exception) {
|
||||
showToast(
|
||||
ToastType.ERROR,
|
||||
"Error executing ripgrep: ${e.message}"
|
||||
)
|
||||
return emptyList()
|
||||
}
|
||||
} else {
|
||||
throw NotImplementedError("Ripgrep not supported, this workspace is remote")
|
||||
|
||||
// Leaving in here for ideas
|
||||
// val projectBasePath = project.basePath ?: return emptyList()
|
||||
// val scope = GlobalSearchScope.projectScope(project)
|
||||
//
|
||||
// // Get all ignore patterns from .continueignore files
|
||||
// val ignorePatterns = mutableSetOf<String>()
|
||||
// VirtualFileManager.getInstance().findFileByUrl("file://$projectBasePath")?.let { root ->
|
||||
// VfsUtil.collectChildrenRecursively(root).forEach { file ->
|
||||
// if (file.name == ".continueignore") {
|
||||
// file.inputStream.bufferedReader().useLines { lines ->
|
||||
// ignorePatterns.addAll(lines.filter { it.isNotBlank() && !it.startsWith("#") })
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return FilenameIndex.getAllFilesByExt(project, "*", scope)
|
||||
// .filter { file ->
|
||||
// val relativePath = file.path.removePrefix("$projectBasePath/")
|
||||
// // Check if file matches pattern and isn't ignored
|
||||
// PatternUtil.(relativePath, pattern) &&
|
||||
// !ignorePatterns.any { PatternUtil.matchesGlob(relativePath, it) }
|
||||
// }
|
||||
// .map { it.path.removePrefix("$projectBasePath/") }
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getSearchResults(query: String): String {
|
||||
val ideInfo = this.getIdeInfo()
|
||||
if (ideInfo.remoteName == "local") {
|
||||
val command = GeneralCommandLine(
|
||||
ripgrep,
|
||||
"-i",
|
||||
"--ignore-file",
|
||||
".continueignore",
|
||||
"--ignore-file",
|
||||
".gitignore",
|
||||
"-C",
|
||||
"2",
|
||||
"--heading",
|
||||
"-e",
|
||||
query,
|
||||
"."
|
||||
)
|
||||
|
||||
command.setWorkDirectory(project.basePath)
|
||||
return ExecUtil.execAndGetOutput(command).stdout
|
||||
try {
|
||||
val command = GeneralCommandLine(
|
||||
ripgrep,
|
||||
"-i",
|
||||
"--ignore-file",
|
||||
".continueignore",
|
||||
"--ignore-file",
|
||||
".gitignore",
|
||||
"-C",
|
||||
"2",
|
||||
"--heading",
|
||||
"-e",
|
||||
query,
|
||||
"."
|
||||
)
|
||||
|
||||
command.setWorkDirectory(project.basePath)
|
||||
return ExecUtil.execAndGetOutput(command).stdout
|
||||
} catch (e: Exception) {
|
||||
showToast(
|
||||
ToastType.ERROR,
|
||||
"Error executing ripgrep: ${e.message}"
|
||||
)
|
||||
return "Error: Unable to execute ripgrep command."
|
||||
}
|
||||
} else {
|
||||
throw NotImplementedError("Ripgrep not supported, this workspace is remote")
|
||||
|
||||
// For remote workspaces, use JetBrains search functionality
|
||||
// val searchResults = StringBuilder()
|
||||
// ApplicationManager.getApplication().invokeAndWait {
|
||||
// val options = FindModel().apply {
|
||||
// stringToFind = query
|
||||
// isCaseSensitive = false
|
||||
// isRegularExpressions = false
|
||||
// isWholeWordsOnly = false
|
||||
// searchContext = FindModel.SearchContext.ANY // or IN_CODE, IN_COMMENTS, IN_STRING_LITERALS, etc.
|
||||
// isMultiline = true // Allow matching across multiple lines
|
||||
// }
|
||||
//
|
||||
// val progressIndicator = EmptyProgressIndicator()
|
||||
// val presentation = FindUsagesProcessPresentation(
|
||||
// UsageViewPresentation()
|
||||
// )
|
||||
// val filesToSearch = ProjectFileIndex.getInstance(project)
|
||||
// .iterateContent(::ArrayList)
|
||||
// .filterNot { it.isDirectory }
|
||||
// .toSet()
|
||||
//
|
||||
//
|
||||
// FindInProjectUtil.findUsages(
|
||||
// options,
|
||||
// project,
|
||||
// progressIndicator,
|
||||
// presentation,
|
||||
// filesToSearch
|
||||
// ) { result ->
|
||||
// val virtualFile = result.virtualFile
|
||||
// searchResults.append(virtualFile.path).append("\n")
|
||||
// searchResults.append("${result..trim()}\n")
|
||||
// true // continue searching
|
||||
// }
|
||||
// }
|
||||
// return searchResults.toString()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
package com.github.continuedev.continueintellijextension.utils
|
||||
|
||||
import com.intellij.ide.plugins.PluginManager
|
||||
import com.intellij.openapi.extensions.PluginId
|
||||
import com.github.continuedev.continueintellijextension.constants.ContinueConstants
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
|
||||
/**
|
||||
* Gets the path to the Continue plugin directory
|
||||
*
|
||||
* @return Path to the plugin directory
|
||||
* @throws Exception if the plugin is not found
|
||||
*/
|
||||
fun getContinuePluginPath(): Path {
|
||||
val pluginDescriptor =
|
||||
PluginManager.getPlugin(PluginId.getId(ContinueConstants.PLUGIN_ID)) ?: throw Exception("Plugin not found")
|
||||
return pluginDescriptor.pluginPath
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path to the Continue core directory with target platform
|
||||
*
|
||||
* @return Path to the Continue core directory with target platform
|
||||
* @throws Exception if the plugin is not found
|
||||
*/
|
||||
fun getContinueCorePath(): String {
|
||||
val pluginPath = getContinuePluginPath()
|
||||
val corePath = Paths.get(pluginPath.toString(), "core").toString()
|
||||
val target = getOsAndArchTarget()
|
||||
return Paths.get(corePath, target).toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path to the Continue binary executable
|
||||
*
|
||||
* @return Path to the Continue binary executable
|
||||
* @throws Exception if the plugin is not found
|
||||
*/
|
||||
fun getContinueBinaryPath(): String {
|
||||
val targetPath = getContinueCorePath()
|
||||
val os = getOS()
|
||||
val exeSuffix = if (os == OS.WINDOWS) ".exe" else ""
|
||||
return Paths.get(targetPath, "continue-binary$exeSuffix").toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path to the Ripgrep executable
|
||||
*
|
||||
* @return Path to the Ripgrep executable
|
||||
* @throws Exception if the plugin is not found
|
||||
*/
|
||||
fun getRipgrepPath(): String {
|
||||
val targetPath = getContinueCorePath()
|
||||
val os = getOS()
|
||||
val exeSuffix = if (os == OS.WINDOWS) ".exe" else ""
|
||||
return Paths.get(targetPath, "rg$exeSuffix").toString()
|
||||
}
|
|
@ -4,7 +4,6 @@ import com.intellij.openapi.vfs.VirtualFile
|
|||
import java.net.NetworkInterface
|
||||
import java.util.*
|
||||
import java.awt.event.KeyEvent.*
|
||||
|
||||
enum class OS {
|
||||
MAC, WINDOWS, LINUX
|
||||
}
|
||||
|
@ -92,4 +91,30 @@ fun Any?.getNestedOrNull(vararg keys: String): Any? {
|
|||
result = (result as? Map<*, *>)?.get(key) ?: return null
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the target string for Continue binary.
|
||||
* The format is "$os-$arch" where:
|
||||
* - os is one of: darwin, win32, or linux
|
||||
* - arch is one of: arm64 or x64
|
||||
*
|
||||
* @return Target string in format "$os-$arch"
|
||||
*/
|
||||
fun getOsAndArchTarget(): String {
|
||||
val os = getOS()
|
||||
val osStr = when (os) {
|
||||
OS.MAC -> "darwin"
|
||||
OS.WINDOWS -> "win32"
|
||||
OS.LINUX -> "linux"
|
||||
}
|
||||
|
||||
val osArch = System.getProperty("os.arch").lowercase()
|
||||
val arch = when {
|
||||
osArch.contains("aarch64") || (osArch.contains("arm") && osArch.contains("64")) -> "arm64"
|
||||
osArch.contains("amd64") || osArch.contains("x86_64") -> "x64"
|
||||
else -> "x64"
|
||||
}
|
||||
|
||||
return "$osStr-$arch"
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "continue",
|
||||
"version": "1.1.33",
|
||||
"version": "1.1.32",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "continue",
|
||||
"version": "1.1.33",
|
||||
"version": "1.1.32",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@continuedev/config-types": "^1.0.14",
|
||||
|
|
|
@ -76,6 +76,12 @@ if (($null -eq $node)) {
|
|||
Write-Host "`nInstalling root-level dependencies..." -ForegroundColor White
|
||||
npm install
|
||||
|
||||
Write-Host "`nBuilding config-yaml..." -ForegroundColor White
|
||||
Push-Location packages/config-yaml
|
||||
npm install
|
||||
npm run build
|
||||
Pop-Location
|
||||
|
||||
Write-Host "`nInstalling Core extension dependencies..." -ForegroundColor White
|
||||
Push-Location core
|
||||
npm install
|
||||
|
|
Loading…
Reference in New Issue