2424from sqlmesh .dbt .test import TestConfig
2525from sqlmesh .dbt .util import DBT_VERSION
2626from sqlmesh .utils .errors import ConfigError
27- from sqlmesh .utils .jinja import MacroInfo , MacroReference , extract_macro_references
27+ from sqlmesh .utils .jinja import MacroInfo , MacroReference , extract_call_names , nodes
2828
2929if t .TYPE_CHECKING :
3030 from dbt .contracts .graph .manifest import Macro , Manifest
@@ -96,10 +96,10 @@ def all_macros(self) -> t.Dict[str, t.Dict[str, MacroInfo]]:
9696 def _load_all (self ) -> None :
9797 if self ._is_loaded :
9898 return
99+ self ._load_macros ()
100+ self ._load_sources ()
99101 self ._load_tests ()
100102 self ._load_models_and_seeds ()
101- self ._load_sources ()
102- self ._load_macros ()
103103 self ._is_loaded = True
104104
105105 def _load_sources (self ) -> None :
@@ -121,15 +121,16 @@ def _load_macros(self) -> None:
121121 if macro .name .startswith ("test_" ):
122122 macro .macro_sql = _convert_jinja_test_to_macro (macro .macro_sql )
123123
124- macro_references = _macro_references (self ._manifest , macro )
124+ dependencies = Dependencies ( macros = _macro_references (self ._manifest , macro ) )
125125 if not macro .name .startswith ("materialization_" ) and not macro .name .startswith ("test_" ):
126- macro_references |= _extra_macro_references ( macro .macro_sql )
126+ dependencies = dependencies . union ( _extra_dependencies ( macro .macro_sql ) )
127127
128128 self ._macros_per_package [macro .package_name ][macro .name ] = MacroConfig (
129129 info = MacroInfo (
130130 definition = macro .macro_sql ,
131- depends_on = list ( macro_references ) ,
131+ depends_on = dependencies . macros ,
132132 ),
133+ dependencies = dependencies ,
133134 path = Path (macro .original_file_path ),
134135 )
135136
@@ -167,10 +168,16 @@ def _load_tests(self) -> None:
167168 dependencies .macros .append (MacroReference (package = "dbt" , name = "get_where_subquery" ))
168169 dependencies .macros .append (MacroReference (package = "dbt" , name = "should_store_failures" ))
169170
171+ sql = node .raw_code if DBT_VERSION >= (1 , 3 ) else node .raw_sql # type: ignore
172+ dependencies = dependencies .union (_extra_dependencies (sql ))
173+ dependencies = dependencies .union (
174+ self ._macro_source_ref_dependencies (dependencies .macros , package_name )
175+ )
176+
170177 test_model = _test_model (node )
171178
172179 test = TestConfig (
173- sql = node . raw_code if DBT_VERSION >= ( 1 , 3 ) else node . raw_sql , # type: ignore
180+ sql = sql ,
174181 model_name = test_model ,
175182 test_kwargs = node .test_metadata .kwargs if hasattr (node , "test_metadata" ) else {},
176183 dependencies = dependencies ,
@@ -193,14 +200,17 @@ def _load_models_and_seeds(self) -> None:
193200
194201 if node .resource_type == "model" :
195202 sql = node .raw_code if DBT_VERSION >= (1 , 3 ) else node .raw_sql # type: ignore
196- macro_references |= _extra_macro_references (sql )
203+ dependencies = Dependencies (
204+ macros = macro_references , refs = _refs (node ), sources = _sources (node )
205+ )
206+ dependencies = dependencies .union (_extra_dependencies (sql ))
207+ dependencies = dependencies .union (
208+ self ._macro_source_ref_dependencies (dependencies .macros , node .package_name )
209+ )
210+
197211 self ._models_per_package [node .package_name ][node .name ] = ModelConfig (
198212 sql = sql ,
199- dependencies = Dependencies (
200- macros = macro_references ,
201- refs = _refs (node ),
202- sources = _sources (node ),
203- ),
213+ dependencies = dependencies ,
204214 tests = tests ,
205215 ** _node_base_config (node ),
206216 )
@@ -260,6 +270,19 @@ def _load_profile(self) -> Profile:
260270 target_override = self .target .name ,
261271 )
262272
273+ def _macro_source_ref_dependencies (
274+ self , macros : t .List [MacroReference ], default_package : str
275+ ) -> Dependencies :
276+ dependencies = Dependencies ()
277+ for macro in macros :
278+ macro_config = self ._macros_per_package [macro .package or default_package ].get (
279+ macro .name
280+ )
281+ if macro_config :
282+ dependencies = dependencies .union (macro_config .dependencies )
283+ dependencies .macros = []
284+ return dependencies
285+
263286
264287def _config (node : t .Union [ManifestNode , SourceDefinition ]) -> t .Dict [str , t .Any ]:
265288 return node .config .to_dict ()
@@ -330,8 +353,29 @@ def _convert_jinja_test_to_macro(test_jinja: str) -> str:
330353 return re .sub (ENDTEST_REGEX , "{% endmacro %}" , macro )
331354
332355
333- def _extra_macro_references (target : str ) -> t . Set [ MacroReference ] :
356+ def _extra_dependencies (target : str ) -> Dependencies :
334357 # We sometimes observe that the manifest doesn't capture certain macros referenced in the model.
335358 # This behavior has been observed with macros like dbt.current_timestamp() and dbt_utils.slugify().
336359 # Here we apply our custom extractor in addition to referenced extracted from the manifest to mitigate this.
337- return {r for r in extract_macro_references (target ) if r .package in ("dbt" , "dbt_utils" )}
360+ dependencies = Dependencies ()
361+ for call_name , node in extract_call_names (target ):
362+ if len (call_name ) == 2 and call_name [0 ] in ("dbt" , "dbt_utils" ):
363+ dependencies .macros .append (MacroReference (package = call_name [0 ], name = call_name [1 ]))
364+ elif call_name [0 ] == "source" :
365+ source = "." .join (_jinja_call_arg_name (arg ) for arg in node .args )
366+ if source :
367+ dependencies .sources .append (source )
368+ elif call_name [0 ] == "ref" :
369+ ref = "." .join (_jinja_call_arg_name (arg ) for arg in node .args )
370+ if ref :
371+ dependencies .refs .append (ref )
372+
373+ return dependencies
374+
375+
376+ def _jinja_call_arg_name (node : nodes .Node ) -> str :
377+ if isinstance (node , nodes .Name ):
378+ return node .name
379+ if isinstance (node , nodes .Const ):
380+ return node .value
381+ return ""
0 commit comments