Skip to content

Commit

Permalink
feat(compose): when --output is used, use --output in supergraph bin
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronArinder committed Aug 12, 2024
1 parent ee9efe1 commit ab80131
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 34 deletions.
6 changes: 5 additions & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,11 @@ impl Rover {
Command::Fed2(command) => command.run(self.get_client_config()?),
Command::Supergraph(command) => {
command
.run(self.get_install_override_path()?, self.get_client_config()?)
.run(
self.get_install_override_path()?,
self.get_client_config()?,
self.output_opts.output_file.clone(),
)
.await
}
Command::Docs(command) => command.run(),
Expand Down
1 change: 1 addition & 0 deletions src/command/dev/compose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ impl ComposeRunner {
self.override_install_path.clone(),
self.client_config.clone(),
supergraph_config,
None,
)
.await,
);
Expand Down
101 changes: 71 additions & 30 deletions src/command/supergraph/compose/do_compose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use apollo_federation_types::{
use camino::Utf8PathBuf;
use clap::{Args, Parser};
use serde::Serialize;
use std::io::Read;

use rover_client::shared::GraphRef;
use rover_client::RoverClientError;
Expand Down Expand Up @@ -112,6 +113,7 @@ impl Compose {
&self,
override_install_path: Option<Utf8PathBuf>,
client_config: StudioClientConfig,
output_file: Option<Utf8PathBuf>,
) -> RoverResult<RoverOutput> {
let mut supergraph_config = get_supergraph_config(
&self.opts.supergraph_config_source.graph_ref,
Expand All @@ -124,18 +126,29 @@ impl Compose {
// WARNING: remove this unwrap
.unwrap();

self.compose(override_install_path, client_config, &mut supergraph_config)
.await
self.compose(
override_install_path,
client_config,
&mut supergraph_config,
output_file,
)
.await
}

pub async fn compose(
&self,
override_install_path: Option<Utf8PathBuf>,
client_config: StudioClientConfig,
supergraph_config: &mut SupergraphConfig,
output_file: Option<Utf8PathBuf>,
) -> RoverResult<RoverOutput> {
let output = self
.exec(override_install_path, client_config, supergraph_config)
.exec(
override_install_path,
client_config,
supergraph_config,
output_file,
)
.await?;
Ok(RoverOutput::CompositionResult(output))
}
Expand All @@ -145,6 +158,7 @@ impl Compose {
override_install_path: Option<Utf8PathBuf>,
client_config: StudioClientConfig,
supergraph_config: &mut SupergraphConfig,
output_file: Option<Utf8PathBuf>,
) -> RoverResult<CompositionOutput> {
// first, grab the _actual_ federation version from the config we just resolved
// (this will always be `Some` as long as we have created with `resolve_supergraph_yaml` so it is safe to unwrap)
Expand Down Expand Up @@ -186,33 +200,60 @@ impl Compose {
&federation_version
);

let output = Command::new(&exe)
.args(["compose", yaml_path.as_ref()])
.output()
.context("Failed to execute command")?;
let stdout = str::from_utf8(&output.stdout)
.with_context(|| format!("Could not parse output of `{} compose`", &exe))?;

match serde_json::from_str::<BuildResult>(stdout) {
Ok(build_result) => match build_result {
Ok(build_output) => Ok(CompositionOutput {
hints: build_output.hints,
supergraph_sdl: build_output.supergraph_sdl,
federation_version: Some(federation_version.to_string()),
}),
Err(build_errors) => Err(RoverError::from(RoverClientError::BuildErrors {
source: build_errors,
num_subgraphs,
})),
},
Err(bad_json) => Err(anyhow!("{}", bad_json))
.with_context(|| anyhow!("{} compose output: {}", &exe, stdout))
.with_context(|| anyhow!("Output from `{} compose` was malformed.", &exe))
.map_err(|e| {
let mut error = RoverError::new(e);
error.set_suggestion(RoverErrorSuggestion::SubmitIssue);
error
}),
// Whether we use stdout or a file dependson whether the the `--output` option was used
let content = match output_file {
// If it was, we use a file in the supergraph binary; this cuts down the overall time
// it takes to do composition when we're working on really large compositions, but it
// carries with it the assumption that stdout is superfluous
Some(filepath) => {
Command::new(&exe)
.args(["compose", yaml_path.as_ref(), &filepath.to_string()])
.output()
.context("Failed to execute command")?;

let mut composition_file = std::fs::File::open(filepath.to_string()).unwrap();
let mut content: String = String::new();
composition_file.read_to_string(&mut content).unwrap();
content
}
// When we aren't using `--output`, we dump the composition directly to stdout
None => {
let output = Command::new(&exe)
.args(["compose", yaml_path.as_ref()])
.output()
.context("Failed to execute command")?;

let content = str::from_utf8(&output.stdout)
.with_context(|| format!("Could not parse output of `{} compose`", &exe))?;
content.to_string()
}
};

// Make sure the composition is well-formed
let composition = match serde_json::from_str::<BuildResult>(&content) {
Ok(res) => res,
Err(err) => {
return Err(anyhow!("{}", err))
.with_context(|| anyhow!("{} compose output: {}", &exe, content))
.with_context(|| anyhow!("Output from `{} compose` was malformed.", &exe))
.map_err(|e| {
let mut error = RoverError::new(e);
error.set_suggestion(RoverErrorSuggestion::SubmitIssue);
error
})
}
};

match composition {
Ok(build_output) => Ok(CompositionOutput {
hints: build_output.hints,
supergraph_sdl: build_output.supergraph_sdl,
federation_version: Some(federation_version.to_string()),
}),
Err(build_errors) => Err(RoverError::from(RoverClientError::BuildErrors {
source: build_errors,
num_subgraphs,
})),
}
}

Expand Down
7 changes: 6 additions & 1 deletion src/command/supergraph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,15 @@ impl Supergraph {
&self,
override_install_path: Option<Utf8PathBuf>,
client_config: StudioClientConfig,
output_file: Option<Utf8PathBuf>,
) -> RoverResult<RoverOutput> {
match &self.command {
Command::Fetch(command) => command.run(client_config).await,
Command::Compose(command) => command.run(override_install_path, client_config).await,
Command::Compose(command) => {
command
.run(override_install_path, client_config, output_file)
.await
}
}
}
}
2 changes: 1 addition & 1 deletion src/options/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ pub struct OutputOpts {

/// Specify a file to write Rover's output to
#[arg(long = "output", short = 'o', global = true, value_parser = Self::parse_absolute_path)]
output_file: Option<Utf8PathBuf>,
pub output_file: Option<Utf8PathBuf>,
}

impl OutputOpts {
Expand Down
3 changes: 2 additions & 1 deletion src/utils/supergraph_config.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use std::str::FromStr;

use anyhow::anyhow;
use apollo_federation_types::build::{BuildError, BuildErrors, SubgraphDefinition};
use apollo_federation_types::config::{
FederationVersion, SchemaSource, SubgraphConfig, SupergraphConfig,
};
use apollo_parser::{cst, Parser};
use futures::future::join_all;
use std::str::FromStr;

use rover_client::blocking::{GraphQLClient, StudioClient};
use rover_client::operations::subgraph;
Expand Down

0 comments on commit ab80131

Please sign in to comment.