From 2771623bacbeda4e77c47d7f511445f3c5db4714 Mon Sep 17 00:00:00 2001
From: "gcp-cherry-pick-bot[bot]"
<98988430+gcp-cherry-pick-bot[bot]@users.noreply.github.com>
Date: Sun, 6 Apr 2025 07:50:12 -0600
Subject: [PATCH] copilot: Create Copilot directory if it does not exist
(cherry-pick #28157) (#28178)
Cherry-picked copilot: Create Copilot directory if it does not exist
(#28157)
Closes https://github.com/zed-industries/zed/issues/27966
Issue:
- Copilot is failing to launch because the copilot directory is missing
Release Notes:
- copilot: Fixed an issue where GitHub Copilot would not install
properly if the directory was not present.
---------
Co-authored-by: Marshall Bowers
Co-authored-by: Richard Hao
Co-authored-by: Marshall Bowers
---
crates/copilot/src/copilot.rs | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/crates/copilot/src/copilot.rs b/crates/copilot/src/copilot.rs
index ac7b4b4a9269d53df58d722e855195c103f4a72a..2a70674daceea64f17cc26ae804a88365791f703 100644
--- a/crates/copilot/src/copilot.rs
+++ b/crates/copilot/src/copilot.rs
@@ -57,11 +57,11 @@ pub fn init(
node_runtime: NodeRuntime,
cx: &mut App,
) {
- copilot_chat::init(fs, http.clone(), cx);
+ copilot_chat::init(fs.clone(), http.clone(), cx);
let copilot = cx.new({
let node_runtime = node_runtime.clone();
- move |cx| Copilot::start(new_server_id, node_runtime, cx)
+ move |cx| Copilot::start(new_server_id, fs, node_runtime, cx)
});
Copilot::set_global(copilot.clone(), cx);
cx.observe(&copilot, |handle, cx| {
@@ -301,6 +301,7 @@ pub struct Completion {
}
pub struct Copilot {
+ fs: Arc,
node_runtime: NodeRuntime,
server: CopilotServer,
buffers: HashSet>,
@@ -332,11 +333,13 @@ impl Copilot {
fn start(
new_server_id: LanguageServerId,
+ fs: Arc,
node_runtime: NodeRuntime,
cx: &mut Context,
) -> Self {
let mut this = Self {
server_id: new_server_id,
+ fs,
node_runtime,
server: CopilotServer::Disabled,
buffers: Default::default(),
@@ -380,12 +383,14 @@ impl Copilot {
return;
}
let server_id = self.server_id;
+ let fs = self.fs.clone();
let node_runtime = self.node_runtime.clone();
let env = self.build_env(&language_settings.edit_predictions.copilot);
let start_task = cx
.spawn(async move |this, cx| {
Self::start_language_server(
server_id,
+ fs,
node_runtime,
env,
this,
@@ -425,6 +430,7 @@ impl Copilot {
#[cfg(any(test, feature = "test-support"))]
pub fn fake(cx: &mut gpui::TestAppContext) -> (Entity, lsp::FakeLanguageServer) {
+ use fs::FakeFs;
use lsp::FakeLanguageServer;
use node_runtime::NodeRuntime;
@@ -442,6 +448,7 @@ impl Copilot {
let node_runtime = NodeRuntime::unavailable();
let this = cx.new(|cx| Self {
server_id: LanguageServerId(0),
+ fs: FakeFs::new(cx.background_executor().clone()),
node_runtime,
server: CopilotServer::Running(RunningCopilotServer {
lsp: Arc::new(server),
@@ -456,6 +463,7 @@ impl Copilot {
async fn start_language_server(
new_server_id: LanguageServerId,
+ fs: Arc,
node_runtime: NodeRuntime,
env: Option>,
this: WeakEntity,
@@ -463,7 +471,7 @@ impl Copilot {
cx: &mut AsyncApp,
) {
let start_language_server = async {
- let server_path = get_copilot_lsp(node_runtime.clone()).await?;
+ let server_path = get_copilot_lsp(fs, node_runtime.clone()).await?;
let node_path = node_runtime.binary_path().await?;
let arguments: Vec = vec![server_path.into(), "--stdio".into()];
let binary = LanguageServerBinary {
@@ -664,11 +672,13 @@ impl Copilot {
let env = self.build_env(&language_settings.edit_predictions.copilot);
let start_task = cx
.spawn({
+ let fs = self.fs.clone();
let node_runtime = self.node_runtime.clone();
let server_id = self.server_id;
async move |this, cx| {
clear_copilot_dir().await;
- Self::start_language_server(server_id, node_runtime, env, this, false, cx).await
+ Self::start_language_server(server_id, fs, node_runtime, env, this, false, cx)
+ .await
}
})
.shared();
@@ -1050,7 +1060,7 @@ async fn clear_copilot_config_dir() {
remove_matching(copilot_chat::copilot_chat_config_dir(), |_| true).await
}
-async fn get_copilot_lsp(node_runtime: NodeRuntime) -> anyhow::Result {
+async fn get_copilot_lsp(fs: Arc, node_runtime: NodeRuntime) -> anyhow::Result {
const PACKAGE_NAME: &str = "@github/copilot-language-server";
const SERVER_PATH: &str =
"node_modules/@github/copilot-language-server/dist/language-server.js";
@@ -1060,6 +1070,8 @@ async fn get_copilot_lsp(node_runtime: NodeRuntime) -> anyhow::Result {
.await?;
let server_path = paths::copilot_dir().join(SERVER_PATH);
+ fs.create_dir(paths::copilot_dir()).await?;
+
let should_install = node_runtime
.should_install_npm_package(
PACKAGE_NAME,