@ -241,7 +241,7 @@ class DependencySettings(object):
""" Immutable configuration settings. """
def __init__ (
self , parent , raw_url , url , managed , custom_deps , custom_vars ,
custom_hooks , deps_file , relative, condition ) :
custom_hooks , deps_file , should_process, relative, condition ) :
# These are not mutable:
self . _parent = parent
self . _deps_file = deps_file
@ -250,9 +250,13 @@ class DependencySettings(object):
# The condition as string (or None). Useful to keep e.g. for flatten.
self . _condition = condition
# 'managed' determines whether or not this dependency is synced/updated by
# gclient after gclient checks it out initially. The user specifies
# 'managed' via the --unmanaged command-line flag or a .gclient config.
# gclient after gclient checks it out initially. The difference between
# 'managed' and 'should_process' is that the user specifies 'managed' via
# the --unmanaged command-line flag or a .gclient config, where
# 'should_process' is dynamically set by gclient if it goes over its
# recursion limit and controls gclient's behavior so it does not misbehave.
self . _managed = managed
self . _should_process = should_process
# If this is a recursed-upon sub-dependency, and the parent has
# use_relative_paths set, then this dependency should check out its own
# dependencies relative to that parent's path for this, rather than
@ -267,10 +271,15 @@ class DependencySettings(object):
self . _custom_deps = custom_deps or { }
self . _custom_hooks = custom_hooks or [ ]
assert self . url is not None , ( self . name , self . url )
# urls are sometime incorrectly written as proto://host/path/@rev. Replace
# it to proto://host/path@rev.
self . set_url ( self . url . replace ( ' /@ ' , ' @ ' ) )
# Post process the url to remove trailing slashes.
if isinstance ( self . url , basestring ) :
# urls are sometime incorrectly written as proto://host/path/@rev. Replace
# it to proto://host/path@rev.
self . set_url ( self . url . replace ( ' /@ ' , ' @ ' ) )
elif not isinstance ( self . url , ( None . __class__ ) ) :
raise gclient_utils . Error (
( ' dependency url must be either string or None, '
' instead of %s ' ) % self . url . __class__ . __name__ )
# Make any deps_file path platform-appropriate.
if self . _deps_file :
@ -297,6 +306,11 @@ class DependencySettings(object):
return self or GClient ( None , None )
return self . parent . root
@property
def should_process ( self ) :
""" True if this dependency should be processed, i.e. checked out. """
return self . _should_process
@property
def custom_vars ( self ) :
return self . _custom_vars . copy ( )
@ -352,12 +366,12 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
""" Object that represents a dependency checkout. """
def __init__ ( self , parent , name , raw_url , url , managed , custom_deps ,
custom_vars , custom_hooks , deps_file , relative, condition ,
print_outbuf= False ) :
custom_vars , custom_hooks , deps_file , should_process ,
relative, condition , print_outbuf= False ) :
gclient_utils . WorkItem . __init__ ( self , name )
DependencySettings . __init__ (
self , parent , raw_url , url , managed , custom_deps , custom_vars ,
custom_hooks , deps_file , relative, condition )
custom_hooks , deps_file , should_process, relative, condition )
# This is in both .gclient and DEPS files:
self . _deps_hooks = [ ]
@ -409,10 +423,12 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
# None.
self . recursedeps = None
self . _OverrideUrl ( )
# This is inherited from WorkItem. We want the URL to be a resource.
# The url is usually given to gclient either as https://blah@123
# or just https://blah. The @123 portion is irrelevant.
self . resources . append ( self . url . split ( ' @ ' ) [ 0 ] )
if self . url and isinstance ( self . url , basestring ) :
# The url is usually given to gclient either as https://blah@123
# or just https://blah. The @123 portion is irrelevant.
self . resources . append ( self . url . split ( ' @ ' ) [ 0 ] )
# Controls whether we want to print git's output when we first clone the
# dependency
@ -421,8 +437,40 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
if not self . name and self . parent :
raise gclient_utils . Error ( ' Dependency without name ' )
def _OverrideUrl ( self ) :
""" Resolves the parsed url from the parent hierarchy. """
parsed_url = self . get_custom_deps ( self . _name , self . url )
if parsed_url != self . url :
logging . info ( ' Dependency( %s )._OverrideUrl( %s ) -> %s ' , self . _name ,
self . url , parsed_url )
self . set_url ( parsed_url )
elif isinstance ( self . url , basestring ) :
parsed_url = urlparse . urlparse ( self . url )
if ( not parsed_url [ 0 ] and
not re . match ( r ' ^ \ w+ \ @[ \ w \ .-]+ \ :[ \ w \ /]+ ' , parsed_url [ 2 ] ) ) :
path = parsed_url [ 2 ]
if not path . startswith ( ' / ' ) :
raise gclient_utils . Error (
' relative DEPS entry \' %s \' must begin with a slash ' % self . url )
# A relative url. Get the parent url, strip from the last '/'
# (equivalent to unix basename), and append the relative url.
parent_url = self . parent . url
parsed_url = parent_url [ : parent_url . rfind ( ' / ' ) ] + self . url
logging . info ( ' Dependency( %s )._OverrideUrl( %s ) -> %s ' , self . name ,
self . url , parsed_url )
self . set_url ( parsed_url )
elif self . url is None :
logging . info ( ' Dependency( %s )._OverrideUrl(None) -> None ' , self . _name )
else :
raise gclient_utils . Error ( ' Unknown url type ' )
def PinToActualRevision ( self ) :
""" Updates self.url and self.raw_url to the revision checked out on disk. """
if self . url is None :
return
url = raw_url = None
scm = self . CreateSCM ( )
if os . path . isdir ( scm . checkout_path ) :
@ -438,7 +486,7 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
condition_part = ( [ ' " condition " : %r , ' % self . condition ]
if self . condition else [ ] )
s . extend ( [
' # %s ' % self . hierarchy ( ) ,
' # %s ' % self . hierarchy ( include_url = False ) ,
' " %s " : { ' % ( self . name , ) ,
' " url " : " %s " , ' % ( self . raw_url , ) ,
] + condition_part + [
@ -472,7 +520,7 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
if self . name :
requirements | = set (
obj . name for obj in self . root . subtree ( )
obj . name for obj in self . root . subtree ( False )
if ( obj is not self
and obj . name and
self . name . startswith ( posixpath . join ( obj . name , ' ' ) ) ) )
@ -511,11 +559,15 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
raise gclient_utils . Error (
' The same name " %s " appears multiple times in the deps section ' %
self . name )
if not self . should_process :
# Return early, no need to set requirements.
return True
# This require a full tree traversal with locks.
siblings = [ d for d in self . root . subtree ( ) if d . name == self . name ]
siblings = [ d for d in self . root . subtree ( False ) if d . name == self . name ]
for sibling in siblings :
if self . url != sibling . url :
# Allow to have only one to be None or ''.
if self . url != sibling . url and bool ( self . url ) == bool ( sibling . url ) :
raise gclient_utils . Error (
( ' Dependency %s specified more than once: \n '
' %s [ %s ] \n '
@ -565,30 +617,11 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
return deps
def FormatUrl ( self , name , url ) :
custom_deps_url = self . get_custom_deps ( name , url )
if url != custom_deps_url :
return custom_deps_url
if url is None :
return None
if not isinstance ( url , basestring ) :
raise gclient_utils . Error (
( ' dependency url must be either string or None, '
' instead of %s ' ) % self . url . __class__ . __name__ )
url = url . format ( * * self . get_vars ( ) )
# For relative URLs, strip the parent url (self.url) from the last '/'
# and append the relative url.
if url [ 0 ] == ' / ' :
url = self . url [ : self . url . rfind ( ' / ' ) ] + url
return url
def _deps_to_objects ( self , deps , use_relative_paths ) :
""" Convert a deps dict to a dict of Dependency objects. """
if not self . recursion_limit :
return [ ]
deps_to_add = [ ]
for name , dep_value in deps . iteritems ( ) :
should_process = self . recursion_limit and self . should_process
deps_file = self . deps_file
if self . recursedeps is not None :
ent = self . recursedeps . get ( name )
@ -598,32 +631,31 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
continue
condition = dep_value . get ( ' condition ' )
dep_type = dep_value . get ( ' dep_type ' , ' git ' )
dep_type = dep_value . get ( ' dep_type ' )
should_process = True
if condition and not self . get_option ( ' process_all_deps ' , False ) :
should_process = gclient_eval . EvaluateCondition (
if condition and not self . _get_option ( ' process_all_deps ' , False ) :
should_process = should_process and gclient_eval . EvaluateCondition (
condition , self . get_vars ( ) )
if not should_process :
continue
if dep_type == ' cipd ' :
cipd_root = self . GetCipdRoot ( )
for package in dep_value . get ( ' packages ' , [ ] ) :
package [ ' version ' ] = package [ ' version ' ] . format ( * * self . get_vars ( ) )
if ' version ' in package :
# Matches version to vars value.
raw_version = package [ ' version ' ]
version = raw_version . format ( * * self . get_vars ( ) )
package [ ' version ' ] = version
deps_to_add . append (
CipdDependency (
self , name , package , cipd_root , self . custom_vars ,
use_relative_paths , condition ) )
should_process, use_relative_paths, condition ) )
else :
raw_url = dep_value . get ( ' url ' )
url = self . FormatUrl ( name , raw_url )
if url :
deps_to_add . append (
GitDependency (
self , name , raw_url , url , None , None , self . custom_vars , None ,
deps_file , use_relative_paths , condition ) )
url = raw_url . format ( * * self . get_vars ( ) ) if raw_url else None
deps_to_add . append (
GitDependency (
self , name , raw_url , url , None , None , self . custom_vars , None ,
deps_file , should_process , use_relative_paths , condition ) )
deps_to_add . sort ( key = lambda x : x . name )
return deps_to_add
@ -660,7 +692,7 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
try :
local_scope = gclient_eval . Parse (
deps_content , expand_vars ,
self . get_option( ' validate_syntax ' , False ) ,
self . _ get_option( ' validate_syntax ' , False ) ,
filepath , self . get_vars ( ) )
except SyntaxError as e :
gclient_utils . SyntaxErrorToError ( filepath , e )
@ -766,8 +798,11 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
self . add_dependencies_and_close ( deps_to_add , hooks_to_run )
logging . info ( ' ParseDepsFile( %s ) done ' % self . name )
def get_option ( self , attr , default = None ) :
return getattr ( self . root . _options , attr , default )
def _get_option ( self , attr , default ) :
obj = self
while not hasattr ( obj , ' _options ' ) :
obj = obj . parent
return getattr ( obj . _options , attr , default )
def add_dependencies_and_close ( self , deps_to_add , hooks ) :
""" Adds the dependencies, hooks and mark the parsing as done. """
@ -793,9 +828,10 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
# Don't enforce this for custom_deps.
if dep . name in self . _custom_deps :
continue
parsed_url = urlparse . urlparse ( dep . url )
if parsed_url . netloc and parsed_url . netloc not in self . _allowed_hosts :
bad_deps . append ( dep )
if isinstance ( dep . url , basestring ) :
parsed_url = urlparse . urlparse ( dep . url )
if parsed_url . netloc and parsed_url . netloc not in self . _allowed_hosts :
bad_deps . append ( dep )
return bad_deps
def FuzzyMatchUrl ( self , candidates ) :
@ -837,6 +873,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
""" Runs |command| then parse the DEPS file. """
logging . info ( ' Dependency( %s ).run() ' % self . name )
assert self . _file_list == [ ]
if not self . should_process :
return
# When running runhooks, there's no need to consult the SCM.
# All known hooks are expected to run unconditionally regardless of working
# copy state, so skip the SCM status check.
@ -886,7 +924,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
self . RunPreDepsHooks ( )
# Parse the dependencies of this dependency.
for s in self . dependencies :
work_queue . enqueue ( s )
if s . should_process :
work_queue . enqueue ( s )
if command == ' recurse ' :
# Skip file only checkout.
@ -896,8 +935,10 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
# Pass in the SCM type as an env variable. Make sure we don't put
# unicode strings in the environment.
env = os . environ . copy ( )
env [ ' GCLIENT_SCM ' ] = str ( scm )
env [ ' GCLIENT_URL ' ] = str ( self . url )
if scm :
env [ ' GCLIENT_SCM ' ] = str ( scm )
if self . url :
env [ ' GCLIENT_URL ' ] = str ( self . url )
env [ ' GCLIENT_DEP_PATH ' ] = str ( self . name )
if options . prepend_dir and scm == ' git ' :
print_stdout = False
@ -928,7 +969,9 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
print_stdout = True
filter_fn = None
if os . path . isdir ( cwd ) :
if self . url is None :
print ( ' Skipped omitted dependency %s ' % cwd , file = sys . stderr )
elif os . path . isdir ( cwd ) :
try :
gclient_utils . CheckCallAndFilter (
args , cwd = cwd , env = env , print_stdout = print_stdout ,
@ -972,7 +1015,7 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
RunOnDeps ( ) must have been called before to load the DEPS .
"""
result = [ ]
if not self . recursion_limit:
if not self . should_process or not self . recursion_limit:
# Don't run the hook when it is above recursion_limit.
return result
# If "--force" was specified, run all hooks regardless of what files have
@ -1017,13 +1060,14 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
return None
return self . root . GetCipdRoot ( )
def subtree ( self ):
def subtree ( self , include_all ):
""" Breadth first recursion excluding root node. """
dependencies = self . dependencies
for d in dependencies :
yield d
if d . should_process or include_all :
yield d
for d in dependencies :
for i in d . subtree ( ) :
for i in d . subtree ( include_all ) :
yield i
@gclient_utils.lockedmethod
@ -1101,7 +1145,7 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
def __str__ ( self ) :
out = [ ]
for i in ( ' name ' , ' url ' , ' custom_deps ' ,
' custom_vars ' , ' deps_hooks ' , ' file_list ' ,
' custom_vars ' , ' deps_hooks ' , ' file_list ' , ' should_process ' ,
' processed ' , ' hooks_ran ' , ' deps_parsed ' , ' requirements ' ,
' allowed_hosts ' ) :
# First try the native property if it exists.
@ -1120,12 +1164,16 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
def __repr__ ( self ) :
return ' %s : %s ' % ( self . name , self . url )
def hierarchy ( self ):
def hierarchy ( self , include_url = True ):
""" Returns a human-readable hierarchical reference to a Dependency. """
out = self . name
def format_name ( d ) :
if include_url :
return ' %s ( %s ) ' % ( d . name , d . url )
return d . name
out = format_name ( self )
i = self . parent
while i and i . name :
out = ' %s -> %s ' % ( i . name , out )
out = ' %s -> %s ' % ( format_name( i ) , out )
i = i . parent
return out
@ -1245,8 +1293,8 @@ solutions = %(solution_list)s
# Do not change previous behavior. Only solution level and immediate DEPS
# are processed.
self . _recursion_limit = 2
GitDependency . __init__ ( self , None , None , ' ' , ' ' , True , None , None , None ,
' unused ' , None, None , True )
GitDependency . __init__ ( self , None , None , None , None , True , None , None , None ,
' unused ' , True, None, None , True )
self . _options = options
if options . deps_os :
enforced_os = options . deps_os . split ( ' , ' )
@ -1264,7 +1312,7 @@ solutions = %(solution_list)s
""" Verify that the config matches the state of the existing checked-out
solutions . """
for dep in self . dependencies :
if dep . managed :
if dep . managed and dep . url :
scm = dep . CreateSCM ( )
actual_url = scm . GetActualRemoteURL ( self . _options )
if actual_url and not scm . DoesRemoteURLMatch ( self . _options ) :
@ -1336,24 +1384,21 @@ it or fix the checkout.
deps_to_add = [ ]
for s in config_dict . get ( ' solutions ' , [ ] ) :
try :
if s [ ' url ' ] :
deps_to_add . append ( GitDependency (
self , s [ ' name ' ] , s [ ' url ' ] , s [ ' url ' ] ,
s . get ( ' managed' , True ) ,
s . get ( ' custom_ dep s' , { } ) ,
s . get ( ' custom_ vars' , { } ) ,
s . get ( ' custom_hooks' , [ ] ) ,
s . get ( ' deps_file ' , ' DEPS ' ) ,
None ,
None ,
True ) )
deps_to_add . append ( GitDependency (
self , s [ ' name ' ] , s [ ' url ' ] , s [ ' url ' ] ,
s . get ( ' managed ' , True ) ,
s . get ( ' custom_deps' , { } ) ,
s . get ( ' custom_ var s' , { } ) ,
s . get ( ' custom_ hooks' , [ ] ) ,
s . get ( ' deps_file' , ' DEPS ' ) ,
True ,
None ,
None ,
True ) )
except KeyError :
raise gclient_utils . Error ( ' Invalid .gclient file. Solution is '
' incomplete: %s ' % s )
self . add_dependencies_and_close ( deps_to_add , config_dict . get ( ' hooks ' , [ ] ) )
if not self . dependencies :
raise gclient_utils . Error ( ' No solution specified ' )
logging . info ( ' SetConfig() done ' )
def SaveConfig ( self ) :
@ -1413,7 +1458,7 @@ it or fix the checkout.
# Sometimes pprint.pformat will use {', sometimes it'll use { ' ... It
# makes testing a bit too fun.
result = ' entries = { \n '
for entry in self . root . subtree ( ) :
for entry in self . root . subtree ( False ) :
result + = ' %s : %s , \n ' % ( pprint . pformat ( entry . name ) ,
pprint . pformat ( entry . url ) )
result + = ' } \n '
@ -1481,6 +1526,9 @@ it or fix the checkout.
command : The command to use ( e . g . , ' status ' or ' diff ' )
args : list of str - extra arguments to add to the command line .
"""
if not self . dependencies :
raise gclient_utils . Error ( ' No solution specified ' )
revision_overrides = { }
patch_refs = { }
# It's unnecessary to check for revision overrides for 'recurse'.
@ -1505,7 +1553,8 @@ it or fix the checkout.
self . _options . jobs , pm , ignore_requirements = ignore_requirements ,
verbose = self . _options . verbose )
for s in self . dependencies :
work_queue . enqueue ( s )
if s . should_process :
work_queue . enqueue ( s )
work_queue . flush ( revision_overrides , command , args , options = self . _options ,
patch_refs = patch_refs )
@ -1542,7 +1591,7 @@ it or fix the checkout.
# Notify the user if there is an orphaned entry in their working copy.
# Only delete the directory if there are no changes in it, and
# delete_unversioned_trees is set to true.
entries = [ i . name for i in self . root . subtree ( ) ]
entries = [ i . name for i in self . root . subtree ( False ) if i . url ]
full_entries = [ os . path . join ( self . root_dir , e . replace ( ' / ' , os . path . sep ) )
for e in entries ]
@ -1639,59 +1688,68 @@ it or fix the checkout.
work_queue = gclient_utils . ExecutionQueue (
self . _options . jobs , None , False , verbose = self . _options . verbose )
for s in self . dependencies :
work_queue . enqueue ( s )
if s . should_process :
work_queue . enqueue ( s )
work_queue . flush ( { } , None , [ ] , options = self . _options , patch_refs = None )
def ShouldPrint ( dep ) :
def ShouldPrint Revision ( dep ) :
return ( not self . _options . filter
or dep . FuzzyMatchUrl ( self . _options . filter ) )
for dep in self . subtree ( ) :
if self . _options . snapshot or self . _options . actual :
dep . PinToActualRevision ( )
if self . _options . snapshot :
json_output = [
{
' name ' : d . name ,
' solution_url ' : d . url ,
' deps_file ' : d . deps_file ,
' managed ' : d . managed ,
' custom_deps ' : {
subdep . name : subdep . url
for subdep in d . subtree ( )
if ShouldPrint ( subdep )
} ,
}
for d in self . dependencies
if ShouldPrint ( d )
]
output = json . dumps ( json_output , indent = 2 , separators = ( ' , ' , ' : ' ) )
if not self . _options . output_json :
output = self . DEFAULT_SNAPSHOT_FILE_TEXT % { ' solution_list ' : output }
elif self . _options . output_json :
json_output = {
d . name : {
' url ' : d . url . split ( ' @ ' ) [ 0 ] ,
' rev ' : d . url . split ( ' @ ' ) [ 1 ] if ' @ ' in d . url else None ,
}
for d in self . subtree ( )
if ShouldPrint ( d )
}
output = json . dumps ( json_output , indent = 2 , separators = ( ' , ' , ' : ' ) )
else :
output = ' \n ' . join (
' %s : %s ' % ( d . name , d . url )
for d in self . subtree ( )
if ShouldPrint ( d )
)
if self . _options . output_json and self . _options . output_json != ' - ' :
with open ( self . _options . output_json , ' w ' ) as f :
f . write ( output )
json_output = [ ]
# First level at .gclient
for d in self . dependencies :
entries = { }
def GrabDeps ( dep ) :
""" Recursively grab dependencies. """
for d in dep . dependencies :
d . PinToActualRevision ( )
if ShouldPrintRevision ( d ) :
entries [ d . name ] = d . url
GrabDeps ( d )
GrabDeps ( d )
json_output . append ( {
' name ' : d . name ,
' solution_url ' : d . url ,
' deps_file ' : d . deps_file ,
' managed ' : d . managed ,
' custom_deps ' : entries ,
} )
if self . _options . output_json == ' - ' :
print ( json . dumps ( json_output , indent = 2 , separators = ( ' , ' , ' : ' ) ) )
elif self . _options . output_json :
with open ( self . _options . output_json , ' w ' ) as f :
json . dump ( json_output , f )
else :
# Print the snapshot configuration file
print ( self . DEFAULT_SNAPSHOT_FILE_TEXT % {
' solution_list ' : pprint . pformat ( json_output , indent = 2 ) ,
} )
else :
print ( output )
entries = { }
for d in self . root . subtree ( False ) :
if self . _options . actual :
d . PinToActualRevision ( )
if ShouldPrintRevision ( d ) :
entries [ d . name ] = d . url
if self . _options . output_json :
json_output = {
name : {
' url ' : rev . split ( ' @ ' ) [ 0 ] if rev else None ,
' rev ' : rev . split ( ' @ ' ) [ 1 ] if rev and ' @ ' in rev else None ,
}
for name , rev in entries . iteritems ( )
}
if self . _options . output_json == ' - ' :
print ( json . dumps ( json_output , indent = 2 , separators = ( ' , ' , ' : ' ) ) )
else :
with open ( self . _options . output_json , ' w ' ) as f :
json . dump ( json_output , f )
else :
keys = sorted ( entries . keys ( ) )
for x in keys :
print ( ' %s : %s ' % ( x , entries [ x ] ) )
logging . info ( str ( self ) )
def ParseDepsFile ( self , expand_vars = None ) :
@ -1749,14 +1807,14 @@ class CipdDependency(Dependency):
def __init__ (
self , parent , name , dep_value , cipd_root ,
custom_vars , relative, condition ) :
custom_vars , should_process, relative, condition ) :
package = dep_value [ ' package ' ]
version = dep_value [ ' version ' ]
url = urlparse . urljoin (
cipd_root . service_url , ' %s @ %s ' % ( package , version ) )
super ( CipdDependency , self ) . __init__ (
parent , name + ' : ' + package , url , url , None , None , custom_vars ,
None , None , relative, condition )
None , None , should_process, relative, condition )
if relative :
# TODO(jbudorick): Implement relative if necessary.
raise gclient_utils . Error (
@ -1773,6 +1831,8 @@ class CipdDependency(Dependency):
patch_refs ) :
""" Runs |command| then parse the DEPS file. """
logging . info ( ' CipdDependency( %s ).run() ' % self . name )
if not self . should_process :
return
self . _CreatePackageIfNecessary ( )
super ( CipdDependency , self ) . run ( revision_overrides , command , args ,
work_queue , options , patch_refs )
@ -1816,7 +1876,7 @@ class CipdDependency(Dependency):
condition_part = ( [ ' " condition " : %r , ' % self . condition ]
if self . condition else [ ] )
s . extend ( [
' # %s ' % self . hierarchy ( ) ,
' # %s ' % self . hierarchy ( include_url = False ) ,
' " %s " : { ' % ( self . name . split ( ' : ' ) [ 0 ] , ) ,
' " packages " : [ ' ,
] )
@ -1935,6 +1995,9 @@ class Flattener(object):
Arguments :
dep ( Dependency ) : dependency to process
"""
if dep . url is None :
return
# Make sure the revision is always fully specified (a hash),
# as opposed to refs or tags which might change. Similarly,
# shortened shas might become ambiguous; make sure to always
@ -1972,6 +2035,7 @@ class Flattener(object):
deps_path = os . path . join ( self . _client . root_dir , dep . name , deps_file )
if not os . path . exists ( deps_path ) :
return
assert dep . url
self . _deps_files . add ( ( dep . url , deps_file , dep . hierarchy_data ( ) ) )
for dep in self . _deps . itervalues ( ) :
add_deps_file ( dep )
@ -1997,7 +2061,8 @@ class Flattener(object):
"""
assert dep . name not in self . _deps or self . _deps . get ( dep . name ) == dep , (
dep . name , self . _deps . get ( dep . name ) )
self . _deps [ dep . name ] = dep
if dep . url :
self . _deps [ dep . name ] = dep
def _flatten_dep ( self , dep ) :
""" Visits a dependency in order to flatten it (see CMDflatten).
@ -2014,7 +2079,7 @@ class Flattener(object):
# Only include vars explicitly listed in the DEPS files or gclient solution,
# not automatic, local overrides (i.e. not all of dep.get_vars()).
hierarchy = dep . hierarchy ( )
hierarchy = dep . hierarchy ( include_url = False )
for key , value in dep . _vars . iteritems ( ) :
# Make sure there are no conflicting variables. It is fine however
# to use same variable name, as long as the value is consistent.
@ -2128,7 +2193,7 @@ def _DepsOsToLines(deps_os):
condition_part = ( [ ' " condition " : %r , ' % dep . condition ]
if dep . condition else [ ] )
s . extend ( [
' # %s ' % dep . hierarchy ( ) ,
' # %s ' % dep . hierarchy ( include_url = False ) ,
' " %s " : { ' % ( name , ) ,
' " url " : " %s " , ' % ( dep . raw_url , ) ,
] + condition_part + [
@ -2147,7 +2212,7 @@ def _HooksToLines(name, hooks):
s = [ ' %s = [ ' % name ]
for dep , hook in hooks :
s . extend ( [
' # %s ' % dep . hierarchy ( ) ,
' # %s ' % dep . hierarchy ( include_url = False ) ,
' { ' ,
] )
if hook . name is not None :
@ -2176,7 +2241,7 @@ def _HooksOsToLines(hooks_os):
s . append ( ' " %s " : [ ' % hook_os )
for dep , hook in os_hooks :
s . extend ( [
' # %s ' % dep . hierarchy ( ) ,
' # %s ' % dep . hierarchy ( include_url = False ) ,
' { ' ,
] )
if hook . name is not None :
@ -2508,12 +2573,16 @@ def CMDsync(parser, args):
ret = client . RunOnDeps ( ' update ' , args )
if options . output_json :
slns = { }
for d in client . subtree ( ) :
for d in client . subtree ( True ) :
normed = d . name . replace ( ' \\ ' , ' / ' ) . rstrip ( ' / ' ) + ' / '
if normed in slns and not d . should_process :
# If an unprocessed dependency would override an existing dependency,
# ignore it.
continue
slns [ normed ] = {
' revision ' : d . got_revision ,
' scm ' : d . used_scm . name if d . used_scm else None ,
' url ' : str ( d . url ) ,
' url ' : str ( d . url ) if d . url else None ,
}
with open ( options . output_json , ' wb ' ) as f :
json . dump ( { ' solutions ' : slns } , f )