@@ -4,16 +4,18 @@ use std::sync::Arc;
44
55use eden_dag:: errors:: BackendError ;
66use eden_dag:: DagAlgorithm ;
7+ use eyre:: Context as EyreContext ;
78use itertools:: Itertools ;
89use lib:: core:: effects:: { Effects , OperationType } ;
910use once_cell:: unsync:: OnceCell ;
1011use thiserror:: Error ;
1112
1213use lib:: core:: dag:: { CommitSet , Dag } ;
13- use lib:: git:: { Repo , ResolvedReferenceInfo } ;
14+ use lib:: git:: { ConfigRead , Repo , ResolvedReferenceInfo } ;
1415use tracing:: instrument;
1516
1617use super :: builtins:: FUNCTIONS ;
18+ use super :: parser:: parse;
1719use super :: pattern:: { Pattern , PatternError } ;
1820use super :: Expr ;
1921
@@ -204,14 +206,33 @@ pub(super) fn eval_name(ctx: &mut Context, name: &str) -> EvalResult {
204206}
205207
206208pub ( super ) fn eval_fn ( ctx : & mut Context , name : & str , args : & [ Expr ] ) -> EvalResult {
207- let function = FUNCTIONS
208- . get ( name)
209- . ok_or_else ( || EvalError :: UnboundFunction {
210- name : name. to_owned ( ) ,
211- available_names : FUNCTIONS . keys ( ) . sorted ( ) . copied ( ) . collect ( ) ,
212- } ) ?;
213-
214- function ( ctx, name, args)
209+ if let Some ( function) = FUNCTIONS . get ( name) {
210+ return function ( ctx, name, args) ;
211+ }
212+
213+ let alias_key = format ! ( "git-branchless.revsets.alias.{}" , name) ;
214+ let alias_template = ctx
215+ . repo
216+ . get_readonly_config ( )
217+ . map_err ( EvalError :: OtherError ) ?
218+ . get :: < String , String > ( alias_key)
219+ . map_err ( EvalError :: OtherError ) ?;
220+ if let Some ( mut alias_template) = alias_template {
221+ for ( i, arg) in args. iter ( ) . enumerate ( ) {
222+ alias_template =
223+ alias_template. replace ( format ! ( "${}" , i + 1 ) . as_str ( ) , format ! ( "{}" , arg) . as_str ( ) ) ;
224+ }
225+ let expr = parse ( & alias_template)
226+ . wrap_err ( "Parsing alias expression" )
227+ . map_err ( EvalError :: OtherError ) ?;
228+ let commits = eval_inner ( ctx, & expr) ;
229+ return commits;
230+ }
231+
232+ Err ( EvalError :: UnboundFunction {
233+ name : name. to_owned ( ) ,
234+ available_names : FUNCTIONS . keys ( ) . sorted ( ) . copied ( ) . collect ( ) ,
235+ } )
215236}
216237
217238#[ instrument]
@@ -935,4 +956,78 @@ mod tests {
935956
936957 Ok ( ( ) )
937958 }
959+
960+ #[ test]
961+ fn test_eval_aliases ( ) -> eyre:: Result < ( ) > {
962+ let git = make_git ( ) ?;
963+ git. init_repo ( ) ?;
964+
965+ git. detach_head ( ) ?;
966+ let test1_oid = git. commit_file ( "test1" , 1 ) ?;
967+ let _test2_oid = git. commit_file ( "test2" , 2 ) ?;
968+ let _test3_oid = git. commit_file ( "test3" , 3 ) ?;
969+
970+ git. run ( & [ "config" , "git-branchless.revsets.alias.oldest" , "roots($1)" ] ) ?;
971+
972+ git. run ( & [
973+ "config" ,
974+ "git-branchless.revsets.alias.grandChildren" ,
975+ "children(children($1))" ,
976+ ] ) ?;
977+
978+ let effects = Effects :: new_suppress_for_test ( Glyphs :: text ( ) ) ;
979+ let repo = git. get_repo ( ) ?;
980+ let conn = repo. get_db_conn ( ) ?;
981+ let event_log_db = EventLogDb :: new ( & conn) ?;
982+ let event_replayer = EventReplayer :: from_event_log_db ( & effects, & repo, & event_log_db) ?;
983+ let event_cursor = event_replayer. make_default_cursor ( ) ;
984+ let references_snapshot = repo. get_references_snapshot ( ) ?;
985+ let mut dag = Dag :: open_and_sync (
986+ & effects,
987+ & repo,
988+ & event_replayer,
989+ event_cursor,
990+ & references_snapshot,
991+ ) ?;
992+
993+ {
994+ let expr = Expr :: FunctionCall (
995+ Cow :: Borrowed ( "oldest" ) ,
996+ vec ! [ Expr :: FunctionCall ( Cow :: Borrowed ( "stack" ) , vec![ ] ) ] ,
997+ ) ;
998+ insta:: assert_debug_snapshot!( eval_and_sort( & effects, & repo, & mut dag, & expr) , @r###"
999+ Ok(
1000+ [
1001+ Commit {
1002+ inner: Commit {
1003+ id: 62fc20d2a290daea0d52bdc2ed2ad4be6491010e,
1004+ summary: "create test1.txt",
1005+ },
1006+ },
1007+ ],
1008+ )
1009+ "### ) ;
1010+ }
1011+
1012+ {
1013+ let expr = Expr :: FunctionCall (
1014+ Cow :: Borrowed ( "grandChildren" ) ,
1015+ vec ! [ Expr :: Name ( Cow :: Owned ( test1_oid. to_string( ) ) ) ] ,
1016+ ) ;
1017+ insta:: assert_debug_snapshot!( eval_and_sort( & effects, & repo, & mut dag, & expr) , @r###"
1018+ Ok(
1019+ [
1020+ Commit {
1021+ inner: Commit {
1022+ id: 70deb1e28791d8e7dd5a1f0c871a51b91282562f,
1023+ summary: "create test3.txt",
1024+ },
1025+ },
1026+ ],
1027+ )
1028+ "### ) ;
1029+ }
1030+
1031+ Ok ( ( ) )
1032+ }
9381033}
0 commit comments