diff --git a/src/command/lsp/mod.rs b/src/command/lsp/mod.rs index e9993e3e8..e274203ec 100644 --- a/src/command/lsp/mod.rs +++ b/src/command/lsp/mod.rs @@ -1,16 +1,19 @@ mod errors; -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; use std::env::temp_dir; use std::io::stdin; use anyhow::Error; use apollo_federation_types::config::FederationVersion::LatestFedTwo; +use apollo_federation_types::config::SubgraphConfig; use apollo_language_server::{ApolloLanguageServer, Config}; +use async_trait::async_trait; use camino::Utf8PathBuf; use clap::Parser; use futures::StreamExt; -use rover_client::blocking::StudioClient; +use rover_client::shared::GraphRef; +use rover_client::RoverClientError; use serde::Serialize; use tower_lsp::lsp_types::{Diagnostic, Range}; use tower_lsp::Server; @@ -33,6 +36,7 @@ use crate::composition::{ CompositionError, CompositionSubgraphAdded, CompositionSubgraphRemoved, CompositionSuccess, }; use crate::utils::effect::exec::TokioCommand; +use crate::utils::effect::fetch_remote_subgraphs::FetchRemoteSubgraphs; use crate::utils::effect::install::InstallBinary; use crate::utils::effect::read_file::FsReadFile; use crate::utils::effect::write_file::FsWriteFile; @@ -100,14 +104,9 @@ async fn run_lsp(client_config: StudioClientConfig, lsp_opts: LspOpts) -> RoverR (service, socket) } Some(supergraph_yaml_path) => { - let studio_client = - client_config.get_authenticated_client(&lsp_opts.plugin_opts.profile)?; // Resolve Supergraph Config -> Lazy - let lazily_resolved_supergraph_config = generate_lazily_resolved_supergraph_config( - &studio_client, - supergraph_yaml_path.clone(), - ) - .await?; + let lazily_resolved_supergraph_config = + generate_lazily_resolved_supergraph_config(supergraph_yaml_path.clone()).await?; let supergraph_yaml_url = Url::from_file_path(supergraph_yaml_path.clone()) .map_err(|_| SupergraphYamlUrlConversionFailed(supergraph_yaml_path.clone()))?; debug!("Supergraph Config Root: {:?}", supergraph_yaml_url); @@ -131,7 +130,6 @@ async fn run_lsp(client_config: StudioClientConfig, lsp_opts: LspOpts) -> RoverR lazily_resolved_supergraph_config, supergraph_yaml_url, client_config, - studio_client, lsp_opts, service.inner().to_owned(), ) @@ -148,12 +146,11 @@ async fn run_lsp(client_config: StudioClientConfig, lsp_opts: LspOpts) -> RoverR } async fn generate_lazily_resolved_supergraph_config( - studio_client: &StudioClient, supergraph_yaml_path: Utf8PathBuf, ) -> Result { // Get the SupergraphConfig in a form we can use let supergraph_config = SupergraphConfigResolver::default() - .load_remote_subgraphs(studio_client, None) + .load_remote_subgraphs(&NullFetchRemoteSubgraphs {}, None) .await? .load_from_file_descriptor( &mut stdin(), @@ -174,7 +171,6 @@ async fn start_composition( lazily_resolved_supergraph_config: LazilyResolvedSupergraphConfig, supergraph_yaml_url: Url, client_config: StudioClientConfig, - studio_client: StudioClient, lsp_opts: LspOpts, language_server: ApolloLanguageServer, ) -> Result<(), StartCompositionError> { @@ -206,7 +202,7 @@ async fn start_composition( .setup_supergraph_config_watcher(lazily_resolved_supergraph_config.clone()) .setup_composition_watcher( lazily_resolved_supergraph_config - .extract_subgraphs_as_sdls(&client_config, &studio_client) + .extract_subgraphs_as_sdls(client_config, lsp_opts.plugin_opts.profile) .await .map_err(ResolveSupergraphConfigError::ResolveSubgraphs)?, supergraph_binary, @@ -288,3 +284,17 @@ async fn start_composition( }); Ok(()) } + +struct NullFetchRemoteSubgraphs {} + +#[async_trait] +impl FetchRemoteSubgraphs for NullFetchRemoteSubgraphs { + type Error = RoverClientError; + + async fn fetch_remote_subgraphs( + &self, + _: &GraphRef, + ) -> Result, Self::Error> { + Ok(BTreeMap::new()) + } +} diff --git a/src/composition/supergraph/config/error/subgraph.rs b/src/composition/supergraph/config/error/subgraph.rs index b9a9c7923..4ecf0192d 100644 --- a/src/composition/supergraph/config/error/subgraph.rs +++ b/src/composition/supergraph/config/error/subgraph.rs @@ -1,5 +1,6 @@ use std::path::PathBuf; +use anyhow::Error; use camino::Utf8PathBuf; /// Errors that may occur as a result of resolving subgraphs @@ -50,7 +51,10 @@ pub enum ResolveSubgraphError { /// The source error source: Box, }, - /// Occurs when a supergraph config filepath waqs expected but not found + /// Occurs when a supergraph config filepath was expected but not found #[error("Failed to find the supergraph config, which is required when resolving schemas in a file relative to a supergraph config")] SupergraphConfigMissing, + /// Occurs when a authenticated client to studio could not be constructed + #[error("Failed to find the supergraph config, which is required when resolving schemas in a file relative to a supergraph config")] + AuthenticationToStudioFailed(#[from] Error), } diff --git a/src/composition/supergraph/config/full/subgraph.rs b/src/composition/supergraph/config/full/subgraph.rs index 09eedd612..94a3aeb82 100644 --- a/src/composition/supergraph/config/full/subgraph.rs +++ b/src/composition/supergraph/config/full/subgraph.rs @@ -11,6 +11,8 @@ use rover_std::Fs; use url::Url; use crate::composition::supergraph::config::lazy::LazilyResolvedSubgraph; +use crate::options::ProfileOpt; +use crate::utils::client::StudioClientConfig; use crate::{ composition::supergraph::config::{ error::ResolveSubgraphError, unresolved::UnresolvedSubgraph, @@ -85,8 +87,8 @@ impl FullyResolvedSubgraph { /// Fully resolves a [`LazilyResolvedSubgraph`] to a [`FullyResolvedSubgraph`] pub async fn fully_resolve( - introspect_subgraph_impl: &impl IntrospectSubgraph, - fetch_remote_subgraph_impl: &impl FetchRemoteSubgraph, + client_config: StudioClientConfig, + profile: ProfileOpt, lazily_resolved_subgraph: LazilyResolvedSubgraph, subgraph_name: String, ) -> Result { @@ -99,7 +101,7 @@ impl FullyResolvedSubgraph { introspection_headers, } => { Self::resolve_subgraph_introspection( - introspect_subgraph_impl, + &client_config, subgraph_name, lazily_resolved_subgraph.routing_url, subgraph_url, @@ -111,8 +113,9 @@ impl FullyResolvedSubgraph { graphref: graph_ref, subgraph, } => { + let studio_client = client_config.get_authenticated_client(&profile)?; Self::resolve_subgraph( - fetch_remote_subgraph_impl, + &studio_client, lazily_resolved_subgraph.routing_url, graph_ref, subgraph, diff --git a/src/composition/supergraph/config/lazy/supergraph.rs b/src/composition/supergraph/config/lazy/supergraph.rs index d4dc9e4fa..d8ea5d7ce 100644 --- a/src/composition/supergraph/config/lazy/supergraph.rs +++ b/src/composition/supergraph/config/lazy/supergraph.rs @@ -11,8 +11,8 @@ use crate::composition::supergraph::config::full::FullyResolvedSubgraph; use crate::composition::supergraph::config::{ error::ResolveSubgraphError, unresolved::UnresolvedSupergraphConfig, }; -use crate::utils::effect::fetch_remote_subgraph::FetchRemoteSubgraph; -use crate::utils::effect::introspect::IntrospectSubgraph; +use crate::options::ProfileOpt; +use crate::utils::client::StudioClientConfig; /// Represents a [`SupergraphConfig`] where all its [`SchemaSource::File`] subgraphs have /// known and valid file paths relative to a supergraph config file (or working directory of the @@ -62,14 +62,14 @@ impl LazilyResolvedSupergraphConfig { /// by retrieving all the schemas as strings pub async fn extract_subgraphs_as_sdls( self, - introspect_subgraph_impl: &impl IntrospectSubgraph, - fetch_remote_subgraph_impl: &impl FetchRemoteSubgraph, + client_config: StudioClientConfig, + profile: ProfileOpt, ) -> Result, Vec> { let subgraphs = stream::iter(self.subgraphs.into_iter().map( |(name, lazily_resolved_subgraph)| async { let result = FullyResolvedSubgraph::fully_resolve( - introspect_subgraph_impl, - fetch_remote_subgraph_impl, + client_config.clone(), + profile.clone(), lazily_resolved_subgraph, name.clone(), )