Skip to content

Commit

Permalink
feat: support proto_paths for gen graphql through proto file
Browse files Browse the repository at this point in the history
  • Loading branch information
DLillard0 authored and tusharmath committed Dec 8, 2024
1 parent a261514 commit 6bcd740
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 18 deletions.
18 changes: 16 additions & 2 deletions src/cli/generator/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,13 @@ pub enum Source<Status = UnResolved> {
is_mutation: Option<bool>,
field_name: String,
},
#[serde(rename_all = "camelCase")]
Proto {
src: Location<Status>,
url: String,
#[serde(skip_serializing_if = "Option::is_none")]
proto_paths: Option<Vec<Location<Status>>>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "connectRPC")]
connect_rpc: Option<bool>,
},
Expand Down Expand Up @@ -220,9 +223,20 @@ impl Source<UnResolved> {
is_mutation,
})
}
Source::Proto { src, url, connect_rpc } => {
Source::Proto { src, url, proto_paths, connect_rpc } => {
let resolved_path = src.into_resolved(parent_dir);
Ok(Source::Proto { src: resolved_path, url, connect_rpc })
let resolved_proto_paths = proto_paths.map(|paths| {
paths
.into_iter()
.map(|path| path.into_resolved(parent_dir))
.collect()

Check warning on line 232 in src/cli/generator/config.rs

View check run for this annotation

Codecov / codecov/patch

src/cli/generator/config.rs#L229-L232

Added lines #L229 - L232 were not covered by tests
});
Ok(Source::Proto {
src: resolved_path,
url,
proto_paths: resolved_proto_paths,
connect_rpc,
})
}
Source::Config { src } => {
let resolved_path = src.into_resolved(parent_dir);
Expand Down
6 changes: 4 additions & 2 deletions src/cli/generator/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,11 @@ impl Generator {
headers: headers.into_btree_map(),
});
}
Source::Proto { src, url, connect_rpc } => {
Source::Proto { src, url, proto_paths, connect_rpc } => {
let path = src.0;
let mut metadata = proto_reader.read(&path).await?;
let proto_paths =
proto_paths.map(|paths| paths.into_iter().map(|l| l.0).collect::<Vec<_>>());
let mut metadata = proto_reader.read(&path, proto_paths.as_deref()).await?;
if let Some(relative_path_to_proto) = to_relative_path(output_dir, &path) {
metadata.path = relative_path_to_proto;
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/config/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl ConfigReader {
}
}
LinkType::Protobuf => {
let meta = self.proto_reader.read(path).await?;
let meta = self.proto_reader.read(path, None).await?;
extensions.add_proto(meta);
}
LinkType::Script => {
Expand Down
60 changes: 47 additions & 13 deletions src/core/proto_reader/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,28 @@ impl ProtoReader {

/// Asynchronously reads all proto files from a list of paths
pub async fn read_all<T: AsRef<str>>(&self, paths: &[T]) -> anyhow::Result<Vec<ProtoMetadata>> {
let resolved_protos = join_all(paths.iter().map(|v| self.read(v.as_ref())))
let resolved_protos = join_all(paths.iter().map(|v| self.read(v.as_ref(), None)))

Check warning on line 68 in src/core/proto_reader/reader.rs

View check run for this annotation

Codecov / codecov/patch

src/core/proto_reader/reader.rs#L68

Added line #L68 was not covered by tests
.await
.into_iter()
.collect::<anyhow::Result<Vec<_>>>()?;
Ok(resolved_protos)
}

/// Reads a proto file from a path
pub async fn read<T: AsRef<str>>(&self, path: T) -> anyhow::Result<ProtoMetadata> {
let file_read = self.read_proto(path.as_ref(), None).await?;
pub async fn read<T: AsRef<str>>(
&self,
path: T,
proto_paths: Option<&[String]>,
) -> anyhow::Result<ProtoMetadata> {
let file_read = self.read_proto(path.as_ref(), None, None).await?;
Self::check_package(&file_read)?;

let descriptors = self
.file_resolve(file_read, PathBuf::from(path.as_ref()).parent())
.file_resolve(
file_read,
PathBuf::from(path.as_ref()).parent(),
proto_paths,
)
.await?;
let metadata = ProtoMetadata {
descriptor_set: FileDescriptorSet { file: descriptors },
Expand Down Expand Up @@ -130,12 +138,22 @@ impl ProtoReader {
&self,
parent_proto: FileDescriptorProto,
parent_path: Option<&Path>,
proto_paths: Option<&[String]>,
) -> anyhow::Result<Vec<FileDescriptorProto>> {
self.resolve_dependencies(parent_proto, |import| {
let parent_path = parent_path.map(|p| p.to_path_buf());
let this = self.clone();

async move { this.read_proto(import, parent_path.as_deref()).await }.boxed()
let proto_paths = proto_paths.map(|paths| {
paths
.iter()
.map(|p| Path::new(p).to_path_buf())
.collect::<Vec<_>>()

Check warning on line 150 in src/core/proto_reader/reader.rs

View check run for this annotation

Codecov / codecov/patch

src/core/proto_reader/reader.rs#L147-L150

Added lines #L147 - L150 were not covered by tests
});
async move {
this.read_proto(import, parent_path.as_deref(), proto_paths.as_deref())
.await
}
.boxed()
})
.await
}
Expand All @@ -159,27 +177,39 @@ impl ProtoReader {
&self,
path: T,
parent_dir: Option<&Path>,
proto_paths: Option<&[PathBuf]>,
) -> anyhow::Result<FileDescriptorProto> {
let content = if let Ok(file) = GoogleFileResolver::new().open_file(path.as_ref()) {
file.source()
.context("Unable to extract content of google well-known proto file")?
.to_string()
} else {
let path = Self::resolve_path(path.as_ref(), parent_dir);
let path = Self::resolve_path(path.as_ref(), parent_dir, proto_paths);
self.reader.read_file(path).await?.content
};
Ok(protox_parse::parse(path.as_ref(), &content)?)
}
/// Checks if path is absolute else it joins file path with relative dir
/// path
fn resolve_path(src: &str, root_dir: Option<&Path>) -> String {
fn resolve_path(src: &str, root_dir: Option<&Path>, proto_paths: Option<&[PathBuf]>) -> String {
if src.starts_with("http") {
return src.to_string();
}

if Path::new(&src).is_absolute() {
src.to_string()
} else if let Some(path) = root_dir {
return src.to_string();
}

if let Some(proto_paths) = proto_paths {
for proto_path in proto_paths {
let path = proto_path.join(src);
if path.exists() {
return path.to_string_lossy().to_string();
}

Check warning on line 208 in src/core/proto_reader/reader.rs

View check run for this annotation

Codecov / codecov/patch

src/core/proto_reader/reader.rs#L204-L208

Added lines #L204 - L208 were not covered by tests
}
}

if let Some(path) = root_dir {
path.join(src).to_string_lossy().to_string()
} else {
src.to_string()
Expand Down Expand Up @@ -210,7 +240,7 @@ mod test_proto_config {
let runtime = crate::core::runtime::test::init(None);
let reader = ProtoReader::init(ResourceReader::<Cached>::cached(runtime.clone()), runtime);
reader
.read_proto("google/protobuf/empty.proto", None)
.read_proto("google/protobuf/empty.proto", None, None)
.await
.unwrap();
}
Expand All @@ -225,7 +255,11 @@ mod test_proto_config {

let reader = ProtoReader::init(ResourceReader::<Cached>::cached(runtime.clone()), runtime);
let file_descriptors = reader
.file_resolve(reader.read_proto(&test_file, None).await?, Some(test_dir))
.file_resolve(
reader.read_proto(&test_file, None, None).await?,
Some(test_dir),
None,
)
.await?;
for file in file_descriptors
.iter()
Expand All @@ -248,7 +282,7 @@ mod test_proto_config {
let reader = ProtoReader::init(ResourceReader::<Cached>::cached(runtime.clone()), runtime);
let proto_no_pkg =
PathBuf::from(tailcall_fixtures::configs::SELF).join("proto_no_pkg.graphql");
let config_module = reader.read(proto_no_pkg.to_str().unwrap()).await;
let config_module = reader.read(proto_no_pkg.to_str().unwrap(), None).await;
assert!(config_module.is_err());
Ok(())
}
Expand Down

0 comments on commit 6bcd740

Please sign in to comment.