@ -19,6 +19,14 @@ else:
from io import StringIO
# TODO(crbug.com/953884): Remove this when python3 migration is done.
try :
basestring
except NameError :
# pylint: disable=redefined-builtin
basestring = str
class _NodeDict ( collections . MutableMapping ) :
""" Dict-like type that also stores information on AST nodes and tokens. """
def __init__ ( self , data , tokens = None ) :
@ -78,35 +86,30 @@ def _NodeDictSchema(dict_schema):
# See https://github.com/keleshev/schema for docs how to configure schema.
_GCLIENT_DEPS_SCHEMA = _NodeDictSchema ( {
schema . Optional ( str ) :
schema . Optional ( basestring ) :
schema . Or (
None ,
str ,
basestring ,
_NodeDictSchema ( {
# Repo and revision to check out under the path
# (same as if no dict was used).
' url ' :
schema . Or ( None , str ) ,
' url ' : schema . Or ( None , basestring ) ,
# Optional condition string. The dep will only be processed
# if the condition evaluates to True.
schema . Optional ( ' condition ' ) :
str ,
schema . Optional ( ' dep_type ' , default = ' git ' ) :
str ,
schema . Optional ( ' condition ' ) : basestring ,
schema . Optional ( ' dep_type ' , default = ' git ' ) : basestring ,
} ) ,
# CIPD package.
_NodeDictSchema ( {
' packages ' : [
_NodeDictSchema ( {
' package ' : str ,
' version ' : str ,
' package ' : basestring ,
' version ' : basestring ,
} )
] ,
schema . Optional ( ' condition ' ) :
str ,
schema . Optional ( ' dep_type ' , default = ' cipd ' ) :
str ,
schema . Optional ( ' condition ' ) : basestring ,
schema . Optional ( ' dep_type ' , default = ' cipd ' ) : basestring ,
} ) ,
) ,
} )
@ -114,26 +117,22 @@ _GCLIENT_DEPS_SCHEMA = _NodeDictSchema({
_GCLIENT_HOOKS_SCHEMA = [
_NodeDictSchema ( {
# Hook action: list of command-line arguments to invoke.
' action ' : [ str ] ,
' action ' : [ basestring ] ,
# Name of the hook. Doesn't affect operation.
schema . Optional ( ' name ' ) :
str ,
schema . Optional ( ' name ' ) : basestring ,
# Hook pattern (regex). Originally intended to limit some hooks to run
# only when files matching the pattern have changed. In practice, with
# git, gclient runs all the hooks regardless of this field.
schema . Optional ( ' pattern ' ) :
str ,
schema . Optional ( ' pattern ' ) : basestring ,
# Working directory where to execute the hook.
schema . Optional ( ' cwd ' ) :
str ,
schema . Optional ( ' cwd ' ) : basestring ,
# Optional condition string. The hook will only be run
# if the condition evaluates to True.
schema . Optional ( ' condition ' ) :
str ,
schema . Optional ( ' condition ' ) : basestring ,
} )
]
@ -142,7 +141,7 @@ _GCLIENT_SCHEMA = schema.Schema(
# List of host names from which dependencies are allowed (whitelist).
# NOTE: when not present, all hosts are allowed.
# NOTE: scoped to current DEPS file, not recursive.
schema . Optional ( ' allowed_hosts ' ) : [ schema . Optional ( str ) ] ,
schema . Optional ( ' allowed_hosts ' ) : [ schema . Optional ( basestring ) ] ,
# Mapping from paths to repo and revision to check out under that path.
# Applying this mapping to the on-disk checkout is the main purpose
@ -152,95 +151,87 @@ _GCLIENT_SCHEMA = schema.Schema(
#
# Var(): allows variable substitution (either from 'vars' dict below,
# or command-line override)
schema . Optional ( ' deps ' ) :
_GCLIENT_DEPS_SCHEMA ,
schema . Optional ( ' deps ' ) : _GCLIENT_DEPS_SCHEMA ,
# Similar to 'deps' (see above) - also keyed by OS (e.g. 'linux').
# Also see 'target_os'.
schema . Optional ( ' deps_os ' ) :
_NodeDictSchema ( {
schema . Optional ( str ) : _GCLIENT_DEPS_SCHEMA ,
} ) ,
schema . Optional ( ' deps_os ' ) : _NodeDictSchema ( {
schema . Optional ( basestring ) : _GCLIENT_DEPS_SCHEMA ,
} ) ,
# Dependency to get gclient_gn_args* settings from. This allows these
# values to be set in a recursedeps file, rather than requiring that
# they exist in the top-level solution.
schema . Optional ( ' gclient_gn_args_from ' ) :
str ,
schema . Optional ( ' gclient_gn_args_from ' ) : basestring ,
# Path to GN args file to write selected variables.
schema . Optional ( ' gclient_gn_args_file ' ) :
str ,
schema . Optional ( ' gclient_gn_args_file ' ) : basestring ,
# Subset of variables to write to the GN args file (see above).
schema . Optional ( ' gclient_gn_args ' ) : [ schema . Optional ( str ) ] ,
schema . Optional ( ' gclient_gn_args ' ) : [ schema . Optional ( basestring ) ] ,
# Hooks executed after gclient sync (unless suppressed), or explicitly
# on gclient hooks. See _GCLIENT_HOOKS_SCHEMA for details.
# Also see 'pre_deps_hooks'.
schema . Optional ( ' hooks ' ) :
_GCLIENT_HOOKS_SCHEMA ,
schema . Optional ( ' hooks ' ) : _GCLIENT_HOOKS_SCHEMA ,
# Similar to 'hooks', also keyed by OS.
schema . Optional ( ' hooks_os ' ) :
_NodeDictSchema ( {
schema . Optional ( str ) : _GCLIENT_HOOKS_SCHEMA
} ) ,
schema . Optional ( ' hooks_os ' ) : _NodeDictSchema ( {
schema . Optional ( basestring ) : _GCLIENT_HOOKS_SCHEMA
} ) ,
# Rules which #includes are allowed in the directory.
# Also see 'skip_child_includes' and 'specific_include_rules'.
schema . Optional ( ' include_rules ' ) : [ schema . Optional ( str ) ] ,
schema . Optional ( ' include_rules ' ) : [ schema . Optional ( basestring ) ] ,
# Hooks executed before processing DEPS. See 'hooks' for more details.
schema . Optional ( ' pre_deps_hooks ' ) :
_GCLIENT_HOOKS_SCHEMA ,
schema . Optional ( ' pre_deps_hooks ' ) : _GCLIENT_HOOKS_SCHEMA ,
# Recursion limit for nested DEPS.
schema . Optional ( ' recursion ' ) :
int ,
schema . Optional ( ' recursion ' ) : int ,
# Whitelists deps for which recursion should be enabled.
schema . Optional ( ' recursedeps ' ) : [
schema . Optional ( schema . Or ( str , ( str , str ) , [ str , str ] ) ) ,
schema . Optional ( schema . Or (
basestring ,
( basestring , basestring ) ,
[ basestring , basestring ]
) ) ,
] ,
# Blacklists directories for checking 'include_rules'.
schema . Optional ( ' skip_child_includes ' ) : [ schema . Optional ( str ) ] ,
schema . Optional ( ' skip_child_includes ' ) : [ schema . Optional ( basestring ) ] ,
# Mapping from paths to include rules specific for that path.
# See 'include_rules' for more details.
schema . Optional ( ' specific_include_rules ' ) :
_NodeDictSchema ( {
schema . Optional ( str ) : [ str ]
} ) ,
schema . Optional ( ' specific_include_rules ' ) : _NodeDictSchema ( {
schema . Optional ( basestring ) : [ basestring ]
} ) ,
# List of additional OS names to consider when selecting dependencies
# from deps_os.
schema . Optional ( ' target_os ' ) : [ schema . Optional ( str ) ] ,
schema . Optional ( ' target_os ' ) : [ schema . Optional ( basestring ) ] ,
# For recursed-upon sub-dependencies, check out their own dependencies
# relative to the parent's path, rather than relative to the .gclient
# file.
schema . Optional ( ' use_relative_paths ' ) :
bool ,
schema . Optional ( ' use_relative_paths ' ) : bool ,
# For recursed-upon sub-dependencies, run their hooks relative to the
# parent's path instead of relative to the .gclient file.
schema . Optional ( ' use_relative_hooks ' ) :
bool ,
schema . Optional ( ' use_relative_hooks ' ) : bool ,
# Variables that can be referenced using Var() - see 'deps'.
schema . Optional ( ' vars ' ) :
_NodeDictSchema ( {
schema . Optional ( str ) : schema . Or ( str , bool ) ,
} ) ,
schema . Optional ( ' vars ' ) : _NodeDictSchema ( {
schema . Optional ( basestring ) : schema . Or ( basestring , bool ) ,
} ) ,
} ) )
def _gclient_eval ( node_or_string , filename = ' <unknown> ' , vars_dict = None ) :
""" Safely evaluates a single expression. Returns the result. """
_allowed_names = { ' None ' : None , ' True ' : True , ' False ' : False }
if isinstance ( node_or_string , str ) :
if isinstance ( node_or_string , basestring ) :
node_or_string = ast . parse ( node_or_string , filename = filename , mode = ' eval ' )
if isinstance ( node_or_string , ast . Expression ) :
node_or_string = node_or_string . body
@ -284,7 +275,7 @@ def _gclient_eval(node_or_string, filename='<unknown>', vars_dict=None):
' Var takes exactly one argument (file %r , line %s ) ' % (
filename , getattr ( node , ' lineno ' , ' <unknown> ' ) ) )
arg = _convert ( node . args [ 0 ] )
if not isinstance ( arg , str ) :
if not isinstance ( arg , basestring ) :
raise ValueError (
' Var \' s argument must be a variable name (file %r , line %s ) ' % (
filename , getattr ( node , ' lineno ' , ' <unknown> ' ) ) )
@ -410,7 +401,7 @@ def ExecLegacy(content, filename='<unknown>', vars_override=None,
return local_scope
def _DeepFormat ( node ) :
if isinstance ( node , str ) :
if isinstance ( node , basestring ) :
return node . format ( * * vars_dict )
elif isinstance ( node , dict ) :
return { k . format ( * * vars_dict ) : _DeepFormat ( v ) for k , v in node . items ( ) }
@ -562,7 +553,7 @@ def EvaluateCondition(condition, variables, referenced_variables=None):
# Allow using "native" types, without wrapping everything in strings.
# Note that schema constraints still apply to variables.
if not isinstance ( value , str ) :
if not isinstance ( value , basestring ) :
return value
# Recursively evaluate the variable reference.