From c40f80818deb5c8091adc452e14399ace20b65dd Mon Sep 17 00:00:00 2001 From: Christian Schilling Date: Mon, 29 May 2023 13:01:20 +0200 Subject: [PATCH] Fix handlebars templates reporting missing objects The handlebars code was not yet converted to using alternate object stores. We did not notice this issue at first, because templateing is only tested with the cli and the cli does not use alternates. Change: fix-handlebars --- josh-core/src/cache.rs | 3 ++ josh-core/src/query.rs | 53 +++++++++++++++++++++++++++--- josh-filter/src/bin/josh-filter.rs | 2 +- josh-proxy/src/bin/josh-proxy.rs | 2 +- tests/proxy/query.t | 11 +++++++ 5 files changed, 64 insertions(+), 7 deletions(-) diff --git a/josh-core/src/cache.rs b/josh-core/src/cache.rs index 91d222472..0af7b9d07 100644 --- a/josh-core/src/cache.rs +++ b/josh-core/src/cache.rs @@ -73,6 +73,9 @@ pub struct Transaction { impl Transaction { pub fn open(path: &std::path::Path, ref_prefix: Option<&str>) -> JoshResult { + if !path.exists() { + return Err(josh_error("path does not exist")); + } Ok(Transaction::new( git2::Repository::open_ext( path, diff --git a/josh-core/src/query.rs b/josh-core/src/query.rs index 591f3316e..d226ad0c1 100644 --- a/josh-core/src/query.rs +++ b/josh-core/src/query.rs @@ -23,7 +23,20 @@ impl GraphQLHelper { .join(path); let path = normalize_path(&path); - let transaction = cache::Transaction::open(&self.repo_path, Some(&self.ref_prefix))?; + let transaction = if let Ok(to) = + cache::Transaction::open(&self.repo_path.join("mirror"), Some(&self.ref_prefix)) + { + to.repo().odb()?.add_disk_alternate( + self.repo_path + .join("overlay") + .join("objects") + .to_str() + .unwrap(), + )?; + to + } else { + cache::Transaction::open(&self.repo_path, Some(&self.ref_prefix))? + }; let tree = transaction.repo().find_commit(self.commit_id)?.tree()?; @@ -41,8 +54,26 @@ impl GraphQLHelper { variables.insert(k.to_string(), juniper::InputValue::scalar(v.render())); } - let transaction = cache::Transaction::open(&self.repo_path, None)?; - let transaction_overlay = cache::Transaction::open(&self.repo_path, None)?; + let (transaction, transaction_overlay) = + if let Ok(to) = cache::Transaction::open(&self.repo_path.join("overlay"), None) { + to.repo().odb()?.add_disk_alternate( + self.repo_path + .join("mirror") + .join("objects") + .to_str() + .unwrap(), + )?; + ( + cache::Transaction::open(&self.repo_path.join("mirror"), None)?, + to, + ) + } else { + ( + cache::Transaction::open(&self.repo_path, None)?, + cache::Transaction::open(&self.repo_path, None)?, + ) + }; + let (res, _errors) = juniper::execute_sync( &query, None, @@ -77,7 +108,7 @@ impl handlebars::HelperDef for GraphQLHelper { h.hash(), rc.get_current_template_name().unwrap_or(&"/".to_owned()), ) - .map_err(|_| handlebars::RenderError::new("josh"))?, + .map_err(|e| handlebars::RenderError::new(format!("{}", e)))?, )); } } @@ -91,6 +122,7 @@ pub fn render( ref_prefix: &str, commit_id: git2::Oid, query_and_params: &str, + split_odb: bool, ) -> JoshResult> { let mut parameters = query_and_params.split('&'); let query = parameters @@ -162,13 +194,24 @@ pub fn render( drop(obj); drop(tree); + let repo_path = if split_odb { + transaction + .repo() + .path() + .parent() + .ok_or(josh_error("parent"))? + .to_owned() + } else { + transaction.repo().path().to_owned() + }; + let mut handlebars = handlebars::Handlebars::new(); handlebars.register_template_string(path, template)?; handlebars.register_helper("concat", Box::new(helpers::concat_helper)); handlebars.register_helper( "graphql", Box::new(GraphQLHelper { - repo_path: transaction.repo().path().to_owned(), + repo_path: repo_path, ref_prefix: ref_prefix.to_owned(), commit_id, }), diff --git a/josh-filter/src/bin/josh-filter.rs b/josh-filter/src/bin/josh-filter.rs index 730622d1b..9a7ca62f8 100644 --- a/josh-filter/src/bin/josh-filter.rs +++ b/josh-filter/src/bin/josh-filter.rs @@ -424,7 +424,7 @@ fn run_filter(args: Vec) -> josh::JoshResult { let commit_id = transaction.repo().refname_to_id(update_target)?; print!( "{}", - josh::query::render(&transaction, "", commit_id, query,)? + josh::query::render(&transaction, "", commit_id, query, false)? .unwrap_or("File not found".to_string()) ); } diff --git a/josh-proxy/src/bin/josh-proxy.rs b/josh-proxy/src/bin/josh-proxy.rs index 307c15317..e0f22ce48 100644 --- a/josh-proxy/src/bin/josh-proxy.rs +++ b/josh-proxy/src/bin/josh-proxy.rs @@ -1358,7 +1358,7 @@ async fn serve_query( let commit_id = josh::filter_commit(&transaction, filter, commit_id, josh::filter::empty())?; - josh::query::render(&transaction, "", commit_id, &q) + josh::query::render(&transaction, "", commit_id, &q, true) }) .in_current_span() .await?; diff --git a/tests/proxy/query.t b/tests/proxy/query.t index 0c399a5a5..50b6dc654 100644 --- a/tests/proxy/query.t +++ b/tests/proxy/query.t @@ -16,10 +16,20 @@ $ git add sub2 $ git commit -m "add file2" 1> /dev/null + $ cat > x.graphql < query { + > hash + > } + > EOF + $ cat > tmpl_file < param: {{ param_val }} + > {{ #with (graphql file="x.graphql") as |gql| }} + > sha: {{ gql.hash }} + > {{ /with }} > EOF + $ git add x.graphql $ git add tmpl_file $ git commit -m "add tmpl_file" 1> /dev/null @@ -47,6 +57,7 @@ JoshError(Error rendering "tmpl_file" line 1, col 8: Variable "param_val" not found in strict mode.) (no-eol) $ curl -s http://localhost:8002/real_repo.git?render=tmpl_file\¶m_val=12345 param: 12345 + sha: 002d20d28aab1ebe3892b01ec1dfc60d43fc598f $ curl -s http://localhost:8002/real_repo.git?get=sub1/file1 contents1 $ curl -s http://localhost:8002/real_repo.git@refs/changes/123/2:nop.git?get=sub2/on_change