windows: Fix eslint
installation (#15331)
Close #13786. To make `eslint` running on Windows, I made the following changes: 1. Ensure that `zed` downloads the `.zip` file. 2. Handle the `$shared` symbolic link by copying files to the link location. 3. In #13891, I mentioned that the `npm` `post-install` script was always failing. After debugging, I found it was due to missing environment variables. This has been fixed, and I will submit a new PR to address the changes in #13891. With this PR, `eslint` can now successfully run on Windows. Video: https://github.com/user-attachments/assets/e85451b8-0388-490a-8a75-01c12d744f7c Release Notes: - Fixed `eslint` not running on Windows ([#13786](https://github.com/zed-industries/zed/issues/13786)). --------- Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
This commit is contained in:
parent
138c3fcfdd
commit
4976a9e9d8
3 changed files with 59 additions and 0 deletions
|
@ -120,6 +120,7 @@ pub async fn get_release_by_tag_name(
|
|||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub enum AssetKind {
|
||||
TarGz,
|
||||
Zip,
|
||||
}
|
||||
|
||||
pub fn build_asset_url(repo_name_with_owner: &str, tag: &str, kind: AssetKind) -> Result<String> {
|
||||
|
@ -132,6 +133,7 @@ pub fn build_asset_url(repo_name_with_owner: &str, tag: &str, kind: AssetKind) -
|
|||
"{tag}.{extension}",
|
||||
extension = match kind {
|
||||
AssetKind::TarGz => "tar.gz",
|
||||
AssetKind::Zip => "zip",
|
||||
}
|
||||
);
|
||||
url.path_segments_mut()
|
||||
|
@ -154,5 +156,11 @@ mod tests {
|
|||
tarball,
|
||||
"https://github.com/microsoft/vscode-eslint/archive/refs/tags/release%2F2.3.5.tar.gz"
|
||||
);
|
||||
|
||||
let zip = build_asset_url(repo_name_with_owner, tag, AssetKind::Zip).unwrap();
|
||||
assert_eq!(
|
||||
zip,
|
||||
"https://github.com/microsoft/vscode-eslint/archive/refs/tags/release%2F2.3.5.zip"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -296,7 +296,11 @@ pub struct EsLintLspAdapter {
|
|||
|
||||
impl EsLintLspAdapter {
|
||||
const CURRENT_VERSION: &'static str = "release/2.4.4";
|
||||
|
||||
#[cfg(not(windows))]
|
||||
const GITHUB_ASSET_KIND: AssetKind = AssetKind::TarGz;
|
||||
#[cfg(windows)]
|
||||
const GITHUB_ASSET_KIND: AssetKind = AssetKind::Zip;
|
||||
|
||||
const SERVER_PATH: &'static str = "vscode-eslint/server/out/eslintServer.js";
|
||||
const SERVER_NAME: &'static str = "eslint";
|
||||
|
@ -443,6 +447,13 @@ impl LspAdapter for EsLintLspAdapter {
|
|||
let archive = Archive::new(decompressed_bytes);
|
||||
archive.unpack(&destination_path).await?;
|
||||
}
|
||||
AssetKind::Zip => {
|
||||
node_runtime::extract_zip(
|
||||
&destination_path,
|
||||
BufReader::new(response.body_mut()),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
let mut dir = fs::read_dir(&destination_path).await?;
|
||||
|
@ -450,6 +461,20 @@ impl LspAdapter for EsLintLspAdapter {
|
|||
let repo_root = destination_path.join("vscode-eslint");
|
||||
fs::rename(first.path(), &repo_root).await?;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
handle_symlink(
|
||||
repo_root.join("$shared"),
|
||||
repo_root.join("client").join("src").join("shared"),
|
||||
)
|
||||
.await?;
|
||||
handle_symlink(
|
||||
repo_root.join("$shared"),
|
||||
repo_root.join("server").join("src").join("shared"),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
self.node
|
||||
.run_npm_subcommand(Some(&repo_root), "install", &[])
|
||||
.await?;
|
||||
|
@ -505,6 +530,25 @@ async fn get_cached_eslint_server_binary(
|
|||
.log_err()
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
async fn handle_symlink(src_dir: PathBuf, dest_dir: PathBuf) -> Result<()> {
|
||||
if fs::metadata(&src_dir).await.is_err() {
|
||||
return Err(anyhow!("Directory {} not present.", src_dir.display()));
|
||||
}
|
||||
if fs::metadata(&dest_dir).await.is_ok() {
|
||||
fs::remove_file(&dest_dir).await?;
|
||||
}
|
||||
fs::create_dir_all(&dest_dir).await?;
|
||||
let mut entries = fs::read_dir(&src_dir).await?;
|
||||
while let Some(entry) = entries.try_next().await? {
|
||||
let entry_path = entry.path();
|
||||
let entry_name = entry.file_name();
|
||||
let dest_path = dest_dir.join(&entry_name);
|
||||
fs::copy(&entry_path, &dest_path).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use gpui::{Context, TestAppContext};
|
||||
|
|
|
@ -290,6 +290,13 @@ impl NodeRuntime for RealNodeRuntime {
|
|||
{
|
||||
command.env("SYSTEMROOT", val);
|
||||
}
|
||||
// Without ComSpec, the post-install will always fail.
|
||||
if let Some(val) = std::env::var("ComSpec")
|
||||
.context("Missing environment variable: ComSpec!")
|
||||
.log_err()
|
||||
{
|
||||
command.env("ComSpec", val);
|
||||
}
|
||||
command.creation_flags(windows::Win32::System::Threading::CREATE_NO_WINDOW.0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue