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 } source is unversioned' )
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 } _tag' , f'dart_{ dep_name } _rev' ]:
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