1919DART_DEPS  =  os .path .realpath (os .path .join (DART_SCRIPT_DIR , '../../flutter/third_party/dart/DEPS' ))
2020FLUTTER_DEPS  =  os .path .realpath (os .path .join (DART_SCRIPT_DIR , '../../../../DEPS' ))
2121
22+ # Path to Dart SDK checkout within Flutter repo. 
23+ DART_SDK_ROOT  =  'engine/src/flutter/third_party/dart' 
24+ 
2225class  VarImpl (object ):
2326  def  __init__ (self , local_scope ):
2427    self ._local_scope  =  local_scope 
@@ -64,22 +67,122 @@ def ParseArgs(args):
6467      default = FLUTTER_DEPS )
6568  return  parser .parse_args (args )
6669
70+ def  PrettifySourcePathForDEPS (flutter_vars , dep_path , source ):
71+   """Prepare source for writing into Flutter DEPS file. 
72+ 
73+   If source is not a string then it is expected to be a dictionary defining 
74+   a CIPD dependency. In this case it is written as is - but sorted to 
75+   guarantee stability of the output. 
76+ 
77+   Otherwise source is a path to a repo plus version (hash or tag): 
78+ 
79+       {repo_host}/{repo_path}@{version} 
80+ 
81+   We want to convert this into one of the following: 
82+ 
83+       Var(repo_host_var) + 'repo_path' + '@' + Var(version_var) 
84+       Var(repo_host_var) + 'repo_path@version' 
85+       'source' 
86+ 
87+   Where repo_host_var is one of '*_git' variables and version_var is one 
88+   of 'dart_{dep_name}_tag' or 'dart_{dep_name}_rev' variables. 
89+   """ 
90+ 
91+   # If this a CIPD dependency then keep it as-is but sort its contents 
92+   # to ensure stable ordering. 
93+   if  not  isinstance (source , str ):
94+     return  dict (sorted (source .items ()))
95+ 
96+   # Decompose source into {repo_host}/{repo_path}@{version} 
97+   repo_host_var  =  None 
98+   version_var  =  None 
99+   repo_path_with_version  =  source 
100+   for  var_name , var_value  in  flutter_vars .items ():
101+     if  var_name .endswith ("_git" ) and  source .startswith (var_value ):
102+       repo_host_var  =  var_name 
103+       repo_path_with_version  =  source [len (var_value ):]
104+       break 
105+ 
106+   if  repo_path_with_version .find ('@' ) ==  - 1 :
107+     raise  ValueError (f'{ dep_path }  )
108+ 
109+   repo_path , version  =  repo_path_with_version .split ('@' , 1 )
110+ 
111+   # Figure out the name of the dependency from its path to compute 
112+   # corresponding version_var. 
113+   # 
114+   # Normally, the last component of the dep_path is the name of the dependency. 
115+   # However some dependencies are placed in a subdirectory named "src" 
116+   # within a directory named after the dependency. 
117+   dep_name  =  os .path .basename (dep_path )
118+   if  dep_name  ==  'src' :
119+     dep_name  =  os .path .basename (os .path .dirname (dep_path ))
120+   for  var_name  in  [f'dart_{ dep_name }  , f'dart_{ dep_name }  ]:
121+     if  var_name  in  flutter_vars :
122+       version_var  =  var_name 
123+       break 
124+ 
125+   # Format result from available individual pieces. 
126+   result  =  []
127+   if  repo_host_var  is  not None :
128+     result  +=  [f"Var('{ repo_host_var }  ]
129+   if  version_var  is  not None :
130+     result  +=  [f"'{ repo_path }  , "'@'" , f"Var('{ version_var }  ]
131+   else :
132+     result  +=  [f"'{ repo_path_with_version }  ]
133+   return  " + " .join (result )
134+ 
135+ def  ComputeDartDeps (flutter_vars , flutter_deps , dart_deps ):
136+   """Compute sources for deps nested under DART_SDK_ROOT in Flutter DEPS. 
137+ 
138+   These dependencies originate from Dart SDK, so their version are 
139+   computed by looking them up in Dart DEPS using appropriately 
140+   relocated paths, e.g. '{DART_SDK_ROOT}/third_party/foo' is located at 
141+   'sdk/third_party/foo' in Dart DEPS. 
142+ 
143+   Source paths are expressed in terms of 'xyz_git' and 'dart_xyz_tag' or 
144+   'dart_xyz_rev' variables if possible. 
145+ 
146+   If corresponding path is not found in Dart DEPS the dependency is considered 
147+   no longer needed and is removed from Flutter DEPS. 
148+ 
149+   Returns: dictionary of dependencies 
150+   """ 
151+   new_dart_deps  =  {}
152+ 
153+   # Trailing / to avoid matching Dart SDK dependency itself. 
154+   dart_sdk_root_dir  =  DART_SDK_ROOT  +  '/' 
155+ 
156+   # Find all dependencies which are nested inside Dart SDK and check 
157+   # if Dart SDK still needs them. If Dart DEPS still mentions them 
158+   # take updated version from Dart DEPS. 
159+   for  (dep_path , dep_source ) in  sorted (flutter_deps .items ()):
160+     if  dep_path .startswith (dart_sdk_root_dir ):
161+       # Dart dependencies are given relative to root directory called `sdk/`. 
162+       dart_dep_path  =  f'sdk/{ dep_path [len (dart_sdk_root_dir ):]}  
163+       if  dart_dep_path  in  dart_deps :
164+         # Still used, add it to the result. 
165+         new_dart_deps [dep_path ] =  PrettifySourcePathForDEPS (flutter_vars , dep_path , dart_deps [dart_dep_path ])
166+ 
167+   return  new_dart_deps 
168+ 
67169def  Main (argv ):
68170  args  =  ParseArgs (argv )
69171  if  args .dart_deps  ==  DART_DEPS  and  not  os .path .isfile (DART_DEPS ):
70172    args .dart_deps  =  OLD_DART_DEPS 
71-   (new_vars ,  new_deps ) =  ParseDepsFile (args .dart_deps )
72-   (old_vars ,  old_deps ) =  ParseDepsFile (args .flutter_deps )
173+   (dart_vars ,  dart_deps ) =  ParseDepsFile (args .dart_deps )
174+   (flutter_vars ,  flutter_deps ) =  ParseDepsFile (args .flutter_deps )
73175
74176  updated_vars  =  {}
75177
76178  # Collect updated dependencies 
77-   for  (k ,v ) in  sorted (old_vars .items ()):
179+   for  (k ,v ) in  sorted (flutter_vars .items ()):
78180    if  k  not  in 'dart_revision' , 'dart_git' ) and  k .startswith ('dart_' ):
79181      dart_key  =  k [len ('dart_' ):]
80-       if  dart_key  in  new_vars :
81-         updated_revision  =  new_vars [dart_key ].lstrip ('@' ) if  dart_key  in  new_vars  else  v 
82-         updated_vars [k ] =  updated_revision 
182+       if  dart_key  in  dart_vars :
183+         updated_vars [k ] =  dart_vars [dart_key ].lstrip ('@' )
184+ 
185+   new_dart_deps  =  ComputeDartDeps (flutter_vars , flutter_deps , dart_deps )
83186
84187  # Write updated DEPS file to a side 
85188  updatedfilename  =  args .flutter_deps  +  ".new" 
@@ -104,40 +207,12 @@ def Main(argv):
104207    elif  lines [i ].startswith ("  # WARNING: Unused Dart dependencies" ):
105208      updatedfile .write ('\n ' )
106209      i  =  i  +  1 
107-       while  i  <  len (lines ) and  ( lines [i ].startswith ("  # WARNING: end of dart dependencies" )  ==   0 ):
210+       while  i  <  len (lines ) and  not   lines [i ].startswith ("  # WARNING: end of dart dependencies" ):
108211        i  =  i  +  1 
109-       for  (k , v ) in  sorted (old_deps .items ()):
110-         if  (k .startswith ('engine/src/flutter/third_party/dart/' )):
111-           for  (dart_k , dart_v ) in  (list (new_deps .items ())):
112-             dart_k_suffix  =  dart_k [len ('sdk/' ) if  dart_k .startswith ('sdk/' ) else  0 :]
113-             if  (k .endswith (dart_k_suffix )):
114-               if  (isinstance (dart_v , str )):
115-                 updated_value  =  dart_v .replace (new_vars ["dart_git" ], "Var('dart_git') + '/" )
116-                 updated_value  =  updated_value .replace (new_vars ["chromium_git" ], "Var('chromium_git') + '" )
117-                 updated_value  =  updated_value .replace (new_vars ["android_git" ], "Var('android_git') + '" )
118- 
119-                 plain_v  =  os .path .basename (dart_k )
120-                 # Some dependencies are placed in a subdirectory named "src" 
121-                 # within a directory named for the package. 
122-                 if  plain_v  ==  'src' :
123-                   plain_v  =  os .path .basename (os .path .dirname (dart_k ))
124-                 # This dependency has to be special-cased here because the 
125-                 # repository name is not the same as the directory name. 
126-                 if  plain_v  ==  "quiver" :
127-                   plain_v  =  "quiver-dart" 
128-                 if  ('dart_'  +  plain_v  +  '_tag'  in  updated_vars ):
129-                   updated_value  =  updated_value [:updated_value .rfind ('@' )] +  "' + '@' + Var('dart_"  +  plain_v  +  "_tag')" 
130-                 elif  ('dart_'  +  plain_v  +  '_rev'  in  updated_vars ):
131-                   updated_value  =  updated_value [:updated_value .rfind ('@' )] +  "' + '@' + Var('dart_"  +  plain_v  +  "_rev')" 
132-                 else :
133-                   updated_value  =  updated_value  +  "'" 
134-               else :
135-                 # Non-string values(dicts) copy verbatim, keeping them sorted 
136-                 # to ensure stable ordering of items. 
137-                 updated_value  =  dict (sorted (dart_v .items ()))
138- 
139-               updatedfile .write ("  '%s':\n    %s,\n \n "  %  (k , updated_value ))
140-               break 
212+ 
213+       for  dep_path , dep_source  in  new_dart_deps .items ():
214+         updatedfile .write (f"  '{ dep_path } \n    { dep_source } \n \n " )
215+ 
141216      updatedfile .write (lines [i ])
142217    i  =  i  +  1 
143218
0 commit comments