php.rs

  1use adapters::latest_github_release;
  2use anyhow::bail;
  3use dap::adapters::TcpArguments;
  4use gpui::AsyncApp;
  5use std::path::PathBuf;
  6use task::DebugTaskDefinition;
  7
  8use crate::*;
  9
 10#[derive(Default)]
 11pub(crate) struct PhpDebugAdapter;
 12
 13impl PhpDebugAdapter {
 14    const ADAPTER_NAME: &'static str = "PHP";
 15    const ADAPTER_PACKAGE_NAME: &'static str = "vscode-php-debug";
 16    const ADAPTER_PATH: &'static str = "extension/out/phpDebug.js";
 17}
 18
 19#[async_trait(?Send)]
 20impl DebugAdapter for PhpDebugAdapter {
 21    fn name(&self) -> DebugAdapterName {
 22        DebugAdapterName(Self::ADAPTER_NAME.into())
 23    }
 24
 25    async fn fetch_latest_adapter_version(
 26        &self,
 27        delegate: &dyn DapDelegate,
 28    ) -> Result<AdapterVersion> {
 29        let release = latest_github_release(
 30            &format!("{}/{}", "xdebug", Self::ADAPTER_PACKAGE_NAME),
 31            true,
 32            false,
 33            delegate.http_client(),
 34        )
 35        .await?;
 36
 37        let asset_name = format!("php-debug-{}.vsix", release.tag_name.replace("v", ""));
 38
 39        Ok(AdapterVersion {
 40            tag_name: release.tag_name,
 41            url: release
 42                .assets
 43                .iter()
 44                .find(|asset| asset.name == asset_name)
 45                .ok_or_else(|| anyhow!("no asset found matching {:?}", asset_name))?
 46                .browser_download_url
 47                .clone(),
 48        })
 49    }
 50
 51    async fn get_installed_binary(
 52        &self,
 53        delegate: &dyn DapDelegate,
 54        config: &DebugAdapterConfig,
 55        user_installed_path: Option<PathBuf>,
 56        _: &mut AsyncApp,
 57    ) -> Result<DebugAdapterBinary> {
 58        let adapter_path = if let Some(user_installed_path) = user_installed_path {
 59            user_installed_path
 60        } else {
 61            let adapter_path = paths::debug_adapters_dir().join(self.name().as_ref());
 62
 63            let file_name_prefix = format!("{}_", self.name());
 64
 65            util::fs::find_file_name_in_dir(adapter_path.as_path(), |file_name| {
 66                file_name.starts_with(&file_name_prefix)
 67            })
 68            .await
 69            .ok_or_else(|| anyhow!("Couldn't find PHP dap directory"))?
 70        };
 71
 72        let Some(tcp_connection) = config.tcp_connection.clone() else {
 73            bail!("PHP Debug Adapter expects tcp connection arguments to be provided");
 74        };
 75        let (host, port, timeout) = crate::configure_tcp_connection(tcp_connection).await?;
 76
 77        Ok(DebugAdapterBinary {
 78            command: delegate
 79                .node_runtime()
 80                .binary_path()
 81                .await?
 82                .to_string_lossy()
 83                .into_owned(),
 84            arguments: Some(vec![
 85                adapter_path.join(Self::ADAPTER_PATH).into(),
 86                format!("--server={}", port).into(),
 87            ]),
 88            connection: Some(TcpArguments {
 89                port,
 90                host,
 91                timeout,
 92            }),
 93            cwd: None,
 94            envs: None,
 95        })
 96    }
 97
 98    async fn install_binary(
 99        &self,
100        version: AdapterVersion,
101        delegate: &dyn DapDelegate,
102    ) -> Result<()> {
103        adapters::download_adapter_from_github(
104            self.name(),
105            version,
106            adapters::DownloadedFileType::Vsix,
107            delegate,
108        )
109        .await?;
110
111        Ok(())
112    }
113
114    fn request_args(&self, config: &DebugTaskDefinition) -> Value {
115        match &config.request {
116            dap::DebugRequestType::Attach(_) => {
117                // php adapter does not support attaching
118                json!({})
119            }
120            dap::DebugRequestType::Launch(launch_config) => {
121                json!({
122                    "program": launch_config.program,
123                    "cwd": launch_config.cwd,
124                })
125            }
126        }
127    }
128}